sequel 3.48.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +114 -0
  3. data/Rakefile +10 -7
  4. data/doc/association_basics.rdoc +25 -23
  5. data/doc/code_order.rdoc +7 -0
  6. data/doc/core_extensions.rdoc +0 -10
  7. data/doc/object_model.rdoc +4 -1
  8. data/doc/querying.rdoc +3 -3
  9. data/doc/release_notes/4.0.0.txt +262 -0
  10. data/doc/security.rdoc +0 -28
  11. data/doc/testing.rdoc +8 -14
  12. data/lib/sequel/adapters/ado.rb +7 -11
  13. data/lib/sequel/adapters/ado/access.rb +8 -8
  14. data/lib/sequel/adapters/ado/mssql.rb +4 -4
  15. data/lib/sequel/adapters/amalgalite.rb +6 -6
  16. data/lib/sequel/adapters/cubrid.rb +7 -7
  17. data/lib/sequel/adapters/db2.rb +5 -9
  18. data/lib/sequel/adapters/dbi.rb +2 -6
  19. data/lib/sequel/adapters/do.rb +4 -4
  20. data/lib/sequel/adapters/firebird.rb +4 -4
  21. data/lib/sequel/adapters/ibmdb.rb +8 -8
  22. data/lib/sequel/adapters/informix.rb +2 -10
  23. data/lib/sequel/adapters/jdbc.rb +17 -17
  24. data/lib/sequel/adapters/jdbc/as400.rb +2 -2
  25. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  27. data/lib/sequel/adapters/jdbc/derby.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/h2.rb +2 -2
  29. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
  30. data/lib/sequel/adapters/jdbc/informix.rb +1 -1
  31. data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
  32. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  33. data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
  35. data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
  36. data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
  37. data/lib/sequel/adapters/mock.rb +7 -7
  38. data/lib/sequel/adapters/mysql.rb +3 -3
  39. data/lib/sequel/adapters/mysql2.rb +4 -4
  40. data/lib/sequel/adapters/odbc.rb +2 -6
  41. data/lib/sequel/adapters/odbc/mssql.rb +1 -1
  42. data/lib/sequel/adapters/openbase.rb +1 -5
  43. data/lib/sequel/adapters/oracle.rb +13 -17
  44. data/lib/sequel/adapters/postgres.rb +20 -25
  45. data/lib/sequel/adapters/shared/cubrid.rb +3 -3
  46. data/lib/sequel/adapters/shared/db2.rb +2 -2
  47. data/lib/sequel/adapters/shared/firebird.rb +7 -7
  48. data/lib/sequel/adapters/shared/mssql.rb +9 -9
  49. data/lib/sequel/adapters/shared/mysql.rb +29 -13
  50. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
  51. data/lib/sequel/adapters/shared/oracle.rb +22 -13
  52. data/lib/sequel/adapters/shared/postgres.rb +61 -46
  53. data/lib/sequel/adapters/shared/sqlite.rb +9 -9
  54. data/lib/sequel/adapters/sqlite.rb +17 -11
  55. data/lib/sequel/adapters/swift.rb +3 -3
  56. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  57. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  58. data/lib/sequel/adapters/tinytds.rb +8 -8
  59. data/lib/sequel/ast_transformer.rb +3 -1
  60. data/lib/sequel/connection_pool.rb +4 -2
  61. data/lib/sequel/connection_pool/sharded_single.rb +2 -2
  62. data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
  63. data/lib/sequel/connection_pool/threaded.rb +7 -7
  64. data/lib/sequel/core.rb +4 -67
  65. data/lib/sequel/database.rb +1 -0
  66. data/lib/sequel/database/connecting.rb +2 -8
  67. data/lib/sequel/database/dataset.rb +2 -7
  68. data/lib/sequel/database/dataset_defaults.rb +0 -18
  69. data/lib/sequel/database/features.rb +4 -4
  70. data/lib/sequel/database/misc.rb +6 -8
  71. data/lib/sequel/database/query.rb +5 -61
  72. data/lib/sequel/database/schema_generator.rb +22 -20
  73. data/lib/sequel/database/schema_methods.rb +48 -20
  74. data/lib/sequel/database/transactions.rb +7 -17
  75. data/lib/sequel/dataset.rb +2 -0
  76. data/lib/sequel/dataset/actions.rb +23 -91
  77. data/lib/sequel/dataset/features.rb +1 -4
  78. data/lib/sequel/dataset/graph.rb +3 -47
  79. data/lib/sequel/dataset/misc.rb +4 -33
  80. data/lib/sequel/dataset/prepared_statements.rb +3 -1
  81. data/lib/sequel/dataset/query.rb +116 -240
  82. data/lib/sequel/dataset/sql.rb +19 -97
  83. data/lib/sequel/deprecated.rb +0 -16
  84. data/lib/sequel/exceptions.rb +0 -3
  85. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  86. data/lib/sequel/extensions/columns_introspection.rb +1 -12
  87. data/lib/sequel/extensions/constraint_validations.rb +3 -3
  88. data/lib/sequel/extensions/core_extensions.rb +0 -9
  89. data/lib/sequel/extensions/date_arithmetic.rb +1 -2
  90. data/lib/sequel/extensions/graph_each.rb +11 -0
  91. data/lib/sequel/extensions/migration.rb +5 -5
  92. data/lib/sequel/extensions/null_dataset.rb +11 -13
  93. data/lib/sequel/extensions/pagination.rb +3 -6
  94. data/lib/sequel/extensions/pg_array.rb +6 -4
  95. data/lib/sequel/extensions/pg_array_ops.rb +35 -1
  96. data/lib/sequel/extensions/pg_json.rb +12 -2
  97. data/lib/sequel/extensions/pg_json_ops.rb +266 -0
  98. data/lib/sequel/extensions/pg_range.rb +2 -2
  99. data/lib/sequel/extensions/pg_range_ops.rb +0 -8
  100. data/lib/sequel/extensions/pg_row.rb +2 -2
  101. data/lib/sequel/extensions/pretty_table.rb +0 -4
  102. data/lib/sequel/extensions/query.rb +3 -8
  103. data/lib/sequel/extensions/schema_caching.rb +0 -7
  104. data/lib/sequel/extensions/schema_dumper.rb +10 -17
  105. data/lib/sequel/extensions/select_remove.rb +0 -4
  106. data/lib/sequel/extensions/set_overrides.rb +28 -0
  107. data/lib/sequel/extensions/to_dot.rb +6 -10
  108. data/lib/sequel/model.rb +6 -7
  109. data/lib/sequel/model/associations.rb +127 -182
  110. data/lib/sequel/model/base.rb +88 -211
  111. data/lib/sequel/model/errors.rb +0 -13
  112. data/lib/sequel/model/plugins.rb +2 -2
  113. data/lib/sequel/no_core_ext.rb +0 -1
  114. data/lib/sequel/plugins/after_initialize.rb +11 -17
  115. data/lib/sequel/plugins/association_autoreloading.rb +1 -47
  116. data/lib/sequel/plugins/association_dependencies.rb +2 -2
  117. data/lib/sequel/plugins/auto_validations.rb +2 -8
  118. data/lib/sequel/plugins/blacklist_security.rb +32 -2
  119. data/lib/sequel/plugins/caching.rb +1 -1
  120. data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
  121. data/lib/sequel/plugins/composition.rb +10 -8
  122. data/lib/sequel/plugins/constraint_validations.rb +2 -2
  123. data/lib/sequel/plugins/dataset_associations.rb +4 -0
  124. data/lib/sequel/plugins/defaults_setter.rb +8 -6
  125. data/lib/sequel/plugins/dirty.rb +6 -6
  126. data/lib/sequel/plugins/force_encoding.rb +13 -8
  127. data/lib/sequel/plugins/hook_class_methods.rb +1 -7
  128. data/lib/sequel/plugins/json_serializer.rb +13 -74
  129. data/lib/sequel/plugins/lazy_attributes.rb +2 -4
  130. data/lib/sequel/plugins/list.rb +1 -1
  131. data/lib/sequel/plugins/many_through_many.rb +4 -11
  132. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
  133. data/lib/sequel/plugins/nested_attributes.rb +1 -1
  134. data/lib/sequel/plugins/optimistic_locking.rb +3 -5
  135. data/lib/sequel/plugins/pg_array_associations.rb +453 -0
  136. data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
  137. data/lib/sequel/plugins/prepared_statements.rb +1 -1
  138. data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
  139. data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
  140. data/lib/sequel/plugins/rcte_tree.rb +1 -1
  141. data/lib/sequel/plugins/serialization.rb +5 -4
  142. data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
  143. data/lib/sequel/plugins/sharding.rb +7 -1
  144. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  145. data/lib/sequel/plugins/timestamps.rb +1 -1
  146. data/lib/sequel/plugins/touch.rb +2 -2
  147. data/lib/sequel/plugins/tree.rb +1 -1
  148. data/lib/sequel/plugins/typecast_on_load.rb +19 -4
  149. data/lib/sequel/plugins/validation_class_methods.rb +0 -30
  150. data/lib/sequel/plugins/validation_helpers.rb +13 -31
  151. data/lib/sequel/plugins/xml_serializer.rb +18 -57
  152. data/lib/sequel/sql.rb +20 -22
  153. data/lib/sequel/version.rb +2 -2
  154. data/spec/adapters/db2_spec.rb +14 -23
  155. data/spec/adapters/firebird_spec.rb +25 -29
  156. data/spec/adapters/informix_spec.rb +11 -14
  157. data/spec/adapters/mssql_spec.rb +71 -77
  158. data/spec/adapters/mysql_spec.rb +165 -172
  159. data/spec/adapters/oracle_spec.rb +36 -39
  160. data/spec/adapters/postgres_spec.rb +175 -100
  161. data/spec/adapters/spec_helper.rb +13 -11
  162. data/spec/adapters/sqlite_spec.rb +36 -44
  163. data/spec/core/connection_pool_spec.rb +2 -1
  164. data/spec/core/database_spec.rb +55 -55
  165. data/spec/core/dataset_spec.rb +45 -249
  166. data/spec/core/deprecated_spec.rb +0 -8
  167. data/spec/core/expression_filters_spec.rb +23 -5
  168. data/spec/core/object_graph_spec.rb +4 -66
  169. data/spec/core/schema_spec.rb +35 -12
  170. data/spec/core/spec_helper.rb +3 -2
  171. data/spec/core_extensions_spec.rb +17 -19
  172. data/spec/extensions/arbitrary_servers_spec.rb +2 -3
  173. data/spec/extensions/association_dependencies_spec.rb +14 -14
  174. data/spec/extensions/auto_validations_spec.rb +7 -0
  175. data/spec/extensions/blacklist_security_spec.rb +5 -5
  176. data/spec/extensions/blank_spec.rb +2 -0
  177. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  178. data/spec/extensions/columns_introspection_spec.rb +2 -29
  179. data/spec/extensions/composition_spec.rb +10 -17
  180. data/spec/extensions/core_refinements_spec.rb +5 -1
  181. data/spec/extensions/dataset_associations_spec.rb +18 -0
  182. data/spec/extensions/date_arithmetic_spec.rb +2 -2
  183. data/spec/extensions/defaults_setter_spec.rb +9 -9
  184. data/spec/extensions/dirty_spec.rb +0 -5
  185. data/spec/extensions/eval_inspect_spec.rb +2 -0
  186. data/spec/extensions/force_encoding_spec.rb +2 -18
  187. data/spec/extensions/hash_aliases_spec.rb +8 -0
  188. data/spec/extensions/hook_class_methods_spec.rb +39 -58
  189. data/spec/extensions/inflector_spec.rb +2 -0
  190. data/spec/extensions/instance_filters_spec.rb +8 -8
  191. data/spec/extensions/json_serializer_spec.rb +1 -41
  192. data/spec/extensions/list_spec.rb +1 -1
  193. data/spec/extensions/many_through_many_spec.rb +106 -109
  194. data/spec/extensions/migration_spec.rb +2 -0
  195. data/spec/extensions/named_timezones_spec.rb +1 -0
  196. data/spec/extensions/pg_array_associations_spec.rb +603 -0
  197. data/spec/extensions/pg_array_ops_spec.rb +25 -0
  198. data/spec/extensions/pg_array_spec.rb +9 -1
  199. data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
  200. data/spec/extensions/pg_hstore_spec.rb +1 -0
  201. data/spec/extensions/pg_json_ops_spec.rb +131 -0
  202. data/spec/extensions/pg_json_spec.rb +10 -4
  203. data/spec/extensions/pg_range_ops_spec.rb +2 -5
  204. data/spec/extensions/pg_range_spec.rb +6 -2
  205. data/spec/extensions/pg_row_ops_spec.rb +2 -0
  206. data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
  207. data/spec/extensions/rcte_tree_spec.rb +15 -15
  208. data/spec/extensions/schema_dumper_spec.rb +0 -1
  209. data/spec/extensions/schema_spec.rb +9 -9
  210. data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
  211. data/spec/extensions/serialization_spec.rb +18 -29
  212. data/spec/extensions/set_overrides_spec.rb +4 -0
  213. data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
  214. data/spec/extensions/single_table_inheritance_spec.rb +4 -4
  215. data/spec/extensions/spec_helper.rb +8 -9
  216. data/spec/extensions/sql_expr_spec.rb +2 -0
  217. data/spec/extensions/string_date_time_spec.rb +2 -0
  218. data/spec/extensions/string_stripper_spec.rb +2 -0
  219. data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
  220. data/spec/extensions/thread_local_timezones_spec.rb +2 -0
  221. data/spec/extensions/timestamps_spec.rb +1 -1
  222. data/spec/extensions/to_dot_spec.rb +1 -1
  223. data/spec/extensions/touch_spec.rb +24 -24
  224. data/spec/extensions/tree_spec.rb +7 -7
  225. data/spec/extensions/typecast_on_load_spec.rb +8 -1
  226. data/spec/extensions/update_primary_key_spec.rb +10 -10
  227. data/spec/extensions/validation_class_methods_spec.rb +10 -39
  228. data/spec/extensions/validation_helpers_spec.rb +29 -47
  229. data/spec/extensions/xml_serializer_spec.rb +1 -23
  230. data/spec/integration/associations_test.rb +231 -40
  231. data/spec/integration/database_test.rb +1 -1
  232. data/spec/integration/dataset_test.rb +64 -64
  233. data/spec/integration/eager_loader_test.rb +28 -28
  234. data/spec/integration/migrator_test.rb +1 -1
  235. data/spec/integration/model_test.rb +2 -2
  236. data/spec/integration/plugin_test.rb +21 -21
  237. data/spec/integration/prepared_statement_test.rb +7 -7
  238. data/spec/integration/schema_test.rb +115 -110
  239. data/spec/integration/spec_helper.rb +17 -27
  240. data/spec/integration/timezone_test.rb +1 -1
  241. data/spec/integration/transaction_test.rb +10 -10
  242. data/spec/integration/type_test.rb +2 -2
  243. data/spec/model/association_reflection_spec.rb +2 -28
  244. data/spec/model/associations_spec.rb +239 -188
  245. data/spec/model/base_spec.rb +27 -68
  246. data/spec/model/dataset_methods_spec.rb +4 -4
  247. data/spec/model/eager_loading_spec.rb +160 -172
  248. data/spec/model/hooks_spec.rb +62 -79
  249. data/spec/model/model_spec.rb +36 -51
  250. data/spec/model/plugins_spec.rb +5 -19
  251. data/spec/model/record_spec.rb +125 -151
  252. data/spec/model/spec_helper.rb +8 -6
  253. data/spec/model/validations_spec.rb +4 -17
  254. data/spec/spec_config.rb +2 -10
  255. metadata +50 -56
  256. data/lib/sequel/deprecated_core_extensions.rb +0 -135
  257. data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
  258. data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
  259. data/lib/sequel/plugins/identity_map.rb +0 -260
  260. data/lib/sequel_core.rb +0 -2
  261. data/lib/sequel_model.rb +0 -2
  262. data/spec/extensions/association_autoreloading_spec.rb +0 -102
  263. data/spec/extensions/identity_map_spec.rb +0 -337
  264. data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
  265. data/spec/extensions/pg_statement_cache_spec.rb +0 -208
  266. data/spec/rcov.opts +0 -8
  267. data/spec/spec_config.rb.example +0 -10
@@ -1,69 +1,66 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
1
+ SEQUEL_ADAPTER_TEST = :oracle
2
2
 
3
- unless defined?(ORACLE_DB)
4
- ORACLE_DB = Sequel.connect('oracle://hr:hr@localhost/XE')
5
- end
6
- INTEGRATION_DB = ORACLE_DB unless defined?(INTEGRATION_DB)
3
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
7
4
 
8
5
  describe "An Oracle database" do
9
6
  before(:all) do
10
- ORACLE_DB.create_table!(:items) do
7
+ DB.create_table!(:items) do
11
8
  String :name, :size => 50
12
9
  Integer :value
13
10
  Date :date_created
14
11
  index :value
15
12
  end
16
13
 
17
- ORACLE_DB.create_table!(:books) do
14
+ DB.create_table!(:books) do
18
15
  Integer :id
19
16
  String :title, :size => 50
20
17
  Integer :category_id
21
18
  end
22
19
 
23
- ORACLE_DB.create_table!(:categories) do
20
+ DB.create_table!(:categories) do
24
21
  Integer :id
25
22
  String :cat_name, :size => 50
26
23
  end
27
- @d = ORACLE_DB[:items]
24
+ @d = DB[:items]
28
25
  end
29
26
  after do
30
27
  @d.delete
31
28
  end
32
29
  after(:all) do
33
- ORACLE_DB.drop_table?(:items, :books, :categories)
30
+ DB.drop_table?(:items, :books, :categories)
34
31
  end
35
32
 
36
33
  specify "should provide disconnect functionality" do
37
- ORACLE_DB.execute("select user from dual")
38
- ORACLE_DB.pool.size.should == 1
39
- ORACLE_DB.disconnect
40
- ORACLE_DB.pool.size.should == 0
34
+ DB.execute("select user from dual")
35
+ DB.pool.size.should == 1
36
+ DB.disconnect
37
+ DB.pool.size.should == 0
41
38
  end
42
39
 
43
40
  specify "should have working view_exists?" do
44
41
  begin
45
- ORACLE_DB.view_exists?(:cats).should be_false
46
- ORACLE_DB.create_view(:cats, ORACLE_DB[:categories])
47
- ORACLE_DB.view_exists?(:cats).should be_true
48
- om = ORACLE_DB.identifier_output_method
49
- im = ORACLE_DB.identifier_input_method
50
- ORACLE_DB.identifier_output_method = :reverse
51
- ORACLE_DB.identifier_input_method = :reverse
52
- ORACLE_DB.view_exists?(:STAC).should be_true
53
- ORACLE_DB.view_exists?(:cats).should be_false
42
+ DB.view_exists?(:cats).should be_false
43
+ DB.create_view(:cats, DB[:categories])
44
+ DB.view_exists?(:cats).should be_true
45
+ om = DB.identifier_output_method
46
+ im = DB.identifier_input_method
47
+ DB.identifier_output_method = :reverse
48
+ DB.identifier_input_method = :reverse
49
+ DB.view_exists?(:STAC).should be_true
50
+ DB.view_exists?(:cats).should be_false
54
51
  ensure
55
- ORACLE_DB.identifier_output_method = om
56
- ORACLE_DB.identifier_input_method = im
57
- ORACLE_DB.drop_view(:cats)
52
+ DB.identifier_output_method = om
53
+ DB.identifier_input_method = im
54
+ DB.drop_view(:cats)
58
55
  end
59
56
  end
60
57
 
61
58
  specify "should be able to get current sequence value with SQL" do
62
59
  begin
63
- ORACLE_DB.create_table!(:foo){primary_key :id}
64
- ORACLE_DB.fetch('SELECT seq_foo_id.nextval FROM DUAL').single_value.should == 1
60
+ DB.create_table!(:foo){primary_key :id}
61
+ DB.fetch('SELECT seq_foo_id.nextval FROM DUAL').single_value.should == 1
65
62
  ensure
66
- ORACLE_DB.drop_table(:foo)
63
+ DB.drop_table(:foo)
67
64
  end
68
65
  end
69
66
 
@@ -78,19 +75,19 @@ describe "An Oracle database" do
78
75
  [:date_created, [:datetime, false, true, nil]]]
79
76
 
80
77
  {:books => books_schema, :categories => categories_schema, :items => items_schema}.each_pair do |table, expected_schema|
81
- schema = ORACLE_DB.schema(table)
78
+ schema = DB.schema(table)
82
79
  schema.should_not be_nil
83
80
  schema.map{|c, s| [c, s.values_at(:type, :primary_key, :allow_null, :ruby_default)]}.should == expected_schema
84
81
  end
85
82
  end
86
83
 
87
84
  specify "should create a temporary table" do
88
- ORACLE_DB.create_table! :test_tmp, :temp => true do
85
+ DB.create_table! :test_tmp, :temp => true do
89
86
  varchar2 :name, :size => 50
90
87
  primary_key :id, :integer, :null => false
91
88
  index :name, :unique => true
92
89
  end
93
- ORACLE_DB.drop_table?(:test_tmp)
90
+ DB.drop_table?(:test_tmp)
94
91
  end
95
92
 
96
93
  specify "should return the correct record count" do
@@ -225,7 +222,7 @@ describe "An Oracle database" do
225
222
  end
226
223
 
227
224
  specify "should support transactions" do
228
- ORACLE_DB.transaction do
225
+ DB.transaction do
229
226
  @d << {:name => 'abc', :value => 1}
230
227
  end
231
228
 
@@ -233,14 +230,14 @@ describe "An Oracle database" do
233
230
  end
234
231
 
235
232
  specify "should return correct result" do
236
- @d1 = ORACLE_DB[:books]
233
+ @d1 = DB[:books]
237
234
  @d1.delete
238
235
  @d1 << {:id => 1, :title => 'aaa', :category_id => 100}
239
236
  @d1 << {:id => 2, :title => 'bbb', :category_id => 100}
240
237
  @d1 << {:id => 3, :title => 'ccc', :category_id => 101}
241
238
  @d1 << {:id => 4, :title => 'ddd', :category_id => 102}
242
239
 
243
- @d2 = ORACLE_DB[:categories]
240
+ @d2 = DB[:categories]
244
241
  @d2.delete
245
242
  @d2 << {:id => 100, :cat_name => 'ruby'}
246
243
  @d2 << {:id => 101, :cat_name => 'rails'}
@@ -270,7 +267,7 @@ describe "An Oracle database" do
270
267
  end
271
268
 
272
269
  specify "should allow columns to be renamed" do
273
- @d1 = ORACLE_DB[:books]
270
+ @d1 = DB[:books]
274
271
  @d1.delete
275
272
  @d1 << {:id => 1, :title => 'aaa', :category_id => 100}
276
273
  @d1 << {:id => 2, :title => 'bbb', :category_id => 100}
@@ -284,14 +281,14 @@ describe "An Oracle database" do
284
281
  end
285
282
 
286
283
  specify "nested queries should work" do
287
- ORACLE_DB[:books].select(:title).group_by(:title).count.should == 2
284
+ DB[:books].select(:title).group_by(:title).count.should == 2
288
285
  end
289
286
 
290
287
  specify "#for_update should use FOR UPDATE" do
291
- ORACLE_DB[:books].for_update.sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
288
+ DB[:books].for_update.sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
292
289
  end
293
290
 
294
291
  specify "#lock_style should accept symbols" do
295
- ORACLE_DB[:books].lock_style(:update).sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
292
+ DB[:books].lock_style(:update).sql.should == 'SELECT * FROM "BOOKS" FOR UPDATE'
296
293
  end
297
294
  end
@@ -1,26 +1,20 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
1
+ SEQUEL_ADAPTER_TEST = :postgres
2
2
 
3
- unless defined?(POSTGRES_DB)
4
- POSTGRES_URL = 'postgres://postgres:postgres@localhost:5432/reality_spec' unless defined? POSTGRES_URL
5
- POSTGRES_DB = Sequel.connect(ENV['SEQUEL_PG_SPEC_DB']||POSTGRES_URL)
6
- end
7
- INTEGRATION_DB = POSTGRES_DB unless defined?(INTEGRATION_DB)
3
+ require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
8
4
 
9
- def POSTGRES_DB.sqls
5
+ def DB.sqls
10
6
  (@sqls ||= [])
11
7
  end
12
8
  logger = Object.new
13
9
  def logger.method_missing(m, msg)
14
- POSTGRES_DB.sqls << msg
10
+ DB.sqls << msg
15
11
  end
16
- POSTGRES_DB.loggers << logger
17
-
18
- #POSTGRES_DB.instance_variable_set(:@server_version, 80200)
12
+ DB.loggers << logger
19
13
 
20
14
  describe "PostgreSQL", '#create_table' do
21
15
  before do
22
- @db = POSTGRES_DB
23
- POSTGRES_DB.sqls.clear
16
+ @db = DB
17
+ DB.sqls.clear
24
18
  end
25
19
  after do
26
20
  @db.drop_table?(:tmp_dolls)
@@ -48,31 +42,52 @@ describe "PostgreSQL", '#create_table' do
48
42
  end
49
43
  end
50
44
 
51
- describe "PostgreSQL temporary views" do
45
+ describe "PostgreSQL views" do
52
46
  before do
53
- @db = POSTGRES_DB
54
- @db.drop_view(:items_view) rescue nil
47
+ @db = DB
48
+ @db.drop_view(:items_view, :cascade=>true, :if_exists=>true)
55
49
  @db.create_table!(:items){Integer :number}
56
50
  @db[:items].insert(10)
57
51
  @db[:items].insert(20)
58
52
  end
59
53
  after do
54
+ @opts ||={}
55
+ @db.drop_view(:items_view, @opts.merge(:if_exists=>true, :cascade=>true)) rescue nil
60
56
  @db.drop_table?(:items)
61
57
  end
62
58
 
63
- specify "should be supported" do
59
+ specify "should support temporary views" do
64
60
  @db.create_view(:items_view, @db[:items].where(:number=>10), :temp=>true)
65
61
  @db[:items_view].map(:number).should == [10]
66
62
  @db.create_or_replace_view(:items_view, @db[:items].where(:number=>20), :temp=>true)
67
63
  @db[:items_view].map(:number).should == [20]
68
- @db.disconnect
69
- lambda{@db[:items_view].map(:number)}.should raise_error(Sequel::DatabaseError)
70
64
  end
71
- end unless POSTGRES_DB.adapter_scheme == :do # Causes freezing later
65
+
66
+ specify "should support recursive views" do
67
+ @db.create_view(:items_view, @db[:items].where(:number=>10).union(@db[:items, :items_view].where(Sequel.-(:number, 5)=>:n).select(:number), :all=>true, :from_self=>false), :recursive=>[:n])
68
+ @db[:items_view].select_order_map(:n).should == [10]
69
+ @db[:items].insert(15)
70
+ @db[:items_view].select_order_map(:n).should == [10, 15, 20]
71
+ end if DB.server_version >= 90300
72
+
73
+ specify "should support materialized views" do
74
+ @opts = {:materialized=>true}
75
+ @db.create_view(:items_view, @db[:items].where{number >= 10}, @opts)
76
+ @db[:items_view].select_order_map(:number).should == [10, 20]
77
+ @db[:items].insert(15)
78
+ @db[:items_view].select_order_map(:number).should == [10, 20]
79
+ @db.refresh_view(:items_view)
80
+ @db[:items_view].select_order_map(:number).should == [10, 15, 20]
81
+ end if DB.server_version >= 90300
82
+
83
+ specify "should support :if_exists=>true for not raising an error if the view does not exist" do
84
+ proc{@db.drop_view(:items_view, :if_exists=>true)}.should_not raise_error
85
+ end
86
+ end
72
87
 
73
88
  describe "A PostgreSQL database" do
74
89
  before(:all) do
75
- @db = POSTGRES_DB
90
+ @db = DB
76
91
  @db.create_table!(:public__testfk){primary_key :id; foreign_key :i, :public__testfk}
77
92
  end
78
93
  after(:all) do
@@ -118,7 +133,7 @@ end
118
133
 
119
134
  describe "A PostgreSQL database with domain types" do
120
135
  before(:all) do
121
- @db = POSTGRES_DB
136
+ @db = DB
122
137
  @db << "DROP DOMAIN IF EXISTS positive_number CASCADE"
123
138
  @db << "CREATE DOMAIN positive_number AS numeric(10,2) CHECK (VALUE > 0)"
124
139
  @db.create_table!(:testfk){positive_number :id, :primary_key=>true}
@@ -137,7 +152,7 @@ end
137
152
 
138
153
  describe "A PostgreSQL dataset" do
139
154
  before(:all) do
140
- @db = POSTGRES_DB
155
+ @db = DB
141
156
  @d = @db[:test]
142
157
  @db.create_table! :test do
143
158
  text :name
@@ -216,7 +231,7 @@ describe "A PostgreSQL dataset" do
216
231
  @db[:atest].insert(2)
217
232
  proc{@db[:atest].insert(2)}.should raise_error(Sequel::Postgres::ExclusionConstraintViolation)
218
233
  @db.alter_table(:atest){drop_constraint 'atest_ex'}
219
- end if POSTGRES_DB.server_version >= 90000
234
+ end if DB.server_version >= 90000
220
235
 
221
236
  specify "should support Database#do for executing anonymous code blocks" do
222
237
  @db.drop_table?(:btest)
@@ -225,7 +240,7 @@ describe "A PostgreSQL dataset" do
225
240
 
226
241
  @db.do "BEGIN EXECUTE 'DROP TABLE btest; CREATE TABLE atest (a INTEGER)'; EXECUTE 'INSERT INTO atest VALUES (1)'; END", :language=>:plpgsql
227
242
  @db[:atest].select_map(:a).should == [1]
228
- end if POSTGRES_DB.server_version >= 90000
243
+ end if DB.server_version >= 90000
229
244
 
230
245
  specify "should support adding foreign key constarints that are not yet valid, and validating them later" do
231
246
  @db.create_table!(:atest){primary_key :id; Integer :fk}
@@ -238,7 +253,7 @@ describe "A PostgreSQL dataset" do
238
253
  @db[:atest].where(:id=>1).update(:fk=>2)
239
254
  @db.alter_table(:atest){validate_constraint :atest_fk}
240
255
  proc{@db.alter_table(:atest){validate_constraint :atest_fk}}.should_not raise_error
241
- end if POSTGRES_DB.server_version >= 90200
256
+ end if DB.server_version >= 90200
242
257
 
243
258
  specify "should support :using when altering a column's type" do
244
259
  @db.create_table!(:atest){Integer :t}
@@ -305,7 +320,7 @@ describe "A PostgreSQL dataset" do
305
320
  @db.transaction(:isolation=>:serializable, :deferrable=>true, :read_only=>true){}
306
321
  @db.transaction(:isolation=>:serializable, :deferrable=>false, :read_only=>false){}
307
322
  @db.sqls.grep(/DEF/).should == ["SET TRANSACTION DEFERRABLE", "SET TRANSACTION NOT DEFERRABLE", "SET TRANSACTION READ ONLY DEFERRABLE", "SET TRANSACTION READ WRITE NOT DEFERRABLE", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE", "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE READ WRITE NOT DEFERRABLE"]
308
- end if POSTGRES_DB.server_version >= 90100
323
+ end if DB.server_version >= 90100
309
324
 
310
325
  specify "should support creating indexes concurrently" do
311
326
  @db.add_index :test, [:name, :value], :concurrently=>true
@@ -339,7 +354,7 @@ describe "A PostgreSQL dataset" do
339
354
  check_sqls do
340
355
  @db.sqls.should == ['DROP INDEX CONCURRENTLY "tnv2"']
341
356
  end
342
- end if POSTGRES_DB.server_version >= 90200
357
+ end if DB.server_version >= 90200
343
358
 
344
359
  specify "#lock should lock table if inside a transaction" do
345
360
  @db.transaction{@d.lock('EXCLUSIVE'); @d.insert(:name=>'a')}
@@ -376,7 +391,7 @@ end
376
391
 
377
392
  describe "Dataset#distinct" do
378
393
  before do
379
- @db = POSTGRES_DB
394
+ @db = DB
380
395
  @db.create_table!(:a) do
381
396
  Integer :a
382
397
  Integer :b
@@ -397,29 +412,29 @@ describe "Dataset#distinct" do
397
412
  end
398
413
  end
399
414
 
400
- if POSTGRES_DB.pool.respond_to?(:max_size) and POSTGRES_DB.pool.max_size > 1
415
+ if DB.pool.respond_to?(:max_size) and DB.pool.max_size > 1
401
416
  describe "Dataset#for_update support" do
402
417
  before do
403
- @db = POSTGRES_DB.create_table!(:items) do
418
+ @db = DB.create_table!(:items) do
404
419
  primary_key :id
405
420
  Integer :number
406
421
  String :name
407
422
  end
408
- @ds = POSTGRES_DB[:items]
423
+ @ds = DB[:items]
409
424
  end
410
425
  after do
411
- POSTGRES_DB.drop_table?(:items)
412
- POSTGRES_DB.disconnect
426
+ DB.drop_table?(:items)
427
+ DB.disconnect
413
428
  end
414
429
 
415
430
  specify "should handle FOR UPDATE" do
416
431
  @ds.insert(:number=>20)
417
432
  c, t = nil, nil
418
433
  q = Queue.new
419
- POSTGRES_DB.transaction do
434
+ DB.transaction do
420
435
  @ds.for_update.first(:id=>1)
421
436
  t = Thread.new do
422
- POSTGRES_DB.transaction do
437
+ DB.transaction do
423
438
  q.push nil
424
439
  @ds.filter(:id=>1).update(:name=>'Jim')
425
440
  c = @ds.first(:id=>1)
@@ -438,10 +453,10 @@ if POSTGRES_DB.pool.respond_to?(:max_size) and POSTGRES_DB.pool.max_size > 1
438
453
  @ds.insert(:number=>20)
439
454
  c, t = nil
440
455
  q = Queue.new
441
- POSTGRES_DB.transaction do
456
+ DB.transaction do
442
457
  @ds.for_share.first(:id=>1)
443
458
  t = Thread.new do
444
- POSTGRES_DB.transaction do
459
+ DB.transaction do
445
460
  c = @ds.for_share.filter(:id=>1).first
446
461
  q.push nil
447
462
  end
@@ -457,7 +472,7 @@ end
457
472
 
458
473
  describe "A PostgreSQL dataset with a timestamp field" do
459
474
  before(:all) do
460
- @db = POSTGRES_DB
475
+ @db = DB
461
476
  @db.create_table! :test3 do
462
477
  Date :date
463
478
  DateTime :time
@@ -492,7 +507,7 @@ describe "A PostgreSQL dataset with a timestamp field" do
492
507
  (t2.is_a?(Time) ? t2.usec : t2.strftime('%N').to_i/1000).should == t.strftime('%N').to_i/1000
493
508
  end
494
509
 
495
- if POSTGRES_DB.adapter_scheme == :postgres
510
+ if DB.adapter_scheme == :postgres
496
511
  specify "should handle infinite timestamps if convert_infinite_timestamps is set" do
497
512
  @d << {:time=>Sequel.cast('infinity', DateTime)}
498
513
  @db.convert_infinite_timestamps = :nil
@@ -566,7 +581,7 @@ describe "A PostgreSQL dataset with a timestamp field" do
566
581
  end
567
582
 
568
583
  specify "explain and analyze should not raise errors" do
569
- @d = POSTGRES_DB[:test3]
584
+ @d = DB[:test3]
570
585
  proc{@d.explain}.should_not raise_error
571
586
  proc{@d.analyze}.should_not raise_error
572
587
  end
@@ -579,7 +594,7 @@ end
579
594
 
580
595
  describe "A PostgreSQL database" do
581
596
  before do
582
- @db = POSTGRES_DB
597
+ @db = DB
583
598
  @db.create_table! :test2 do
584
599
  text :name
585
600
  integer :value
@@ -624,7 +639,7 @@ end
624
639
 
625
640
  describe "A PostgreSQL database" do
626
641
  before do
627
- @db = POSTGRES_DB
642
+ @db = DB
628
643
  @db.drop_table?(:posts)
629
644
  @db.sqls.clear
630
645
  end
@@ -671,12 +686,12 @@ describe "A PostgreSQL database" do
671
686
  end
672
687
 
673
688
  specify "should support fulltext indexes and searching" do
674
- @db.create_table(:posts){text :title; text :body; full_text_index [:title, :body]; full_text_index :title, :language => 'french'}
689
+ @db.create_table(:posts){text :title; text :body; full_text_index [:title, :body]; full_text_index :title, :language => 'french', :index_type=>:gist}
675
690
  check_sqls do
676
691
  @db.sqls.should == [
677
692
  %{CREATE TABLE "posts" ("title" text, "body" text)},
678
693
  %{CREATE INDEX "posts_title_body_index" ON "posts" USING gin (to_tsvector('simple'::regconfig, (COALESCE("title", '') || ' ' || COALESCE("body", ''))))},
679
- %{CREATE INDEX "posts_title_index" ON "posts" USING gin (to_tsvector('french'::regconfig, (COALESCE("title", ''))))}
694
+ %{CREATE INDEX "posts_title_index" ON "posts" USING gist (to_tsvector('french'::regconfig, (COALESCE("title", ''))))}
680
695
  ]
681
696
  end
682
697
 
@@ -757,7 +772,7 @@ end
757
772
 
758
773
  describe "Postgres::Dataset#import" do
759
774
  before do
760
- @db = POSTGRES_DB
775
+ @db = DB
761
776
  @db.create_table!(:test){primary_key :x; Integer :y}
762
777
  @db.sqls.clear
763
778
  @ds = @db[:test]
@@ -793,7 +808,7 @@ end
793
808
 
794
809
  describe "Postgres::Dataset#insert" do
795
810
  before do
796
- @db = POSTGRES_DB
811
+ @db = DB
797
812
  @db.create_table!(:test5){primary_key :xid; Integer :value}
798
813
  @db.sqls.clear
799
814
  @ds = @db[:test5]
@@ -844,14 +859,13 @@ end
844
859
 
845
860
  describe "Postgres::Database schema qualified tables" do
846
861
  before do
847
- @db = POSTGRES_DB
862
+ @db = DB
848
863
  @db << "CREATE SCHEMA schema_test"
849
864
  @db.instance_variable_set(:@primary_keys, {})
850
865
  @db.instance_variable_set(:@primary_key_sequences, {})
851
866
  end
852
867
  after do
853
868
  @db << "DROP SCHEMA schema_test CASCADE"
854
- @db.default_schema = nil
855
869
  end
856
870
 
857
871
  specify "should be able to create, drop, select and insert into tables in a given schema" do
@@ -869,7 +883,7 @@ describe "Postgres::Database schema qualified tables" do
869
883
 
870
884
  specify "#tables should not include tables in a default non-public schema" do
871
885
  @db.create_table(:schema_test__schema_test){integer :i}
872
- @db.tables.should include(:schema_test)
886
+ @db.tables(:schema=>:schema_test).should include(:schema_test)
873
887
  @db.tables.should_not include(:pg_am)
874
888
  @db.tables.should_not include(:domain_udt_usage)
875
889
  end
@@ -965,7 +979,7 @@ end
965
979
 
966
980
  describe "Postgres::Database schema qualified tables and eager graphing" do
967
981
  before(:all) do
968
- @db = POSTGRES_DB
982
+ @db = DB
969
983
  @db.run "DROP SCHEMA s CASCADE" rescue nil
970
984
  @db.run "CREATE SCHEMA s"
971
985
 
@@ -1141,21 +1155,21 @@ describe "Postgres::Database schema qualified tables and eager graphing" do
1141
1155
 
1142
1156
  end
1143
1157
 
1144
- if POSTGRES_DB.server_version >= 80300
1158
+ if DB.server_version >= 80300
1145
1159
  describe "PostgreSQL tsearch2" do
1146
1160
  before(:all) do
1147
- POSTGRES_DB.create_table! :test6 do
1161
+ DB.create_table! :test6 do
1148
1162
  text :title
1149
1163
  text :body
1150
1164
  full_text_index [:title, :body]
1151
1165
  end
1152
- @ds = POSTGRES_DB[:test6]
1166
+ @ds = DB[:test6]
1153
1167
  end
1154
1168
  after do
1155
- POSTGRES_DB[:test6].delete
1169
+ DB[:test6].delete
1156
1170
  end
1157
1171
  after(:all) do
1158
- POSTGRES_DB.drop_table?(:test6)
1172
+ DB.drop_table?(:test6)
1159
1173
  end
1160
1174
 
1161
1175
  specify "should search by indexed column" do
@@ -1178,10 +1192,10 @@ if POSTGRES_DB.server_version >= 80300
1178
1192
  end
1179
1193
  end
1180
1194
 
1181
- if POSTGRES_DB.dataset.supports_window_functions?
1195
+ if DB.dataset.supports_window_functions?
1182
1196
  describe "Postgres::Dataset named windows" do
1183
1197
  before do
1184
- @db = POSTGRES_DB
1198
+ @db = DB
1185
1199
  @db.create_table!(:i1){Integer :id; Integer :group_id; Integer :amount}
1186
1200
  @ds = @db[:i1].order(:id)
1187
1201
  @ds.insert(:id=>1, :group_id=>1, :amount=>1)
@@ -1210,7 +1224,7 @@ end
1210
1224
 
1211
1225
  describe "Postgres::Database functions, languages, schemas, and triggers" do
1212
1226
  before do
1213
- @d = POSTGRES_DB
1227
+ @d = DB
1214
1228
  end
1215
1229
  after do
1216
1230
  @d.drop_function('tf', :if_exists=>true, :cascade=>true)
@@ -1260,9 +1274,11 @@ describe "Postgres::Database functions, languages, schemas, and triggers" do
1260
1274
 
1261
1275
  specify "#create_schema and #drop_schema should create and drop schemas" do
1262
1276
  @d.send(:create_schema_sql, :sequel).should == 'CREATE SCHEMA "sequel"'
1277
+ @d.send(:create_schema_sql, :sequel, :if_not_exists=>true, :owner=>:foo).should == 'CREATE SCHEMA IF NOT EXISTS "sequel" AUTHORIZATION "foo"'
1263
1278
  @d.send(:drop_schema_sql, :sequel).should == 'DROP SCHEMA "sequel"'
1264
1279
  @d.send(:drop_schema_sql, :sequel, :if_exists=>true, :cascade=>true).should == 'DROP SCHEMA IF EXISTS "sequel" CASCADE'
1265
1280
  @d.create_schema(:sequel)
1281
+ @d.create_schema(:sequel, :if_not_exists=>true) if @d.server_version >= 90300
1266
1282
  @d.create_table(:sequel__test){Integer :a}
1267
1283
  @d.drop_schema(:sequel, :if_exists=>true, :cascade=>true)
1268
1284
  end
@@ -1288,10 +1304,10 @@ describe "Postgres::Database functions, languages, schemas, and triggers" do
1288
1304
  end
1289
1305
  end
1290
1306
 
1291
- if POSTGRES_DB.adapter_scheme == :postgres
1307
+ if DB.adapter_scheme == :postgres
1292
1308
  describe "Postgres::Dataset #use_cursor" do
1293
1309
  before(:all) do
1294
- @db = POSTGRES_DB
1310
+ @db = DB
1295
1311
  @db.create_table!(:test_cursor){Integer :x}
1296
1312
  @db.sqls.clear
1297
1313
  @ds = @db[:test_cursor]
@@ -1329,7 +1345,7 @@ if POSTGRES_DB.adapter_scheme == :postgres
1329
1345
 
1330
1346
  describe "Postgres::PG_NAMED_TYPES" do
1331
1347
  before do
1332
- @db = POSTGRES_DB
1348
+ @db = DB
1333
1349
  Sequel::Postgres::PG_NAMED_TYPES[:interval] = lambda{|v| v.reverse}
1334
1350
  @db.extension :pg_array
1335
1351
  @db.reset_conversion_procs
@@ -1354,10 +1370,10 @@ if POSTGRES_DB.adapter_scheme == :postgres
1354
1370
  end
1355
1371
  end
1356
1372
 
1357
- if ((POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG) || POSTGRES_DB.adapter_scheme == :jdbc) && POSTGRES_DB.server_version >= 90000
1373
+ if ((DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG) || DB.adapter_scheme == :jdbc) && DB.server_version >= 90000
1358
1374
  describe "Postgres::Database#copy_into" do
1359
1375
  before(:all) do
1360
- @db = POSTGRES_DB
1376
+ @db = DB
1361
1377
  @db.create_table!(:test_copy){Integer :x; Integer :y}
1362
1378
  @ds = @db[:test_copy].order(:x, :y)
1363
1379
  end
@@ -1436,7 +1452,7 @@ if ((POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG) || POST
1436
1452
 
1437
1453
  describe "Postgres::Database#copy_table" do
1438
1454
  before(:all) do
1439
- @db = POSTGRES_DB
1455
+ @db = DB
1440
1456
  @db.create_table!(:test_copy){Integer :x; Integer :y}
1441
1457
  ds = @db[:test_copy]
1442
1458
  ds.insert(1, 2)
@@ -1506,10 +1522,10 @@ if ((POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG) || POST
1506
1522
  end
1507
1523
  end
1508
1524
 
1509
- if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRES_DB.server_version >= 90000
1525
+ if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && DB.server_version >= 90000
1510
1526
  describe "Postgres::Database LISTEN/NOTIFY" do
1511
1527
  before(:all) do
1512
- @db = POSTGRES_DB
1528
+ @db = DB
1513
1529
  end
1514
1530
 
1515
1531
  specify "should support listen and notify" do
@@ -1591,7 +1607,7 @@ end
1591
1607
 
1592
1608
  describe 'PostgreSQL special float handling' do
1593
1609
  before do
1594
- @db = POSTGRES_DB
1610
+ @db = DB
1595
1611
  @db.create_table!(:test5){Float :value}
1596
1612
  @db.sqls.clear
1597
1613
  @ds = @db[:test5]
@@ -1617,7 +1633,7 @@ describe 'PostgreSQL special float handling' do
1617
1633
  end
1618
1634
  end
1619
1635
 
1620
- if POSTGRES_DB.adapter_scheme == :postgres
1636
+ if DB.adapter_scheme == :postgres
1621
1637
  specify 'inserts NaN' do
1622
1638
  nan = 0.0/0.0
1623
1639
  @ds.insert(:value=>nan)
@@ -1640,11 +1656,11 @@ end
1640
1656
 
1641
1657
  describe 'PostgreSQL array handling' do
1642
1658
  before(:all) do
1643
- @db = POSTGRES_DB
1659
+ @db = DB
1644
1660
  @db.extension :pg_array
1645
1661
  @ds = @db[:items]
1646
- @native = POSTGRES_DB.adapter_scheme == :postgres
1647
- @jdbc = POSTGRES_DB.adapter_scheme == :jdbc
1662
+ @native = DB.adapter_scheme == :postgres
1663
+ @jdbc = DB.adapter_scheme == :jdbc
1648
1664
  @tp = lambda{@db.schema(:items).map{|a| a.last[:type]}}
1649
1665
  end
1650
1666
  after do
@@ -1841,7 +1857,7 @@ describe 'PostgreSQL array handling' do
1841
1857
  @ds.insert(rs.first)
1842
1858
  @ds.all.should == rs
1843
1859
  end
1844
- end unless POSTGRES_DB.adapter_scheme == :jdbc
1860
+ end unless DB.adapter_scheme == :jdbc
1845
1861
 
1846
1862
  specify 'use arrays in bound variables' do
1847
1863
  @db.create_table!(:items) do
@@ -1901,7 +1917,7 @@ describe 'PostgreSQL array handling' do
1901
1917
  @ds.get(:i).should == a
1902
1918
  @ds.filter(:i=>:$i).call(:first, :i=>a).should == {:i=>a}
1903
1919
  @ds.filter(:i=>:$i).call(:first, :i=>Sequel.pg_array([Sequel.blob("b\0")], 'bytea')).should == nil
1904
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
1920
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
1905
1921
 
1906
1922
  specify 'with models' do
1907
1923
  @db.create_table!(:items) do
@@ -1943,6 +1959,10 @@ describe 'PostgreSQL array handling' do
1943
1959
  @ds.get(Sequel.expr(1=>Sequel.pg_array(:i3).all)).should be_false
1944
1960
  @ds.get(Sequel.expr(4=>Sequel.pg_array(:i3).all)).should be_true
1945
1961
 
1962
+ @ds.get(Sequel.expr(1=>Sequel.pg_array(:i)[1..1].any)).should be_true
1963
+ @ds.get(Sequel.expr(2=>Sequel.pg_array(:i)[1..1].any)).should be_false
1964
+
1965
+ @ds.get(Sequel.pg_array(:i2)[1]).should == 2
1946
1966
  @ds.get(Sequel.pg_array(:i2)[1]).should == 2
1947
1967
  @ds.get(Sequel.pg_array(:i2)[2]).should == 1
1948
1968
 
@@ -1962,28 +1982,41 @@ describe 'PostgreSQL array handling' do
1962
1982
  @ds.get(Sequel.pg_array(:i).length).should == 3
1963
1983
  @ds.get(Sequel.pg_array(:i).lower).should == 1
1964
1984
 
1985
+ if @db.server_version >= 80400
1986
+ @ds.select(Sequel.pg_array(:i).unnest).from_self.count.should == 3
1987
+ end
1965
1988
  if @db.server_version >= 90000
1966
1989
  @ds.get(Sequel.pg_array(:i5).join).should == '15'
1967
1990
  @ds.get(Sequel.pg_array(:i5).join(':')).should == '1:5'
1968
1991
  @ds.get(Sequel.pg_array(:i5).join(':', '*')).should == '1:*:5'
1969
1992
  end
1970
- @ds.select(Sequel.pg_array(:i).unnest).from_self.count.should == 3 if @db.server_version >= 80400
1993
+ if @db.server_version >= 90300
1994
+ @ds.get(Sequel.pg_array(:i5).remove(1).length).should == 2
1995
+ @ds.get(Sequel.pg_array(:i5).replace(1, 4).contains([1])).should be_false
1996
+ @ds.get(Sequel.pg_array(:i5).replace(1, 4).contains([4])).should be_true
1997
+ end
1971
1998
 
1972
1999
  if @native
1973
2000
  @ds.get(Sequel.pg_array(:i).push(4)).should == [1, 2, 3, 4]
1974
2001
  @ds.get(Sequel.pg_array(:i).unshift(4)).should == [4, 1, 2, 3]
1975
2002
  @ds.get(Sequel.pg_array(:i).concat(:i2)).should == [1, 2, 3, 2, 1]
1976
2003
  end
2004
+
2005
+ if @db.type_supported?(:hstore)
2006
+ Sequel.extension :pg_hstore, :pg_hstore_ops
2007
+ @db.get(Sequel.pg_array(['a', 'b']).op.hstore['a']).should == 'b'
2008
+ @db.get(Sequel.pg_array(['a', 'b']).op.hstore(['c', 'd'])['a']).should == 'c'
2009
+ end
1977
2010
  end
1978
2011
  end
1979
2012
 
1980
2013
  describe 'PostgreSQL hstore handling' do
1981
2014
  before(:all) do
1982
- @db = POSTGRES_DB
2015
+ @db = DB
1983
2016
  @db.extension :pg_array, :pg_hstore
1984
2017
  @ds = @db[:items]
1985
2018
  @h = {'a'=>'b', 'c'=>nil, 'd'=>'NULL', 'e'=>'\\\\" \\\' ,=>'}
1986
- @native = POSTGRES_DB.adapter_scheme == :postgres
2019
+ @native = DB.adapter_scheme == :postgres
1987
2020
  end
1988
2021
  after do
1989
2022
  @db.drop_table?(:items)
@@ -2043,7 +2076,7 @@ describe 'PostgreSQL hstore handling' do
2043
2076
  @ds.get(:i).should == @h
2044
2077
  @ds.filter(:i=>:$i).call(:first, :i=>@h).should == {:i=>@h}
2045
2078
  @ds.filter(:i=>:$i).call(:first, :i=>{}).should == nil
2046
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2079
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2047
2080
 
2048
2081
  specify 'with models and associations' do
2049
2082
  @db.create_table!(:items) do
@@ -2224,16 +2257,16 @@ describe 'PostgreSQL hstore handling' do
2224
2257
  @ds.get(h1.avals.length).should == 2
2225
2258
  @ds.get(h2.avals.length).should == 1
2226
2259
  end
2227
- end if POSTGRES_DB.type_supported?(:hstore)
2260
+ end if DB.type_supported?(:hstore)
2228
2261
 
2229
2262
  describe 'PostgreSQL json type' do
2230
2263
  before(:all) do
2231
- @db = POSTGRES_DB
2264
+ @db = DB
2232
2265
  @db.extension :pg_array, :pg_json
2233
2266
  @ds = @db[:items]
2234
2267
  @a = [1, 2, {'a'=>'b'}, 3.0]
2235
2268
  @h = {'a'=>'b', '1'=>[3, 4, 5]}
2236
- @native = POSTGRES_DB.adapter_scheme == :postgres
2269
+ @native = DB.adapter_scheme == :postgres
2237
2270
  end
2238
2271
  after do
2239
2272
  @db.drop_table?(:items)
@@ -2312,7 +2345,7 @@ describe 'PostgreSQL json type' do
2312
2345
  @ds.get(:i).should == j
2313
2346
  @ds.filter(Sequel.cast(:i, 'text[]')=>:$i).call(:first, :i=>j).should == {:i=>j}
2314
2347
  @ds.filter(Sequel.cast(:i, 'text[]')=>:$i).call(:first, :i=>Sequel.pg_array([])).should == nil
2315
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2348
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2316
2349
 
2317
2350
  specify 'with models' do
2318
2351
  @db.create_table!(:items) do
@@ -2324,13 +2357,55 @@ describe 'PostgreSQL json type' do
2324
2357
  c.create(:h=>Sequel.pg_json(@h)).h.should == @h
2325
2358
  c.create(:h=>Sequel.pg_json(@a)).h.should == @a
2326
2359
  end
2327
- end if POSTGRES_DB.server_version >= 90200
2360
+
2361
+ specify 'operations/functions with pg_json_ops' do
2362
+ Sequel.extension :pg_json_ops
2363
+ jo = Sequel.pg_json('a'=>1, 'b'=>{'c'=>2, 'd'=>{'e'=>3}}).op
2364
+ ja = Sequel.pg_json([2, 3, %w'a b']).op
2365
+
2366
+ @db.get(jo['a']).should == 1
2367
+ @db.get(jo['b']['c']).should == 2
2368
+ @db.get(jo[%w'b c']).should == 2
2369
+ @db.get(jo['b'].get_text(%w'd e')).should == "3"
2370
+ @db.get(jo[%w'b d'].get_text('e')).should == "3"
2371
+ @db.get(ja[1]).should == 3
2372
+ @db.get(ja[%w'2 1']).should == 'b'
2373
+
2374
+ @db.get(jo.extract('a')).should == 1
2375
+ @db.get(jo.extract('b').extract('c')).should == 2
2376
+ @db.get(jo.extract('b', 'c')).should == 2
2377
+ @db.get(jo.extract('b', 'd', 'e')).should == 3
2378
+ @db.get(jo.extract_text('b', 'd')).should == '{"e":3}'
2379
+ @db.get(jo.extract_text('b', 'd', 'e')).should == '3'
2380
+
2381
+ @db.get(ja.array_length).should == 3
2382
+ @db.from(ja.array_elements.as(:v)).select_map(:v).should == [2, 3, %w'a b']
2383
+
2384
+ @db.from(jo.keys.as(:k)).select_order_map(:k).should == %w'a b'
2385
+ @db.from(jo.each).select_order_map(:key).should == %w'a b'
2386
+ @db.from(jo.each).order(:key).select_map(:value).should == [1, {'c'=>2, 'd'=>{'e'=>3}}]
2387
+ @db.from(jo.each_text).select_order_map(:key).should == %w'a b'
2388
+ @db.from(jo.each_text).order(:key).where(:key=>'b').get(:value).should =~ /\{"d":\{"e":3\},"c":2\}|\{"c":2,"d":\{"e":3\}\}/
2389
+
2390
+ Sequel.extension :pg_row_ops
2391
+ @db.create_table!(:items) do
2392
+ Integer :a
2393
+ String :b
2394
+ end
2395
+ j = Sequel.pg_json('a'=>1, 'b'=>'c').op
2396
+ @db.get(j.populate(Sequel.cast(nil, :items)).pg_row[:a]).should == 1
2397
+ @db.get(j.populate(Sequel.cast(nil, :items)).pg_row[:b]).should == 'c'
2398
+ j = Sequel.pg_json([{'a'=>1, 'b'=>'c'}, {'a'=>2, 'b'=>'d'}]).op
2399
+ @db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:a).should == [1, 2]
2400
+ @db.from(j.populate_set(Sequel.cast(nil, :items))).select_order_map(:b).should == %w'c d'
2401
+ end if DB.server_version >= 90300 && DB.adapter_scheme == :postgres
2402
+ end if DB.server_version >= 90200
2328
2403
 
2329
2404
  describe 'PostgreSQL inet/cidr types' do
2330
2405
  ipv6_broken = (IPAddr.new('::1'); false) rescue true
2331
2406
 
2332
2407
  before(:all) do
2333
- @db = POSTGRES_DB
2408
+ @db = DB
2334
2409
  @db.extension :pg_array, :pg_inet
2335
2410
  @ds = @db[:items]
2336
2411
  @v4 = '127.0.0.1'
@@ -2343,7 +2418,7 @@ describe 'PostgreSQL inet/cidr types' do
2343
2418
  @ipv6 = IPAddr.new(@v6)
2344
2419
  @ipv6nm = IPAddr.new(@v6nm)
2345
2420
  end
2346
- @native = POSTGRES_DB.adapter_scheme == :postgres
2421
+ @native = DB.adapter_scheme == :postgres
2347
2422
  end
2348
2423
  after do
2349
2424
  @db.drop_table?(:items)
@@ -2424,7 +2499,7 @@ describe 'PostgreSQL inet/cidr types' do
2424
2499
  @ds.filter(:i=>:$i, :c=>:$c, :m=>:$m).call(:first, :i=>[@ipv4], :c=>[@ipv4nm], :m=>['12:34:56:78:90:ab']).should == {:i=>[@ipv4], :c=>[@ipv4nm], :m=>['12:34:56:78:90:ab']}
2425
2500
  @ds.filter(:i=>:$i, :c=>:$c, :m=>:$m).call(:first, :i=>[], :c=>[], :m=>[]).should == nil
2426
2501
  @ds.filter(:i=>:$i, :c=>:$c, :m=>:$m).call(:delete, :i=>[@ipv4], :c=>[@ipv4nm], :m=>['12:34:56:78:90:ab']).should == 1
2427
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2502
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2428
2503
 
2429
2504
  specify 'with models' do
2430
2505
  @db.create_table!(:items) do
@@ -2443,7 +2518,7 @@ end
2443
2518
 
2444
2519
  describe 'PostgreSQL range types' do
2445
2520
  before(:all) do
2446
- @db = POSTGRES_DB
2521
+ @db = DB
2447
2522
  @db.extension :pg_array, :pg_range
2448
2523
  @ds = @db[:items]
2449
2524
  @map = {:i4=>'int4range', :i8=>'int8range', :n=>'numrange', :d=>'daterange', :t=>'tsrange', :tz=>'tstzrange'}
@@ -2454,7 +2529,7 @@ describe 'PostgreSQL range types' do
2454
2529
  @r.each{|k, v| @ra[k] = Sequel.pg_array([v], @map[k])}
2455
2530
  @r.each{|k, v| @pgr[k] = Sequel.pg_range(v)}
2456
2531
  @r.each{|k, v| @pgra[k] = Sequel.pg_array([Sequel.pg_range(v)], @map[k])}
2457
- @native = POSTGRES_DB.adapter_scheme == :postgres
2532
+ @native = DB.adapter_scheme == :postgres
2458
2533
  end
2459
2534
  after do
2460
2535
  @db.drop_table?(:items)
@@ -2526,7 +2601,7 @@ describe 'PostgreSQL range types' do
2526
2601
  @ds.filter(h).call(:first, @pgra).each{|k, v| v.should == @ra[k].to_a}
2527
2602
  @ds.filter(h).call(:first, r2).should == nil
2528
2603
  @ds.filter(h).call(:delete, @ra).should == 1
2529
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2604
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2530
2605
 
2531
2606
  specify 'with models' do
2532
2607
  @db.create_table!(:items){primary_key :id; int4range :i4; int8range :i8; numrange :n; daterange :d; tsrange :t; tstzrange :tz}
@@ -2614,14 +2689,14 @@ describe 'PostgreSQL range types' do
2614
2689
  @db.get(Sequel::Postgres::PGRange.new(1, 5, :db_type=>:int4range).op.upper_inf).should be_false
2615
2690
  @db.get(Sequel::Postgres::PGRange.new(1, nil, :db_type=>:int4range).op.upper_inf).should be_true
2616
2691
  end
2617
- end if POSTGRES_DB.server_version >= 90200
2692
+ end if DB.server_version >= 90200
2618
2693
 
2619
2694
  describe 'PostgreSQL interval types' do
2620
2695
  before(:all) do
2621
- @db = POSTGRES_DB
2696
+ @db = DB
2622
2697
  @db.extension :pg_array, :pg_interval
2623
2698
  @ds = @db[:items]
2624
- @native = POSTGRES_DB.adapter_scheme == :postgres
2699
+ @native = DB.adapter_scheme == :postgres
2625
2700
  end
2626
2701
  after(:all) do
2627
2702
  Sequel::Postgres::PG_TYPES.delete(1186)
@@ -2699,7 +2774,7 @@ describe 'PostgreSQL interval types' do
2699
2774
  @ds.filter(:i=>:$i).call(:first, :i=>[d]).should == {:i=>[d]}
2700
2775
  @ds.filter(:i=>:$i).call(:first, :i=>[]).should == nil
2701
2776
  @ds.filter(:i=>:$i).call(:delete, :i=>[d]).should == 1
2702
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2777
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2703
2778
 
2704
2779
  specify 'with models' do
2705
2780
  @db.create_table!(:items) do
@@ -2717,7 +2792,7 @@ end if (begin require 'active_support/duration'; require 'active_support/inflect
2717
2792
 
2718
2793
  describe 'PostgreSQL row-valued/composite types' do
2719
2794
  before(:all) do
2720
- @db = POSTGRES_DB
2795
+ @db = DB
2721
2796
  Sequel.extension :pg_array_ops, :pg_row_ops
2722
2797
  @db.extension :pg_array, :pg_row
2723
2798
  @ds = @db[:person]
@@ -2739,7 +2814,7 @@ describe 'PostgreSQL row-valued/composite types' do
2739
2814
  @db.register_row_type(Sequel.qualify(:public, :person))
2740
2815
  @db.register_row_type(:public__company)
2741
2816
 
2742
- @native = POSTGRES_DB.adapter_scheme == :postgres
2817
+ @native = DB.adapter_scheme == :postgres
2743
2818
  end
2744
2819
  after(:all) do
2745
2820
  @db.drop_table?(:company, :person, :address)
@@ -2784,7 +2859,7 @@ describe 'PostgreSQL row-valued/composite types' do
2784
2859
  @db.drop_table(:domain_check)
2785
2860
  @db << "DROP DOMAIN positive_integer"
2786
2861
  end
2787
- end if POSTGRES_DB.adapter_scheme == :postgres
2862
+ end if DB.adapter_scheme == :postgres
2788
2863
 
2789
2864
  specify 'insert and retrieve arrays of row types' do
2790
2865
  @ds = @db[:company]
@@ -2814,7 +2889,7 @@ describe 'PostgreSQL row-valued/composite types' do
2814
2889
  @ds.delete
2815
2890
  @ds.call(:insert, {:address=>Sequel.pg_row([nil, nil, nil])}, {:address=>:$address, :id=>1})
2816
2891
  @ds.get(:address).should == {:street=>nil, :city=>nil, :zip=>nil}
2817
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2892
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2818
2893
 
2819
2894
  specify 'use arrays of row types in bound variables' do
2820
2895
  @ds = @db[:company]
@@ -2826,7 +2901,7 @@ describe 'PostgreSQL row-valued/composite types' do
2826
2901
  @ds.delete
2827
2902
  @ds.call(:insert, {:employees=>Sequel.pg_array([@db.row_type(:person, [1, Sequel.pg_row([nil, nil, nil])])])}, {:employees=>:$employees, :id=>1})
2828
2903
  @ds.get(:employees).should == [{:address=>{:city=>nil, :zip=>nil, :street=>nil}, :id=>1}]
2829
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2904
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2830
2905
 
2831
2906
  specify 'operations/functions with pg_row_ops' do
2832
2907
  @ds.insert(:id=>1, :address=>Sequel.pg_row(['123 Sesame St', 'Somewhere', '12345']))
@@ -2952,7 +3027,7 @@ describe 'PostgreSQL row-valued/composite types' do
2952
3027
  @ds.get(:address).should == @a
2953
3028
  @ds.filter(:address=>Sequel.cast(:$address, :address)).call(:first, :address=>@a)[:id].should == 1
2954
3029
  @ds.filter(:address=>Sequel.cast(:$address, :address)).call(:first, :address=>Address.new(:street=>'123 Sesame St', :city=>'Somewhere', :zip=>'12356')).should == nil
2955
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
3030
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2956
3031
 
2957
3032
  specify 'use arrays of model objects in bound variables' do
2958
3033
  @ds = @db[:company]
@@ -2960,7 +3035,7 @@ describe 'PostgreSQL row-valued/composite types' do
2960
3035
  @ds.get(:company).should == Company.new(:id=>1, :employees=>@es)
2961
3036
  @ds.filter(:employees=>Sequel.cast(:$employees, 'person[]')).call(:first, :employees=>@es)[:id].should == 1
2962
3037
  @ds.filter(:employees=>Sequel.cast(:$employees, 'person[]')).call(:first, :employees=>Sequel.pg_array([@db.row_type(:person, [1, Sequel.pg_row(['123 Sesame St', 'Somewhere', '12356'])])])).should == nil
2963
- end if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
3038
+ end if DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG
2964
3039
 
2965
3040
  specify 'model typecasting' do
2966
3041
  Person.plugin :pg_typecast_on_load, :address unless @native