sequel 3.21.0 → 3.39.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 (352) hide show
  1. data/CHANGELOG +1061 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +103 -63
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +67 -51
  7. data/doc/advanced_associations.rdoc +189 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/cheat_sheet.rdoc +21 -21
  10. data/doc/core_extensions.rdoc +374 -0
  11. data/doc/dataset_basics.rdoc +10 -10
  12. data/doc/dataset_filtering.rdoc +54 -42
  13. data/doc/mass_assignment.rdoc +56 -0
  14. data/doc/migration.rdoc +89 -557
  15. data/doc/model_hooks.rdoc +80 -29
  16. data/doc/object_model.rdoc +547 -0
  17. data/doc/opening_databases.rdoc +114 -53
  18. data/doc/prepared_statements.rdoc +41 -15
  19. data/doc/querying.rdoc +137 -56
  20. data/doc/reflection.rdoc +36 -10
  21. data/doc/release_notes/3.22.0.txt +39 -0
  22. data/doc/release_notes/3.23.0.txt +172 -0
  23. data/doc/release_notes/3.24.0.txt +420 -0
  24. data/doc/release_notes/3.25.0.txt +88 -0
  25. data/doc/release_notes/3.26.0.txt +88 -0
  26. data/doc/release_notes/3.27.0.txt +82 -0
  27. data/doc/release_notes/3.28.0.txt +304 -0
  28. data/doc/release_notes/3.29.0.txt +459 -0
  29. data/doc/release_notes/3.30.0.txt +135 -0
  30. data/doc/release_notes/3.31.0.txt +146 -0
  31. data/doc/release_notes/3.32.0.txt +202 -0
  32. data/doc/release_notes/3.33.0.txt +157 -0
  33. data/doc/release_notes/3.34.0.txt +671 -0
  34. data/doc/release_notes/3.35.0.txt +144 -0
  35. data/doc/release_notes/3.36.0.txt +245 -0
  36. data/doc/release_notes/3.37.0.txt +338 -0
  37. data/doc/release_notes/3.38.0.txt +234 -0
  38. data/doc/release_notes/3.39.0.txt +237 -0
  39. data/doc/schema_modification.rdoc +585 -0
  40. data/doc/sharding.rdoc +99 -8
  41. data/doc/sql.rdoc +154 -112
  42. data/doc/testing.rdoc +169 -0
  43. data/doc/thread_safety.rdoc +17 -0
  44. data/doc/transactions.rdoc +137 -0
  45. data/doc/validations.rdoc +1 -1
  46. data/doc/virtual_rows.rdoc +78 -43
  47. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  48. data/lib/sequel/adapters/ado.rb +40 -18
  49. data/lib/sequel/adapters/amalgalite.rb +17 -9
  50. data/lib/sequel/adapters/db2.rb +175 -86
  51. data/lib/sequel/adapters/dbi.rb +15 -15
  52. data/lib/sequel/adapters/do/mysql.rb +17 -11
  53. data/lib/sequel/adapters/do/postgres.rb +2 -61
  54. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  55. data/lib/sequel/adapters/do.rb +18 -36
  56. data/lib/sequel/adapters/firebird.rb +27 -208
  57. data/lib/sequel/adapters/ibmdb.rb +453 -0
  58. data/lib/sequel/adapters/informix.rb +6 -23
  59. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  60. data/lib/sequel/adapters/jdbc/db2.rb +56 -0
  61. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  62. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  63. data/lib/sequel/adapters/jdbc/h2.rb +73 -31
  64. data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
  65. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  66. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  67. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  68. data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
  69. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  70. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  71. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  73. data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
  74. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  75. data/lib/sequel/adapters/jdbc.rb +279 -97
  76. data/lib/sequel/adapters/mock.rb +372 -0
  77. data/lib/sequel/adapters/mysql.rb +125 -222
  78. data/lib/sequel/adapters/mysql2.rb +65 -56
  79. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  80. data/lib/sequel/adapters/odbc.rb +28 -9
  81. data/lib/sequel/adapters/openbase.rb +3 -5
  82. data/lib/sequel/adapters/oracle.rb +349 -53
  83. data/lib/sequel/adapters/postgres.rb +368 -138
  84. data/lib/sequel/adapters/shared/access.rb +32 -9
  85. data/lib/sequel/adapters/shared/db2.rb +343 -0
  86. data/lib/sequel/adapters/shared/firebird.rb +221 -0
  87. data/lib/sequel/adapters/shared/informix.rb +53 -0
  88. data/lib/sequel/adapters/shared/mssql.rb +401 -116
  89. data/lib/sequel/adapters/shared/mysql.rb +424 -89
  90. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
  91. data/lib/sequel/adapters/shared/oracle.rb +257 -45
  92. data/lib/sequel/adapters/shared/postgres.rb +675 -279
  93. data/lib/sequel/adapters/shared/progress.rb +5 -8
  94. data/lib/sequel/adapters/shared/sqlite.rb +285 -96
  95. data/lib/sequel/adapters/sqlite.rb +101 -39
  96. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  97. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  98. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  99. data/lib/sequel/adapters/swift.rb +28 -19
  100. data/lib/sequel/adapters/tinytds.rb +174 -22
  101. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  102. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  103. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  104. data/lib/sequel/ast_transformer.rb +194 -0
  105. data/lib/sequel/connection_pool/sharded_single.rb +11 -1
  106. data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
  107. data/lib/sequel/connection_pool/single.rb +5 -0
  108. data/lib/sequel/connection_pool/threaded.rb +43 -14
  109. data/lib/sequel/connection_pool.rb +10 -2
  110. data/lib/sequel/core.rb +143 -11
  111. data/lib/sequel/database/connecting.rb +38 -28
  112. data/lib/sequel/database/dataset.rb +4 -4
  113. data/lib/sequel/database/dataset_defaults.rb +63 -2
  114. data/lib/sequel/database/logging.rb +7 -2
  115. data/lib/sequel/database/misc.rb +190 -46
  116. data/lib/sequel/database/query.rb +272 -110
  117. data/lib/sequel/database/schema_generator.rb +103 -36
  118. data/lib/sequel/database/schema_methods.rb +300 -67
  119. data/lib/sequel/dataset/actions.rb +344 -90
  120. data/lib/sequel/dataset/features.rb +101 -8
  121. data/lib/sequel/dataset/graph.rb +42 -15
  122. data/lib/sequel/dataset/misc.rb +52 -25
  123. data/lib/sequel/dataset/mutation.rb +12 -7
  124. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  125. data/lib/sequel/dataset/query.rb +305 -54
  126. data/lib/sequel/dataset/sql.rb +720 -292
  127. data/lib/sequel/dataset.rb +8 -0
  128. data/lib/sequel/exceptions.rb +4 -0
  129. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  130. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  131. data/lib/sequel/extensions/blank.rb +4 -0
  132. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  133. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  134. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  135. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  136. data/lib/sequel/extensions/inflector.rb +4 -0
  137. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  138. data/lib/sequel/extensions/migration.rb +100 -11
  139. data/lib/sequel/extensions/named_timezones.rb +9 -0
  140. data/lib/sequel/extensions/null_dataset.rb +94 -0
  141. data/lib/sequel/extensions/pagination.rb +4 -0
  142. data/lib/sequel/extensions/pg_array.rb +537 -0
  143. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  144. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  145. data/lib/sequel/extensions/pg_hstore.rb +313 -0
  146. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  147. data/lib/sequel/extensions/pg_inet.rb +113 -0
  148. data/lib/sequel/extensions/pg_interval.rb +191 -0
  149. data/lib/sequel/extensions/pg_json.rb +208 -0
  150. data/lib/sequel/extensions/pg_range.rb +512 -0
  151. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  152. data/lib/sequel/extensions/pg_row.rb +572 -0
  153. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  154. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  155. data/lib/sequel/extensions/pretty_table.rb +17 -72
  156. data/lib/sequel/extensions/query.rb +8 -4
  157. data/lib/sequel/extensions/query_literals.rb +79 -0
  158. data/lib/sequel/extensions/schema_caching.rb +76 -0
  159. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  160. data/lib/sequel/extensions/select_remove.rb +39 -0
  161. data/lib/sequel/extensions/server_block.rb +140 -0
  162. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  163. data/lib/sequel/extensions/sql_expr.rb +8 -110
  164. data/lib/sequel/extensions/string_date_time.rb +4 -0
  165. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  166. data/lib/sequel/extensions/to_dot.rb +99 -83
  167. data/lib/sequel/model/associations.rb +1263 -409
  168. data/lib/sequel/model/base.rb +624 -171
  169. data/lib/sequel/model/errors.rb +1 -1
  170. data/lib/sequel/model/exceptions.rb +24 -2
  171. data/lib/sequel/model/inflections.rb +1 -1
  172. data/lib/sequel/model.rb +30 -11
  173. data/lib/sequel/no_core_ext.rb +2 -0
  174. data/lib/sequel/plugins/active_model.rb +13 -1
  175. data/lib/sequel/plugins/association_pks.rb +22 -4
  176. data/lib/sequel/plugins/caching.rb +25 -18
  177. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  178. data/lib/sequel/plugins/composition.rb +44 -12
  179. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  180. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  181. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  182. data/lib/sequel/plugins/dirty.rb +214 -0
  183. data/lib/sequel/plugins/eager_each.rb +59 -0
  184. data/lib/sequel/plugins/force_encoding.rb +6 -6
  185. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  186. data/lib/sequel/plugins/identity_map.rb +134 -15
  187. data/lib/sequel/plugins/instance_filters.rb +10 -0
  188. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  189. data/lib/sequel/plugins/json_serializer.rb +58 -6
  190. data/lib/sequel/plugins/list.rb +13 -2
  191. data/lib/sequel/plugins/many_through_many.rb +103 -51
  192. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  193. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  194. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  195. data/lib/sequel/plugins/pg_row.rb +121 -0
  196. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  197. data/lib/sequel/plugins/prepared_statements.rb +167 -0
  198. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  199. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  200. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  201. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  202. data/lib/sequel/plugins/schema.rb +8 -3
  203. data/lib/sequel/plugins/serialization.rb +98 -49
  204. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  205. data/lib/sequel/plugins/sharding.rb +21 -54
  206. data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
  207. data/lib/sequel/plugins/static_cache.rb +99 -0
  208. data/lib/sequel/plugins/subclasses.rb +29 -3
  209. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  210. data/lib/sequel/plugins/timestamps.rb +1 -1
  211. data/lib/sequel/plugins/tree.rb +3 -3
  212. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  213. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  214. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  215. data/lib/sequel/plugins/validation_helpers.rb +55 -4
  216. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  217. data/lib/sequel/sql.rb +649 -122
  218. data/lib/sequel/timezones.rb +67 -40
  219. data/lib/sequel/version.rb +1 -1
  220. data/spec/adapters/db2_spec.rb +146 -0
  221. data/spec/adapters/firebird_spec.rb +1 -1
  222. data/spec/adapters/mssql_spec.rb +194 -66
  223. data/spec/adapters/mysql_spec.rb +475 -306
  224. data/spec/adapters/oracle_spec.rb +92 -117
  225. data/spec/adapters/postgres_spec.rb +1982 -325
  226. data/spec/adapters/spec_helper.rb +9 -6
  227. data/spec/adapters/sqlite_spec.rb +203 -75
  228. data/spec/core/connection_pool_spec.rb +218 -93
  229. data/spec/core/database_spec.rb +956 -522
  230. data/spec/core/dataset_spec.rb +1631 -1242
  231. data/spec/core/expression_filters_spec.rb +690 -334
  232. data/spec/core/mock_adapter_spec.rb +453 -0
  233. data/spec/core/object_graph_spec.rb +88 -129
  234. data/spec/core/schema_generator_spec.rb +4 -4
  235. data/spec/core/schema_spec.rb +556 -53
  236. data/spec/core/spec_helper.rb +7 -48
  237. data/spec/core_extensions_spec.rb +626 -0
  238. data/spec/extensions/active_model_spec.rb +13 -0
  239. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  240. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  241. data/spec/extensions/association_dependencies_spec.rb +15 -25
  242. data/spec/extensions/association_pks_spec.rb +66 -32
  243. data/spec/extensions/association_proxies_spec.rb +4 -4
  244. data/spec/extensions/boolean_readers_spec.rb +25 -25
  245. data/spec/extensions/caching_spec.rb +47 -51
  246. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  247. data/spec/extensions/columns_introspection_spec.rb +91 -0
  248. data/spec/extensions/composition_spec.rb +18 -13
  249. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  250. data/spec/extensions/constraint_validations_spec.rb +316 -0
  251. data/spec/extensions/dataset_associations_spec.rb +199 -0
  252. data/spec/extensions/defaults_setter_spec.rb +88 -0
  253. data/spec/extensions/dirty_spec.rb +155 -0
  254. data/spec/extensions/eager_each_spec.rb +34 -0
  255. data/spec/extensions/eval_inspect_spec.rb +67 -0
  256. data/spec/extensions/force_encoding_spec.rb +4 -2
  257. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  258. data/spec/extensions/identity_map_spec.rb +142 -24
  259. data/spec/extensions/inflector_spec.rb +0 -4
  260. data/spec/extensions/instance_filters_spec.rb +11 -21
  261. data/spec/extensions/instance_hooks_spec.rb +72 -0
  262. data/spec/extensions/json_serializer_spec.rb +49 -12
  263. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  264. data/spec/extensions/list_spec.rb +49 -40
  265. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  266. data/spec/extensions/many_through_many_spec.rb +368 -254
  267. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  268. data/spec/extensions/migration_spec.rb +140 -35
  269. data/spec/extensions/named_timezones_spec.rb +29 -11
  270. data/spec/extensions/nested_attributes_spec.rb +268 -89
  271. data/spec/extensions/null_dataset_spec.rb +85 -0
  272. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  273. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  274. data/spec/extensions/pg_array_spec.rb +320 -0
  275. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  276. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  277. data/spec/extensions/pg_hstore_spec.rb +194 -0
  278. data/spec/extensions/pg_inet_spec.rb +47 -0
  279. data/spec/extensions/pg_interval_spec.rb +72 -0
  280. data/spec/extensions/pg_json_spec.rb +99 -0
  281. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  282. data/spec/extensions/pg_range_spec.rb +395 -0
  283. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  284. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  285. data/spec/extensions/pg_row_spec.rb +323 -0
  286. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  287. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  288. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  289. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  290. data/spec/extensions/prepared_statements_spec.rb +87 -0
  291. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  292. data/spec/extensions/pretty_table_spec.rb +7 -6
  293. data/spec/extensions/query_literals_spec.rb +167 -0
  294. data/spec/extensions/query_spec.rb +9 -3
  295. data/spec/extensions/rcte_tree_spec.rb +50 -43
  296. data/spec/extensions/schema_caching_spec.rb +41 -0
  297. data/spec/extensions/schema_dumper_spec.rb +434 -49
  298. data/spec/extensions/schema_spec.rb +30 -49
  299. data/spec/extensions/select_remove_spec.rb +38 -0
  300. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  301. data/spec/extensions/serialization_spec.rb +86 -48
  302. data/spec/extensions/server_block_spec.rb +90 -0
  303. data/spec/extensions/sharding_spec.rb +69 -143
  304. data/spec/extensions/single_table_inheritance_spec.rb +23 -29
  305. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  306. data/spec/extensions/spec_helper.rb +34 -67
  307. data/spec/extensions/split_array_nil_spec.rb +24 -0
  308. data/spec/extensions/sql_expr_spec.rb +29 -60
  309. data/spec/extensions/static_cache_spec.rb +145 -0
  310. data/spec/extensions/subclasses_spec.rb +14 -0
  311. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  312. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  313. data/spec/extensions/timestamps_spec.rb +6 -6
  314. data/spec/extensions/to_dot_spec.rb +8 -11
  315. data/spec/extensions/touch_spec.rb +13 -14
  316. data/spec/extensions/tree_spec.rb +11 -26
  317. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  318. data/spec/extensions/update_primary_key_spec.rb +30 -24
  319. data/spec/extensions/validation_class_methods_spec.rb +58 -67
  320. data/spec/extensions/validation_helpers_spec.rb +31 -37
  321. data/spec/extensions/xml_serializer_spec.rb +29 -4
  322. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  323. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  324. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  325. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  326. data/spec/integration/associations_test.rb +659 -21
  327. data/spec/integration/database_test.rb +11 -5
  328. data/spec/integration/dataset_test.rb +717 -129
  329. data/spec/integration/eager_loader_test.rb +38 -54
  330. data/spec/integration/migrator_test.rb +2 -3
  331. data/spec/integration/model_test.rb +81 -2
  332. data/spec/integration/plugin_test.rb +604 -147
  333. data/spec/integration/prepared_statement_test.rb +272 -128
  334. data/spec/integration/schema_test.rb +367 -57
  335. data/spec/integration/spec_helper.rb +42 -32
  336. data/spec/integration/timezone_test.rb +38 -12
  337. data/spec/integration/transaction_test.rb +183 -8
  338. data/spec/integration/type_test.rb +31 -8
  339. data/spec/model/association_reflection_spec.rb +207 -8
  340. data/spec/model/associations_spec.rb +1206 -693
  341. data/spec/model/base_spec.rb +334 -100
  342. data/spec/model/dataset_methods_spec.rb +45 -27
  343. data/spec/model/eager_loading_spec.rb +828 -692
  344. data/spec/model/hooks_spec.rb +355 -67
  345. data/spec/model/model_spec.rb +251 -179
  346. data/spec/model/plugins_spec.rb +24 -13
  347. data/spec/model/record_spec.rb +506 -232
  348. data/spec/model/spec_helper.rb +16 -77
  349. data/spec/model/validations_spec.rb +38 -2
  350. data/spec/rcov.opts +2 -0
  351. metadata +209 -80
  352. data/spec/core/core_sql_spec.rb +0 -451
@@ -0,0 +1,395 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "pg_range extension" do
4
+ before(:all) do
5
+ @pg_types = Sequel::Postgres::PG_TYPES.dup
6
+ end
7
+ after(:all) do
8
+ Sequel::Postgres::PG_TYPES.replace(@pg_types)
9
+ end
10
+
11
+ before do
12
+ @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
13
+ @R = Sequel::Postgres::PGRange
14
+ @db.extend_datasets(Module.new{def supports_timestamp_timezones?; false; end; def supports_timestamp_usecs?; false; end})
15
+ @db.extension(:pg_array, :pg_range)
16
+ end
17
+
18
+ it "should literalize Range instances to strings correctly" do
19
+ @db.literal(Date.new(2011, 1, 2)...Date.new(2011, 3, 2)).should == "'[2011-01-02,2011-03-02)'"
20
+ @db.literal(Time.local(2011, 1, 2, 10, 20, 30)...Time.local(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
21
+ @db.literal(DateTime.new(2011, 1, 2, 10, 20, 30)...DateTime.new(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
22
+ @db.literal(DateTime.new(2011, 1, 2, 10, 20, 30)...DateTime.new(2011, 2, 3, 10, 20, 30)).should == "'[2011-01-02 10:20:30,2011-02-03 10:20:30)'"
23
+ @db.literal(1..2).should == "'[1,2]'"
24
+ @db.literal(1.0..2.0).should == "'[1.0,2.0]'"
25
+ @db.literal(BigDecimal.new('1.0')..BigDecimal.new('2.0')).should == "'[1.0,2.0]'"
26
+ @db.literal(Sequel.lit('a')..Sequel.lit('z')).should == "'[a,z]'"
27
+ @db.literal(''..'()[]",\\2').should == "'[\"\",\\(\\)\\[\\]\\\"\\,\\\\2]'"
28
+ end
29
+
30
+ it "should literalize PGRange instances to strings correctly" do
31
+ @db.literal(@R.new(1, 2)).should == "'[1,2]'"
32
+ @db.literal(@R.new(true, false)).should == "'[true,false]'"
33
+ @db.literal(@R.new(1, 2, :exclude_begin=>true)).should == "'(1,2]'"
34
+ @db.literal(@R.new(1, 2, :exclude_end=>true)).should == "'[1,2)'"
35
+ @db.literal(@R.new(nil, 2)).should == "'[,2]'"
36
+ @db.literal(@R.new(1, nil)).should == "'[1,]'"
37
+ @db.literal(@R.new(1, 2, :db_type=>'int8range')).should == "'[1,2]'::int8range"
38
+ @db.literal(@R.new(nil, nil, :empty=>true)).should == "'empty'"
39
+ @db.literal(@R.new("", 2)).should == "'[\"\",2]'"
40
+ end
41
+
42
+ it "should not affect literalization of custom objects" do
43
+ o = Object.new
44
+ def o.sql_literal(ds) 'v' end
45
+ @db.literal(o).should == 'v'
46
+ end
47
+
48
+ it "should support using Range instances as bound variables" do
49
+ @db.bound_variable_arg(1..2, nil).should == "[1,2]"
50
+ end
51
+
52
+ it "should support using PGRange instances as bound variables" do
53
+ @db.bound_variable_arg(@R.new(1, 2), nil).should == "[1,2]"
54
+ end
55
+
56
+ it "should support using arrays of Range instances as bound variables" do
57
+ @db.bound_variable_arg([1..2,2...3], nil).should == '{"[1,2]","[2,3)"}'
58
+ end
59
+
60
+ it "should support using PGRange instances as bound variables" do
61
+ @db.bound_variable_arg([@R.new(1, 2),@R.new(2, 3)], nil).should == '{"[1,2]","[2,3]"}'
62
+ end
63
+
64
+ it "should parse range types from the schema correctly" do
65
+ @db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i4', :db_type=>'int4range'}, {:name=>'i8', :db_type=>'int8range'}, {:name=>'n', :db_type=>'numrange'}, {:name=>'d', :db_type=>'daterange'}, {:name=>'ts', :db_type=>'tsrange'}, {:name=>'tz', :db_type=>'tstzrange'}]
66
+ @db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :int4range, :int8range, :numrange, :daterange, :tsrange, :tstzrange]
67
+ end
68
+
69
+ it "should parse arrays of range types from the schema correctly" do
70
+ @db.fetch = [{:name=>'id', :db_type=>'integer'}, {:name=>'i4', :db_type=>'int4range[]'}, {:name=>'i8', :db_type=>'int8range[]'}, {:name=>'n', :db_type=>'numrange[]'}, {:name=>'d', :db_type=>'daterange[]'}, {:name=>'ts', :db_type=>'tsrange[]'}, {:name=>'tz', :db_type=>'tstzrange[]'}]
71
+ @db.schema(:items).map{|e| e[1][:type]}.should == [:integer, :int4range_array, :int8range_array, :numrange_array, :daterange_array, :tsrange_array, :tstzrange_array]
72
+ end
73
+
74
+ describe "database typecasting" do
75
+ before do
76
+ @o = @R.new(1, 2, :db_type=>'int4range')
77
+ @o2 = @R.new(1, 2, :db_type=>'int8range')
78
+ @eo = @R.new(nil, nil, :empty=>true, :db_type=>'int4range')
79
+ @eo2 = @R.new(nil, nil, :empty=>true, :db_type=>'int8range')
80
+ end
81
+
82
+ it "should handle multiple range types" do
83
+ %w'int4 int8 num date ts tstz'.each do |i|
84
+ @db.typecast_value(:"#{i}range", @R.new(1, 2, :db_type=>"#{i}range")).should == @R.new(1, 2, :db_type=>"#{i}range")
85
+ end
86
+ end
87
+
88
+ it "should handle multiple array range types" do
89
+ %w'int4 int8 num date ts tstz'.each do |i|
90
+ @db.typecast_value(:"#{i}range_array", [@R.new(1, 2, :db_type=>"#{i}range")]).should be_a_kind_of(Sequel::Postgres::PGArray)
91
+ @db.typecast_value(:"#{i}range_array", [@R.new(1, 2, :db_type=>"#{i}range")]).should == [@R.new(1, 2, :db_type=>"#{i}range")]
92
+ end
93
+ end
94
+
95
+ it "should return PGRange value as is if they have the same subtype" do
96
+ @db.typecast_value(:int4range, @o).should equal(@o)
97
+ end
98
+
99
+ it "should return new PGRange value as is if they have a different subtype" do
100
+ @db.typecast_value(:int8range, @o).should_not equal(@o)
101
+ @db.typecast_value(:int8range, @o).should == @o2
102
+ end
103
+
104
+ it "should return new PGRange value as is if they have a different subtype and value is empty" do
105
+ @db.typecast_value(:int8range, @eo).should == @eo2
106
+ end
107
+
108
+ it "should return new PGRange value if given a Range" do
109
+ @db.typecast_value(:int4range, 1..2).should == @o
110
+ @db.typecast_value(:int4range, 1..2).should_not == @o2
111
+ @db.typecast_value(:int8range, 1..2).should == @o2
112
+ end
113
+
114
+ it "should parse a string argument as the PostgreSQL output format" do
115
+ @db.typecast_value(:int4range, '[1,2]').should == @o
116
+ end
117
+
118
+ it "should raise errors for unparsable formats" do
119
+ proc{@db.typecast_value(:int8range, 'foo')}.should raise_error(Sequel::InvalidValue)
120
+ end
121
+
122
+ it "should raise errors for unhandled values" do
123
+ proc{@db.typecast_value(:int4range, 1)}.should raise_error(Sequel::InvalidValue)
124
+ end
125
+ end
126
+
127
+ it "should support registering custom range types" do
128
+ @R.register('foorange')
129
+ @db.typecast_value(:foorange, 1..2).should be_a_kind_of(@R)
130
+ @db.fetch = [{:name=>'id', :db_type=>'foorange'}]
131
+ @db.schema(:items).map{|e| e[1][:type]}.should == [:foorange]
132
+ end
133
+
134
+ it "should support using a block as a custom conversion proc given as block" do
135
+ @R.register('foo2range'){|s| (s*2).to_i}
136
+ @db.typecast_value(:foo2range, '[1,2]').should == (11..22)
137
+ end
138
+
139
+ it "should support using a block as a custom conversion proc given as :converter option" do
140
+ @R.register('foo3range', :converter=>proc{|s| (s*2).to_i})
141
+ @db.typecast_value(:foo3range, '[1,2]').should == (11..22)
142
+ end
143
+
144
+ it "should support using an existing scaler conversion proc via the :subtype_oid option" do
145
+ @R.register('foo4range', :subtype_oid=>16)
146
+ @db.typecast_value(:foo4range, '[t,f]').should == @R.new(true, false, :db_type=>'foo4range')
147
+ end
148
+
149
+ it "should raise an error if using :subtype_oid option with unexisting scalar conversion proc" do
150
+ proc{@R.register('fooirange', :subtype_oid=>0)}.should raise_error(Sequel::Error)
151
+ end
152
+
153
+ it "should raise an error if using :converter option and a block argument" do
154
+ proc{@R.register('fooirange', :converter=>proc{}){}}.should raise_error(Sequel::Error)
155
+ end
156
+
157
+ it "should raise an error if using :subtype_oid option and a block argument" do
158
+ proc{@R.register('fooirange', :subtype_oid=>16){}}.should raise_error(Sequel::Error)
159
+ end
160
+
161
+ it "should support registering custom types with :oid option" do
162
+ @R.register('foo5range', :oid=>331)
163
+ Sequel::Postgres::PG_TYPES[331].call('[1,3)').should be_a_kind_of(@R)
164
+ end
165
+
166
+ describe "parser" do
167
+ before do
168
+ @p = Sequel::Postgres::PG_TYPES[3904]
169
+ @sp = @R::Parser.new(nil)
170
+ end
171
+
172
+ it "should have db_type method to return the database type string" do
173
+ @p.db_type.should == 'int4range'
174
+ end
175
+
176
+ it "should have converter method which returns a callable used for conversion" do
177
+ @p.converter.call('1').should == 1
178
+ end
179
+
180
+ it "should have call parse input string argument into PGRange instance" do
181
+ @p.call('[1,2]').should == @R.new(1, 2, :db_type=>'int4range')
182
+ end
183
+
184
+ it "should handle empty ranges" do
185
+ @p.call('empty').should == @R.new(nil, nil, :empty=>true, :db_type=>'int4range')
186
+ end
187
+
188
+ it "should handle exclusive beginnings and endings" do
189
+ @p.call('(1,3]').should == @R.new(1, 3, :exclude_begin=>true, :db_type=>'int4range')
190
+ @p.call('[1,3)').should == @R.new(1, 3, :exclude_end=>true, :db_type=>'int4range')
191
+ @p.call('(1,3)').should == @R.new(1, 3, :exclude_begin=>true, :exclude_end=>true, :db_type=>'int4range')
192
+ end
193
+
194
+ it "should handle unbounded beginnings and endings" do
195
+ @p.call('[,2]').should == @R.new(nil, 2, :db_type=>'int4range')
196
+ @p.call('[1,]').should == @R.new(1, nil, :db_type=>'int4range')
197
+ @p.call('[,]').should == @R.new(nil, nil, :db_type=>'int4range')
198
+ end
199
+
200
+ it "should unescape quoted beginnings and endings" do
201
+ @sp.call('["\\\\ \\"","\\" \\\\"]').should == @R.new("\\ \"", "\" \\")
202
+ end
203
+
204
+ it "should treat empty quoted string not as unbounded" do
205
+ @sp.call('["","z"]').should == @R.new("", "z")
206
+ @sp.call('["a",""]').should == @R.new("a", "")
207
+ @sp.call('["",""]').should == @R.new("", "")
208
+ end
209
+ end
210
+
211
+ it "should set appropriate timestamp range conversion procs when getting conversion procs" do
212
+ procs = @db.conversion_procs
213
+ 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)))
214
+ 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)))
215
+ end
216
+
217
+ it "should set appropriate timestamp range array conversion procs when getting conversion procs" do
218
+ procs = @db.conversion_procs
219
+ 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)]
220
+ 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)]
221
+ end
222
+
223
+ describe "a PGRange instance" do
224
+ before do
225
+ @r1 = @R.new(1, 2)
226
+ @r2 = @R.new(3, nil, :exclude_begin=>true, :db_type=>'int4range')
227
+ @r3 = @R.new(nil, 4, :exclude_end=>true, :db_type=>'int8range')
228
+ end
229
+
230
+ it "should have #begin return the beginning of the range" do
231
+ @r1.begin.should == 1
232
+ @r2.begin.should == 3
233
+ @r3.begin.should == nil
234
+ end
235
+
236
+ it "should have #end return the end of the range" do
237
+ @r1.end.should == 2
238
+ @r2.end.should == nil
239
+ @r3.end.should == 4
240
+ end
241
+
242
+ it "should have #db_type return the range's database type" do
243
+ @r1.db_type.should == nil
244
+ @r2.db_type.should == 'int4range'
245
+ @r3.db_type.should == 'int8range'
246
+ end
247
+
248
+ it "should be able to be created by Sequel.pg_range" do
249
+ Sequel.pg_range(1..2).should == @r1
250
+ end
251
+
252
+ it "should have Sequel.pg_range be able to take a database type" do
253
+ Sequel.pg_range(1..2, :int4range).should == @R.new(1, 2, :db_type=>:int4range)
254
+ end
255
+
256
+ it "should have Sequel.pg_range return a PGRange as is" do
257
+ a = Sequel.pg_range(1..2)
258
+ Sequel.pg_range(a).should equal(a)
259
+ end
260
+
261
+ it "should have Sequel.pg_range return a new PGRange if the database type differs" do
262
+ a = Sequel.pg_range(1..2, :int4range)
263
+ b = Sequel.pg_range(a, :int8range)
264
+ a.to_range.should == b.to_range
265
+ a.should_not equal(b)
266
+ a.db_type.should == :int4range
267
+ b.db_type.should == :int8range
268
+ end
269
+
270
+ it "should have #initialize raise if requesting an empty range with beginning or ending" do
271
+ proc{@R.new(1, nil, :empty=>true)}.should raise_error(Sequel::Error)
272
+ proc{@R.new(nil, 2, :empty=>true)}.should raise_error(Sequel::Error)
273
+ proc{@R.new(nil, nil, :empty=>true, :exclude_begin=>true)}.should raise_error(Sequel::Error)
274
+ proc{@R.new(nil, nil, :empty=>true, :exclude_end=>true)}.should raise_error(Sequel::Error)
275
+ end
276
+
277
+ it "should quack like a range" do
278
+ if RUBY_VERSION >= '1.9'
279
+ @r1.cover?(1.5).should be_true
280
+ @r1.cover?(2.5).should be_false
281
+ @r1.first(1).should == [1]
282
+ @r1.last(1).should == [2]
283
+ end
284
+ @r1.to_a.should == [1, 2]
285
+ @r1.first.should == 1
286
+ @r1.last.should == 2
287
+ a = []
288
+ @r1.step{|x| a << x}
289
+ a.should == [1, 2]
290
+ end
291
+
292
+ it "should only consider PGRanges equal if they have the same db_type" do
293
+ @R.new(1, 2, :db_type=>'int4range').should == @R.new(1, 2, :db_type=>'int4range')
294
+ @R.new(1, 2, :db_type=>'int8range').should_not == @R.new(1, 2, :db_type=>'int4range')
295
+ end
296
+
297
+ it "should only consider empty PGRanges equal with other empty PGRanges" do
298
+ @R.new(nil, nil, :empty=>true).should == @R.new(nil, nil, :empty=>true)
299
+ @R.new(nil, nil, :empty=>true).should_not == @R.new(nil, nil)
300
+ @R.new(nil, nil).should_not == @R.new(nil, nil, :empty=>true)
301
+ end
302
+
303
+ it "should only consider empty PGRanges equal if they have the same bounds" do
304
+ @R.new(1, 2).should == @R.new(1, 2)
305
+ @R.new(1, 2).should_not == @R.new(1, 3)
306
+ end
307
+
308
+ it "should only consider empty PGRanges equal if they have the same bound exclusions" do
309
+ @R.new(1, 2, :exclude_begin=>true).should == @R.new(1, 2, :exclude_begin=>true)
310
+ @R.new(1, 2, :exclude_end=>true).should == @R.new(1, 2, :exclude_end=>true)
311
+ @R.new(1, 2, :exclude_begin=>true).should_not == @R.new(1, 2, :exclude_end=>true)
312
+ @R.new(1, 2, :exclude_end=>true).should_not == @R.new(1, 2, :exclude_begin=>true)
313
+ end
314
+
315
+ it "should consider PGRanges equal with a Range they represent" do
316
+ @R.new(1, 2).should == (1..2)
317
+ @R.new(1, 2, :exclude_end=>true).should == (1...2)
318
+ @R.new(1, 3).should_not == (1..2)
319
+ @R.new(1, 2, :exclude_end=>true).should_not == (1..2)
320
+ end
321
+
322
+ it "should not consider a PGRange equal with a Range if it can't be expressed as a range" do
323
+ @R.new(nil, nil).should_not == (1..2)
324
+ end
325
+
326
+ it "should not consider a PGRange equal to other objects" do
327
+ @R.new(nil, nil).should_not == 1
328
+ end
329
+
330
+ it "should have #=== be true if given an equal PGRange" do
331
+ @R.new(1, 2).should === @R.new(1, 2)
332
+ @R.new(1, 2).should_not === @R.new(1, 3)
333
+
334
+ end
335
+
336
+ it "should have #=== be true if it would be true for the Range represented by the PGRange" do
337
+ @R.new(1, 2).should === 1.5
338
+ @R.new(1, 2).should_not === 2.5
339
+ end
340
+
341
+ it "should have #=== be false if the PGRange cannot be represented by a Range" do
342
+ @R.new(nil, nil).should_not === 1.5
343
+ end
344
+
345
+ it "should have #empty? indicate whether the range is empty" do
346
+ @R.empty.should be_empty
347
+ @R.new(1, 2).should_not be_empty
348
+ end
349
+
350
+ it "should have #exclude_begin? and #exclude_end indicate whether the beginning or ending of the range is excluded" do
351
+ @r1.exclude_begin?.should be_false
352
+ @r1.exclude_end?.should be_false
353
+ @r2.exclude_begin?.should be_true
354
+ @r2.exclude_end?.should be_false
355
+ @r3.exclude_begin?.should be_false
356
+ @r3.exclude_end?.should be_true
357
+ end
358
+
359
+ it "should have #to_range raise an exception if the PGRange cannot be represented by a Range" do
360
+ proc{@R.new(nil, 1).to_range}.should raise_error(Sequel::Error)
361
+ proc{@R.new(1, nil).to_range}.should raise_error(Sequel::Error)
362
+ proc{@R.new(0, 1, :exclude_begin=>true).to_range}.should raise_error(Sequel::Error)
363
+ proc{@R.empty.to_range}.should raise_error(Sequel::Error)
364
+ end
365
+
366
+ it "should have #to_range return the represented range" do
367
+ @r1.to_range.should == (1..2)
368
+ end
369
+
370
+ it "should have #to_range cache the returned value" do
371
+ @r1.to_range.should equal(@r1.to_range)
372
+ end
373
+
374
+ it "should have #unbounded_begin? and #unbounded_end indicate whether the beginning or ending of the range is unbounded" do
375
+ @r1.unbounded_begin?.should be_false
376
+ @r1.unbounded_end?.should be_false
377
+ @r2.unbounded_begin?.should be_false
378
+ @r2.unbounded_end?.should be_true
379
+ @r3.unbounded_begin?.should be_true
380
+ @r3.unbounded_end?.should be_false
381
+ end
382
+
383
+ it "should have #valid_ruby_range? return true if the PGRange can be represented as a Range" do
384
+ @r1.valid_ruby_range?.should be_true
385
+ @R.new(1, 2, :exclude_end=>true).valid_ruby_range?.should be_true
386
+ end
387
+
388
+ it "should have #valid_ruby_range? return false if the PGRange cannot be represented as a Range" do
389
+ @R.new(nil, 1).valid_ruby_range?.should be_false
390
+ @R.new(1, nil).valid_ruby_range?.should be_false
391
+ @R.new(0, 1, :exclude_begin=>true).valid_ruby_range?.should be_false
392
+ @R.empty.valid_ruby_range?.should be_false
393
+ end
394
+ end
395
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Postgres::PGRowOp" do
4
+ before do
5
+ @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
+ @a = Sequel.pg_row_op(:a)
7
+ end
8
+
9
+ it "#[] should access members of the composite type" do
10
+ @db.literal(@a[:b]).should == "(a).b"
11
+ end
12
+
13
+ it "#[] should be chainable" do
14
+ @db.literal(@a[:b][:c]).should == "((a).b).c"
15
+ end
16
+
17
+ it "#[] should support array access if not given an identifier" do
18
+ @db.literal(@a[:b][1]).should == "(a).b[1]"
19
+ end
20
+
21
+ it "#[] should be chainable with array access" do
22
+ @db.literal(@a[1][:b]).should == "(a[1]).b"
23
+ end
24
+
25
+ it "#splat should return a splatted argument inside parentheses" do
26
+ @db.literal(@a.splat).should == "(a.*)"
27
+ end
28
+
29
+ it "#splat(type) should return a splatted argument cast to given type" do
30
+ @db.literal(@a.splat(:b)).should == "(a.*)::b"
31
+ end
32
+
33
+ it "#splat should not work on an already accessed composite type" do
34
+ proc{@a[:a].splat(:b)}.should raise_error(Sequel::Error)
35
+ end
36
+
37
+ it "#* should reference all members of the composite type as separate columns if given no arguments" do
38
+ @db.literal(@a.*).should == "(a).*"
39
+ @db.literal(@a[:b].*).should == "((a).b).*"
40
+ end
41
+
42
+ it "#* should use a multiplication operation if any arguments are given" do
43
+ @db.literal(@a.*(1)).should == "(a * 1)"
44
+ @db.literal(@a[:b].*(1)).should == "((a).b * 1)"
45
+ end
46
+
47
+ it "#pg_row should be callable on literal strings" do
48
+ @db.literal(Sequel.lit('a').pg_row[:b]).should == "(a).b"
49
+ end
50
+
51
+ it "#pg_row should be callable on Sequel expressions" do
52
+ @db.literal(Sequel.function(:a).pg_row[:b]).should == "(a()).b"
53
+ end
54
+
55
+ it "Sequel.pg_row should work as well if the pg_row extension is loaded" do
56
+ @db.literal(Sequel.pg_row(Sequel.function(:a))[:b]).should == "(a()).b"
57
+ end
58
+ end
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::PgRow" do
4
+ before(:all) do
5
+ @db = Sequel.connect('mock://postgres', :quote_identifiers=>false)
6
+ @db.extension(:pg_array)
7
+ @c = Class.new(Sequel::Model(@db[:address]))
8
+ @c.columns :street, :city
9
+ @c.db_schema[:street][:type] = :string
10
+ @c.db_schema[:city][:type] = :string
11
+ @db.fetch = [[{:oid=>1098, :typrelid=>2, :typarray=>3}], [{:attname=>'street', :atttypid=>1324}, {:attname=>'city', :atttypid=>1324}]]
12
+ @c.plugin :pg_row
13
+
14
+ @c2 = Class.new(Sequel::Model(@db[:company]))
15
+ @c2.columns :address
16
+ @c2.db_schema[:address].merge!(:type=>:pg_row_address)
17
+ end
18
+
19
+ it "should set up a parser for the type that creates a model class" do
20
+ @db.conversion_procs[1098].call('(123 Foo St,Bar City)').should == @c.load(:street=>'123 Foo St', :city=>'Bar City')
21
+ end
22
+
23
+ it "should set up type casting for the type" do
24
+ @c2.new(:address=>{'street'=>123, 'city'=>:Bar}).address.should == @c.load(:street=>'123', :city=>'Bar')
25
+ end
26
+
27
+ it "should return model instances as is when typecasting to rows" do
28
+ o = @c.load(:street=>'123', :city=>'Bar')
29
+ @c2.new(:address=>o).address.should equal(o)
30
+ end
31
+
32
+ it "should handle literalizing model instances" do
33
+ @db.literal(@c.load(:street=>'123 Foo St', :city=>'Bar City')).should == "ROW('123 Foo St', 'Bar City')::address"
34
+ end
35
+
36
+ it "should handle model instances in bound variables" do
37
+ @db.bound_variable_arg(1, nil).should == 1
38
+ @db.bound_variable_arg(@c.load(:street=>'123 Foo St', :city=>'Bar City'), nil).should == '("123 Foo St","Bar City")'
39
+ end
40
+
41
+ it "should handle model instances in arrays of bound variables" do
42
+ @db.bound_variable_arg(1, nil).should == 1
43
+ @db.bound_variable_arg(Sequel.pg_array([@c.load(:street=>'123 Foo St', :city=>'Bar City')]), nil).should == '{"(\\"123 Foo St\\",\\"Bar City\\")"}'
44
+ end
45
+
46
+ it "should allow inserting just this model value" do
47
+ @c2.insert_sql(@c.load(:street=>'123', :city=>'Bar')).should == "INSERT INTO company VALUES (ROW('123', 'Bar')::address)"
48
+ end
49
+ end