sequel 4.47.0 → 4.48.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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +134 -0
  3. data/Rakefile +1 -1
  4. data/doc/release_notes/4.48.0.txt +293 -0
  5. data/lib/sequel/adapters/ado/access.rb +2 -1
  6. data/lib/sequel/adapters/do/postgres.rb +5 -2
  7. data/lib/sequel/adapters/ibmdb.rb +24 -7
  8. data/lib/sequel/adapters/jdbc.rb +36 -22
  9. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  10. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  11. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  12. data/lib/sequel/adapters/jdbc/postgresql.rb +43 -18
  13. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  14. data/lib/sequel/adapters/jdbc/sqlserver.rb +11 -4
  15. data/lib/sequel/adapters/mock.rb +24 -19
  16. data/lib/sequel/adapters/mysql.rb +17 -16
  17. data/lib/sequel/adapters/mysql2.rb +4 -5
  18. data/lib/sequel/adapters/oracle.rb +5 -9
  19. data/lib/sequel/adapters/postgres.rb +89 -102
  20. data/lib/sequel/adapters/shared/db2.rb +22 -6
  21. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  22. data/lib/sequel/adapters/shared/mysql.rb +75 -24
  23. data/lib/sequel/adapters/shared/postgres.rb +196 -94
  24. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  25. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  26. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  27. data/lib/sequel/adapters/sqlite.rb +5 -3
  28. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  29. data/lib/sequel/adapters/tinytds.rb +0 -5
  30. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  31. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  32. data/lib/sequel/core.rb +2 -2
  33. data/lib/sequel/database/connecting.rb +5 -5
  34. data/lib/sequel/database/dataset.rb +6 -3
  35. data/lib/sequel/database/misc.rb +1 -1
  36. data/lib/sequel/database/query.rb +3 -0
  37. data/lib/sequel/database/schema_methods.rb +1 -1
  38. data/lib/sequel/dataset/actions.rb +18 -10
  39. data/lib/sequel/dataset/graph.rb +1 -1
  40. data/lib/sequel/dataset/misc.rb +1 -0
  41. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  42. data/lib/sequel/dataset/query.rb +19 -8
  43. data/lib/sequel/extensions/core_extensions.rb +4 -1
  44. data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
  45. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  46. data/lib/sequel/extensions/filter_having.rb +2 -0
  47. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  48. data/lib/sequel/extensions/from_block.rb +1 -1
  49. data/lib/sequel/extensions/graph_each.rb +2 -2
  50. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  51. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  52. data/lib/sequel/extensions/meta_def.rb +2 -0
  53. data/lib/sequel/extensions/migration.rb +6 -6
  54. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  55. data/lib/sequel/extensions/pagination.rb +1 -1
  56. data/lib/sequel/extensions/pg_array.rb +207 -130
  57. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  58. data/lib/sequel/extensions/pg_inet.rb +18 -6
  59. data/lib/sequel/extensions/pg_interval.rb +19 -12
  60. data/lib/sequel/extensions/pg_json.rb +25 -14
  61. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  62. data/lib/sequel/extensions/pg_range.rb +133 -100
  63. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  64. data/lib/sequel/extensions/pg_row.rb +68 -39
  65. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  66. data/lib/sequel/extensions/query_literals.rb +2 -0
  67. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  68. data/lib/sequel/extensions/s.rb +1 -1
  69. data/lib/sequel/extensions/schema_dumper.rb +24 -24
  70. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  71. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  72. data/lib/sequel/extensions/set_overrides.rb +2 -2
  73. data/lib/sequel/extensions/string_agg.rb +0 -1
  74. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  75. data/lib/sequel/model.rb +25 -57
  76. data/lib/sequel/model/associations.rb +14 -5
  77. data/lib/sequel/model/base.rb +96 -32
  78. data/lib/sequel/plugins/association_pks.rb +73 -46
  79. data/lib/sequel/plugins/association_proxies.rb +1 -1
  80. data/lib/sequel/plugins/auto_validations.rb +6 -2
  81. data/lib/sequel/plugins/boolean_readers.rb +1 -1
  82. data/lib/sequel/plugins/caching.rb +19 -13
  83. data/lib/sequel/plugins/class_table_inheritance.rb +19 -10
  84. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  85. data/lib/sequel/plugins/column_select.rb +1 -1
  86. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  87. data/lib/sequel/plugins/defaults_setter.rb +10 -0
  88. data/lib/sequel/plugins/eager_each.rb +1 -1
  89. data/lib/sequel/plugins/force_encoding.rb +2 -2
  90. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  91. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  92. data/lib/sequel/plugins/instance_filters.rb +3 -1
  93. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  94. data/lib/sequel/plugins/json_serializer.rb +17 -10
  95. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  96. data/lib/sequel/plugins/modification_detection.rb +3 -0
  97. data/lib/sequel/plugins/nested_attributes.rb +5 -1
  98. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  99. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  100. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  101. data/lib/sequel/plugins/serialization.rb +3 -10
  102. data/lib/sequel/plugins/single_table_inheritance.rb +2 -2
  103. data/lib/sequel/plugins/split_values.rb +6 -5
  104. data/lib/sequel/plugins/static_cache.rb +31 -25
  105. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  106. data/lib/sequel/plugins/table_select.rb +1 -1
  107. data/lib/sequel/plugins/touch.rb +2 -1
  108. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  109. data/lib/sequel/plugins/validation_helpers.rb +2 -4
  110. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  111. data/lib/sequel/sql.rb +2 -2
  112. data/lib/sequel/version.rb +1 -1
  113. data/spec/adapters/db2_spec.rb +115 -14
  114. data/spec/adapters/mysql_spec.rb +78 -28
  115. data/spec/adapters/oracle_spec.rb +24 -24
  116. data/spec/adapters/postgres_spec.rb +38 -24
  117. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  118. data/spec/adapters/sqlite_spec.rb +29 -24
  119. data/spec/core/connection_pool_spec.rb +17 -0
  120. data/spec/core/database_spec.rb +6 -0
  121. data/spec/core/dataset_spec.rb +46 -36
  122. data/spec/core/schema_spec.rb +16 -0
  123. data/spec/core/spec_helper.rb +1 -0
  124. data/spec/core_extensions_spec.rb +6 -2
  125. data/spec/extensions/active_model_spec.rb +1 -1
  126. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  127. data/spec/extensions/association_pks_spec.rb +34 -2
  128. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  129. data/spec/extensions/auto_validations_spec.rb +2 -0
  130. data/spec/extensions/boolean_readers_spec.rb +1 -1
  131. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  132. data/spec/extensions/class_table_inheritance_spec.rb +48 -2
  133. data/spec/extensions/column_conflicts_spec.rb +11 -0
  134. data/spec/extensions/connection_validator_spec.rb +1 -1
  135. data/spec/extensions/dataset_associations_spec.rb +8 -8
  136. data/spec/extensions/defaults_setter_spec.rb +1 -1
  137. data/spec/extensions/filter_having_spec.rb +5 -3
  138. data/spec/extensions/hash_aliases_spec.rb +3 -1
  139. data/spec/extensions/identifier_columns_spec.rb +3 -1
  140. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  141. data/spec/extensions/json_serializer_spec.rb +18 -0
  142. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  143. data/spec/extensions/meta_def_spec.rb +9 -0
  144. data/spec/extensions/migration_spec.rb +3 -3
  145. data/spec/extensions/nested_attributes_spec.rb +14 -3
  146. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  147. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  148. data/spec/extensions/pg_array_spec.rb +44 -25
  149. data/spec/extensions/pg_hstore_spec.rb +10 -0
  150. data/spec/extensions/pg_inet_spec.rb +26 -0
  151. data/spec/extensions/pg_interval_spec.rb +20 -0
  152. data/spec/extensions/pg_json_spec.rb +24 -0
  153. data/spec/extensions/pg_range_spec.rb +98 -14
  154. data/spec/extensions/pg_row_spec.rb +14 -4
  155. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  156. data/spec/extensions/query_literals_spec.rb +3 -1
  157. data/spec/extensions/schema_dumper_spec.rb +96 -98
  158. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  159. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  160. data/spec/extensions/single_table_inheritance_spec.rb +1 -1
  161. data/spec/extensions/spec_helper.rb +7 -1
  162. data/spec/extensions/static_cache_spec.rb +75 -24
  163. data/spec/extensions/string_agg_spec.rb +1 -1
  164. data/spec/extensions/touch_spec.rb +9 -0
  165. data/spec/extensions/validation_helpers_spec.rb +9 -3
  166. data/spec/extensions/whitelist_security_spec.rb +26 -0
  167. data/spec/integration/dataset_test.rb +45 -44
  168. data/spec/integration/plugin_test.rb +20 -0
  169. data/spec/integration/prepared_statement_test.rb +3 -0
  170. data/spec/integration/schema_test.rb +21 -1
  171. data/spec/integration/transaction_test.rb +40 -40
  172. data/spec/model/class_dataset_methods_spec.rb +14 -4
  173. data/spec/model/dataset_methods_spec.rb +12 -3
  174. data/spec/model/model_spec.rb +8 -0
  175. metadata +6 -4
  176. data/spec/adapters/firebird_spec.rb +0 -405
  177. data/spec/adapters/informix_spec.rb +0 -100
@@ -9,7 +9,9 @@ describe Sequel::Model, "class dataset methods" do
9
9
  end
10
10
 
11
11
  it "should call the dataset method of the same name with the same args" do
12
- @c.<<({}).must_equal @d
12
+ deprecated do
13
+ @c.<<({}).must_equal @d
14
+ end
13
15
  @db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES"]
14
16
  @c.all.must_equal [@c.load(:id=>1)]
15
17
  @db.sqls.must_equal ["SELECT * FROM items"]
@@ -27,7 +29,9 @@ describe Sequel::Model, "class dataset methods" do
27
29
  @c.except(@d, :from_self=>false).sql.must_equal "SELECT * FROM items EXCEPT SELECT * FROM items"
28
30
  @c.exclude(:a).sql.must_equal "SELECT * FROM items WHERE NOT a"
29
31
  @c.exclude_having(:a).sql.must_equal "SELECT * FROM items HAVING NOT a"
30
- @c.exclude_where(:a).sql.must_equal "SELECT * FROM items WHERE NOT a"
32
+ deprecated do
33
+ @c.exclude_where(:a).sql.must_equal "SELECT * FROM items WHERE NOT a"
34
+ end
31
35
  @c.fetch_rows("S"){|r| r.must_equal(:id=>1)}
32
36
  @db.sqls.must_equal ["S"]
33
37
  @c.filter(:a).sql.must_equal "SELECT * FROM items WHERE a"
@@ -56,7 +60,9 @@ describe Sequel::Model, "class dataset methods" do
56
60
  @c.insert.must_equal 2
57
61
  @db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES"]
58
62
  @c.intersect(@d, :from_self=>false).sql.must_equal "SELECT * FROM items INTERSECT SELECT * FROM items"
59
- @c.interval(:id).must_equal 1
63
+ deprecated do
64
+ @c.interval(:id).must_equal 1
65
+ end
60
66
  @db.sqls.must_equal ["SELECT (max(id) - min(id)) AS interval FROM items LIMIT 1"]
61
67
  @c.join(@c.table_name).sql.must_equal "SELECT * FROM items INNER JOIN items"
62
68
  @c.join_table(:inner, @c.table_name).sql.must_equal "SELECT * FROM items INNER JOIN items"
@@ -116,6 +122,8 @@ describe Sequel::Model, "class dataset methods" do
116
122
  @db.sqls.must_equal ["SELECT * FROM items"]
117
123
  @c.sum(:id).must_equal 1
118
124
  @db.sqls.must_equal ["SELECT sum(id) AS sum FROM items LIMIT 1"]
125
+ @c.as_hash(:id, :id).must_equal(1=>1)
126
+ @db.sqls.must_equal ["SELECT * FROM items"]
119
127
  @c.to_hash(:id, :id).must_equal(1=>1)
120
128
  @db.sqls.must_equal ["SELECT * FROM items"]
121
129
  @c.to_hash_groups(:id, :id).must_equal(1=>[1])
@@ -134,7 +142,9 @@ describe Sequel::Model, "class dataset methods" do
134
142
  sc.invert.sql.must_equal 'SELECT a FROM items WHERE NOT a GROUP BY a ORDER BY a LIMIT 2'
135
143
  sc.dataset = sc.dataset.with_fetch(:v1=>1, :v2=>2)
136
144
  @db.sqls
137
- sc.range(:a).must_equal(1..2)
145
+ deprecated do
146
+ sc.range(:a).must_equal(1..2)
147
+ end
138
148
  @db.sqls.must_equal ["SELECT min(a) AS v1, max(a) AS v2 FROM (SELECT a FROM items WHERE a GROUP BY a ORDER BY a LIMIT 2) AS t1 LIMIT 1"]
139
149
  sc.reverse.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
140
150
  sc.reverse_order.sql.must_equal 'SELECT a FROM items WHERE a GROUP BY a ORDER BY a DESC LIMIT 2'
@@ -38,7 +38,7 @@ describe Sequel::Model::DatasetMethods, "#destroy" do
38
38
  end
39
39
  end
40
40
 
41
- describe Sequel::Model::DatasetMethods, "#to_hash" do
41
+ describe Sequel::Model::DatasetMethods, "#as_hash" do
42
42
  before do
43
43
  @c = Class.new(Sequel::Model(:items)) do
44
44
  set_primary_key :name
@@ -47,6 +47,15 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
47
47
  end
48
48
 
49
49
  it "should result in a hash with primary key value keys and model object values" do
50
+ @d = @d.with_fetch([{:name=>1}, {:name=>2}])
51
+ h = @d.as_hash
52
+ h.must_be_kind_of(Hash)
53
+ a = h.to_a
54
+ a.collect{|x| x[1].class}.must_equal [@c, @c]
55
+ a.sort_by{|x| x[0]}.collect{|x| [x[0], x[1].values]}.must_equal [[1, {:name=>1}], [2, {:name=>2}]]
56
+ end
57
+
58
+ it "should be aliased as to_hash" do
50
59
  @d = @d.with_fetch([{:name=>1}, {:name=>2}])
51
60
  h = @d.to_hash
52
61
  h.must_be_kind_of(Hash)
@@ -57,7 +66,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
57
66
 
58
67
  it "should result in a hash with given value keys and model object values" do
59
68
  @d = @d.with_fetch([{:name=>1, :number=>3}, {:name=>2, :number=>4}])
60
- h = @d.to_hash(:number)
69
+ h = @d.as_hash(:number)
61
70
  h.must_be_kind_of(Hash)
62
71
  a = h.to_a
63
72
  a.collect{|x| x[1].class}.must_equal [@c, @c]
@@ -66,7 +75,7 @@ describe Sequel::Model::DatasetMethods, "#to_hash" do
66
75
 
67
76
  it "should raise an error if the class doesn't have a primary key" do
68
77
  @c.no_primary_key
69
- proc{@d.to_hash}.must_raise(Sequel::Error)
78
+ proc{@d.as_hash}.must_raise(Sequel::Error)
70
79
  end
71
80
  end
72
81
 
@@ -489,6 +489,14 @@ describe Sequel::Model, ".require_valid_table = true" do
489
489
  c.set_dataset @db[:bars]
490
490
  c.columns.must_equal [:id]
491
491
  end
492
+
493
+ deprecated "should assume nil value is the same as false" do
494
+ c = Class.new(Sequel::Model)
495
+ c.require_valid_table = nil
496
+ ds = @db.dataset
497
+ def ds.columns; raise Sequel::Error; end
498
+ c.set_dataset(ds)
499
+ end
492
500
  end
493
501
 
494
502
  describe Sequel::Model, "constructors" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.47.0
4
+ version: 4.48.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-01 00:00:00.000000000 Z
11
+ date: 2017-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -249,6 +249,7 @@ extra_rdoc_files:
249
249
  - doc/release_notes/4.45.0.txt
250
250
  - doc/release_notes/4.46.0.txt
251
251
  - doc/release_notes/4.47.0.txt
252
+ - doc/release_notes/4.48.0.txt
252
253
  files:
253
254
  - CHANGELOG
254
255
  - MIT-LICENSE
@@ -387,6 +388,7 @@ files:
387
388
  - doc/release_notes/4.45.0.txt
388
389
  - doc/release_notes/4.46.0.txt
389
390
  - doc/release_notes/4.47.0.txt
391
+ - doc/release_notes/4.48.0.txt
390
392
  - doc/release_notes/4.5.0.txt
391
393
  - doc/release_notes/4.6.0.txt
392
394
  - doc/release_notes/4.7.0.txt
@@ -563,6 +565,7 @@ files:
563
565
  - lib/sequel/extensions/schema_dumper.rb
564
566
  - lib/sequel/extensions/select_remove.rb
565
567
  - lib/sequel/extensions/sequel_3_dataset_methods.rb
568
+ - lib/sequel/extensions/sequel_4_dataset_methods.rb
566
569
  - lib/sequel/extensions/server_block.rb
567
570
  - lib/sequel/extensions/server_logging.rb
568
571
  - lib/sequel/extensions/set_overrides.rb
@@ -676,8 +679,6 @@ files:
676
679
  - lib/sequel/version.rb
677
680
  - spec/adapter_spec.rb
678
681
  - spec/adapters/db2_spec.rb
679
- - spec/adapters/firebird_spec.rb
680
- - spec/adapters/informix_spec.rb
681
682
  - spec/adapters/mssql_spec.rb
682
683
  - spec/adapters/mysql_spec.rb
683
684
  - spec/adapters/oracle_spec.rb
@@ -812,6 +813,7 @@ files:
812
813
  - spec/extensions/scissors_spec.rb
813
814
  - spec/extensions/select_remove_spec.rb
814
815
  - spec/extensions/sequel_3_dataset_methods_spec.rb
816
+ - spec/extensions/sequel_4_dataset_methods_spec.rb
815
817
  - spec/extensions/serialization_modification_detection_spec.rb
816
818
  - spec/extensions/serialization_spec.rb
817
819
  - spec/extensions/server_block_spec.rb
@@ -1,405 +0,0 @@
1
- SEQUEL_ADAPTER_TEST = :firebird
2
-
3
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
4
-
5
- def DB.sqls
6
- (@sqls ||= [])
7
- end
8
- logger = Object.new
9
- def logger.method_missing(m, msg)
10
- DB.sqls.push(msg)
11
- end
12
- DB.loggers = [logger]
13
-
14
- DB.create_table! :test do
15
- varchar :name, :size => 50
16
- integer :val, :index => true
17
- end
18
-
19
- DB.create_table! :test2 do
20
- integer :val
21
- timestamp :time_stamp
22
- end
23
-
24
- DB.create_table! :test3 do
25
- integer :val
26
- timestamp :time_stamp
27
- end
28
-
29
- DB.create_table! :test5 do
30
- primary_key :xid
31
- integer :val
32
- end
33
-
34
- DB.create_table! :test6 do
35
- primary_key :xid
36
- blob :val
37
- String :val2
38
- varchar :val3, :size=>200
39
- String :val4, :text=>true
40
- end
41
-
42
- describe "A Firebird database" do
43
- before do
44
- @db = DB
45
- end
46
-
47
- it "should provide disconnect functionality" do
48
- @db.tables
49
- @db.pool.size.must_equal 1
50
- @db.disconnect
51
- @db.pool.size.must_equal 0
52
- end
53
-
54
- it "should raise Sequel::Error on error" do
55
- proc{@db << "SELECT 1 + 'a'"}.must_raise(Sequel::Error)
56
- end
57
- end
58
-
59
- describe "A Firebird dataset" do
60
- before do
61
- @d = DB[:test].with_quote_identifiers(true)
62
- @d.delete
63
- end
64
-
65
- it "should return the correct record count" do
66
- @d.count.must_equal 0
67
- @d << {:name => 'abc', :val => 123}
68
- @d << {:name => 'abc', :val => 456}
69
- @d << {:name => 'def', :val => 789}
70
- @d.count.must_equal 3
71
- end
72
-
73
- it "should return the correct records" do
74
- @d.to_a.must_equal []
75
- @d << {:name => 'abc', :val => 123}
76
- @d << {:name => 'abc', :val => 456}
77
- @d << {:name => 'def', :val => 789}
78
-
79
- @d.order(:val).to_a.must_equal [
80
- {:name => 'abc', :val => 123},
81
- {:name => 'abc', :val => 456},
82
- {:name => 'def', :val => 789}
83
- ]
84
- end
85
-
86
- it "should update records correctly" do
87
- @d << {:name => 'abc', :val => 123}
88
- @d << {:name => 'abc', :val => 456}
89
- @d << {:name => 'def', :val => 789}
90
- @d.filter(:name => 'abc').update(:val => 530)
91
-
92
- @d[:name => 'def'][:val].must_equal 789
93
- @d.filter(:val => 530).count.must_equal 2
94
- end
95
-
96
- it "should delete records correctly" do
97
- @d << {:name => 'abc', :val => 123}
98
- @d << {:name => 'abc', :val => 456}
99
- @d << {:name => 'def', :val => 789}
100
- @d.filter(:name => 'abc').delete
101
-
102
- @d.count.must_equal 1
103
- @d.first[:name].must_equal 'def'
104
- end
105
-
106
- it "should be able to literalize booleans" do
107
- @d.literal(true)
108
- @d.literal(false)
109
- end
110
-
111
- it "should quote columns and tables using double quotes if quoting identifiers" do
112
- @d.select(:name).sql.must_equal \
113
- 'SELECT "NAME" FROM "TEST"'
114
-
115
- @d.select('COUNT(*)'.lit).sql.must_equal \
116
- 'SELECT COUNT(*) FROM "TEST"'
117
-
118
- @d.select(:max[:val]).sql.must_equal \
119
- 'SELECT max("VAL") FROM "TEST"'
120
-
121
- @d.select(:now[]).sql.must_equal \
122
- 'SELECT now() FROM "TEST"'
123
-
124
- @d.select(:max[Sequel[:items][:val]]).sql.must_equal \
125
- 'SELECT max("ITEMS"."VAL") FROM "TEST"'
126
-
127
- @d.order(:name.desc).sql.must_equal \
128
- 'SELECT * FROM "TEST" ORDER BY "NAME" DESC'
129
-
130
- @d.select('TEST.NAME AS item_:name'.lit).sql.must_equal \
131
- 'SELECT TEST.NAME AS item_:name FROM "TEST"'
132
-
133
- @d.select('"NAME"'.lit).sql.must_equal \
134
- 'SELECT "NAME" FROM "TEST"'
135
-
136
- @d.select('max(TEST."NAME") AS "max_:name"'.lit).sql.must_equal \
137
- 'SELECT max(TEST."NAME") AS "max_:name" FROM "TEST"'
138
-
139
- @d.select(:test[:ABC, 'hello']).sql.must_equal \
140
- "SELECT test(\"ABC\", 'hello') FROM \"TEST\""
141
-
142
- @d.select(:test[Sequel[:ABC][:DEF], 'hello']).sql.must_equal \
143
- "SELECT test(\"ABC\".\"DEF\", 'hello') FROM \"TEST\""
144
-
145
- @d.select(:test[Sequel[:ABC][:DEF], 'hello'].as(:X2)).sql.must_equal \
146
- "SELECT test(\"ABC\".\"DEF\", 'hello') AS \"X2\" FROM \"TEST\""
147
-
148
- @d.insert_sql(:val => 333).must_match \
149
- /\AINSERT INTO "TEST" \("VAL"\) VALUES \(333\)( RETURNING NULL)?\z/
150
-
151
- @d.insert_sql(:X => :Y).must_match \
152
- /\AINSERT INTO "TEST" \("X"\) VALUES \("Y"\)( RETURNING NULL)?\z/
153
- end
154
-
155
- it "should quote fields correctly when reversing the order if quoting identifiers" do
156
- @d.reverse_order(:name).sql.must_equal \
157
- 'SELECT * FROM "TEST" ORDER BY "NAME" DESC'
158
-
159
- @d.reverse_order(:name.desc).sql.must_equal \
160
- 'SELECT * FROM "TEST" ORDER BY "NAME" ASC'
161
-
162
- @d.reverse_order(:name, :test.desc).sql.must_equal \
163
- 'SELECT * FROM "TEST" ORDER BY "NAME" DESC, "TEST" ASC'
164
-
165
- @d.reverse_order(:name.desc, :test).sql.must_equal \
166
- 'SELECT * FROM "TEST" ORDER BY "NAME" ASC, "TEST" DESC'
167
- end
168
-
169
- it "should support transactions" do
170
- DB.transaction do
171
- @d << {:name => 'abc', :val => 1}
172
- end
173
-
174
- @d.count.must_equal 1
175
- end
176
-
177
- it "should have #transaction yield the connection" do
178
- DB.transaction do |conn|
179
- conn.wont_equal nil
180
- end
181
- end
182
-
183
- it "should correctly rollback transactions" do
184
- proc do
185
- DB.transaction do
186
- @d << {:name => 'abc', :val => 1}
187
- raise RuntimeError, 'asdf'
188
- end
189
- end.must_raise(RuntimeError)
190
-
191
- @d.count.must_equal 0
192
- end
193
-
194
- it "should handle returning inside of the block by committing" do
195
- def DB.ret_commit
196
- transaction do
197
- self[:test] << {:name => 'abc'}
198
- return
199
- self[:test] << {:name => 'd'}
200
- end
201
- end
202
- @d.count.must_equal 0
203
- DB.ret_commit
204
- @d.count.must_equal 1
205
- DB.ret_commit
206
- @d.count.must_equal 2
207
- proc do
208
- DB.transaction do
209
- raise RuntimeError, 'asdf'
210
- end
211
- end.must_raise(RuntimeError)
212
-
213
- @d.count.must_equal 2
214
- end
215
-
216
- it "should quote and upcase reserved keywords" do
217
- @d = DB[:testing]
218
- @d.select(:select).sql.must_equal \
219
- 'SELECT "SELECT" FROM "TESTING"'
220
- end
221
- end
222
-
223
- describe "A Firebird dataset with a timestamp field" do
224
- before do
225
- @d = DB[:test3]
226
- @d.delete
227
- end
228
-
229
- it "should store milliseconds in time fields" do
230
- t = Time.now
231
- @d << {:val=>1, :time_stamp=>t}
232
- @d.literal(@d[:val =>'1'][:time_stamp]).must_equal @d.literal(t)
233
- @d[:val=>'1'][:time_stamp].usec.must_equal t.usec - t.usec % 100
234
- end
235
- end
236
-
237
- describe "A Firebird database" do
238
- before do
239
- @db = DB
240
- @db.drop_table?(:posts)
241
- @db.sqls.clear
242
- end
243
-
244
- it "should allow us to name the sequences" do
245
- @db.create_table(:posts){primary_key :id, :sequence_name => "seq_test"}
246
- check_sqls do
247
- @db.sqls.must_equal [
248
- "DROP SEQUENCE SEQ_TEST",
249
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
250
- "CREATE SEQUENCE SEQ_TEST",
251
- " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
252
- ]
253
- end
254
- end
255
-
256
- it "should allow us to set the starting position for the sequences" do
257
- @db.create_table(:posts){primary_key :id, :sequence_start_position => 999}
258
- check_sqls do
259
- @db.sqls.must_equal [
260
- "DROP SEQUENCE SEQ_POSTS_ID",
261
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
262
- "CREATE SEQUENCE SEQ_POSTS_ID",
263
- "ALTER SEQUENCE SEQ_POSTS_ID RESTART WITH 999",
264
- " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
265
- ]
266
- end
267
- end
268
-
269
- it "should allow us to name and set the starting position for the sequences" do
270
- @db.create_table(:posts){primary_key :id, :sequence_name => "seq_test", :sequence_start_position => 999}
271
- check_sqls do
272
- @db.sqls.must_equal [
273
- "DROP SEQUENCE SEQ_TEST",
274
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
275
- "CREATE SEQUENCE SEQ_TEST",
276
- "ALTER SEQUENCE SEQ_TEST RESTART WITH 999",
277
- " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_test;\n end\n end\n\n"
278
- ]
279
- end
280
- end
281
-
282
- it "should allow us to name the triggers" do
283
- @db.create_table(:posts){primary_key :id, :trigger_name => "trig_test"}
284
- check_sqls do
285
- @db.sqls.must_equal [
286
- "DROP SEQUENCE SEQ_POSTS_ID",
287
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
288
- "CREATE SEQUENCE SEQ_POSTS_ID",
289
- " CREATE TRIGGER TRIG_TEST for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
290
- ]
291
- end
292
- end
293
-
294
- it "should allow us to not create the sequence" do
295
- @db.create_table(:posts){primary_key :id, :create_sequence => false}
296
- check_sqls do
297
- @db.sqls.must_equal [
298
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
299
- " CREATE TRIGGER BI_POSTS_ID for POSTS\n ACTIVE BEFORE INSERT position 0\n as begin\n if ((new.ID is null) or (new.ID = 0)) then\n begin\n new.ID = next value for seq_posts_id;\n end\n end\n\n"
300
- ]
301
- end
302
- end
303
-
304
- it "should allow us to not create the trigger" do
305
- @db.create_table(:posts){primary_key :id, :create_trigger => false}
306
- check_sqls do
307
- @db.sqls.must_equal [
308
- "DROP SEQUENCE SEQ_POSTS_ID",
309
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )",
310
- "CREATE SEQUENCE SEQ_POSTS_ID",
311
- ]
312
- end
313
- end
314
-
315
- it "should allow us to not create either the sequence nor the trigger" do
316
- @db.create_table(:posts){primary_key :id, :create_sequence => false, :create_trigger => false}
317
- check_sqls do
318
- @db.sqls.must_equal [
319
- "CREATE TABLE POSTS (ID integer PRIMARY KEY )"
320
- ]
321
- end
322
- end
323
-
324
- it "should support column operations" do
325
- @db.create_table!(:test2){varchar :name, :size => 50; integer :val}
326
- @db[:test2] << {}
327
- @db[:test2].columns.must_equal [:name, :val]
328
-
329
- @db.add_column :test2, :xyz, :varchar, :size => 50
330
- @db[:test2].columns.must_equal [:name, :val, :xyz]
331
-
332
- @db[:test2].columns.must_equal [:name, :val, :xyz]
333
- @db.drop_column :test2, :xyz
334
-
335
- @db[:test2].columns.must_equal [:name, :val]
336
-
337
- @db[:test2].delete
338
- @db.add_column :test2, :xyz, :varchar, :default => '000', :size => 50#, :create_domain => 'xyz_varchar'
339
- @db[:test2] << {:name => 'mmm', :val => 111, :xyz => 'qqqq'}
340
-
341
- @db[:test2].columns.must_equal [:name, :val, :xyz]
342
- @db.rename_column :test2, :xyz, :zyx
343
- @db[:test2].columns.must_equal [:name, :val, :zyx]
344
- @db[:test2].first[:zyx].must_equal 'qqqq'
345
-
346
- @db.add_column :test2, :xyz, :decimal, :elements => [12, 2]
347
- @db[:test2].delete
348
- @db[:test2] << {:name => 'mmm', :val => 111, :xyz => 56.4}
349
- @db.set_column_type :test2, :xyz, :varchar, :size => 50
350
-
351
- @db[:test2].first[:xyz].must_equal "56.40"
352
- end
353
-
354
- it "should allow us to retrieve the primary key for a table" do
355
- @db.create_table!(:test2){primary_key :id}
356
- @db.primary_key(:test2).must_equal ["id"]
357
- end
358
- end
359
-
360
- describe "Postgres::Dataset#insert" do
361
- before do
362
- @ds = DB[:test5]
363
- @ds.delete
364
- end
365
-
366
- it "should have insert_returning_sql use the RETURNING keyword" do
367
- @ds.insert_returning_sql(:XID, :val=>10).must_equal "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID"
368
- @ds.insert_returning_sql('*'.lit, :val=>10).must_equal "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING *"
369
- @ds.insert_returning_sql('NULL'.lit, :val=>10).must_equal "INSERT INTO TEST5 (VAL) VALUES (10) RETURNING NULL"
370
- end
371
-
372
- it "should correctly return the inserted record's primary key value" do
373
- value1 = 10
374
- id1 = @ds.insert(:val=>value1)
375
- @ds.first(:XID=>id1)[:val].must_equal value1
376
- value2 = 20
377
- id2 = @ds.insert(:val=>value2)
378
- @ds.first(:XID=>id2)[:val].must_equal value2
379
- end
380
-
381
- it "should return nil if the table has no primary key" do
382
- ds = DB[:test]
383
- ds.delete
384
- ds.insert(:name=>'a').must_be_nil
385
- end
386
- end
387
-
388
- describe "Postgres::Dataset#insert" do
389
- before do
390
- @ds = DB[:test6]
391
- @ds.delete
392
- end
393
-
394
- it "should insert and retrieve a blob successfully" do
395
- value1 = "\1\2\2\2\2222\2\2\2"
396
- value2 = "abcd"
397
- value3 = "efgh"
398
- value4 = "ijkl"
399
- id1 = @ds.insert(:val=>value1, :val2=>value2, :val3=>value3, :val4=>value4)
400
- @ds.first(:XID=>id1)[:val].must_equal value1
401
- @ds.first(:XID=>id1)[:val2].must_equal value2
402
- @ds.first(:XID=>id1)[:val3].must_equal value3
403
- @ds.first(:XID=>id1)[:val4].must_equal value4
404
- end
405
- end