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,5 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ Sequel.extension :pg_array, :pg_array_ops, :pg_hstore, :pg_hstore_ops
4
+
3
5
  describe "Sequel::Postgres::ArrayOp" do
4
6
  before do
5
7
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
@@ -18,6 +20,10 @@ describe "Sequel::Postgres::ArrayOp" do
18
20
  @db.literal(@a[1][2]).should == "a[1][2]"
19
21
  end
20
22
 
23
+ it "#[] with a range should return an ArrayOp" do
24
+ @db.literal(@a[1..2].any).should == "ANY(a[1:2])"
25
+ end
26
+
21
27
  it "#any should use the ANY method" do
22
28
  @db.literal(1=>@a.any).should == "(1 = ANY(a))"
23
29
  end
@@ -43,6 +49,16 @@ describe "Sequel::Postgres::ArrayOp" do
43
49
  @db.literal(@a.concat(:b)).should == "(a || b)"
44
50
  end
45
51
 
52
+ it "#remove should remove the element from the array" do
53
+ @db.literal(@a.remove(1)).should == "array_remove(a, 1)"
54
+ @db.literal(@a.remove(1)[2]).should == "array_remove(a, 1)[2]"
55
+ end
56
+
57
+ it "#remove should replace the element in the array with another" do
58
+ @db.literal(@a.replace(1, 2)).should == "array_replace(a, 1, 2)"
59
+ @db.literal(@a.replace(1, 2)[3]).should == "array_replace(a, 1, 2)[3]"
60
+ end
61
+
46
62
  it "#unshift should use the || operator in prepend mode" do
47
63
  @db.literal(@a.unshift(:b)).should == "(b || a)"
48
64
  end
@@ -68,6 +84,15 @@ describe "Sequel::Postgres::ArrayOp" do
68
84
  @db.literal(@a.join(':', '*')).should == "array_to_string(a, ':', '*')"
69
85
  end
70
86
 
87
+ it "#hstore should convert the item to an hstore using the hstore function" do
88
+ @db.literal(@a.hstore).should == "hstore(a)"
89
+ @db.literal(@a.hstore['a']).should == "(hstore(a) -> 'a')"
90
+ @db.literal(@a.hstore(:b)).should == "hstore(a, b)"
91
+ @db.literal(@a.hstore(:b)['a']).should == "(hstore(a, b) -> 'a')"
92
+ @db.literal(@a.hstore(%w'1')).should == "hstore(a, ARRAY['1'])"
93
+ @db.literal(@a.hstore(%w'1')['a']).should == "(hstore(a, ARRAY['1']) -> 'a')"
94
+ end
95
+
71
96
  it "#unnest should use the unnest function" do
72
97
  @db.literal(@a.unnest).should == "unnest(a)"
73
98
  end
@@ -2,10 +2,13 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "pg_array extension" do
4
4
  before(:all) do
5
+ Sequel.extension :pg_array
5
6
  @pg_types = Sequel::Postgres::PG_TYPES.dup
7
+ @pg_named_types = Sequel::Postgres::PG_NAMED_TYPES.dup
6
8
  end
7
9
  after(:all) do
8
10
  Sequel::Postgres::PG_TYPES.replace(@pg_types)
11
+ Sequel::Postgres::PG_NAMED_TYPES.replace(@pg_named_types)
9
12
  end
10
13
 
11
14
  before do
@@ -357,10 +360,15 @@ describe "pg_array extension" do
357
360
  @db.typecast_value(:banana_array, %w'1 2').should == [1,2]
358
361
  end
359
362
 
360
- it "should set appropriate timestamp conversion procs when getting conversion procs" do
363
+ it "should set appropriate timestamp conversion procs when resetting conversion procs" do
364
+ Sequel::Postgres::PG_NAMED_TYPES[:foo] = proc{|v| v*2}
365
+ @db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
366
+ @db.reset_conversion_procs
361
367
  procs = @db.conversion_procs
362
368
  procs[1185].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
363
369
  procs[1115].call('{"2011-10-20 11:12:13"}').should == [Time.local(2011, 10, 20, 11, 12, 13)]
370
+ procs[2222].call('1').should == '11'
371
+ procs[2223].call('{"2"}').should == ['22']
364
372
  end
365
373
 
366
374
  it "should return correct results for Database#schema_type_class" do
@@ -1,5 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ Sequel.extension :pg_array, :pg_array_ops, :pg_hstore, :pg_hstore_ops
4
+
3
5
  describe "Sequel::Postgres::HStoreOp" do
4
6
  before do
5
7
  @ds = Sequel.connect('mock://postgres', :quote_identifiers=>false).dataset
@@ -42,6 +44,17 @@ describe "Sequel::Postgres::HStoreOp" do
42
44
  @ds.literal(@h[%w'a'][0]).should == "(h -> ARRAY['a'])[0]"
43
45
  end
44
46
 
47
+ it "#[] should not return a PGArrayOp if given an array but pg_array_op is not supported" do
48
+ begin
49
+ module Sequel::Postgres::HStoreOp::Sequel
50
+ SQL = ::Sequel::SQL
51
+ end
52
+ @ds.literal(@h[%w'a']).should_not be_a_kind_of(Sequel::Postgres::ArrayOp)
53
+ ensure
54
+ Sequel::Postgres::HStoreOp.send(:remove_const, :Sequel)
55
+ end
56
+ end
57
+
45
58
  it "#[] should return a PGArrayOp if given a PGArray" do
46
59
  @ds.literal(@h[Sequel.pg_array(%w'a')][0]).should == "(h -> ARRAY['a'])[0]"
47
60
  end
@@ -2,6 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "pg_hstore extension" do
4
4
  before do
5
+ Sequel.extension :pg_array, :pg_hstore
5
6
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
7
  @m = Sequel::Postgres
7
8
  @c = @m::HStore
@@ -0,0 +1,131 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ Sequel.extension :pg_array, :pg_array_ops, :pg_json, :pg_json_ops
4
+
5
+ describe "Sequel::Postgres::JSONOp" do
6
+ before do
7
+ @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
8
+ @j = Sequel.pg_json_op(:j)
9
+ @l = proc{|o| @db.literal(o)}
10
+ end
11
+
12
+ it "should have #[] get the element" do
13
+ @l[@j[1]].should == "(j -> 1)"
14
+ @l[@j['a']].should == "(j -> 'a')"
15
+ end
16
+
17
+ it "should have #[] accept an array" do
18
+ @l[@j[%w'a b']].should == "(j #> ARRAY['a','b'])"
19
+ @l[@j[Sequel.pg_array(%w'a b')]].should == "(j #> ARRAY['a','b'])"
20
+ @l[@j[Sequel.pg_array(:a)]].should == "(j #> a)"
21
+ end
22
+
23
+ it "should have #[] return a JSONOp" do
24
+ @l[@j[1][2]].should == "((j -> 1) -> 2)"
25
+ @l[@j[%w'a b'][2]].should == "((j #> ARRAY['a','b']) -> 2)"
26
+ end
27
+
28
+ it "should have #get be an alias to #[]" do
29
+ @l[@j.get(1)].should == "(j -> 1)"
30
+ @l[@j.get(%w'a b')].should == "(j #> ARRAY['a','b'])"
31
+ end
32
+
33
+ it "should have #get_text get the element as text" do
34
+ @l[@j.get_text(1)].should == "(j ->> 1)"
35
+ @l[@j.get_text('a')].should == "(j ->> 'a')"
36
+ end
37
+
38
+ it "should have #get_text accept an array" do
39
+ @l[@j.get_text(%w'a b')].should == "(j #>> ARRAY['a','b'])"
40
+ @l[@j.get_text(Sequel.pg_array(%w'a b'))].should == "(j #>> ARRAY['a','b'])"
41
+ @l[@j.get_text(Sequel.pg_array(:a))].should == "(j #>> a)"
42
+ end
43
+
44
+ it "should have #get_text return an SQL::StringExpression" do
45
+ @l[@j.get_text(1) + 'a'].should == "((j ->> 1) || 'a')"
46
+ @l[@j.get_text(%w'a b') + 'a'].should == "((j #>> ARRAY['a','b']) || 'a')"
47
+ end
48
+
49
+ it "should have #array_length use the json_array_length function" do
50
+ @l[@j.array_length].should == "json_array_length(j)"
51
+ end
52
+
53
+ it "should have #array_length return a numeric expression" do
54
+ @l[@j.array_length & 1].should == "(json_array_length(j) & 1)"
55
+ end
56
+
57
+ it "should have #each use the json_each function" do
58
+ @l[@j.each].should == "json_each(j)"
59
+ end
60
+
61
+ it "should have #each_text use the json_each_text function" do
62
+ @l[@j.each_text].should == "json_each_text(j)"
63
+ end
64
+
65
+ it "should have #extract use the json_extract_path function" do
66
+ @l[@j.extract('a')].should == "json_extract_path(j, 'a')"
67
+ @l[@j.extract('a', 'b')].should == "json_extract_path(j, 'a', 'b')"
68
+ end
69
+
70
+ it "should have #extract return a JSONOp" do
71
+ @l[@j.extract('a')[1]].should == "(json_extract_path(j, 'a') -> 1)"
72
+ end
73
+
74
+ it "should have #extract_text use the json_extract_path_text function" do
75
+ @l[@j.extract_text('a')].should == "json_extract_path_text(j, 'a')"
76
+ @l[@j.extract_text('a', 'b')].should == "json_extract_path_text(j, 'a', 'b')"
77
+ end
78
+
79
+ it "should have #extract_text return an SQL::StringExpression" do
80
+ @l[@j.extract_text('a') + 'a'].should == "(json_extract_path_text(j, 'a') || 'a')"
81
+ end
82
+
83
+ it "should have #keys use the json_object_keys function" do
84
+ @l[@j.keys].should == "json_object_keys(j)"
85
+ end
86
+
87
+ it "should have #array_elements use the json_array_elements function" do
88
+ @l[@j.array_elements].should == "json_array_elements(j)"
89
+ end
90
+
91
+ it "should have #populate use the json_populate_record function" do
92
+ @l[@j.populate(:a)].should == "json_populate_record(a, j)"
93
+ end
94
+
95
+ it "should have #populate_set use the json_populate_record function" do
96
+ @l[@j.populate_set(:a)].should == "json_populate_recordset(a, j)"
97
+ end
98
+
99
+ it "#pg_json should return self" do
100
+ @j.pg_json.should equal(@j)
101
+ end
102
+
103
+ it "Sequel.pg_json_op should return arg for JSONOp" do
104
+ Sequel.pg_json_op(@j).should equal(@j)
105
+ end
106
+
107
+ it "should be able to turn expressions into json ops using pg_json" do
108
+ @db.literal(Sequel.qualify(:b, :a).pg_json[1]).should == "(b.a -> 1)"
109
+ @db.literal(Sequel.function(:a, :b).pg_json[1]).should == "(a(b) -> 1)"
110
+ end
111
+
112
+ it "should be able to turn literal strings into json ops using pg_json" do
113
+ @db.literal(Sequel.lit('a').pg_json[1]).should == "(a -> 1)"
114
+ end
115
+
116
+ it "should be able to turn symbols into json ops using Sequel.pg_json_op" do
117
+ @db.literal(Sequel.pg_json_op(:a)[1]).should == "(a -> 1)"
118
+ end
119
+
120
+ it "should be able to turn symbols into json ops using Sequel.pg_json" do
121
+ @db.literal(Sequel.pg_json(:a)[1]).should == "(a -> 1)"
122
+ end
123
+
124
+ it "should allow transforming JSONArray instances into ArrayOp instances" do
125
+ @db.literal(Sequel.pg_json([1,2]).op[1]).should == "('[1,2]'::json -> 1)"
126
+ end
127
+
128
+ it "should allow transforming JSONHash instances into ArrayOp instances" do
129
+ @db.literal(Sequel.pg_json('a'=>1).op['a']).should == "('{\"a\":1}'::json -> 'a')"
130
+ end
131
+ end
@@ -1,5 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ Sequel.extension :pg_array, :pg_json
4
+
3
5
  describe "pg_json extension" do
4
6
  before(:all) do
5
7
  m = Sequel::Postgres
@@ -36,6 +38,14 @@ describe "pg_json extension" do
36
38
  @m.parse_json('{"a": "b", "c": {"d": "e"}}').to_hash.should == {'a'=>'b', 'c'=>{'d'=>'e'}}
37
39
  end
38
40
 
41
+ it "should parse json and non-json plain strings, integers, and floats correctly in db_parse_json" do
42
+ @m.db_parse_json('{"a": "b", "c": {"d": "e"}}').to_hash.should == {'a'=>'b', 'c'=>{'d'=>'e'}}
43
+ @m.db_parse_json('[1, [2], {"a": "b"}]').to_a.should == [1, [2], {'a'=>'b'}]
44
+ @m.db_parse_json('1').should == 1
45
+ @m.db_parse_json('"b"').should == 'b'
46
+ @m.db_parse_json('1.1').should == 1.1
47
+ end
48
+
39
49
  it "should raise an error when attempting to parse invalid json" do
40
50
  proc{@m.parse_json('')}.should raise_error(Sequel::InvalidValue)
41
51
  proc{@m.parse_json('1')}.should raise_error(Sequel::InvalidValue)
@@ -69,10 +79,6 @@ describe "pg_json extension" do
69
79
  Sequel.pg_json(a).should equal(a)
70
80
  end
71
81
 
72
- it "should have Sequel.pg_json raise an Error if called with a non-hash or array" do
73
- proc{Sequel.pg_json(:a)}.should raise_error(Sequel::Error)
74
- end
75
-
76
82
  it "should have JSONHash#to_hash method for getting underlying hash" do
77
83
  Sequel.pg_json({}).to_hash.should be_a_kind_of(Hash)
78
84
  end
@@ -1,5 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ Sequel.extension :pg_array, :pg_range, :pg_range_ops
4
+
3
5
  describe "Sequel::Postgres::RangeOp" do
4
6
  before do
5
7
  @ds = Sequel.connect('mock://postgres', :quote_identifiers=>false).dataset
@@ -38,11 +40,6 @@ describe "Sequel::Postgres::RangeOp" do
38
40
  @ds.literal(@h.adjacent_to(@h)).should == "(h -|- h)"
39
41
  end
40
42
 
41
- qspecify "should define methods for the deprecated PostgreSQL range operators" do
42
- @ds.literal(@h.starts_before(@h)).should == "(h &< h)"
43
- @ds.literal(@h.ends_after(@h)).should == "(h &> h)"
44
- end
45
-
46
43
  it "should define methods for all of the PostgreSQL range functions" do
47
44
  @ds.literal(@h.lower).should == "lower(h)"
48
45
  @ds.literal(@h.upper).should == "upper(h)"
@@ -1,7 +1,9 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+
3
4
  describe "pg_range extension" do
4
5
  before(:all) do
6
+ Sequel.extension :pg_array, :pg_range
5
7
  @pg_types = Sequel::Postgres::PG_TYPES.dup
6
8
  end
7
9
  after(:all) do
@@ -213,13 +215,15 @@ describe "pg_range extension" do
213
215
  end
214
216
  end
215
217
 
216
- it "should set appropriate timestamp range conversion procs when getting conversion procs" do
218
+ it "should set appropriate timestamp range conversion procs when resetting conversion procs" do
219
+ @db.reset_conversion_procs
217
220
  procs = @db.conversion_procs
218
221
  procs[3908].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').should == (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
219
222
  procs[3910].call('[2011-10-20 11:12:13,2011-10-20 11:12:14]').should == (Time.local(2011, 10, 20, 11, 12, 13)..(Time.local(2011, 10, 20, 11, 12, 14)))
220
223
  end
221
224
 
222
- it "should set appropriate timestamp range array conversion procs when getting conversion procs" do
225
+ it "should set appropriate timestamp range array conversion procs when resetting conversion procs" do
226
+ @db.reset_conversion_procs
223
227
  procs = @db.conversion_procs
224
228
  procs[3909].call('{"[2011-10-20 11:12:13,2011-10-20 11:12:14]"}').should == [Time.local(2011, 10, 20, 11, 12, 13)..Time.local(2011, 10, 20, 11, 12, 14)]
225
229
  procs[3911].call('{"[2011-10-20 11:12:13,2011-10-20 11:12:14]"}').should == [Time.local(2011, 10, 20, 11, 12, 13)..Time.local(2011, 10, 20, 11, 12, 14)]
@@ -1,5 +1,7 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
+ Sequel.extension :pg_array, :pg_array_ops, :pg_row, :pg_row_ops
4
+
3
5
  describe "Sequel::Postgres::PGRowOp" do
4
6
  before do
5
7
  @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
@@ -19,6 +19,7 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
19
19
  @Artist.plugin :prepared_statements_associations
20
20
  @Album.plugin :prepared_statements_associations
21
21
  @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
22
+ @Artist.one_to_one :album, :class=>@Album, :key=>:artist_id
22
23
  @Album.many_to_one :artist, :class=>@Artist
23
24
  @Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
24
25
  @Artist.plugin :many_through_many
@@ -30,6 +31,9 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
30
31
  @Artist.load(:id=>1).albums
31
32
  @db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1) -- prepared"]
32
33
 
34
+ @Artist.load(:id=>1).album
35
+ @db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1) LIMIT 1 -- prepared"]
36
+
33
37
  @Album.load(:id=>1, :artist_id=>2).artist
34
38
  @db.sqls.should == ["SELECT * FROM artists WHERE (artists.id = 2) LIMIT 1 -- prepared"]
35
39
 
@@ -42,6 +46,7 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
42
46
 
43
47
  specify "should run correct SQL for composite key associations" do
44
48
  @Artist.one_to_many :albums, :class=>@Album, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
49
+ @Artist.one_to_one :album, :class=>@Album, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
45
50
  @Album.many_to_one :artist, :class=>@Artist, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
46
51
  @Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>[:album_id, :album_id2], :right_key=>[:tag_id, :tag_id2], :right_primary_key=>[:id, :id2], :left_primary_key=>[:id, :id2]
47
52
  @Artist.many_through_many :tags, [[:albums, [:artist_id, :artist_id2], [:id, :id2]], [:albums_tags, [:album_id, :album_id2], [:tag_id, :tag_id2]]], :class=>@Tag, :right_primary_key=>[:id, :id2], :left_primary_key=>[:id, :id2]
@@ -49,6 +54,9 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
49
54
  @Artist.load(:id=>1, :id2=>2).albums
50
55
  @db.sqls.should == ["SELECT * FROM albums WHERE ((albums.artist_id = 1) AND (albums.artist_id2 = 2)) -- prepared"]
51
56
 
57
+ @Artist.load(:id=>1, :id2=>2).album
58
+ @db.sqls.should == ["SELECT * FROM albums WHERE ((albums.artist_id = 1) AND (albums.artist_id2 = 2)) LIMIT 1 -- prepared"]
59
+
52
60
  @Album.load(:id=>1, :artist_id=>2, :artist_id2=>3).artist
53
61
  @db.sqls.should == ["SELECT * FROM artists WHERE ((artists.id = 2) AND (artists.id2 = 3)) LIMIT 1 -- prepared"]
54
62
 
@@ -89,10 +97,23 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
89
97
  @db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
90
98
  end
91
99
 
92
- specify "should run a regular query if :conditions option is used when defining the association" do
93
- @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>1}
100
+ specify "should use a prepared statement if the associated dataset has conditions" do
101
+ @Album.dataset = @Album.dataset.where(:a=>2)
102
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
103
+ @Artist.load(:id=>1).albums
104
+ @db.sqls.should == ["SELECT * FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
105
+ end
106
+
107
+ specify "should use a prepared statement if the :conditions association option" do
108
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>2}
94
109
  @Artist.load(:id=>1).albums
95
- @db.sqls.should == ["SELECT * FROM albums WHERE ((a = 1) AND (albums.artist_id = 1))"]
110
+ @db.sqls.should == ["SELECT * FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
111
+ end
112
+
113
+ specify "should not use a prepared statement if :conditions association option uses an identifier" do
114
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{Sequel.identifier('a')=>2}
115
+ @Artist.load(:id=>1).albums
116
+ @db.sqls.should == ["SELECT * FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
96
117
  end
97
118
 
98
119
  specify "should run a regular query if :dataset option is used when defining the association" do
@@ -103,9 +124,9 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
103
124
  end
104
125
 
105
126
  specify "should run a regular query if :cloning an association that doesn't used prepared statements" do
106
- @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>1}
127
+ @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id do |ds| ds end
107
128
  @Artist.one_to_many :oalbums, :clone=>:albums
108
129
  @Artist.load(:id=>1).oalbums
109
- @db.sqls.should == ["SELECT * FROM albums WHERE ((a = 1) AND (albums.artist_id = 1))"]
130
+ @db.sqls.should == ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
110
131
  end
111
132
  end
@@ -2,14 +2,14 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "rcte_tree" do
4
4
  before do
5
- @c = Class.new(Sequel::Model(MODEL_DB[:nodes]))
5
+ @c = Class.new(Sequel::Model(DB[:nodes]))
6
6
  @c.class_eval do
7
7
  def self.name; 'Node'; end
8
8
  columns :id, :name, :parent_id, :i, :pi
9
9
  end
10
10
  @ds = @c.dataset
11
11
  @o = @c.load(:id=>2, :parent_id=>1, :name=>'AA', :i=>3, :pi=>4)
12
- MODEL_DB.reset
12
+ DB.reset
13
13
  end
14
14
 
15
15
  it "should define the correct associations" do
@@ -102,7 +102,7 @@ describe Sequel::Model, "rcte_tree" do
102
102
  {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
103
103
  {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]]
104
104
  os = @ds.eager(:ancestors).all
105
- sqls = MODEL_DB.sqls
105
+ sqls = DB.sqls
106
106
  sqls.first.should == "SELECT * FROM nodes"
107
107
  sqls.last.should =~ /WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(id IN \([12], [12]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\)\) SELECT \* FROM t AS nodes/
108
108
  os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D'), @c.load(:id=>9, :parent_id=>nil, :name=>'E')]
@@ -114,7 +114,7 @@ describe Sequel::Model, "rcte_tree" do
114
114
  os.map{|o| o.parent.parent if o.parent}.should == [@c.load(:id=>8, :name=>'?', :parent_id=>nil), @c.load(:id=>1, :name=>'00', :parent_id=>8), @c.load(:id=>8, :name=>'?', :parent_id=>nil), nil]
115
115
  os.map{|o| o.parent.parent.parent if o.parent and o.parent.parent}.should == [nil, @c.load(:id=>8, :name=>'?', :parent_id=>nil), nil, nil]
116
116
  os.map{|o| o.parent.parent.parent.parent if o.parent and o.parent.parent and o.parent.parent.parent}.should == [nil, nil, nil, nil]
117
- MODEL_DB.sqls.should == []
117
+ DB.sqls.should == []
118
118
  end
119
119
 
120
120
  it "should eagerly load ancestors when giving options" do
@@ -124,7 +124,7 @@ describe Sequel::Model, "rcte_tree" do
124
124
  {:i=>1, :name=>'00', :pi=>8, :kal=>1}, {:i=>1, :name=>'00', :pi=>8, :kal=>2},
125
125
  {:i=>8, :name=>'?', :pi=>nil, :kal=>2}, {:i=>8, :name=>'?', :pi=>nil, :kal=>1}]]
126
126
  os = @ds.eager(:as).all
127
- sqls = MODEL_DB.sqls
127
+ sqls = DB.sqls
128
128
  sqls.first.should == "SELECT * FROM nodes"
129
129
  sqls.last.should =~ /WITH cte AS \(SELECT i AS kal, nodes\.\* FROM nodes WHERE \(i IN \([12], [12]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.pi = nodes\.i\)\) SELECT \* FROM cte/
130
130
  os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D'), @c.load(:i=>9, :pi=>nil, :name=>'E')]
@@ -145,7 +145,7 @@ describe Sequel::Model, "rcte_tree" do
145
145
  {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>1}, {:id=>1, :name=>'00', :parent_id=>8, :x_root_x=>2},
146
146
  {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>2}, {:id=>8, :name=>'?', :parent_id=>nil, :x_root_x=>1}]]
147
147
  @ds.eager(:ancestors).all
148
- sqls = MODEL_DB.sqls
148
+ sqls = DB.sqls
149
149
  sqls.first.should == "SELECT * FROM nodes"
150
150
  sqls.last.should =~ /WITH t AS \(SELECT id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(id IN \([12], [12]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.parent_id = nodes\.id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/
151
151
  end
@@ -157,7 +157,7 @@ describe Sequel::Model, "rcte_tree" do
157
157
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
158
158
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]]
159
159
  os = @ds.eager(:descendants).all
160
- sqls = MODEL_DB.sqls
160
+ sqls = DB.sqls
161
161
  sqls.first.should == "SELECT * FROM nodes"
162
162
  sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\)\) SELECT \* FROM t AS nodes/
163
163
  os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
@@ -167,7 +167,7 @@ describe Sequel::Model, "rcte_tree" do
167
167
  os.map{|o| o.children}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E')], [@c.load(:id=>3, :name=>'00', :parent_id=>6)], [@c.load(:id=>4, :name=>'?', :parent_id=>7)]]
168
168
  os.map{|o1| o1.children.map{|o2| o2.children}}.should == [[[@c.load(:id=>3, :name=>'00', :parent_id=>6)], []], [[]], [[@c.load(:id=>5, :name=>'?', :parent_id=>4)]]]
169
169
  os.map{|o1| o1.children.map{|o2| o2.children.map{|o3| o3.children}}}.should == [[[[]], []], [[]], [[[]]]]
170
- MODEL_DB.sqls.should == []
170
+ DB.sqls.should == []
171
171
  end
172
172
 
173
173
  it "should eagerly load descendants when giving options" do
@@ -177,7 +177,7 @@ describe Sequel::Model, "rcte_tree" do
177
177
  {:i=>3, :name=>'00', :pi=>6, :kal=>6}, {:i=>3, :name=>'00', :pi=>6, :kal=>2},
178
178
  {:i=>4, :name=>'?', :pi=>7, :kal=>7}, {:i=>5, :name=>'?', :pi=>4, :kal=>7}]]
179
179
  os = @ds.eager(:ds).all
180
- sqls = MODEL_DB.sqls
180
+ sqls = DB.sqls
181
181
  sqls.first.should == "SELECT * FROM nodes"
182
182
  sqls.last.should =~ /WITH cte AS \(SELECT pi AS kal, nodes\.\* FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\* FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\)\) SELECT \* FROM cte/
183
183
  os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
@@ -187,7 +187,7 @@ describe Sequel::Model, "rcte_tree" do
187
187
  os.map{|o| o.cs}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E')], [@c.load(:i=>3, :name=>'00', :pi=>6)], [@c.load(:i=>4, :name=>'?', :pi=>7)]]
188
188
  os.map{|o1| o1.cs.map{|o2| o2.cs}}.should == [[[@c.load(:i=>3, :name=>'00', :pi=>6)], []], [[]], [[@c.load(:i=>5, :name=>'?', :pi=>4)]]]
189
189
  os.map{|o1| o1.cs.map{|o2| o2.cs.map{|o3| o3.cs}}}.should == [[[[]], []], [[]], [[[]]]]
190
- MODEL_DB.sqls.should == []
190
+ DB.sqls.should == []
191
191
  end
192
192
 
193
193
  it "should eagerly load descendants to a given level" do
@@ -197,7 +197,7 @@ describe Sequel::Model, "rcte_tree" do
197
197
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6, :x_level_x=>0}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2, :x_level_x=>1},
198
198
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7, :x_level_x=>0}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7, :x_level_x=>1}]]
199
199
  os = @ds.eager(:descendants=>2).all
200
- sqls = MODEL_DB.sqls
200
+ sqls = DB.sqls
201
201
  sqls.first.should == "SELECT * FROM nodes"
202
202
  sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\*, 0 AS x_level_x FROM nodes WHERE \(parent_id IN \([267], [267], [267]\)\) UNION ALL SELECT t\.x_root_x, nodes\.\*, \(t\.x_level_x \+ 1\) AS x_level_x FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(t\.x_level_x < 1\)\) SELECT \* FROM t AS nodes/
203
203
  os.should == [@c.load(:id=>2, :parent_id=>1, :name=>'AA'), @c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>7, :parent_id=>1, :name=>'D')]
@@ -207,7 +207,7 @@ describe Sequel::Model, "rcte_tree" do
207
207
  os.map{|o| o.associations[:children]}.should == [[@c.load(:id=>6, :parent_id=>2, :name=>'C'), @c.load(:id=>9, :parent_id=>2, :name=>'E')], [@c.load(:id=>3, :name=>'00', :parent_id=>6)], [@c.load(:id=>4, :name=>'?', :parent_id=>7)]]
208
208
  os.map{|o1| o1.associations[:children].map{|o2| o2.associations[:children]}}.should == [[[@c.load(:id=>3, :name=>'00', :parent_id=>6)], []], [[]], [[@c.load(:id=>5, :name=>'?', :parent_id=>4)]]]
209
209
  os.map{|o1| o1.associations[:children].map{|o2| o2.associations[:children].map{|o3| o3.associations[:children]}}}.should == [[[[]], []], [[]], [[nil]]]
210
- MODEL_DB.sqls.should == []
210
+ DB.sqls.should == []
211
211
  end
212
212
 
213
213
  it "should eagerly load descendants to a given level when giving options" do
@@ -217,7 +217,7 @@ describe Sequel::Model, "rcte_tree" do
217
217
  {:i=>3, :name=>'00', :pi=>6, :kal=>6, :lal=>0}, {:i=>3, :name=>'00', :pi=>6, :kal=>2, :lal=>1},
218
218
  {:i=>4, :name=>'?', :pi=>7, :kal=>7, :lal=>0}, {:i=>5, :name=>'?', :pi=>4, :kal=>7, :lal=>1}]]
219
219
  os = @ds.eager(:ds=>2).all
220
- sqls = MODEL_DB.sqls
220
+ sqls = DB.sqls
221
221
  sqls.first.should == "SELECT * FROM nodes"
222
222
  sqls.last.should =~ /WITH cte AS \(SELECT pi AS kal, nodes\.\*, 0 AS lal FROM nodes WHERE \(pi IN \([267], [267], [267]\)\) UNION ALL SELECT cte\.kal, nodes\.\*, \(cte\.lal \+ 1\) AS lal FROM nodes INNER JOIN cte ON \(cte\.i = nodes\.pi\) WHERE \(cte\.lal < 1\)\) SELECT \* FROM cte/
223
223
  os.should == [@c.load(:i=>2, :pi=>1, :name=>'AA'), @c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>7, :pi=>1, :name=>'D')]
@@ -227,7 +227,7 @@ describe Sequel::Model, "rcte_tree" do
227
227
  os.map{|o| o.associations[:cs]}.should == [[@c.load(:i=>6, :pi=>2, :name=>'C'), @c.load(:i=>9, :pi=>2, :name=>'E')], [@c.load(:i=>3, :name=>'00', :pi=>6)], [@c.load(:i=>4, :name=>'?', :pi=>7)]]
228
228
  os.map{|o1| o1.associations[:cs].map{|o2| o2.associations[:cs]}}.should == [[[@c.load(:i=>3, :name=>'00', :pi=>6)], []], [[]], [[@c.load(:i=>5, :name=>'?', :pi=>4)]]]
229
229
  os.map{|o1| o1.associations[:cs].map{|o2| o2.associations[:cs].map{|o3| o3.associations[:cs]}}}.should == [[[[]], []], [[]], [[nil]]]
230
- MODEL_DB.sqls.should == []
230
+ DB.sqls.should == []
231
231
  end
232
232
 
233
233
  it "should eagerly load descendants respecting association option :conditions" do
@@ -237,7 +237,7 @@ describe Sequel::Model, "rcte_tree" do
237
237
  {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>6}, {:id=>3, :name=>'00', :parent_id=>6, :x_root_x=>2},
238
238
  {:id=>4, :name=>'?', :parent_id=>7, :x_root_x=>7}, {:id=>5, :name=>'?', :parent_id=>4, :x_root_x=>7}]]
239
239
  @ds.eager(:descendants).all
240
- sqls = MODEL_DB.sqls
240
+ sqls = DB.sqls
241
241
  sqls.first.should == "SELECT * FROM nodes"
242
242
  sqls.last.should =~ /WITH t AS \(SELECT parent_id AS x_root_x, nodes\.\* FROM nodes WHERE \(\(parent_id IN \([267], [267], [267]\)\) AND \(i = 1\)\) UNION ALL SELECT t\.x_root_x, nodes\.\* FROM nodes INNER JOIN t ON \(t\.id = nodes\.parent_id\) WHERE \(i = 1\)\) SELECT \* FROM t AS nodes WHERE \(i = 1\)/
243
243
  end