sequel 3.37.0 → 3.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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',