sequel 4.47.0 → 4.48.0

Sign up to get free protection for your applications and to get access to all the features.
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