sequel 3.21.0 → 3.41.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 (363) hide show
  1. data/CHANGELOG +1131 -3
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +106 -65
  4. data/Rakefile +59 -27
  5. data/bin/sequel +50 -26
  6. data/doc/active_record.rdoc +68 -52
  7. data/doc/advanced_associations.rdoc +201 -75
  8. data/doc/association_basics.rdoc +327 -79
  9. data/doc/bin_sequel.rdoc +144 -0
  10. data/doc/cheat_sheet.rdoc +21 -21
  11. data/doc/core_extensions.rdoc +374 -0
  12. data/doc/dataset_basics.rdoc +10 -10
  13. data/doc/dataset_filtering.rdoc +54 -42
  14. data/doc/mass_assignment.rdoc +56 -0
  15. data/doc/migration.rdoc +89 -557
  16. data/doc/model_hooks.rdoc +80 -29
  17. data/doc/object_model.rdoc +576 -0
  18. data/doc/opening_databases.rdoc +121 -53
  19. data/doc/prepared_statements.rdoc +41 -15
  20. data/doc/querying.rdoc +137 -56
  21. data/doc/reflection.rdoc +36 -10
  22. data/doc/release_notes/3.22.0.txt +39 -0
  23. data/doc/release_notes/3.23.0.txt +172 -0
  24. data/doc/release_notes/3.24.0.txt +420 -0
  25. data/doc/release_notes/3.25.0.txt +88 -0
  26. data/doc/release_notes/3.26.0.txt +88 -0
  27. data/doc/release_notes/3.27.0.txt +82 -0
  28. data/doc/release_notes/3.28.0.txt +304 -0
  29. data/doc/release_notes/3.29.0.txt +459 -0
  30. data/doc/release_notes/3.30.0.txt +135 -0
  31. data/doc/release_notes/3.31.0.txt +146 -0
  32. data/doc/release_notes/3.32.0.txt +202 -0
  33. data/doc/release_notes/3.33.0.txt +157 -0
  34. data/doc/release_notes/3.34.0.txt +671 -0
  35. data/doc/release_notes/3.35.0.txt +144 -0
  36. data/doc/release_notes/3.36.0.txt +245 -0
  37. data/doc/release_notes/3.37.0.txt +338 -0
  38. data/doc/release_notes/3.38.0.txt +234 -0
  39. data/doc/release_notes/3.39.0.txt +237 -0
  40. data/doc/release_notes/3.40.0.txt +73 -0
  41. data/doc/release_notes/3.41.0.txt +155 -0
  42. data/doc/schema_modification.rdoc +585 -0
  43. data/doc/sharding.rdoc +99 -8
  44. data/doc/sql.rdoc +154 -112
  45. data/doc/testing.rdoc +169 -0
  46. data/doc/thread_safety.rdoc +17 -0
  47. data/doc/transactions.rdoc +137 -0
  48. data/doc/validations.rdoc +1 -1
  49. data/doc/virtual_rows.rdoc +78 -43
  50. data/lib/sequel/adapters/ado/access.rb +334 -0
  51. data/lib/sequel/adapters/ado/mssql.rb +18 -12
  52. data/lib/sequel/adapters/ado.rb +69 -21
  53. data/lib/sequel/adapters/amalgalite.rb +17 -14
  54. data/lib/sequel/adapters/cubrid.rb +143 -0
  55. data/lib/sequel/adapters/db2.rb +178 -85
  56. data/lib/sequel/adapters/dbi.rb +19 -21
  57. data/lib/sequel/adapters/do/mysql.rb +17 -11
  58. data/lib/sequel/adapters/do/postgres.rb +2 -61
  59. data/lib/sequel/adapters/do/sqlite.rb +0 -10
  60. data/lib/sequel/adapters/do.rb +20 -39
  61. data/lib/sequel/adapters/firebird.rb +33 -210
  62. data/lib/sequel/adapters/ibmdb.rb +452 -0
  63. data/lib/sequel/adapters/informix.rb +6 -29
  64. data/lib/sequel/adapters/jdbc/as400.rb +16 -34
  65. data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
  66. data/lib/sequel/adapters/jdbc/db2.rb +78 -0
  67. data/lib/sequel/adapters/jdbc/derby.rb +325 -0
  68. data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
  69. data/lib/sequel/adapters/jdbc/h2.rb +68 -31
  70. data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -0
  71. data/lib/sequel/adapters/jdbc/informix.rb +21 -0
  72. data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
  73. data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
  74. data/lib/sequel/adapters/jdbc/mysql.rb +16 -28
  75. data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
  76. data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
  77. data/lib/sequel/adapters/jdbc/progress.rb +21 -0
  78. data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
  79. data/lib/sequel/adapters/jdbc/sqlserver.rb +72 -0
  80. data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
  81. data/lib/sequel/adapters/jdbc.rb +308 -114
  82. data/lib/sequel/adapters/mock.rb +372 -0
  83. data/lib/sequel/adapters/mysql.rb +130 -230
  84. data/lib/sequel/adapters/mysql2.rb +64 -63
  85. data/lib/sequel/adapters/odbc/mssql.rb +17 -9
  86. data/lib/sequel/adapters/odbc.rb +29 -10
  87. data/lib/sequel/adapters/openbase.rb +7 -11
  88. data/lib/sequel/adapters/oracle.rb +364 -57
  89. data/lib/sequel/adapters/postgres.rb +379 -145
  90. data/lib/sequel/adapters/shared/access.rb +236 -11
  91. data/lib/sequel/adapters/shared/cubrid.rb +216 -0
  92. data/lib/sequel/adapters/shared/db2.rb +353 -0
  93. data/lib/sequel/adapters/shared/firebird.rb +231 -0
  94. data/lib/sequel/adapters/shared/informix.rb +53 -0
  95. data/lib/sequel/adapters/shared/mssql.rb +412 -116
  96. data/lib/sequel/adapters/shared/mysql.rb +396 -89
  97. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
  98. data/lib/sequel/adapters/shared/oracle.rb +262 -45
  99. data/lib/sequel/adapters/shared/postgres.rb +688 -279
  100. data/lib/sequel/adapters/shared/progress.rb +5 -8
  101. data/lib/sequel/adapters/shared/sqlite.rb +317 -96
  102. data/lib/sequel/adapters/sqlite.rb +109 -46
  103. data/lib/sequel/adapters/swift/mysql.rb +10 -12
  104. data/lib/sequel/adapters/swift/postgres.rb +13 -79
  105. data/lib/sequel/adapters/swift/sqlite.rb +9 -6
  106. data/lib/sequel/adapters/swift.rb +31 -27
  107. data/lib/sequel/adapters/tinytds.rb +177 -25
  108. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
  109. data/lib/sequel/adapters/utils/pg_types.rb +81 -0
  110. data/lib/sequel/adapters/utils/split_alter_table.rb +36 -0
  111. data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
  112. data/lib/sequel/ast_transformer.rb +194 -0
  113. data/lib/sequel/connection_pool/sharded_single.rb +23 -13
  114. data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
  115. data/lib/sequel/connection_pool/single.rb +11 -3
  116. data/lib/sequel/connection_pool/threaded.rb +69 -20
  117. data/lib/sequel/connection_pool.rb +20 -18
  118. data/lib/sequel/core.rb +143 -11
  119. data/lib/sequel/database/connecting.rb +66 -29
  120. data/lib/sequel/database/dataset.rb +4 -4
  121. data/lib/sequel/database/dataset_defaults.rb +63 -2
  122. data/lib/sequel/database/logging.rb +7 -2
  123. data/lib/sequel/database/misc.rb +192 -51
  124. data/lib/sequel/database/query.rb +299 -114
  125. data/lib/sequel/database/schema_generator.rb +103 -36
  126. data/lib/sequel/database/schema_methods.rb +310 -69
  127. data/lib/sequel/dataset/actions.rb +344 -90
  128. data/lib/sequel/dataset/features.rb +101 -8
  129. data/lib/sequel/dataset/graph.rb +42 -15
  130. data/lib/sequel/dataset/misc.rb +52 -25
  131. data/lib/sequel/dataset/mutation.rb +12 -7
  132. data/lib/sequel/dataset/prepared_statements.rb +68 -30
  133. data/lib/sequel/dataset/query.rb +322 -68
  134. data/lib/sequel/dataset/sql.rb +716 -293
  135. data/lib/sequel/dataset.rb +8 -0
  136. data/lib/sequel/exceptions.rb +4 -0
  137. data/lib/sequel/extensions/_pretty_table.rb +83 -0
  138. data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
  139. data/lib/sequel/extensions/blank.rb +4 -0
  140. data/lib/sequel/extensions/columns_introspection.rb +72 -0
  141. data/lib/sequel/extensions/connection_validator.rb +109 -0
  142. data/lib/sequel/extensions/constraint_validations.rb +451 -0
  143. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
  144. data/lib/sequel/extensions/eval_inspect.rb +173 -0
  145. data/lib/sequel/extensions/inflector.rb +4 -0
  146. data/lib/sequel/extensions/looser_typecasting.rb +5 -4
  147. data/lib/sequel/extensions/migration.rb +100 -11
  148. data/lib/sequel/extensions/named_timezones.rb +9 -0
  149. data/lib/sequel/extensions/null_dataset.rb +94 -0
  150. data/lib/sequel/extensions/pagination.rb +4 -0
  151. data/lib/sequel/extensions/pg_array.rb +539 -0
  152. data/lib/sequel/extensions/pg_array_ops.rb +263 -0
  153. data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
  154. data/lib/sequel/extensions/pg_hstore.rb +334 -0
  155. data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
  156. data/lib/sequel/extensions/pg_inet.rb +113 -0
  157. data/lib/sequel/extensions/pg_interval.rb +191 -0
  158. data/lib/sequel/extensions/pg_json.rb +212 -0
  159. data/lib/sequel/extensions/pg_range.rb +513 -0
  160. data/lib/sequel/extensions/pg_range_ops.rb +150 -0
  161. data/lib/sequel/extensions/pg_row.rb +576 -0
  162. data/lib/sequel/extensions/pg_row_ops.rb +182 -0
  163. data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
  164. data/lib/sequel/extensions/pretty_table.rb +17 -72
  165. data/lib/sequel/extensions/query.rb +8 -4
  166. data/lib/sequel/extensions/query_literals.rb +79 -0
  167. data/lib/sequel/extensions/schema_caching.rb +76 -0
  168. data/lib/sequel/extensions/schema_dumper.rb +282 -76
  169. data/lib/sequel/extensions/select_remove.rb +39 -0
  170. data/lib/sequel/extensions/server_block.rb +140 -0
  171. data/lib/sequel/extensions/split_array_nil.rb +65 -0
  172. data/lib/sequel/extensions/sql_expr.rb +8 -110
  173. data/lib/sequel/extensions/string_date_time.rb +4 -0
  174. data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
  175. data/lib/sequel/extensions/to_dot.rb +99 -83
  176. data/lib/sequel/model/associations.rb +1263 -409
  177. data/lib/sequel/model/base.rb +624 -171
  178. data/lib/sequel/model/errors.rb +1 -1
  179. data/lib/sequel/model/exceptions.rb +24 -2
  180. data/lib/sequel/model/inflections.rb +1 -1
  181. data/lib/sequel/model.rb +30 -11
  182. data/lib/sequel/no_core_ext.rb +2 -0
  183. data/lib/sequel/plugins/active_model.rb +13 -1
  184. data/lib/sequel/plugins/association_pks.rb +137 -16
  185. data/lib/sequel/plugins/caching.rb +25 -18
  186. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  187. data/lib/sequel/plugins/composition.rb +44 -12
  188. data/lib/sequel/plugins/constraint_validations.rb +198 -0
  189. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  190. data/lib/sequel/plugins/defaults_setter.rb +72 -0
  191. data/lib/sequel/plugins/dirty.rb +214 -0
  192. data/lib/sequel/plugins/eager_each.rb +59 -0
  193. data/lib/sequel/plugins/force_encoding.rb +6 -6
  194. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  195. data/lib/sequel/plugins/identity_map.rb +134 -15
  196. data/lib/sequel/plugins/instance_filters.rb +10 -0
  197. data/lib/sequel/plugins/instance_hooks.rb +1 -1
  198. data/lib/sequel/plugins/json_serializer.rb +77 -6
  199. data/lib/sequel/plugins/list.rb +13 -2
  200. data/lib/sequel/plugins/many_through_many.rb +103 -51
  201. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  202. data/lib/sequel/plugins/nested_attributes.rb +150 -66
  203. data/lib/sequel/plugins/optimistic_locking.rb +8 -0
  204. data/lib/sequel/plugins/pg_row.rb +121 -0
  205. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  206. data/lib/sequel/plugins/prepared_statements.rb +168 -0
  207. data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
  208. data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
  209. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  210. data/lib/sequel/plugins/rcte_tree.rb +31 -17
  211. data/lib/sequel/plugins/schema.rb +8 -3
  212. data/lib/sequel/plugins/serialization.rb +98 -49
  213. data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
  214. data/lib/sequel/plugins/sharding.rb +21 -54
  215. data/lib/sequel/plugins/single_table_inheritance.rb +57 -12
  216. data/lib/sequel/plugins/static_cache.rb +99 -0
  217. data/lib/sequel/plugins/subclasses.rb +29 -3
  218. data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
  219. data/lib/sequel/plugins/timestamps.rb +1 -1
  220. data/lib/sequel/plugins/touch.rb +18 -6
  221. data/lib/sequel/plugins/tree.rb +3 -3
  222. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  223. data/lib/sequel/plugins/update_primary_key.rb +2 -2
  224. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  225. data/lib/sequel/plugins/validation_helpers.rb +57 -4
  226. data/lib/sequel/plugins/xml_serializer.rb +15 -4
  227. data/lib/sequel/sql.rb +721 -141
  228. data/lib/sequel/timezones.rb +67 -40
  229. data/lib/sequel/version.rb +1 -1
  230. data/spec/adapters/db2_spec.rb +146 -0
  231. data/spec/adapters/firebird_spec.rb +53 -39
  232. data/spec/adapters/mssql_spec.rb +261 -66
  233. data/spec/adapters/mysql_spec.rb +597 -352
  234. data/spec/adapters/oracle_spec.rb +92 -117
  235. data/spec/adapters/postgres_spec.rb +2103 -341
  236. data/spec/adapters/spec_helper.rb +16 -6
  237. data/spec/adapters/sqlite_spec.rb +237 -76
  238. data/spec/core/connection_pool_spec.rb +270 -141
  239. data/spec/core/database_spec.rb +980 -524
  240. data/spec/core/dataset_spec.rb +1658 -1243
  241. data/spec/core/expression_filters_spec.rb +741 -334
  242. data/spec/core/mock_adapter_spec.rb +453 -0
  243. data/spec/core/object_graph_spec.rb +88 -129
  244. data/spec/core/schema_generator_spec.rb +4 -4
  245. data/spec/core/schema_spec.rb +556 -53
  246. data/spec/core/spec_helper.rb +7 -48
  247. data/spec/core_extensions_spec.rb +626 -0
  248. data/spec/extensions/active_model_spec.rb +13 -0
  249. data/spec/extensions/arbitrary_servers_spec.rb +110 -0
  250. data/spec/extensions/association_autoreloading_spec.rb +18 -10
  251. data/spec/extensions/association_dependencies_spec.rb +15 -25
  252. data/spec/extensions/association_pks_spec.rb +227 -33
  253. data/spec/extensions/association_proxies_spec.rb +4 -4
  254. data/spec/extensions/boolean_readers_spec.rb +25 -25
  255. data/spec/extensions/caching_spec.rb +47 -51
  256. data/spec/extensions/class_table_inheritance_spec.rb +31 -83
  257. data/spec/extensions/columns_introspection_spec.rb +91 -0
  258. data/spec/extensions/composition_spec.rb +18 -13
  259. data/spec/extensions/connection_validator_spec.rb +118 -0
  260. data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
  261. data/spec/extensions/constraint_validations_spec.rb +316 -0
  262. data/spec/extensions/dataset_associations_spec.rb +199 -0
  263. data/spec/extensions/defaults_setter_spec.rb +88 -0
  264. data/spec/extensions/dirty_spec.rb +155 -0
  265. data/spec/extensions/eager_each_spec.rb +34 -0
  266. data/spec/extensions/eval_inspect_spec.rb +67 -0
  267. data/spec/extensions/force_encoding_spec.rb +4 -2
  268. data/spec/extensions/hook_class_methods_spec.rb +97 -128
  269. data/spec/extensions/identity_map_spec.rb +142 -24
  270. data/spec/extensions/inflector_spec.rb +0 -4
  271. data/spec/extensions/instance_filters_spec.rb +11 -21
  272. data/spec/extensions/instance_hooks_spec.rb +72 -0
  273. data/spec/extensions/json_serializer_spec.rb +49 -12
  274. data/spec/extensions/lazy_attributes_spec.rb +16 -20
  275. data/spec/extensions/list_spec.rb +49 -40
  276. data/spec/extensions/looser_typecasting_spec.rb +7 -7
  277. data/spec/extensions/many_through_many_spec.rb +368 -254
  278. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  279. data/spec/extensions/migration_spec.rb +140 -35
  280. data/spec/extensions/named_timezones_spec.rb +29 -11
  281. data/spec/extensions/nested_attributes_spec.rb +268 -89
  282. data/spec/extensions/null_dataset_spec.rb +85 -0
  283. data/spec/extensions/optimistic_locking_spec.rb +24 -21
  284. data/spec/extensions/pg_array_ops_spec.rb +112 -0
  285. data/spec/extensions/pg_array_spec.rb +324 -0
  286. data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
  287. data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
  288. data/spec/extensions/pg_hstore_spec.rb +200 -0
  289. data/spec/extensions/pg_inet_spec.rb +47 -0
  290. data/spec/extensions/pg_interval_spec.rb +72 -0
  291. data/spec/extensions/pg_json_spec.rb +99 -0
  292. data/spec/extensions/pg_range_ops_spec.rb +56 -0
  293. data/spec/extensions/pg_range_spec.rb +395 -0
  294. data/spec/extensions/pg_row_ops_spec.rb +58 -0
  295. data/spec/extensions/pg_row_plugin_spec.rb +49 -0
  296. data/spec/extensions/pg_row_spec.rb +340 -0
  297. data/spec/extensions/pg_statement_cache_spec.rb +208 -0
  298. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  299. data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
  300. data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
  301. data/spec/extensions/prepared_statements_spec.rb +87 -0
  302. data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
  303. data/spec/extensions/pretty_table_spec.rb +7 -6
  304. data/spec/extensions/query_literals_spec.rb +167 -0
  305. data/spec/extensions/query_spec.rb +9 -3
  306. data/spec/extensions/rcte_tree_spec.rb +50 -43
  307. data/spec/extensions/schema_caching_spec.rb +41 -0
  308. data/spec/extensions/schema_dumper_spec.rb +434 -49
  309. data/spec/extensions/schema_spec.rb +30 -49
  310. data/spec/extensions/select_remove_spec.rb +38 -0
  311. data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
  312. data/spec/extensions/serialization_spec.rb +86 -48
  313. data/spec/extensions/server_block_spec.rb +90 -0
  314. data/spec/extensions/sharding_spec.rb +69 -143
  315. data/spec/extensions/single_table_inheritance_spec.rb +65 -29
  316. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  317. data/spec/extensions/spec_helper.rb +34 -67
  318. data/spec/extensions/split_array_nil_spec.rb +24 -0
  319. data/spec/extensions/sql_expr_spec.rb +29 -60
  320. data/spec/extensions/static_cache_spec.rb +145 -0
  321. data/spec/extensions/subclasses_spec.rb +14 -0
  322. data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
  323. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  324. data/spec/extensions/timestamps_spec.rb +6 -6
  325. data/spec/extensions/to_dot_spec.rb +8 -11
  326. data/spec/extensions/touch_spec.rb +53 -14
  327. data/spec/extensions/tree_spec.rb +11 -26
  328. data/spec/extensions/typecast_on_load_spec.rb +9 -6
  329. data/spec/extensions/update_primary_key_spec.rb +30 -24
  330. data/spec/extensions/validation_class_methods_spec.rb +77 -68
  331. data/spec/extensions/validation_helpers_spec.rb +48 -37
  332. data/spec/extensions/xml_serializer_spec.rb +29 -4
  333. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
  334. data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
  335. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
  336. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
  337. data/spec/integration/associations_test.rb +659 -21
  338. data/spec/integration/database_test.rb +25 -5
  339. data/spec/integration/dataset_test.rb +729 -141
  340. data/spec/integration/eager_loader_test.rb +38 -54
  341. data/spec/integration/migrator_test.rb +2 -3
  342. data/spec/integration/model_test.rb +81 -2
  343. data/spec/integration/plugin_test.rb +871 -160
  344. data/spec/integration/prepared_statement_test.rb +272 -128
  345. data/spec/integration/schema_test.rb +377 -57
  346. data/spec/integration/spec_helper.rb +49 -32
  347. data/spec/integration/timezone_test.rb +38 -12
  348. data/spec/integration/transaction_test.rb +183 -8
  349. data/spec/integration/type_test.rb +40 -8
  350. data/spec/model/association_reflection_spec.rb +207 -8
  351. data/spec/model/associations_spec.rb +1206 -693
  352. data/spec/model/base_spec.rb +334 -100
  353. data/spec/model/dataset_methods_spec.rb +45 -27
  354. data/spec/model/eager_loading_spec.rb +828 -692
  355. data/spec/model/hooks_spec.rb +355 -67
  356. data/spec/model/model_spec.rb +251 -179
  357. data/spec/model/plugins_spec.rb +24 -13
  358. data/spec/model/record_spec.rb +506 -232
  359. data/spec/model/spec_helper.rb +16 -77
  360. data/spec/model/validations_spec.rb +38 -2
  361. data/spec/rcov.opts +2 -0
  362. metadata +223 -81
  363. data/spec/core/core_sql_spec.rb +0 -451
@@ -2,15 +2,19 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe Sequel::Model::Associations::AssociationReflection, "#associated_class" do
4
4
  before do
5
- @c = Class.new(Sequel::Model)
5
+ @c = Class.new(Sequel::Model(:foo))
6
6
  class ::ParParent < Sequel::Model; end
7
7
  end
8
+ after do
9
+ Object.send(:remove_const, :ParParent)
10
+ end
8
11
 
9
12
  it "should use the :class value if present" do
10
13
  @c.many_to_one :c, :class=>ParParent
11
14
  @c.association_reflection(:c).keys.should include(:class)
12
15
  @c.association_reflection(:c).associated_class.should == ParParent
13
16
  end
17
+
14
18
  it "should figure out the class if the :class value is not present" do
15
19
  @c.many_to_one :c, :class=>'ParParent'
16
20
  @c.association_reflection(:c).keys.should_not include(:class)
@@ -20,15 +24,19 @@ end
20
24
 
21
25
  describe Sequel::Model::Associations::AssociationReflection, "#primary_key" do
22
26
  before do
23
- @c = Class.new(Sequel::Model)
27
+ @c = Class.new(Sequel::Model(:foo))
24
28
  class ::ParParent < Sequel::Model; end
25
29
  end
30
+ after do
31
+ Object.send(:remove_const, :ParParent)
32
+ end
26
33
 
27
34
  it "should use the :primary_key value if present" do
28
35
  @c.many_to_one :c, :class=>ParParent, :primary_key=>:blah__blah
29
36
  @c.association_reflection(:c).keys.should include(:primary_key)
30
37
  @c.association_reflection(:c).primary_key.should == :blah__blah
31
38
  end
39
+
32
40
  it "should use the associated table's primary key if :primary_key is not present" do
33
41
  @c.many_to_one :c, :class=>'ParParent'
34
42
  @c.association_reflection(:c).keys.should_not include(:primary_key)
@@ -49,8 +57,8 @@ describe Sequel::Model::Associations::AssociationReflection, "#reciprocal" do
49
57
  end
50
58
 
51
59
  it "should use the :reciprocal value if present" do
52
- @c = Class.new(Sequel::Model)
53
- @d = Class.new(Sequel::Model)
60
+ @c = Class.new(Sequel::Model(:foo))
61
+ @d = Class.new(Sequel::Model(:foo))
54
62
  @c.many_to_one :c, :class=>@d, :reciprocal=>:xx
55
63
  @c.association_reflection(:c).keys.should include(:reciprocal)
56
64
  @c.association_reflection(:c).reciprocal.should == :xx
@@ -111,9 +119,12 @@ end
111
119
 
112
120
  describe Sequel::Model::Associations::AssociationReflection, "#select" do
113
121
  before do
114
- @c = Class.new(Sequel::Model)
122
+ @c = Class.new(Sequel::Model(:foo))
115
123
  class ::ParParent < Sequel::Model; end
116
124
  end
125
+ after do
126
+ Object.send(:remove_const, :ParParent)
127
+ end
117
128
 
118
129
  it "should use the :select value if present" do
119
130
  @c.many_to_one :c, :class=>ParParent, :select=>[:par_parents__id]
@@ -123,7 +134,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#select" do
123
134
  it "should be the associated_table.* if :select is not present for a many_to_many associaiton" do
124
135
  @c.many_to_many :cs, :class=>'ParParent'
125
136
  @c.association_reflection(:cs).keys.should_not include(:select)
126
- @c.association_reflection(:cs).select.should == :par_parents.*
137
+ @c.association_reflection(:cs).select.should == Sequel::SQL::ColumnAll.new(:par_parents)
127
138
  end
128
139
  it "should be if :select is not present for a many_to_one and one_to_many associaiton" do
129
140
  @c.one_to_many :cs, :class=>'ParParent'
@@ -143,9 +154,12 @@ end
143
154
 
144
155
  describe Sequel::Model::Associations::AssociationReflection, "#associated_object_keys" do
145
156
  before do
146
- @c = Class.new(Sequel::Model)
157
+ @c = Class.new(Sequel::Model(:foo))
147
158
  class ::ParParent < Sequel::Model; end
148
159
  end
160
+ after do
161
+ Object.send(:remove_const, :ParParent)
162
+ end
149
163
 
150
164
  it "should use the primary keys for a many_to_one association" do
151
165
  @c.many_to_one :c, :class=>ParParent
@@ -173,9 +187,41 @@ describe Sequel::Model::Associations::AssociationReflection, "#associated_object
173
187
  end
174
188
  end
175
189
 
190
+ describe Sequel::Model::Associations::AssociationReflection do
191
+ before do
192
+ @c = Class.new(Sequel::Model(:foo))
193
+ @c.meta_def(:name){"C"}
194
+ end
195
+
196
+ it "#eager_loading_predicate_key should be an alias of predicate_key for backwards compatibility" do
197
+ @c.one_to_many :cs, :class=>@c
198
+ @c.dataset.literal(@c.association_reflection(:cs).eager_loading_predicate_key).should == 'foo.c_id'
199
+ end
200
+
201
+ it "one_to_many #qualified_primary_key should be a qualified version of the primary key" do
202
+ @c.one_to_many :cs, :class=>@c
203
+ @c.dataset.literal(@c.association_reflection(:cs).qualified_primary_key).should == 'foo.id'
204
+ end
205
+
206
+ it "many_to_many #associated_key_column should be the left key" do
207
+ @c.many_to_many :cs, :class=>@c
208
+ @c.association_reflection(:cs).associated_key_column.should == :c_id
209
+ end
210
+
211
+ it "many_to_many #qualified_right_key should be a qualified version of the primary key" do
212
+ @c.many_to_many :cs, :class=>@c, :right_key=>:c2_id
213
+ @c.dataset.literal(@c.association_reflection(:cs).qualified_right_key).should == 'cs_cs.c2_id'
214
+ end
215
+
216
+ it "many_to_many #qualified_right_primary_key should be a qualified version of the primary key" do
217
+ @c.many_to_many :cs, :class=>@c
218
+ @c.dataset.literal(@c.association_reflection(:cs).qualified_right_primary_key).should == 'foo.id'
219
+ end
220
+ end
221
+
176
222
  describe Sequel::Model::Associations::AssociationReflection, "#remove_before_destroy?" do
177
223
  before do
178
- @c = Class.new(Sequel::Model)
224
+ @c = Class.new(Sequel::Model(:foo))
179
225
  end
180
226
 
181
227
  it "should be true for many_to_one and many_to_many associations" do
@@ -184,6 +230,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#remove_before_des
184
230
  @c.many_to_many :cs, :class=>@c
185
231
  @c.association_reflection(:cs).remove_before_destroy?.should be_true
186
232
  end
233
+
187
234
  it "should be false for one_to_one and one_to_many associations" do
188
235
  @c.one_to_one :c, :class=>@c
189
236
  @c.association_reflection(:c).remove_before_destroy?.should be_false
@@ -192,3 +239,155 @@ describe Sequel::Model::Associations::AssociationReflection, "#remove_before_des
192
239
  end
193
240
  end
194
241
 
242
+ describe Sequel::Model::Associations::AssociationReflection, "#eager_limit_strategy" do
243
+ before do
244
+ @c = Class.new(Sequel::Model(:a))
245
+ end
246
+ after do
247
+ Sequel::Model.default_eager_limit_strategy = nil
248
+ end
249
+
250
+ it "should be nil by default for *_one associations" do
251
+ @c.many_to_one :c, :class=>@c
252
+ @c.association_reflection(:c).eager_limit_strategy.should be_nil
253
+ @c.one_to_one :c, :class=>@c
254
+ @c.association_reflection(:c).eager_limit_strategy.should be_nil
255
+ end
256
+
257
+ it "should be :ruby by default for *_many associations" do
258
+ @c.one_to_many :cs, :class=>@c, :limit=>1
259
+ @c.association_reflection(:cs).eager_limit_strategy.should == :ruby
260
+ @c.many_to_many :cs, :class=>@c, :limit=>1
261
+ @c.association_reflection(:cs).eager_limit_strategy.should == :ruby
262
+ end
263
+
264
+ it "should be nil for many_to_one associations" do
265
+ @c.many_to_one :c, :class=>@c, :eager_limit_strategy=>true
266
+ @c.association_reflection(:c).eager_limit_strategy.should be_nil
267
+ @c.many_to_one :c, :class=>@c, :eager_limit_strategy=>:distinct_on
268
+ @c.association_reflection(:c).eager_limit_strategy.should be_nil
269
+ end
270
+
271
+ it "should be a symbol for other associations if given a symbol" do
272
+ @c.one_to_one :c, :class=>@c, :eager_limit_strategy=>:distinct_on
273
+ @c.association_reflection(:c).eager_limit_strategy.should == :distinct_on
274
+ @c.one_to_many :cs, :class=>@c, :eager_limit_strategy=>:window_function, :limit=>1
275
+ @c.association_reflection(:cs).eager_limit_strategy.should == :window_function
276
+ end
277
+
278
+ it "should use :distinct_on for one_to_one associations if picking and the association dataset supports ordered distinct on" do
279
+ @c.dataset.meta_def(:supports_ordered_distinct_on?){true}
280
+ @c.one_to_one :c, :class=>@c, :eager_limit_strategy=>true
281
+ @c.association_reflection(:c).eager_limit_strategy.should == :distinct_on
282
+ end
283
+
284
+ it "should use :window_function for associations if picking and the association dataset supports window functions" do
285
+ @c.dataset.meta_def(:supports_window_functions?){true}
286
+ @c.one_to_one :c, :class=>@c, :eager_limit_strategy=>true
287
+ @c.association_reflection(:c).eager_limit_strategy.should == :window_function
288
+ @c.one_to_many :cs, :class=>@c, :eager_limit_strategy=>true, :limit=>1
289
+ @c.association_reflection(:cs).eager_limit_strategy.should == :window_function
290
+ @c.many_to_many :cs, :class=>@c, :eager_limit_strategy=>true, :limit=>1
291
+ @c.association_reflection(:cs).eager_limit_strategy.should == :window_function
292
+ end
293
+
294
+ it "should use :ruby for *_many associations if picking and the association dataset doesn't window functions" do
295
+ @c.one_to_many :cs, :class=>@c, :eager_limit_strategy=>true, :limit=>1
296
+ @c.association_reflection(:cs).eager_limit_strategy.should == :ruby
297
+ @c.many_to_many :cs, :class=>@c, :eager_limit_strategy=>true, :limit=>1
298
+ @c.association_reflection(:cs).eager_limit_strategy.should == :ruby
299
+ end
300
+
301
+ it "should respect Model.default_eager_limit_strategy to *_many associations" do
302
+ Sequel::Model.default_eager_limit_strategy = :window_function
303
+ Sequel::Model.default_eager_limit_strategy.should == :window_function
304
+ c = Class.new(Sequel::Model)
305
+ c.dataset = :a
306
+ c.default_eager_limit_strategy.should == :window_function
307
+ c.one_to_many :cs, :class=>c, :limit=>1
308
+ c.association_reflection(:cs).eager_limit_strategy.should == :window_function
309
+ c.many_to_many :cs, :class=>c, :limit=>1
310
+ c.association_reflection(:cs).eager_limit_strategy.should == :window_function
311
+
312
+ Sequel::Model.default_eager_limit_strategy = true
313
+ c = Class.new(Sequel::Model)
314
+ c.dataset = :a
315
+ c.one_to_many :cs, :class=>c, :limit=>1
316
+ c.association_reflection(:cs).eager_limit_strategy.should == :ruby
317
+ c.dataset.meta_def(:supports_window_functions?){true}
318
+ c.many_to_many :cs, :class=>c, :limit=>1
319
+ c.association_reflection(:cs).eager_limit_strategy.should == :window_function
320
+
321
+ c.default_eager_limit_strategy = :correlated_subquery
322
+ c.many_to_many :cs, :class=>c, :limit=>1
323
+ c.association_reflection(:cs).eager_limit_strategy.should == :correlated_subquery
324
+ end
325
+
326
+ it "should ignore Model.default_eager_limit_strategy for one_to_one associations" do
327
+ @c.default_eager_limit_strategy = :correlated_subquery
328
+ @c.one_to_one :c, :class=>@c
329
+ @c.association_reflection(:c).eager_limit_strategy.should be_nil
330
+ end
331
+ end
332
+
333
+ describe Sequel::Model, " association reflection methods" do
334
+ before do
335
+ @c1 = Class.new(Sequel::Model(:nodes)) do
336
+ def self.name; 'Node'; end
337
+ def self.to_s; 'Node'; end
338
+ end
339
+ MODEL_DB.reset
340
+ end
341
+
342
+ it "#all_association_reflections should include all association reflection hashes" do
343
+ @c1.all_association_reflections.should == []
344
+
345
+ @c1.associate :many_to_one, :parent, :class => @c1
346
+ @c1.all_association_reflections.collect{|v| v[:name]}.should == [:parent]
347
+ @c1.all_association_reflections.collect{|v| v[:type]}.should == [:many_to_one]
348
+ @c1.all_association_reflections.collect{|v| v[:class]}.should == [@c1]
349
+
350
+ @c1.associate :one_to_many, :children, :class => @c1
351
+ @c1.all_association_reflections.sort_by{|x|x[:name].to_s}
352
+ @c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:name]}.should == [:children, :parent]
353
+ @c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:type]}.should == [:one_to_many, :many_to_one]
354
+ @c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:class]}.should == [@c1, @c1]
355
+ end
356
+
357
+ it "#association_reflection should return nil for nonexistent association" do
358
+ @c1.association_reflection(:blah).should == nil
359
+ end
360
+
361
+ it "#association_reflection should return association reflection hash if association exists" do
362
+ @c1.associate :many_to_one, :parent, :class => @c1
363
+ @c1.association_reflection(:parent).should be_a_kind_of(Sequel::Model::Associations::AssociationReflection)
364
+ @c1.association_reflection(:parent)[:name].should == :parent
365
+ @c1.association_reflection(:parent)[:type].should == :many_to_one
366
+ @c1.association_reflection(:parent)[:class].should == @c1
367
+
368
+ @c1.associate :one_to_many, :children, :class => @c1
369
+ @c1.association_reflection(:children).should be_a_kind_of(Sequel::Model::Associations::AssociationReflection)
370
+ @c1.association_reflection(:children)[:name].should == :children
371
+ @c1.association_reflection(:children)[:type].should == :one_to_many
372
+ @c1.association_reflection(:children)[:class].should == @c1
373
+ end
374
+
375
+ it "#associations should include all association names" do
376
+ @c1.associations.should == []
377
+ @c1.associate :many_to_one, :parent, :class => @c1
378
+ @c1.associations.should == [:parent]
379
+ @c1.associate :one_to_many, :children, :class => @c1
380
+ @c1.associations.sort_by{|x|x.to_s}.should == [:children, :parent]
381
+ end
382
+
383
+ it "association reflections should be copied upon subclasing" do
384
+ @c1.associate :many_to_one, :parent, :class => @c1
385
+ c = Class.new(@c1)
386
+ @c1.associations.should == [:parent]
387
+ c.associations.should == [:parent]
388
+ c.associate :many_to_one, :parent2, :class => @c1
389
+ @c1.associations.should == [:parent]
390
+ c.associations.sort_by{|x| x.to_s}.should == [:parent, :parent2]
391
+ c.instance_methods.map{|x| x.to_s}.should include('parent')
392
+ end
393
+ end