sequel 3.37.0 → 3.38.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/CHANGELOG +56 -0
  2. data/README.rdoc +82 -58
  3. data/Rakefile +6 -5
  4. data/bin/sequel +1 -1
  5. data/doc/active_record.rdoc +67 -52
  6. data/doc/advanced_associations.rdoc +33 -48
  7. data/doc/association_basics.rdoc +41 -51
  8. data/doc/cheat_sheet.rdoc +21 -21
  9. data/doc/core_extensions.rdoc +374 -0
  10. data/doc/dataset_basics.rdoc +5 -5
  11. data/doc/dataset_filtering.rdoc +47 -43
  12. data/doc/mass_assignment.rdoc +1 -1
  13. data/doc/migration.rdoc +4 -5
  14. data/doc/model_hooks.rdoc +3 -3
  15. data/doc/object_model.rdoc +31 -25
  16. data/doc/opening_databases.rdoc +19 -5
  17. data/doc/prepared_statements.rdoc +2 -2
  18. data/doc/querying.rdoc +109 -52
  19. data/doc/reflection.rdoc +6 -6
  20. data/doc/release_notes/3.38.0.txt +234 -0
  21. data/doc/schema_modification.rdoc +22 -13
  22. data/doc/sharding.rdoc +8 -9
  23. data/doc/sql.rdoc +154 -112
  24. data/doc/testing.rdoc +47 -7
  25. data/doc/thread_safety.rdoc +1 -1
  26. data/doc/transactions.rdoc +1 -1
  27. data/doc/validations.rdoc +1 -1
  28. data/doc/virtual_rows.rdoc +29 -43
  29. data/lib/sequel/adapters/do/postgres.rb +1 -4
  30. data/lib/sequel/adapters/jdbc.rb +14 -3
  31. data/lib/sequel/adapters/jdbc/db2.rb +9 -0
  32. data/lib/sequel/adapters/jdbc/derby.rb +41 -4
  33. data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
  35. data/lib/sequel/adapters/mock.rb +10 -4
  36. data/lib/sequel/adapters/postgres.rb +1 -28
  37. data/lib/sequel/adapters/shared/mssql.rb +23 -13
  38. data/lib/sequel/adapters/shared/postgres.rb +46 -0
  39. data/lib/sequel/adapters/swift.rb +21 -13
  40. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  41. data/lib/sequel/adapters/swift/postgres.rb +4 -5
  42. data/lib/sequel/adapters/swift/sqlite.rb +2 -1
  43. data/lib/sequel/adapters/tinytds.rb +14 -2
  44. data/lib/sequel/adapters/utils/pg_types.rb +5 -0
  45. data/lib/sequel/core.rb +29 -17
  46. data/lib/sequel/database/query.rb +1 -1
  47. data/lib/sequel/database/schema_generator.rb +3 -0
  48. data/lib/sequel/dataset/actions.rb +5 -6
  49. data/lib/sequel/dataset/query.rb +7 -7
  50. data/lib/sequel/dataset/sql.rb +5 -18
  51. data/lib/sequel/extensions/core_extensions.rb +8 -12
  52. data/lib/sequel/extensions/pg_array.rb +59 -33
  53. data/lib/sequel/extensions/pg_array_ops.rb +32 -4
  54. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
  55. data/lib/sequel/extensions/pg_hstore.rb +32 -17
  56. data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
  57. data/lib/sequel/extensions/pg_inet.rb +1 -2
  58. data/lib/sequel/extensions/pg_interval.rb +0 -1
  59. data/lib/sequel/extensions/pg_json.rb +41 -23
  60. data/lib/sequel/extensions/pg_range.rb +36 -11
  61. data/lib/sequel/extensions/pg_range_ops.rb +32 -4
  62. data/lib/sequel/extensions/pg_row.rb +572 -0
  63. data/lib/sequel/extensions/pg_row_ops.rb +164 -0
  64. data/lib/sequel/extensions/query.rb +3 -3
  65. data/lib/sequel/extensions/schema_dumper.rb +7 -8
  66. data/lib/sequel/extensions/select_remove.rb +1 -1
  67. data/lib/sequel/model/base.rb +1 -0
  68. data/lib/sequel/no_core_ext.rb +1 -1
  69. data/lib/sequel/plugins/pg_row.rb +121 -0
  70. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  71. data/lib/sequel/plugins/validation_helpers.rb +31 -0
  72. data/lib/sequel/sql.rb +64 -44
  73. data/lib/sequel/version.rb +1 -1
  74. data/spec/adapters/mssql_spec.rb +37 -12
  75. data/spec/adapters/mysql_spec.rb +39 -75
  76. data/spec/adapters/oracle_spec.rb +11 -11
  77. data/spec/adapters/postgres_spec.rb +414 -237
  78. data/spec/adapters/spec_helper.rb +1 -1
  79. data/spec/adapters/sqlite_spec.rb +14 -14
  80. data/spec/core/database_spec.rb +6 -6
  81. data/spec/core/dataset_spec.rb +169 -205
  82. data/spec/core/expression_filters_spec.rb +182 -295
  83. data/spec/core/object_graph_spec.rb +6 -6
  84. data/spec/core/schema_spec.rb +14 -14
  85. data/spec/core/spec_helper.rb +1 -0
  86. data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
  87. data/spec/extensions/columns_introspection_spec.rb +5 -5
  88. data/spec/extensions/hook_class_methods_spec.rb +28 -36
  89. data/spec/extensions/many_through_many_spec.rb +4 -4
  90. data/spec/extensions/pg_array_ops_spec.rb +15 -7
  91. data/spec/extensions/pg_array_spec.rb +81 -48
  92. data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
  93. data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
  94. data/spec/extensions/pg_hstore_spec.rb +66 -65
  95. data/spec/extensions/pg_inet_spec.rb +2 -4
  96. data/spec/extensions/pg_interval_spec.rb +2 -3
  97. data/spec/extensions/pg_json_spec.rb +20 -18
  98. data/spec/extensions/pg_range_ops_spec.rb +11 -4
  99. data/spec/extensions/pg_range_spec.rb +30 -7
  100. data/spec/extensions/pg_row_ops_spec.rb +48 -0
  101. data/spec/extensions/pg_row_plugin_spec.rb +45 -0
  102. data/spec/extensions/pg_row_spec.rb +323 -0
  103. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  104. data/spec/extensions/query_literals_spec.rb +11 -11
  105. data/spec/extensions/query_spec.rb +3 -3
  106. data/spec/extensions/schema_dumper_spec.rb +20 -4
  107. data/spec/extensions/schema_spec.rb +18 -41
  108. data/spec/extensions/select_remove_spec.rb +4 -4
  109. data/spec/extensions/spec_helper.rb +4 -8
  110. data/spec/extensions/to_dot_spec.rb +5 -5
  111. data/spec/extensions/validation_class_methods_spec.rb +28 -16
  112. data/spec/integration/associations_test.rb +20 -20
  113. data/spec/integration/dataset_test.rb +98 -98
  114. data/spec/integration/eager_loader_test.rb +13 -27
  115. data/spec/integration/plugin_test.rb +5 -5
  116. data/spec/integration/prepared_statement_test.rb +22 -13
  117. data/spec/integration/schema_test.rb +28 -18
  118. data/spec/integration/spec_helper.rb +1 -1
  119. data/spec/integration/timezone_test.rb +2 -2
  120. data/spec/integration/type_test.rb +15 -6
  121. data/spec/model/association_reflection_spec.rb +1 -1
  122. data/spec/model/associations_spec.rb +4 -4
  123. data/spec/model/base_spec.rb +5 -5
  124. data/spec/model/eager_loading_spec.rb +15 -15
  125. data/spec/model/model_spec.rb +32 -32
  126. data/spec/model/record_spec.rb +16 -0
  127. data/spec/model/spec_helper.rb +2 -6
  128. data/spec/model/validations_spec.rb +1 -1
  129. metadata +16 -4
data/lib/sequel/sql.rb CHANGED
@@ -217,7 +217,7 @@ module Sequel
217
217
  module AliasMethods
218
218
  # Create an SQL alias (+AliasedExpression+) of the receiving column or expression to the given alias.
219
219
  #
220
- # :column.as(:alias) # "column" AS "alias"
220
+ # Sequel.function(:func).as(:alias) # func() AS "alias"
221
221
  def as(aliaz)
222
222
  AliasedExpression.new(self, aliaz)
223
223
  end
@@ -389,6 +389,20 @@ module Sequel
389
389
  end
390
390
 
391
391
  case arg
392
+ when Symbol
393
+ t, c, a = Sequel.split_symbol(arg)
394
+
395
+ arg = if t
396
+ SQL::QualifiedIdentifier.new(t, c)
397
+ else
398
+ SQL::Identifier.new(c)
399
+ end
400
+
401
+ if a
402
+ arg = SQL::AliasedExpression.new(arg, a)
403
+ end
404
+
405
+ arg
392
406
  when SQL::Expression, LiteralString, SQL::Blob
393
407
  arg
394
408
  when Hash
@@ -573,8 +587,8 @@ module Sequel
573
587
  # Cast the reciever to the given SQL type. You can specify a ruby class as a type,
574
588
  # and it is handled similarly to using a database independent type in the schema methods.
575
589
  #
576
- # :a.cast(:integer) # CAST(a AS integer)
577
- # :a.cast(String) # CAST(a AS varchar(255))
590
+ # Sequel.function(:func).cast(:integer) # CAST(func() AS integer)
591
+ # Sequel.function(:func).cast(String) # CAST(func() AS varchar(255))
578
592
  def cast(sql_type)
579
593
  Cast.new(self, sql_type)
580
594
  end
@@ -583,8 +597,8 @@ module Sequel
583
597
  # and return the result as a +NumericExpression+, so you can use the bitwise operators
584
598
  # on the result.
585
599
  #
586
- # :a.cast_numeric # CAST(a AS integer)
587
- # :a.cast_numeric(Float) # CAST(a AS double precision)
600
+ # Sequel.function(:func).cast_numeric # CAST(func() AS integer)
601
+ # Sequel.function(:func).cast_numeric(Float) # CAST(func() AS double precision)
588
602
  def cast_numeric(sql_type = nil)
589
603
  cast(sql_type || Integer).sql_number
590
604
  end
@@ -593,13 +607,13 @@ module Sequel
593
607
  # and return the result as a +StringExpression+, so you can use +
594
608
  # directly on the result for SQL string concatenation.
595
609
  #
596
- # :a.cast_string # CAST(a AS varchar(255))
597
- # :a.cast_string(:text) # CAST(a AS text)
610
+ # Sequel.function(:func).cast_string # CAST(func() AS varchar(255))
611
+ # Sequel.function(:func).cast_string(:text) # CAST(func() AS text)
598
612
  def cast_string(sql_type = nil)
599
613
  cast(sql_type || String).sql_string
600
614
  end
601
615
  end
602
-
616
+
603
617
  # Adds methods that allow you to treat an object as an instance of a specific
604
618
  # +ComplexExpression+ subclass. This is useful if another library
605
619
  # overrides the methods defined by Sequel.
@@ -614,7 +628,7 @@ module Sequel
614
628
  #
615
629
  # :price.sql_number/10 > 100
616
630
  module ComplexExpressionMethods
617
- # Extract a datetime_part (e.g. year, month) from self:
631
+ # Extract a datetime part (e.g. year, month) from self:
618
632
  #
619
633
  # :date.extract(:year) # extract(year FROM "date")
620
634
  #
@@ -646,25 +660,13 @@ module Sequel
646
660
  end
647
661
  end
648
662
 
649
- # Includes an +identifier+ method that returns <tt>Identifier</tt>s.
650
- module IdentifierMethods
651
- # Return self wrapped as an <tt>SQL::Identifier</tt>.
652
- #
653
- # :a__b # "a"."b"
654
- # :a__b.identifier # "a__b"
655
- def identifier
656
- Identifier.new(self)
657
- end
658
- end
659
-
660
663
  # This module includes the inequality methods (>, <, >=, <=) that are defined on objects that can be
661
- # used in a numeric or string context in SQL (+Symbol+ (except on ruby 1.9), +LiteralString+,
662
- # <tt>SQL::GenericExpression</tt>).
664
+ # used in a numeric or string context in SQL.
663
665
  #
664
- # 'a'.lit > :b # a > "b"
665
- # 'a'.lit < :b # a > "b"
666
- # 'a'.lit >= :b # a >= "b"
667
- # 'a'.lit <= :b # a <= "b"
666
+ # Sequel.lit('a') > :b # a > "b"
667
+ # Sequel.lit('a') < :b # a > "b"
668
+ # Sequel.lit('a') >= :b # a >= "b"
669
+ # Sequel.lit('a') <= :b # a <= "b"
668
670
  module InequalityMethods
669
671
  ComplexExpression::INEQUALITY_OPERATORS.each do |o|
670
672
  module_eval("def #{o}(o) BooleanExpression.new(#{o.inspect}, self, o) end", __FILE__, __LINE__)
@@ -772,13 +774,25 @@ module Sequel
772
774
  end
773
775
 
774
776
  # Includes a +qualify+ method that created <tt>QualifiedIdentifier</tt>s, used for qualifying column
775
- # names with a table or table names with a schema.
777
+ # names with a table or table names with a schema, and the * method for returning all columns in
778
+ # the identifier if no arguments are given.
776
779
  module QualifyingMethods
780
+ # If no arguments are given, return an SQL::ColumnAll:
781
+ #
782
+ # Sequel.expr(:a__b).* # a.b.*
783
+ def *(ce=(arg=false;nil))
784
+ if arg == false
785
+ Sequel::SQL::ColumnAll.new(self)
786
+ else
787
+ super(ce)
788
+ end
789
+ end
790
+
777
791
  # Qualify the receiver with the given +qualifier+ (table for column/schema for table).
778
792
  #
779
- # :column.qualify(:table) # "table"."column"
780
- # :table.qualify(:schema) # "schema"."table"
781
- # :column.qualify(:table).qualify(:schema) # "schema"."table"."column"
793
+ # Sequel.expr(:column).qualify(:table) # "table"."column"
794
+ # Sequel.expr(:table).qualify(:schema) # "schema"."table"
795
+ # Sequel.qualify(:table, :column).qualify(:schema) # "schema"."table"."column"
782
796
  def qualify(qualifier)
783
797
  QualifiedIdentifier.new(qualifier, self)
784
798
  end
@@ -852,8 +866,16 @@ module Sequel
852
866
  # stored as a blob type in the database. Sequel represents binary data as a Blob object because
853
867
  # most database engines require binary data to be escaped differently than regular strings.
854
868
  class Blob < ::String
855
- # Returns +self+, used so that Blobs don't get wrapped in multiple
856
- # levels.
869
+ include SQL::AliasMethods
870
+ include SQL::CastMethods
871
+
872
+ # Return a LiteralString with the same content if no args are given, otherwise
873
+ # return a SQL::PlaceholderLiteralString with the current string and the given args.
874
+ def lit(*args)
875
+ args.empty? ? LiteralString.new(self) : SQL::PlaceholderLiteralString.new(self, args)
876
+ end
877
+
878
+ # Returns +self+, since it is already a blob.
857
879
  def to_sequel_blob
858
880
  self
859
881
  end
@@ -1570,20 +1592,18 @@ module Sequel
1570
1592
  include SQL::NumericMethods
1571
1593
  include SQL::StringMethods
1572
1594
  include SQL::InequalityMethods
1573
-
1574
- # If the core extensions are enabled, these will already be included
1575
- # in String, so we don't need to include/define them here.
1576
- unless Sequel.core_extensions?
1577
- include Sequel::SQL::AliasMethods
1578
- include Sequel::SQL::CastMethods
1595
+ include SQL::AliasMethods
1596
+ include SQL::CastMethods
1579
1597
 
1580
- def lit(*args)
1581
- args.empty? ? self : SQL::PlaceholderLiteralString.new(self, args)
1582
- end
1598
+ # Return self if no args are given, otherwise return a SQL::PlaceholderLiteralString
1599
+ # with the current string and the given args.
1600
+ def lit(*args)
1601
+ args.empty? ? self : SQL::PlaceholderLiteralString.new(self, args)
1602
+ end
1583
1603
 
1584
- def to_sequel_blob
1585
- SQL::Blob.new(self)
1586
- end
1604
+ # Convert a literal string to a SQL::Blob.
1605
+ def to_sequel_blob
1606
+ SQL::Blob.new(self)
1587
1607
  end
1588
1608
  end
1589
1609
 
@@ -3,7 +3,7 @@ module Sequel
3
3
  MAJOR = 3
4
4
  # The minor version of Sequel. Bumped for every non-patch level
5
5
  # release, generally around once a month.
6
- MINOR = 37
6
+ MINOR = 38
7
7
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
8
8
  # releases that fix regressions from previous versions.
9
9
  TINY = 0
@@ -19,20 +19,20 @@ end
19
19
  MSSQL_DB.loggers = [logger]
20
20
 
21
21
  MSSQL_DB.create_table! :test do
22
- text :name
23
- integer :value, :index => true
22
+ String :name, :type=>:text
23
+ Integer :value, :index => true
24
24
  end
25
25
  MSSQL_DB.create_table! :test2 do
26
- text :name
27
- integer :value
26
+ String :name, :type=>:text
27
+ Integer :value
28
28
  end
29
29
  MSSQL_DB.create_table! :test3 do
30
- integer :value
31
- timestamp :time
30
+ Integer :value
31
+ Time :time
32
32
  end
33
33
  MSSQL_DB.create_table! :test4 do
34
- varchar :name, :size => 20
35
- varbinary :value
34
+ String :name, :size => 20
35
+ column :value, 'varbinary(max)'
36
36
  end
37
37
 
38
38
  describe "A MSSQL database" do
@@ -115,7 +115,7 @@ describe "MSSQL Dataset#output" do
115
115
  specify "should format OUTPUT clauses without INTO for DELETE statements" do
116
116
  @ds.output(nil, [:deleted__name, :deleted__value]).delete_sql.should =~
117
117
  /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].\[(NAME|VALUE)\], \[DELETED\].\[(NAME|VALUE)\]/
118
- @ds.output(nil, [:deleted.*]).delete_sql.should =~
118
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:deleted)]).delete_sql.should =~
119
119
  /DELETE FROM \[ITEMS\] OUTPUT \[DELETED\].*/
120
120
  end
121
121
 
@@ -129,7 +129,7 @@ describe "MSSQL Dataset#output" do
129
129
  specify "should format OUTPUT clauses without INTO for INSERT statements" do
130
130
  @ds.output(nil, [:inserted__name, :inserted__value]).insert_sql(:name => "name", :value => 1).should =~
131
131
  /INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].\[(NAME|VALUE)\], \[INSERTED\].\[(NAME|VALUE)\] VALUES \((N'name'|1), (N'name'|1)\)/
132
- @ds.output(nil, [:inserted.*]).insert_sql(:name => "name", :value => 1).should =~
132
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).insert_sql(:name => "name", :value => 1).should =~
133
133
  /INSERT INTO \[ITEMS\] \(\[(NAME|VALUE)\], \[(NAME|VALUE)\]\) OUTPUT \[INSERTED\].* VALUES \((N'name'|1), (N'name'|1)\)/
134
134
  end
135
135
 
@@ -143,7 +143,7 @@ describe "MSSQL Dataset#output" do
143
143
  specify "should format OUTPUT clauses without INTO for UPDATE statements" do
144
144
  @ds.output(nil, [:inserted__name, :deleted__value]).update_sql(:value => 2).should =~
145
145
  /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\], \[(INSERTED\].\[NAME|DELETED\].\[VALUE)\]/
146
- @ds.output(nil, [:inserted.*]).update_sql(:value => 2).should =~
146
+ @ds.output(nil, [Sequel::SQL::ColumnAll.new(:inserted)]).update_sql(:value => 2).should =~
147
147
  /UPDATE \[ITEMS\] SET \[VALUE\] = 2 OUTPUT \[INSERTED\].*/
148
148
  end
149
149
 
@@ -329,7 +329,7 @@ describe "Common Table Expressions" do
329
329
 
330
330
  specify "using #with_recursive should be able to update" do
331
331
  ds = @ds.with_recursive(:t, @ds.filter(:parent_id=>1).or(:id => 1), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
332
- ds.filter(~{:id => @db[:t].select(:i)}).update(:parent_id => 1)
332
+ ds.exclude(:id => @db[:t].select(:i)).update(:parent_id => 1)
333
333
  @ds[:id => 1].should == {:id => 1, :parent_id => nil}
334
334
  @ds[:id => 2].should == {:id => 2, :parent_id => 1}
335
335
  @ds[:id => 5].should == {:id => 5, :parent_id => 3}
@@ -383,6 +383,7 @@ describe "MSSSQL::Dataset#insert" do
383
383
  @ds = @db[:test5]
384
384
  end
385
385
  after do
386
+ @db[:test4].delete
386
387
  @db.drop_table?(:test5)
387
388
  end
388
389
 
@@ -400,6 +401,14 @@ describe "MSSSQL::Dataset#insert" do
400
401
  h[:value].should == 10
401
402
  @ds.first(:xid=>h[:xid])[:value].should == 10
402
403
  end
404
+
405
+ cspecify "should allow large text and binary values", :odbc do
406
+ blob = Sequel::SQL::Blob.new("0" * (65*1024))
407
+ @db[:test4].insert(:name => 'max varbinary test', :value => blob)
408
+ b = @db[:test4].where(:name => 'max varbinary test').get(:value)
409
+ b.length.should == blob.length
410
+ b.should == blob
411
+ end
403
412
  end
404
413
 
405
414
  describe "MSSSQL::Dataset#disable_insert_output" do
@@ -542,3 +551,19 @@ describe "A MSSQL database adds index with include" do
542
551
  @db.indexes(@table_name).should have_key("#{@table_name}_col1_index".to_sym)
543
552
  end
544
553
  end
554
+
555
+ describe "MSSQL::Database#drop_column with a schema" do
556
+ before do
557
+ MSSQL_DB.run "create schema test" rescue nil
558
+ end
559
+ after do
560
+ MSSQL_DB.drop_table(:test__items)
561
+ MSSQL_DB.run "drop schema test" rescue nil
562
+ end
563
+
564
+ specify "drops columns with a default value" do
565
+ MSSQL_DB.create_table!(:test__items){ Integer :id; String :name, :default => 'widget' }
566
+ MSSQL_DB.drop_column(:test__items, :name)
567
+ MSSQL_DB[:test__items].columns.should == [:id]
568
+ end
569
+ end
@@ -81,7 +81,7 @@ describe "MySQL", '#create_table' do
81
81
  @db.schema(:dolls).map{|k, v| v[:auto_increment]}.should == [nil, nil, true]
82
82
  end
83
83
 
84
- cspecify "should support collate with various other column options", :swift do
84
+ specify "should support collate with various other column options" do
85
85
  @db.create_table!(:dolls){ String :name, :size=>128, :collate=>:utf8_bin, :default=>'foo', :null=>false, :unique=>true}
86
86
  @db[:dolls].insert
87
87
  @db[:dolls].select_map(:name).should == ["foo"]
@@ -164,72 +164,36 @@ describe "A MySQL dataset" do
164
164
 
165
165
  specify "should quote columns and tables using back-ticks if quoting identifiers" do
166
166
  @d.quote_identifiers = true
167
- @d.select(:name).sql.should == \
168
- 'SELECT `name` FROM `items`'
169
-
170
- @d.select('COUNT(*)'.lit).sql.should == \
171
- 'SELECT COUNT(*) FROM `items`'
172
-
173
- @d.select(:max.sql_function(:value)).sql.should == \
174
- 'SELECT max(`value`) FROM `items`'
175
-
176
- @d.select(:NOW.sql_function).sql.should == \
177
- 'SELECT NOW() FROM `items`'
178
-
179
- @d.select(:max.sql_function(:items__value)).sql.should == \
180
- 'SELECT max(`items`.`value`) FROM `items`'
181
-
182
- @d.order(:name.desc).sql.should == \
183
- 'SELECT * FROM `items` ORDER BY `name` DESC'
184
-
185
- @d.select('items.name AS item_name'.lit).sql.should == \
186
- 'SELECT items.name AS item_name FROM `items`'
187
-
188
- @d.select('`name`'.lit).sql.should == \
189
- 'SELECT `name` FROM `items`'
190
-
191
- @d.select('max(items.`name`) AS `max_name`'.lit).sql.should == \
192
- 'SELECT max(items.`name`) AS `max_name` FROM `items`'
193
-
194
- @d.select(:test.sql_function(:abc, 'hello')).sql.should == \
195
- "SELECT test(`abc`, 'hello') FROM `items`"
196
-
197
- @d.select(:test.sql_function(:abc__def, 'hello')).sql.should == \
198
- "SELECT test(`abc`.`def`, 'hello') FROM `items`"
199
-
200
- @d.select(:test.sql_function(:abc__def, 'hello').as(:x2)).sql.should == \
201
- "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
202
-
203
- @d.insert_sql(:value => 333).should == \
204
- 'INSERT INTO `items` (`value`) VALUES (333)'
205
-
206
- @d.insert_sql(:x => :y).should == \
207
- 'INSERT INTO `items` (`x`) VALUES (`y`)'
167
+ @d.select(:name).sql.should == 'SELECT `name` FROM `items`'
168
+ @d.select(Sequel.lit('COUNT(*)')).sql.should == 'SELECT COUNT(*) FROM `items`'
169
+ @d.select(Sequel.function(:max, :value)).sql.should == 'SELECT max(`value`) FROM `items`'
170
+ @d.select(Sequel.function(:NOW)).sql.should == 'SELECT NOW() FROM `items`'
171
+ @d.select(Sequel.function(:max, :items__value)).sql.should == 'SELECT max(`items`.`value`) FROM `items`'
172
+ @d.order(Sequel.expr(:name).desc).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC'
173
+ @d.select(Sequel.lit('items.name AS item_name')).sql.should == 'SELECT items.name AS item_name FROM `items`'
174
+ @d.select(Sequel.lit('`name`')).sql.should == 'SELECT `name` FROM `items`'
175
+ @d.select(Sequel.lit('max(items.`name`) AS `max_name`')).sql.should == 'SELECT max(items.`name`) AS `max_name` FROM `items`'
176
+ @d.select(Sequel.function(:test, :abc, 'hello')).sql.should == "SELECT test(`abc`, 'hello') FROM `items`"
177
+ @d.select(Sequel.function(:test, :abc__def, 'hello')).sql.should == "SELECT test(`abc`.`def`, 'hello') FROM `items`"
178
+ @d.select(Sequel.function(:test, :abc__def, 'hello').as(:x2)).sql.should == "SELECT test(`abc`.`def`, 'hello') AS `x2` FROM `items`"
179
+ @d.insert_sql(:value => 333).should == 'INSERT INTO `items` (`value`) VALUES (333)'
180
+ @d.insert_sql(:x => :y).should == 'INSERT INTO `items` (`x`) VALUES (`y`)'
208
181
  end
209
182
 
210
183
  specify "should quote fields correctly when reversing the order" do
211
184
  @d.quote_identifiers = true
212
- @d.reverse_order(:name).sql.should == \
213
- 'SELECT * FROM `items` ORDER BY `name` DESC'
214
-
215
- @d.reverse_order(:name.desc).sql.should == \
216
- 'SELECT * FROM `items` ORDER BY `name` ASC'
217
-
218
- @d.reverse_order(:name, :test.desc).sql.should == \
219
- 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
220
-
221
- @d.reverse_order(:name.desc, :test).sql.should == \
222
- 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
185
+ @d.reverse_order(:name).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC'
186
+ @d.reverse_order(Sequel.desc(:name)).sql.should == 'SELECT * FROM `items` ORDER BY `name` ASC'
187
+ @d.reverse_order(:name, Sequel.desc(:test)).sql.should == 'SELECT * FROM `items` ORDER BY `name` DESC, `test` ASC'
188
+ @d.reverse_order(Sequel.desc(:name), :test).sql.should == 'SELECT * FROM `items` ORDER BY `name` ASC, `test` DESC'
223
189
  end
224
190
 
225
191
  specify "should support ORDER clause in UPDATE statements" do
226
- @d.order(:name).update_sql(:value => 1).should == \
227
- 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
192
+ @d.order(:name).update_sql(:value => 1).should == 'UPDATE `items` SET `value` = 1 ORDER BY `name`'
228
193
  end
229
194
 
230
195
  specify "should support LIMIT clause in UPDATE statements" do
231
- @d.limit(10).update_sql(:value => 1).should == \
232
- 'UPDATE `items` SET `value` = 1 LIMIT 10'
196
+ @d.limit(10).update_sql(:value => 1).should == 'UPDATE `items` SET `value` = 1 LIMIT 10'
233
197
  end
234
198
 
235
199
  specify "should support regexps" do
@@ -272,9 +236,9 @@ describe "MySQL datasets" do
272
236
  @d.quote_identifiers = true
273
237
  market = 'ICE'
274
238
  ack_stamp = Time.now - 15 * 60 # 15 minutes ago
275
- @d.select(:market, :minute.sql_function(:from_unixtime.sql_function(:ack)).as(:minute)).
276
- where{|o|(:ack.sql_number > ack_stamp) & {:market => market}}.
277
- group_by(:minute.sql_function(:from_unixtime.sql_function(:ack))).sql.should == \
239
+ @d.select(:market, Sequel.function(:minute, Sequel.function(:from_unixtime, :ack)).as(:minute)).
240
+ where{(ack > ack_stamp) & {:market => market}}.
241
+ group_by(Sequel.function(:minute, Sequel.function(:from_unixtime, :ack))).sql.should == \
278
242
  "SELECT `market`, minute(from_unixtime(`ack`)) AS `minute` FROM `orders` WHERE ((`ack` > #{@d.literal(ack_stamp)}) AND (`market` = 'ICE')) GROUP BY minute(from_unixtime(`ack`))"
279
243
  end
280
244
  end
@@ -296,7 +260,7 @@ describe "Dataset#distinct" do
296
260
  @ds.insert(20, 10)
297
261
  @ds.insert(30, 10)
298
262
  @ds.order(:b, :a).distinct.map(:a).should == [20, 30]
299
- @ds.order(:b, :a.desc).distinct.map(:a).should == [30, 20]
263
+ @ds.order(:b, Sequel.desc(:a)).distinct.map(:a).should == [30, 20]
300
264
  # MySQL doesn't respect orders when using the nonstandard GROUP BY
301
265
  [[20], [30]].should include(@ds.order(:b, :a).distinct(:b).map(:a))
302
266
  end
@@ -1036,25 +1000,25 @@ describe "MySQL::Dataset#complex_expression_sql" do
1036
1000
  end
1037
1001
 
1038
1002
  specify "should handle pattern matches correctly" do
1039
- @d.literal(:x.like('a')).should == "(`x` LIKE BINARY 'a')"
1040
- @d.literal(~:x.like('a')).should == "(`x` NOT LIKE BINARY 'a')"
1041
- @d.literal(:x.ilike('a')).should == "(`x` LIKE 'a')"
1042
- @d.literal(~:x.ilike('a')).should == "(`x` NOT LIKE 'a')"
1043
- @d.literal(:x.like(/a/)).should == "(`x` REGEXP BINARY 'a')"
1044
- @d.literal(~:x.like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
1045
- @d.literal(:x.like(/a/i)).should == "(`x` REGEXP 'a')"
1046
- @d.literal(~:x.like(/a/i)).should == "(`x` NOT REGEXP 'a')"
1003
+ @d.literal(Sequel.expr(:x).like('a')).should == "(`x` LIKE BINARY 'a')"
1004
+ @d.literal(~Sequel.expr(:x).like('a')).should == "(`x` NOT LIKE BINARY 'a')"
1005
+ @d.literal(Sequel.expr(:x).ilike('a')).should == "(`x` LIKE 'a')"
1006
+ @d.literal(~Sequel.expr(:x).ilike('a')).should == "(`x` NOT LIKE 'a')"
1007
+ @d.literal(Sequel.expr(:x).like(/a/)).should == "(`x` REGEXP BINARY 'a')"
1008
+ @d.literal(~Sequel.expr(:x).like(/a/)).should == "(`x` NOT REGEXP BINARY 'a')"
1009
+ @d.literal(Sequel.expr(:x).like(/a/i)).should == "(`x` REGEXP 'a')"
1010
+ @d.literal(~Sequel.expr(:x).like(/a/i)).should == "(`x` NOT REGEXP 'a')"
1047
1011
  end
1048
1012
 
1049
1013
  specify "should handle string concatenation with CONCAT if more than one record" do
1050
- @d.literal([:x, :y].sql_string_join).should == "CONCAT(`x`, `y`)"
1051
- @d.literal([:x, :y].sql_string_join(' ')).should == "CONCAT(`x`, ' ', `y`)"
1052
- @d.literal([:x.sql_function(:y), 1, 'z'.lit].sql_string_join(:y.sql_subscript(1))).should == "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
1014
+ @d.literal(Sequel.join([:x, :y])).should == "CONCAT(`x`, `y`)"
1015
+ @d.literal(Sequel.join([:x, :y], ' ')).should == "CONCAT(`x`, ' ', `y`)"
1016
+ @d.literal(Sequel.join([Sequel.function(:x, :y), 1, Sequel.lit('z')], Sequel.subscript(:y, 1))).should == "CONCAT(x(`y`), `y`[1], '1', `y`[1], z)"
1053
1017
  end
1054
1018
 
1055
1019
  specify "should handle string concatenation as simple string if just one record" do
1056
- @d.literal([:x].sql_string_join).should == "`x`"
1057
- @d.literal([:x].sql_string_join(' ')).should == "`x`"
1020
+ @d.literal(Sequel.join([:x])).should == "`x`"
1021
+ @d.literal(Sequel.join([:x], ' ')).should == "`x`"
1058
1022
  end
1059
1023
  end
1060
1024
 
@@ -1076,7 +1040,7 @@ describe "MySQL::Dataset#calc_found_rows" do
1076
1040
  MYSQL_DB.sqls.clear
1077
1041
 
1078
1042
  MYSQL_DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.should == [{:a => 1}]
1079
- MYSQL_DB.dataset.select(:FOUND_ROWS.sql_function.as(:rows)).all.should == [{:rows => 2 }]
1043
+ MYSQL_DB.dataset.select(Sequel.function(:FOUND_ROWS).as(:rows)).all.should == [{:rows => 2 }]
1080
1044
 
1081
1045
  MYSQL_DB.sqls.should == [
1082
1046
  'SELECT SQL_CALC_FOUND_ROWS * FROM `items` WHERE (`a` = 1) LIMIT 1',