Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add Array#sql_array to handle ruby arrays of all two pairs as SQL arr…
…ays (Fixes #245)

Previously, this wasn't possible, as ruby arrays of all two pairs
were interpreted as conditions (sort of like an ordered hash).

This allows you to do things like:

  DB[:foo].filter([:a,:b] => [[1,2],[3,4]].sql_array)
  # => SELECT * FROM foo WHERE ((a, b) IN ((1, 2), (3, 4)))
  • Loading branch information
jeremyevans committed Oct 27, 2008
1 parent ffafaaa commit f0bf091
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG
@@ -1,5 +1,7 @@
=== HEAD

* Add Array#sql_array to handle ruby arrays of all two pairs as SQL arrays (jeremyevans) (#245)

* Add ComplexExpression#== and #eql?, for checking equality (rubymage) (#244)

* Allow full text search on PostgreSQL to include rows where a search column is NULL (jeremyevans)
Expand Down
7 changes: 7 additions & 0 deletions lib/sequel_core/core_sql.rb
Expand Up @@ -11,6 +11,13 @@ def case(default, expression = nil)
::Sequel::SQL::CaseExpression.new(self, default, expression)
end

# Return a Sequel::SQL::Array created from this array. Used if this array contains
# all two pairs and you want it treated as an SQL array instead of a ordered hash-like
# conditions.
def sql_array
::Sequel::SQL::SQLArray.new(self)
end

# Return a Sequel::SQL::BooleanExpression created from this array, matching all of the
# conditions.
def sql_expr
Expand Down
7 changes: 6 additions & 1 deletion lib/sequel_core/dataset/sql.rb
Expand Up @@ -29,6 +29,11 @@ def aliased_expression_sql(ae)
as_sql(literal(ae.expression), ae.aliaz)
end

# SQL fragment for the SQL array.
def array_sql(a)
a.empty? ? '(NULL)' : "(#{expression_list(a)})"
end

# SQL fragment for specifying given CaseExpression.
def case_expression_sql(ce)
sql = '(CASE '
Expand Down Expand Up @@ -470,7 +475,7 @@ def literal(v)
when ::Sequel::SQL::Expression
v.to_s(self)
when Array
v.all_two_pairs? ? literal(v.sql_expr) : (v.empty? ? '(NULL)' : "(#{expression_list(v)})")
v.all_two_pairs? ? literal(v.sql_expr) : array_sql(v)
when Hash
literal(v.sql_expr)
when Time, DateTime
Expand Down
16 changes: 16 additions & 0 deletions lib/sequel_core/sql.rb
Expand Up @@ -407,6 +407,22 @@ def to_s(ds)
end
end

# Represents an SQL array. Added so it is possible to deal with a
# ruby array of all two pairs as an SQL array instead of an ordered
# hash-like conditions specifier.
class SQLArray < Expression
# Create an object with the given array.
def initialize(array)
@array = array
end

# Delegate the creation of the resulting SQL to the given dataset,
# since it may be database dependent.
def to_s(ds)
ds.array_sql(@array)
end
end

# Blob is used to represent binary data in the Ruby environment that is
# stored as a blob type in the database. In PostgreSQL, the blob type is
# called bytea. Sequel represents binary data as a Blob object because
Expand Down
11 changes: 11 additions & 0 deletions spec/sequel_core/core_sql_spec.rb
Expand Up @@ -51,6 +51,17 @@
end
end

context "Array#sql_array" do
setup do
@d = Sequel::Dataset.new(nil)
end

specify "should treat the array as an SQL array instead of conditions" do
@d.literal([[:x, 1], [:y, 2]]).should == '((x = 1) AND (y = 2))'
@d.literal([[:x, 1], [:y, 2]].sql_array).should == '((x, 1), (y, 2))'
end
end

context "Array#to_sql" do
specify "should concatenate multiple lines into a single string" do
"SELECT * \r\nFROM items\r\n WHERE a = 1".split.to_sql. \
Expand Down

0 comments on commit f0bf091

Please sign in to comment.