sequel 4.46.0 → 4.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +210 -0
  3. data/Rakefile +1 -1
  4. data/doc/advanced_associations.rdoc +1 -1
  5. data/doc/opening_databases.rdoc +3 -2
  6. data/doc/release_notes/4.47.0.txt +56 -0
  7. data/doc/release_notes/4.48.0.txt +293 -0
  8. data/doc/release_notes/4.49.0.txt +222 -0
  9. data/lib/sequel/adapters/ado/access.rb +2 -1
  10. data/lib/sequel/adapters/do/postgres.rb +5 -2
  11. data/lib/sequel/adapters/ibmdb.rb +30 -8
  12. data/lib/sequel/adapters/jdbc/as400.rb +1 -1
  13. data/lib/sequel/adapters/jdbc/db2.rb +12 -3
  14. data/lib/sequel/adapters/jdbc/derby.rb +4 -5
  15. data/lib/sequel/adapters/jdbc/h2.rb +10 -1
  16. data/lib/sequel/adapters/jdbc/oracle.rb +16 -2
  17. data/lib/sequel/adapters/jdbc/postgresql.rb +46 -20
  18. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +9 -7
  19. data/lib/sequel/adapters/jdbc/sqlserver.rb +20 -6
  20. data/lib/sequel/adapters/jdbc.rb +39 -23
  21. data/lib/sequel/adapters/mock.rb +27 -19
  22. data/lib/sequel/adapters/mysql.rb +17 -16
  23. data/lib/sequel/adapters/mysql2.rb +5 -6
  24. data/lib/sequel/adapters/oracle.rb +5 -9
  25. data/lib/sequel/adapters/postgres.rb +91 -103
  26. data/lib/sequel/adapters/shared/db2.rb +22 -6
  27. data/lib/sequel/adapters/shared/mssql.rb +5 -4
  28. data/lib/sequel/adapters/shared/mysql.rb +79 -25
  29. data/lib/sequel/adapters/shared/oracle.rb +26 -3
  30. data/lib/sequel/adapters/shared/postgres.rb +199 -95
  31. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  32. data/lib/sequel/adapters/shared/sqlite.rb +72 -82
  33. data/lib/sequel/adapters/sqlanywhere.rb +4 -1
  34. data/lib/sequel/adapters/sqlite.rb +5 -3
  35. data/lib/sequel/adapters/swift/postgres.rb +5 -2
  36. data/lib/sequel/adapters/tinytds.rb +0 -5
  37. data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
  38. data/lib/sequel/adapters/utils/pg_types.rb +2 -76
  39. data/lib/sequel/ast_transformer.rb +1 -1
  40. data/lib/sequel/connection_pool/sharded_single.rb +1 -1
  41. data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
  42. data/lib/sequel/connection_pool/single.rb +2 -2
  43. data/lib/sequel/connection_pool/threaded.rb +2 -2
  44. data/lib/sequel/connection_pool.rb +9 -2
  45. data/lib/sequel/core.rb +2 -2
  46. data/lib/sequel/database/connecting.rb +8 -8
  47. data/lib/sequel/database/dataset.rb +6 -3
  48. data/lib/sequel/database/dataset_defaults.rb +14 -1
  49. data/lib/sequel/database/misc.rb +1 -1
  50. data/lib/sequel/database/query.rb +3 -0
  51. data/lib/sequel/database/schema_methods.rb +1 -1
  52. data/lib/sequel/dataset/actions.rb +72 -10
  53. data/lib/sequel/dataset/dataset_module.rb +58 -0
  54. data/lib/sequel/dataset/graph.rb +1 -1
  55. data/lib/sequel/dataset/misc.rb +1 -0
  56. data/lib/sequel/dataset/prepared_statements.rb +3 -3
  57. data/lib/sequel/dataset/query.rb +22 -11
  58. data/lib/sequel/dataset.rb +1 -1
  59. data/lib/sequel/exceptions.rb +8 -0
  60. data/lib/sequel/extensions/_model_pg_row.rb +5 -2
  61. data/lib/sequel/extensions/core_extensions.rb +4 -1
  62. data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
  63. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  64. data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -3
  65. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +3 -0
  66. data/lib/sequel/extensions/filter_having.rb +2 -0
  67. data/lib/sequel/extensions/freeze_datasets.rb +2 -0
  68. data/lib/sequel/extensions/from_block.rb +1 -1
  69. data/lib/sequel/extensions/graph_each.rb +2 -2
  70. data/lib/sequel/extensions/hash_aliases.rb +2 -0
  71. data/lib/sequel/extensions/identifier_mangling.rb +0 -7
  72. data/lib/sequel/extensions/meta_def.rb +2 -0
  73. data/lib/sequel/extensions/migration.rb +11 -8
  74. data/lib/sequel/extensions/no_auto_literal_strings.rb +1 -1
  75. data/lib/sequel/extensions/null_dataset.rb +1 -0
  76. data/lib/sequel/extensions/pagination.rb +1 -1
  77. data/lib/sequel/extensions/pg_array.rb +207 -130
  78. data/lib/sequel/extensions/pg_hstore.rb +38 -20
  79. data/lib/sequel/extensions/pg_inet.rb +18 -6
  80. data/lib/sequel/extensions/pg_interval.rb +19 -12
  81. data/lib/sequel/extensions/pg_json.rb +25 -14
  82. data/lib/sequel/extensions/pg_json_ops.rb +2 -2
  83. data/lib/sequel/extensions/pg_range.rb +133 -100
  84. data/lib/sequel/extensions/pg_range_ops.rb +4 -3
  85. data/lib/sequel/extensions/pg_row.rb +68 -39
  86. data/lib/sequel/extensions/pg_row_ops.rb +11 -5
  87. data/lib/sequel/extensions/query_literals.rb +2 -0
  88. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +2 -0
  89. data/lib/sequel/extensions/s.rb +1 -1
  90. data/lib/sequel/extensions/schema_dumper.rb +29 -25
  91. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +3 -1
  92. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +83 -0
  93. data/lib/sequel/extensions/server_block.rb +32 -15
  94. data/lib/sequel/extensions/set_overrides.rb +2 -2
  95. data/lib/sequel/extensions/string_agg.rb +0 -1
  96. data/lib/sequel/extensions/symbol_aref.rb +0 -4
  97. data/lib/sequel/model/associations.rb +35 -7
  98. data/lib/sequel/model/base.rb +113 -87
  99. data/lib/sequel/model/dataset_module.rb +5 -43
  100. data/lib/sequel/model/errors.rb +2 -1
  101. data/lib/sequel/model/inflections.rb +17 -5
  102. data/lib/sequel/model.rb +26 -58
  103. data/lib/sequel/plugins/active_model.rb +2 -2
  104. data/lib/sequel/plugins/association_autoreloading.rb +2 -0
  105. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  106. data/lib/sequel/plugins/association_pks.rb +73 -46
  107. data/lib/sequel/plugins/association_proxies.rb +1 -1
  108. data/lib/sequel/plugins/auto_validations.rb +6 -2
  109. data/lib/sequel/plugins/boolean_readers.rb +2 -2
  110. data/lib/sequel/plugins/boolean_subsets.rb +1 -1
  111. data/lib/sequel/plugins/caching.rb +19 -13
  112. data/lib/sequel/plugins/class_table_inheritance.rb +24 -13
  113. data/lib/sequel/plugins/column_conflicts.rb +7 -2
  114. data/lib/sequel/plugins/column_select.rb +3 -3
  115. data/lib/sequel/plugins/composition.rb +2 -2
  116. data/lib/sequel/plugins/csv_serializer.rb +8 -8
  117. data/lib/sequel/plugins/dataset_associations.rb +25 -13
  118. data/lib/sequel/plugins/defaults_setter.rb +13 -1
  119. data/lib/sequel/plugins/eager_each.rb +1 -1
  120. data/lib/sequel/plugins/force_encoding.rb +2 -2
  121. data/lib/sequel/plugins/hook_class_methods.rb +9 -12
  122. data/lib/sequel/plugins/identifier_columns.rb +2 -0
  123. data/lib/sequel/plugins/instance_filters.rb +3 -1
  124. data/lib/sequel/plugins/instance_hooks.rb +17 -9
  125. data/lib/sequel/plugins/json_serializer.rb +19 -12
  126. data/lib/sequel/plugins/lazy_attributes.rb +8 -7
  127. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +2 -0
  128. data/lib/sequel/plugins/modification_detection.rb +3 -0
  129. data/lib/sequel/plugins/nested_attributes.rb +6 -2
  130. data/lib/sequel/plugins/pg_array_associations.rb +5 -0
  131. data/lib/sequel/plugins/pg_row.rb +4 -2
  132. data/lib/sequel/plugins/pg_typecast_on_load.rb +2 -0
  133. data/lib/sequel/plugins/prepared_statements.rb +1 -0
  134. data/lib/sequel/plugins/rcte_tree.rb +4 -24
  135. data/lib/sequel/plugins/serialization.rb +9 -15
  136. data/lib/sequel/plugins/single_table_inheritance.rb +8 -3
  137. data/lib/sequel/plugins/split_values.rb +6 -5
  138. data/lib/sequel/plugins/static_cache.rb +31 -25
  139. data/lib/sequel/plugins/subset_conditions.rb +3 -1
  140. data/lib/sequel/plugins/table_select.rb +1 -1
  141. data/lib/sequel/plugins/touch.rb +4 -2
  142. data/lib/sequel/plugins/validation_class_methods.rb +5 -6
  143. data/lib/sequel/plugins/validation_helpers.rb +14 -8
  144. data/lib/sequel/plugins/xml_serializer.rb +4 -4
  145. data/lib/sequel/sql.rb +18 -9
  146. data/lib/sequel/version.rb +1 -1
  147. data/spec/adapters/db2_spec.rb +115 -14
  148. data/spec/adapters/mssql_spec.rb +4 -4
  149. data/spec/adapters/mysql_spec.rb +83 -29
  150. data/spec/adapters/oracle_spec.rb +28 -24
  151. data/spec/adapters/postgres_spec.rb +40 -24
  152. data/spec/adapters/sqlanywhere_spec.rb +88 -86
  153. data/spec/adapters/sqlite_spec.rb +29 -24
  154. data/spec/bin_spec.rb +7 -1
  155. data/spec/core/connection_pool_spec.rb +45 -14
  156. data/spec/core/database_spec.rb +155 -0
  157. data/spec/core/dataset_spec.rb +219 -36
  158. data/spec/core/schema_spec.rb +16 -0
  159. data/spec/core/spec_helper.rb +1 -0
  160. data/spec/core_extensions_spec.rb +6 -2
  161. data/spec/extensions/active_model_spec.rb +1 -1
  162. data/spec/extensions/arbitrary_servers_spec.rb +1 -1
  163. data/spec/extensions/association_pks_spec.rb +34 -2
  164. data/spec/extensions/auto_literal_strings_spec.rb +5 -1
  165. data/spec/extensions/auto_validations_spec.rb +2 -0
  166. data/spec/extensions/boolean_readers_spec.rb +1 -1
  167. data/spec/extensions/boolean_subsets_spec.rb +1 -1
  168. data/spec/extensions/class_table_inheritance_spec.rb +106 -19
  169. data/spec/extensions/column_conflicts_spec.rb +11 -0
  170. data/spec/extensions/column_select_spec.rb +1 -0
  171. data/spec/extensions/composition_spec.rb +13 -0
  172. data/spec/extensions/connection_validator_spec.rb +1 -1
  173. data/spec/extensions/dataset_associations_spec.rb +20 -8
  174. data/spec/extensions/defaults_setter_spec.rb +15 -1
  175. data/spec/extensions/filter_having_spec.rb +5 -3
  176. data/spec/extensions/hash_aliases_spec.rb +3 -1
  177. data/spec/extensions/identifier_columns_spec.rb +3 -1
  178. data/spec/extensions/implicit_subquery_spec.rb +4 -2
  179. data/spec/extensions/json_serializer_spec.rb +18 -0
  180. data/spec/extensions/lazy_attributes_spec.rb +3 -3
  181. data/spec/extensions/many_through_many_spec.rb +4 -4
  182. data/spec/extensions/meta_def_spec.rb +9 -0
  183. data/spec/extensions/migration_spec.rb +3 -3
  184. data/spec/extensions/nested_attributes_spec.rb +14 -3
  185. data/spec/extensions/no_auto_literal_strings_spec.rb +8 -4
  186. data/spec/extensions/null_dataset_spec.rb +1 -1
  187. data/spec/extensions/pg_array_associations_spec.rb +29 -18
  188. data/spec/extensions/pg_array_spec.rb +44 -25
  189. data/spec/extensions/pg_hstore_spec.rb +10 -0
  190. data/spec/extensions/pg_inet_spec.rb +26 -0
  191. data/spec/extensions/pg_interval_spec.rb +20 -0
  192. data/spec/extensions/pg_json_spec.rb +24 -0
  193. data/spec/extensions/pg_range_spec.rb +98 -14
  194. data/spec/extensions/pg_row_spec.rb +14 -4
  195. data/spec/extensions/pg_typecast_on_load_spec.rb +11 -9
  196. data/spec/extensions/prepared_statements_safe_spec.rb +1 -1
  197. data/spec/extensions/query_literals_spec.rb +3 -1
  198. data/spec/extensions/schema_dumper_spec.rb +108 -94
  199. data/spec/extensions/sequel_3_dataset_methods_spec.rb +10 -6
  200. data/spec/extensions/sequel_4_dataset_methods_spec.rb +121 -0
  201. data/spec/extensions/serialization_spec.rb +1 -1
  202. data/spec/extensions/server_block_spec.rb +7 -0
  203. data/spec/extensions/single_table_inheritance_spec.rb +17 -1
  204. data/spec/extensions/spec_helper.rb +7 -1
  205. data/spec/extensions/static_cache_spec.rb +75 -24
  206. data/spec/extensions/string_agg_spec.rb +1 -1
  207. data/spec/extensions/touch_spec.rb +9 -0
  208. data/spec/extensions/validation_helpers_spec.rb +10 -5
  209. data/spec/extensions/whitelist_security_spec.rb +26 -0
  210. data/spec/integration/associations_test.rb +8 -0
  211. data/spec/integration/dataset_test.rb +45 -44
  212. data/spec/integration/model_test.rb +53 -4
  213. data/spec/integration/plugin_test.rb +28 -4
  214. data/spec/integration/prepared_statement_test.rb +3 -0
  215. data/spec/integration/schema_test.rb +21 -1
  216. data/spec/integration/transaction_test.rb +40 -40
  217. data/spec/model/association_reflection_spec.rb +43 -1
  218. data/spec/model/associations_spec.rb +29 -9
  219. data/spec/model/class_dataset_methods_spec.rb +20 -4
  220. data/spec/model/dataset_methods_spec.rb +12 -3
  221. data/spec/model/eager_loading_spec.rb +8 -8
  222. data/spec/model/model_spec.rb +45 -1
  223. data/spec/model/plugins_spec.rb +34 -0
  224. data/spec/model/record_spec.rb +1 -1
  225. data/spec/spec_config.rb +2 -0
  226. metadata +11 -4
  227. data/spec/adapters/firebird_spec.rb +0 -405
  228. data/spec/adapters/informix_spec.rb +0 -100
@@ -462,7 +462,7 @@ describe "NestedAttributes plugin" do
462
462
  ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
463
463
  end
464
464
 
465
- it "should not raise an Error if an unmatched primary key is given, if the :strict=>false option is used" do
465
+ deprecated "should not raise an Error if an unmatched primary key is given, if the :strict=>false option is used" do
466
466
  @Artist.nested_attributes :albums, :strict=>false
467
467
  al = @Album.load(:id=>10, :name=>'Al')
468
468
  ar = @Artist.load(:id=>20, :name=>'Ar')
@@ -492,7 +492,7 @@ describe "NestedAttributes plugin" do
492
492
  ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])
493
493
  end
494
494
 
495
- it "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
495
+ deprecated "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
496
496
  @Artist.nested_attributes :concerts, :strict=>false
497
497
  ar = @Artist.load(:id=>10, :name=>'Ar')
498
498
  co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
@@ -503,6 +503,17 @@ describe "NestedAttributes plugin" do
503
503
  @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
504
504
  end
505
505
 
506
+ it "should not raise an Error if an unmatched composite primary key is given, if the :unmatched_pk=>:ignore option is used" do
507
+ @Artist.nested_attributes :concerts, :unmatched_pk=>:ignore
508
+ ar = @Artist.load(:id=>10, :name=>'Ar')
509
+ co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
510
+ ar.associations[:concerts] = [co]
511
+ ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-06', :_delete=>'t'}])
512
+ @db.sqls.must_equal []
513
+ ar.save
514
+ @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
515
+ end
516
+
506
517
  it "should not save if nested attribute is not valid and should include nested attribute validation errors in the main object's validation errors" do
507
518
  @Artist.class_eval do
508
519
  def validate
@@ -604,7 +615,7 @@ describe "NestedAttributes plugin" do
604
615
  end
605
616
 
606
617
  it "should return objects created/modified in the internal methods" do
607
- @Album.nested_attributes :tags, :remove=>true, :strict=>false
618
+ @Album.nested_attributes :tags, :remove=>true, :unmatched_pk=>:ignore
608
619
  objs = []
609
620
  @Album.class_eval do
610
621
  define_method(:nested_attributes_create){|*a| objs << [super(*a), :create]}
@@ -9,9 +9,11 @@ describe "no_auto_literal_strings extension" do
9
9
  proc{@ds.where("a")}.must_raise Sequel::Error
10
10
  proc{@ds.having("a")}.must_raise Sequel::Error
11
11
  proc{@ds.filter("a")}.must_raise Sequel::Error
12
- proc{@ds.exclude_where("a")}.must_raise Sequel::Error
13
12
  proc{@ds.exclude_having("a")}.must_raise Sequel::Error
14
- proc{@ds.and("a")}.must_raise Sequel::Error
13
+ deprecated do
14
+ proc{@ds.exclude_where("a")}.must_raise Sequel::Error
15
+ proc{@ds.and("a")}.must_raise Sequel::Error
16
+ end
15
17
  proc{@ds.where(:a).or("a")}.must_raise Sequel::Error
16
18
  proc{@ds.first("a")}.must_raise Sequel::Error
17
19
  proc{@ds.order(:a).last("a")}.must_raise Sequel::Error
@@ -26,9 +28,11 @@ describe "no_auto_literal_strings extension" do
26
28
  @ds.where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
27
29
  @ds.having(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t HAVING (a)'
28
30
  @ds.filter(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
29
- @ds.exclude_where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE NOT (a)'
30
31
  @ds.exclude_having(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t HAVING NOT (a)'
31
- @ds.and(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
32
+ deprecated do
33
+ @ds.exclude_where(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE NOT (a)'
34
+ @ds.and(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a)'
35
+ end
32
36
  @ds.where(:a).or(Sequel.lit("a")).sql.must_equal 'SELECT * FROM t WHERE (a OR (a))'
33
37
  @ds.first(Sequel.lit("a"))
34
38
  @ds.order(:a).last(Sequel.lit("a"))
@@ -73,7 +73,7 @@ describe "null_dataset extension" do
73
73
  @i.must_equal 1
74
74
  end
75
75
 
76
- it "should have nullify! method modify receiver" do
76
+ deprecated "should have nullify! method modify receiver" do
77
77
  ds = @db[:table]
78
78
  # SEQUEL5: Remove
79
79
  unless ds.frozen?
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model, "pg_array_associations" do
4
4
  before do
5
- @db = Sequel.mock(:numrows=>1)
5
+ @db = Sequel.mock(:host=>'postgres', :numrows=>1)
6
6
  @db.extend_datasets{def quote_identifiers?; false end}
7
7
  class ::Artist < Sequel::Model(@db)
8
8
  attr_accessor :yyy
@@ -71,7 +71,7 @@ describe Sequel::Model, "pg_array_associations" do
71
71
  end
72
72
 
73
73
  it "should allowing filtering by associations with :conditions" do
74
- @c1.filter(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), 'f')"
74
+ @c1.filter(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), false)"
75
75
  @c2.filter(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1))))"
76
76
  end
77
77
 
@@ -81,7 +81,7 @@ describe Sequel::Model, "pg_array_associations" do
81
81
  end
82
82
 
83
83
  it "should allowing excluding by associations with :conditions" do
84
- @c1.exclude(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), 'f') OR (artists.tag_ids IS NULL))"
84
+ @c1.exclude(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), false) OR (artists.tag_ids IS NULL))"
85
85
  @c2.exclude(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1)))) OR (tags.id IS NULL))"
86
86
  end
87
87
 
@@ -91,7 +91,7 @@ describe Sequel::Model, "pg_array_associations" do
91
91
  end
92
92
 
93
93
  it "should allowing filtering by multiple associations with :conditions" do
94
- @c1.filter(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), 'f')"
94
+ @c1.filter(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), false)"
95
95
  @c2.filter(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8)))))"
96
96
  end
97
97
 
@@ -101,40 +101,40 @@ describe Sequel::Model, "pg_array_associations" do
101
101
  end
102
102
 
103
103
  it "should allowing excluding by multiple associations with :conditions" do
104
- @c1.exclude(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), 'f') OR (artists.tag_ids IS NULL))"
104
+ @c1.exclude(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), false) OR (artists.tag_ids IS NULL))"
105
105
  @c2.exclude(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8))))) OR (tags.id IS NULL))"
106
106
  end
107
107
 
108
108
  it "should allowing filtering/excluding associations with NULL or empty values" do
109
- @c1.filter(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE \'f\''
110
- @c1.exclude(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE \'t\''
111
- @c2.filter(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE \'f\''
112
- @c2.exclude(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE \'t\''
109
+ @c1.filter(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE false'
110
+ @c1.exclude(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE true'
111
+ @c2.filter(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE false'
112
+ @c2.exclude(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE true'
113
113
 
114
- @c2.filter(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE \'f\''
115
- @c2.exclude(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE \'t\''
114
+ @c2.filter(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE false'
115
+ @c2.exclude(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE true'
116
116
 
117
117
  @c1.filter(:tags=>[@c2.new, @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"
118
118
  @c2.filter(:artists=>[@c1.load(:tag_ids=>Sequel.pg_array([3, 4])), @c1.new]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (3, 4))"
119
119
  end
120
120
 
121
121
  it "should allowing filtering by association datasets" do
122
- @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), 'f')"
122
+ @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), false)"
123
123
  @c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1)))"
124
124
  end
125
125
 
126
126
  it "should allowing filtering by association datasets with :conditions" do
127
- @c1.filter(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), 'f')"
127
+ @c1.filter(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), false)"
128
128
  @c2.filter(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1))))))"
129
129
  end
130
130
 
131
131
  it "should allowing excluding by association datasets" do
132
- @c1.exclude(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), 'f') OR (artists.tag_ids IS NULL))"
132
+ @c1.exclude(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), false) OR (artists.tag_ids IS NULL))"
133
133
  @c2.exclude(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1))) OR (tags.id IS NULL))"
134
134
  end
135
135
 
136
136
  it "should allowing excluding by association datasets with :conditions" do
137
- @c1.exclude(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), 'f') OR (artists.tag_ids IS NULL))"
137
+ @c1.exclude(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), false) OR (artists.tag_ids IS NULL))"
138
138
  @c2.exclude(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1)))))) OR (tags.id IS NULL))"
139
139
  end
140
140
 
@@ -145,7 +145,7 @@ describe Sequel::Model, "pg_array_associations" do
145
145
 
146
146
  @c1.filter(:tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids[1:2] @> ARRAY[6]::integer[])"
147
147
  @c2.filter(:artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (3, 6, 9))"
148
- @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids[1:2] && (SELECT array_agg((tags.id * 3)) FROM tags WHERE (id = 1))), 'f')"
148
+ @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids[1:2] && (SELECT array_agg((tags.id * 3)) FROM tags WHERE (id = 1))), false)"
149
149
  @c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (SELECT unnest(artists.tag_ids[1:2]) FROM artists WHERE (id = 1)))"
150
150
  end
151
151
 
@@ -315,6 +315,7 @@ describe Sequel::Model, "pg_array_associations" do
315
315
 
316
316
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
317
317
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
318
+ @db.sqls
318
319
 
319
320
  @o1.tags2.must_equal [@o2]
320
321
  @db.sqls.first.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
@@ -328,6 +329,7 @@ describe Sequel::Model, "pg_array_associations" do
328
329
 
329
330
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
330
331
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
332
+ @db.sqls
331
333
 
332
334
  a = @c1.eager(:tags2).all
333
335
  sqls = @db.sqls
@@ -340,6 +342,7 @@ describe Sequel::Model, "pg_array_associations" do
340
342
 
341
343
  @c2.dataset = @c2.dataset.with_fetch(:id=>2)
342
344
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
345
+ @db.sqls
343
346
 
344
347
  a = @c2.eager(:artists2).all
345
348
  @db.sqls.must_equal ["SELECT * FROM tags", "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
@@ -351,6 +354,7 @@ describe Sequel::Model, "pg_array_associations" do
351
354
 
352
355
  it "should respect the :limit option when eager loading" do
353
356
  @c2.dataset = @c2.dataset.with_fetch([{:id=>1},{:id=>2}, {:id=>3}])
357
+ @db.sqls
354
358
 
355
359
  @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>2
356
360
  a = @c1.eager(:tags).all
@@ -381,6 +385,7 @@ describe Sequel::Model, "pg_array_associations" do
381
385
 
382
386
  @c2.dataset = @c2.dataset.with_fetch(:id=>2)
383
387
  @c1.dataset = @c1.dataset.with_fetch([{:id=>5, :tag_ids=>Sequel.pg_array([1,2,3])},{:id=>6, :tag_ids=>Sequel.pg_array([2,3])}, {:id=>7, :tag_ids=>Sequel.pg_array([1,2])}])
388
+ @db.sqls
384
389
 
385
390
  @c2.many_to_pg_array :artists, :clone=>:artists, :limit=>2
386
391
  a = @c2.eager(:artists).all
@@ -417,6 +422,7 @@ describe Sequel::Model, "pg_array_associations" do
417
422
  it "should eagerly graph associations" do
418
423
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]))
419
424
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
425
+ @db.sqls
420
426
 
421
427
  a = @c1.eager_graph(:tags).all
422
428
  @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
@@ -434,6 +440,7 @@ describe Sequel::Model, "pg_array_associations" do
434
440
  it "should allow cascading of eager graphing for associations of associated models" do
435
441
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
436
442
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
443
+ @db.sqls
437
444
 
438
445
  a = @c1.eager_graph(:tags=>:artists).all
439
446
  @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id, artists_0.id AS artists_0_id, artists_0.tag_ids AS artists_0_tag_ids FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) LEFT OUTER JOIN artists AS artists_0 ON (artists_0.tag_ids @> ARRAY[tags.id])"]
@@ -457,6 +464,7 @@ describe Sequel::Model, "pg_array_associations" do
457
464
 
458
465
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2)
459
466
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3]))
467
+ @db.sqls
460
468
 
461
469
  a = @c1.eager_graph(:tags).all
462
470
  a.must_equal [@o1]
@@ -477,6 +485,7 @@ describe Sequel::Model, "pg_array_associations" do
477
485
 
478
486
  @c2.dataset = @c2.dataset.with_fetch(:id=>2, :artists_id=>1)
479
487
  @c1.dataset = @c1.dataset.with_fetch(:id=>1, :id2=>2, :tag_ids=>Sequel.pg_array([1,2,3]))
488
+ @db.sqls
480
489
 
481
490
  a = @c1.eager_graph(:tags).all
482
491
  @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id2 FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
@@ -738,15 +747,17 @@ end
738
747
 
739
748
  describe "Sequel::Model.finalize_associations" do
740
749
  before do
741
- class ::Foo < Sequel::Model
750
+ @db = Sequel.mock(:host=>'postgres', :numrows=>1)
751
+ class ::Foo < Sequel::Model(@db)
742
752
  plugin :pg_array_associations
743
753
  many_to_pg_array :items
744
754
  end
745
- class ::Item < Sequel::Model
755
+ class ::Item < Sequel::Model(@db)
746
756
  plugin :pg_array_associations
747
757
  pg_array_to_many :foos
748
758
  end
749
759
  [Foo, Item].each(&:finalize_associations)
760
+ @db.sqls
750
761
  end
751
762
  after do
752
763
  Object.send(:remove_const, :Item)
@@ -3,10 +3,10 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
3
3
  describe "pg_array extension" do
4
4
  before(:all) do
5
5
  Sequel.extension :pg_array
6
- @pg_types = Sequel::Postgres::PG_TYPES.dup
6
+ @pg_types = Sequel::Postgres::PG__TYPES.dup # SEQUEL5: Remove
7
7
  end
8
8
  after(:all) do
9
- Sequel::Postgres::PG_TYPES.replace(@pg_types)
9
+ Sequel::Postgres::PG__TYPES.replace(@pg_types) # SEQUEL5: Remove
10
10
  end
11
11
 
12
12
  before do
@@ -18,7 +18,7 @@ describe "pg_array extension" do
18
18
  end)
19
19
  @db.extension(:pg_array)
20
20
  @m = Sequel::Postgres
21
- @converter = @m::PG_TYPES
21
+ @converter = @db.conversion_procs
22
22
  @db.sqls
23
23
  end
24
24
 
@@ -34,6 +34,11 @@ describe "pg_array extension" do
34
34
  c.call('{a,b}').to_a.must_equal ['a', 'b']
35
35
  end
36
36
 
37
+ it "should preserve encoding when parsing text arrays" do
38
+ c = @converter[1009]
39
+ c.call("{a,\u00E4}".encode('ISO-8859-1')).map(&:encoding).must_equal [Encoding::ISO_8859_1, Encoding::ISO_8859_1]
40
+ end if RUBY_VERSION >= '1.9'
41
+
37
42
  it "should parse multi-dimensional text arrays" do
38
43
  c = @converter[1009]
39
44
  c.call("{{}}").to_a.must_equal [[]]
@@ -256,42 +261,53 @@ describe "pg_array extension" do
256
261
  @db.select(Sequel.pg_array([1], :integer).as(:col1)).sql.must_equal 'SELECT ARRAY[1]::integer[] AS col1'
257
262
  end
258
263
 
259
- it "should support registering custom array types" do
264
+ deprecated "should support registering custom array types" do
260
265
  Sequel::Postgres::PGArray.register('foo')
261
266
  @db.typecast_value(:foo_array, []).class.must_equal(Sequel::Postgres::PGArray)
262
267
  @db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
263
268
  @db.schema(:items).map{|e| e[1][:type]}.must_equal [:foo_array]
264
269
  end
265
270
 
271
+ deprecated "should raise error if register given convertor option and block" do
272
+ proc{Sequel::Postgres::PGArray.register('foo', :converter=>:to_s.to_proc, &:to_s)}.must_raise Sequel::Error
273
+ end
274
+
275
+ it "should support registering custom array types" do
276
+ @db.register_array_type('foo')
277
+ @db.typecast_value(:foo_array, []).class.must_equal(Sequel::Postgres::PGArray)
278
+ @db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
279
+ @db.schema(:items).map{|e| e[1][:type]}.must_equal [:foo_array]
280
+ end
281
+
266
282
  it "should support registering custom types with :type_symbol option" do
267
- Sequel::Postgres::PGArray.register('foo', :type_symbol=>:bar)
283
+ @db.register_array_type('foo', :type_symbol=>:bar)
268
284
  @db.typecast_value(:bar_array, []).class.must_equal(Sequel::Postgres::PGArray)
269
285
  @db.fetch = [{:name=>'id', :db_type=>'foo[]'}]
270
286
  @db.schema(:items).map{|e| e[1][:type]}.must_equal [:bar_array]
271
287
  end
272
288
 
273
289
  it "should support using a block as a custom conversion proc given as block" do
274
- Sequel::Postgres::PGArray.register('foo', :oid=>1234){|s| (s*2).to_i}
275
- @converter[1234].call('{1}').must_equal [11]
290
+ @db.register_array_type('foo', :oid=>1234){|s| (s*2).to_i}
291
+ @db.conversion_procs[1234].call('{1}').must_equal [11]
276
292
  end
277
293
 
278
294
  it "should support using a block as a custom conversion proc given as :converter option" do
279
- Sequel::Postgres::PGArray.register('foo', :oid=>1234, :converter=>proc{|s| (s*2).to_i})
280
- @converter[1234].call('{1}').must_equal [11]
295
+ @db.register_array_type('foo', :oid=>1234, :converter=>proc{|s| (s*2).to_i})
296
+ @db.conversion_procs[1234].call('{1}').must_equal [11]
281
297
  end
282
298
 
283
299
  it "should support using an existing scaler conversion proc via the :scalar_oid option" do
284
- Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16)
285
- @converter[1234].call('{t}').must_equal [true]
300
+ @db.register_array_type('foo', :oid=>1234, :scalar_oid=>16)
301
+ @db.conversion_procs[1234].call('{t}').must_equal [true]
286
302
  end
287
303
 
288
- it "should support using a given conversion procs hash via the :type_procs option" do
304
+ deprecated "should support using a given conversion procs hash via the :type_procs option" do
289
305
  h = {16=>proc{|s| "!#{s}"}}
290
306
  Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>16, :type_procs=>h)
291
307
  h[1234].call('{t}').must_equal ["!t"]
292
308
  end
293
309
 
294
- it "should support adding methods to the given module via the :typecast_methods_module option" do
310
+ deprecated "should support adding methods to the given module via the :typecast_methods_module option" do
295
311
  m = Module.new
296
312
  Sequel::Postgres::PGArray.register('foo15', :scalar_typecast=>:boolean, :typecast_methods_module=>m)
297
313
  @db.typecast_value(:foo15_array, ['t']).must_equal ['t']
@@ -300,32 +316,31 @@ describe "pg_array extension" do
300
316
  end
301
317
 
302
318
  it "should not raise an error if using :scalar_oid option with unexisting scalar conversion proc" do
303
- h = {}
304
- Sequel::Postgres::PGArray.register('foo', :oid=>1234, :scalar_oid=>0, :type_procs=>h)
305
- h[1234].call('{t}').must_equal ["t"]
319
+ @db.register_array_type('foo', :oid=>1234, :scalar_oid=>0)
320
+ @db.conversion_procs[1234].call('{t}').must_equal ["t"]
306
321
  end
307
322
 
308
323
  it "should raise an error if using :converter option and a block argument" do
309
- proc{Sequel::Postgres::PGArray.register('foo', :converter=>proc{}){}}.must_raise(Sequel::Error)
324
+ proc{@db.register_array_type('foo', :converter=>proc{}){}}.must_raise(Sequel::Error)
310
325
  end
311
326
 
312
327
  it "should raise an error if using :scalar_oid option and a block argument" do
313
- proc{Sequel::Postgres::PGArray.register('foo', :scalar_oid=>16){}}.must_raise(Sequel::Error)
328
+ proc{@db.register_array_type('foo', :scalar_oid=>16){}}.must_raise(Sequel::Error)
314
329
  end
315
330
 
316
331
  it "should support registering custom types with :oid option" do
317
- Sequel::Postgres::PGArray.register('foo', :oid=>1)
318
- Sequel::Postgres::PG_TYPES[1].call('{1}').class.must_equal(Sequel::Postgres::PGArray)
332
+ @db.register_array_type('foo', :oid=>1)
333
+ @db.conversion_procs[1].call('{1}').class.must_equal(Sequel::Postgres::PGArray)
319
334
  end
320
335
 
321
336
  it "should support registering converters with blocks" do
322
- Sequel::Postgres::PGArray.register('foo', :oid=>4){|s| s.to_i * 2}
323
- Sequel::Postgres::PG_TYPES[4].call('{{1,2},{3,4}}').must_equal [[2, 4], [6, 8]]
337
+ @db.register_array_type('foo', :oid=>4){|s| s.to_i * 2}
338
+ @db.conversion_procs[4].call('{{1,2},{3,4}}').must_equal [[2, 4], [6, 8]]
324
339
  end
325
340
 
326
341
  it "should support registering custom types with :array_type option" do
327
- Sequel::Postgres::PGArray.register('foo', :oid=>3, :array_type=>:blah)
328
- @db.literal(Sequel::Postgres::PG_TYPES[3].call('{}')).must_equal "'{}'::blah[]"
342
+ @db.register_array_type('foo', :oid=>3, :array_type=>:blah)
343
+ @db.literal(@db.conversion_procs[3].call('{}')).must_equal "'{}'::blah[]"
329
344
  end
330
345
 
331
346
  it "should not support registering custom array types on a per-Database basis for frozen databases" do
@@ -373,9 +388,13 @@ describe "pg_array extension" do
373
388
  @db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
374
389
  end
375
390
 
391
+ it "should set appropriate timestamp conversion procs" do
392
+ @db.conversion_procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
393
+ @db.conversion_procs[1115].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
394
+ end
395
+
376
396
  it "should set appropriate timestamp conversion procs when adding conversion procs" do
377
397
  @db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
378
- @db.reset_conversion_procs
379
398
  @db.add_named_conversion_proc(:foo){|v| v*2}
380
399
  procs = @db.conversion_procs
381
400
  procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
@@ -7,6 +7,7 @@ describe "pg_hstore extension" do
7
7
  @db.extend_datasets{def quote_identifiers?; false end}
8
8
  @m = Sequel::Postgres
9
9
  @c = @m::HStore
10
+ @db.fetch = {:oid=>9999, :typname=>'hstore'}
10
11
  @db.extension :pg_hstore
11
12
  end
12
13
 
@@ -34,6 +35,15 @@ describe "pg_hstore extension" do
34
35
  ['\'"a"=>"b","c"=>"d"\'::hstore', '\'"c"=>"d","a"=>"b"\'::hstore'].must_include(@db.literal(Sequel.hstore("a"=>"b","c"=>"d")))
35
36
  end
36
37
 
38
+ it "should register conversion proc correctly" do
39
+ @db.conversion_procs[9999].call('"a"=>"b"').must_equal('a'=>'b')
40
+ end
41
+
42
+ deprecated "should reregister conversion proc when resetting conversion procs" do
43
+ @db.reset_conversion_procs
44
+ @db.conversion_procs[9999].call('"a"=>"b"').must_equal('a'=>'b')
45
+ end
46
+
37
47
  it "should have Sequel.hstore method for creating HStore instances" do
38
48
  Sequel.hstore({}).class.must_equal(@c)
39
49
  end
@@ -18,6 +18,32 @@ describe "pg_inet extension" do
18
18
  @db.literal(IPAddr.new('2001:4f8:3:ba:2e0:81ff:fe22:d1f1')).must_equal "'2001:4f8:3:ba:2e0:81ff:fe22:d1f1/128'"
19
19
  end unless ipv6_broken
20
20
 
21
+ deprecated "should set up conversion procs correctly" do
22
+ cp = Sequel::Postgres::PG__TYPES
23
+ cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
24
+ cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
25
+ end
26
+
27
+ deprecated "should set up conversion procs for arrays correctly" do
28
+ cp = Sequel::Postgres::PG__TYPES
29
+ cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
30
+ cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
31
+ cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
32
+ end
33
+
34
+ it "should set up conversion procs correctly" do
35
+ cp = @db.conversion_procs
36
+ cp[869].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
37
+ cp[650].call("127.0.0.1").must_equal IPAddr.new('127.0.0.1')
38
+ end
39
+
40
+ it "should set up conversion procs for arrays correctly" do
41
+ cp = @db.conversion_procs
42
+ cp[1041].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
43
+ cp[651].call("{127.0.0.1}").must_equal [IPAddr.new('127.0.0.1')]
44
+ cp[1040].call("{127.0.0.1}").must_equal ['127.0.0.1']
45
+ end
46
+
21
47
  it "should not affect literalization of custom objects" do
22
48
  o = Object.new
23
49
  def o.sql_literal(ds) 'v' end
@@ -34,6 +34,26 @@ describe "pg_interval extension" do
34
34
  end
35
35
  end
36
36
 
37
+ deprecated "should set up conversion procs correctly" do
38
+ cp = Sequel::Postgres::PG__TYPES
39
+ cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
40
+ end
41
+
42
+ deprecated "should set up conversion procs for arrays correctly" do
43
+ cp = Sequel::Postgres::PG__TYPES
44
+ cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
45
+ end
46
+
47
+ it "should set up conversion procs correctly" do
48
+ cp = @db.conversion_procs
49
+ cp[1186].call("1 sec").must_equal ActiveSupport::Duration.new(1, [[:seconds, 1]])
50
+ end
51
+
52
+ it "should set up conversion procs for arrays correctly" do
53
+ cp = @db.conversion_procs
54
+ cp[1187].call("{1 sec}").must_equal [ActiveSupport::Duration.new(1, [[:seconds, 1]])]
55
+ end
56
+
37
57
  it "should not affect literalization of custom objects" do
38
58
  o = Object.new
39
59
  def o.sql_literal(ds) 'v' end
@@ -17,6 +17,30 @@ describe "pg_json extension" do
17
17
  @db.extension(:pg_array, :pg_json)
18
18
  end
19
19
 
20
+ deprecated "should set up conversion procs correctly" do
21
+ cp = Sequel::Postgres::PG__TYPES
22
+ cp[114].call("{}").must_equal @hc.new({})
23
+ cp[3802].call("{}").must_equal @bhc.new({})
24
+ end
25
+
26
+ deprecated "should set up conversion procs for arrays correctly" do
27
+ cp = Sequel::Postgres::PG__TYPES
28
+ cp[199].call("{[]}").must_equal [@ac.new([])]
29
+ cp[3807].call("{[]}").must_equal [@bac.new([])]
30
+ end
31
+
32
+ it "should set up conversion procs correctly" do
33
+ cp = @db.conversion_procs
34
+ cp[114].call("{}").must_equal @hc.new({})
35
+ cp[3802].call("{}").must_equal @bhc.new({})
36
+ end
37
+
38
+ it "should set up conversion procs for arrays correctly" do
39
+ cp = @db.conversion_procs
40
+ cp[199].call("{[]}").must_equal [@ac.new([])]
41
+ cp[3807].call("{[]}").must_equal [@bac.new([])]
42
+ end
43
+
20
44
  it "should parse json strings correctly" do
21
45
  @m.parse_json('[]').class.must_equal(@ac)
22
46
  @m.parse_json('[]').to_a.must_equal []