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
@@ -1,192 +1,185 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
- describe "Model hooks" do
3
+ model_class = proc do |klass, &block|
4
+ c = Class.new(klass)
5
+ c.plugin :hook_class_methods
6
+ c.class_eval(&block) if block
7
+ c
8
+ end
9
+
10
+ describe Sequel::Model, "hook_class_methods plugin" do
4
11
  before do
5
12
  MODEL_DB.reset
6
13
  end
7
14
 
8
15
  specify "should be definable using a block" do
9
- $adds = []
10
- c = Class.new(Sequel::Model)
11
- c.class_eval do
12
- before_save {$adds << 'hi'}
16
+ adds = []
17
+ c = model_class.call Sequel::Model do
18
+ before_save{adds << 'hi'}
13
19
  end
14
20
 
15
21
  c.new.before_save
16
- $adds.should == ['hi']
22
+ adds.should == ['hi']
17
23
  end
18
24
 
19
25
  specify "should be definable using a method name" do
20
- $adds = []
21
- c = Class.new(Sequel::Model)
22
- c.class_eval do
23
- def bye; $adds << 'bye'; end
26
+ adds = []
27
+ c = model_class.call Sequel::Model do
28
+ define_method(:bye){adds << 'bye'}
24
29
  before_save :bye
25
30
  end
26
31
 
27
32
  c.new.before_save
28
- $adds.should == ['bye']
33
+ adds.should == ['bye']
29
34
  end
30
35
 
31
36
  specify "should be additive" do
32
- $adds = []
33
- c = Class.new(Sequel::Model)
34
- c.class_eval do
35
- after_save {$adds << 'hyiyie'}
36
- after_save {$adds << 'byiyie'}
37
+ adds = []
38
+ c = model_class.call Sequel::Model do
39
+ after_save{adds << 'hyiyie'}
40
+ after_save{adds << 'byiyie'}
37
41
  end
38
42
 
39
43
  c.new.after_save
40
- $adds.should == ['hyiyie', 'byiyie']
44
+ adds.should == ['hyiyie', 'byiyie']
41
45
  end
42
46
 
43
47
  specify "before hooks should run in reverse order" do
44
- $adds = []
45
- c = Class.new(Sequel::Model)
46
- c.class_eval do
47
- before_save {$adds << 'hyiyie'}
48
- before_save {$adds << 'byiyie'}
48
+ adds = []
49
+ c = model_class.call Sequel::Model do
50
+ before_save{adds << 'hyiyie'}
51
+ before_save{adds << 'byiyie'}
49
52
  end
50
53
 
51
54
  c.new.before_save
52
- $adds.should == ['byiyie', 'hyiyie']
55
+ adds.should == ['byiyie', 'hyiyie']
53
56
  end
54
57
 
55
58
  specify "should not be additive if the method or tag already exists" do
56
- $adds = []
57
- c = Class.new(Sequel::Model)
58
- c.class_eval do
59
- def bye; $adds << 'bye'; end
59
+ adds = []
60
+ c = model_class.call Sequel::Model do
61
+ define_method(:bye){adds << 'bye'}
60
62
  before_save :bye
61
63
  before_save :bye
62
64
  end
63
65
 
64
66
  c.new.before_save
65
- $adds.should == ['bye']
67
+ adds.should == ['bye']
66
68
 
67
- $adds = []
68
- d = Class.new(Sequel::Model)
69
- d.class_eval do
70
- before_save(:bye){$adds << 'hyiyie'}
71
- before_save(:bye){$adds << 'byiyie'}
69
+ adds = []
70
+ d = model_class.call Sequel::Model do
71
+ before_save(:bye){adds << 'hyiyie'}
72
+ before_save(:bye){adds << 'byiyie'}
72
73
  end
73
74
 
74
75
  d.new.before_save
75
- $adds.should == ['byiyie']
76
+ adds.should == ['byiyie']
76
77
 
77
- $adds = []
78
- e = Class.new(Sequel::Model)
79
- e.class_eval do
80
- def bye; $adds << 'bye'; end
78
+ adds = []
79
+ e = model_class.call Sequel::Model do
80
+ define_method(:bye){adds << 'bye'}
81
81
  before_save :bye
82
- before_save(:bye){$adds << 'byiyie'}
82
+ before_save(:bye){adds << 'byiyie'}
83
83
  end
84
84
 
85
85
  e.new.before_save
86
- $adds.should == ['byiyie']
86
+ adds.should == ['byiyie']
87
87
 
88
- $adds = []
89
- e = Class.new(Sequel::Model)
90
- e.class_eval do
91
- def bye; $adds << 'bye'; end
92
- before_save(:bye){$adds << 'byiyie'}
88
+ adds = []
89
+ e = model_class.call Sequel::Model do
90
+ define_method(:bye){adds << 'bye'}
91
+ before_save(:bye){adds << 'byiyie'}
93
92
  before_save :bye
94
93
  end
95
94
 
96
95
  e.new.before_save
97
- $adds.should == ['bye']
96
+ adds.should == ['bye']
98
97
  end
99
98
 
100
99
  specify "should be inheritable" do
101
- # pending
102
-
103
- $adds = []
104
- a = Class.new(Sequel::Model)
105
- a.class_eval do
106
- after_save {$adds << '123'}
100
+ adds = []
101
+ a = model_class.call Sequel::Model do
102
+ after_save{adds << '123'}
107
103
  end
108
104
 
109
105
  b = Class.new(a)
110
106
  b.class_eval do
111
- after_save {$adds << '456'}
112
- after_save {$adds << '789'}
107
+ after_save{adds << '456'}
108
+ after_save{adds << '789'}
113
109
  end
114
110
 
115
111
  b.new.after_save
116
- $adds.should == ['123', '456', '789']
112
+ adds.should == ['123', '456', '789']
117
113
  end
118
114
 
119
115
  specify "should be overridable in descendant classes" do
120
- $adds = []
121
- a = Class.new(Sequel::Model)
122
- a.class_eval do
123
- before_save {$adds << '123'}
116
+ adds = []
117
+ a = model_class.call Sequel::Model do
118
+ before_save{adds << '123'}
124
119
  end
125
120
 
126
121
  b = Class.new(a)
127
122
  b.class_eval do
128
- def before_save; $adds << '456'; end
123
+ define_method(:before_save){adds << '456'}
129
124
  end
130
125
 
131
126
  a.new.before_save
132
- $adds.should == ['123']
133
- $adds = []
127
+ adds.should == ['123']
128
+ adds = []
134
129
  b.new.before_save
135
- $adds.should == ['456']
130
+ adds.should == ['456']
136
131
  end
137
132
 
138
133
  specify "should stop processing if a before hook returns false" do
139
- $flag = true
140
- $adds = []
134
+ flag = true
135
+ adds = []
141
136
 
142
- a = Class.new(Sequel::Model)
143
- a.class_eval do
144
- before_save {$adds << 'cruel'; $flag}
145
- before_save {$adds << 'blah'; $flag}
137
+ a = model_class.call Sequel::Model do
138
+ before_save{adds << 'cruel'; flag}
139
+ before_save{adds << 'blah'; flag}
146
140
  end
147
141
 
148
142
  a.new.before_save
149
- $adds.should == ['blah', 'cruel']
143
+ adds.should == ['blah', 'cruel']
150
144
 
151
145
  # chain should not break on nil
152
- $adds = []
153
- $flag = nil
146
+ adds = []
147
+ flag = nil
154
148
  a.new.before_save
155
- $adds.should == ['blah', 'cruel']
149
+ adds.should == ['blah', 'cruel']
156
150
 
157
- $adds = []
158
- $flag = false
151
+ adds = []
152
+ flag = false
159
153
  a.new.before_save
160
- $adds.should == ['blah']
154
+ adds.should == ['blah']
161
155
 
162
156
  b = Class.new(a)
163
157
  b.class_eval do
164
- before_save {$adds << 'mau'}
158
+ before_save{adds << 'mau'}
165
159
  end
166
160
 
167
- $adds = []
161
+ adds = []
168
162
  b.new.before_save
169
- $adds.should == ['mau', 'blah']
163
+ adds.should == ['mau', 'blah']
170
164
  end
171
165
  end
172
166
 
173
167
  describe "Model#after_initialize" do
174
168
  specify "should be called after initialization" do
175
- $values1 = nil
176
- $reached_after_initialized = false
169
+ values1 = nil
170
+ reached_after_initialized = false
177
171
 
178
- a = Class.new(Sequel::Model)
179
- a.class_eval do
172
+ a = model_class.call Sequel::Model do
180
173
  columns :x, :y
181
174
  after_initialize do
182
- $values1 = @values.clone
183
- $reached_after_initialized = true
175
+ values1 = @values.clone
176
+ reached_after_initialized = true
184
177
  end
185
178
  end
186
179
 
187
180
  a.new(:x => 1, :y => 2)
188
- $values1.should == {:x => 1, :y => 2}
189
- $reached_after_initialized.should == true
181
+ values1.should == {:x => 1, :y => 2}
182
+ reached_after_initialized.should == true
190
183
  end
191
184
  end
192
185
 
@@ -194,8 +187,7 @@ describe "Model#before_create && Model#after_create" do
194
187
  before do
195
188
  MODEL_DB.reset
196
189
 
197
- @c = Class.new(Sequel::Model(:items))
198
- @c.class_eval do
190
+ @c = model_class.call Sequel::Model(:items) do
199
191
  columns :x
200
192
  no_primary_key
201
193
 
@@ -206,11 +198,7 @@ describe "Model#before_create && Model#after_create" do
206
198
  specify "should be called around new record creation" do
207
199
  @c.before_create {MODEL_DB << "BLAH before"}
208
200
  @c.create(:x => 2)
209
- MODEL_DB.sqls.should == [
210
- 'BLAH before',
211
- 'INSERT INTO items (x) VALUES (2)',
212
- 'BLAH after'
213
- ]
201
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after']
214
202
  end
215
203
 
216
204
  specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
@@ -232,8 +220,7 @@ describe "Model#before_update && Model#after_update" do
232
220
  before do
233
221
  MODEL_DB.reset
234
222
 
235
- @c = Class.new(Sequel::Model(:items))
236
- @c.class_eval do
223
+ @c = model_class.call(Sequel::Model(:items)) do
237
224
  after_update {MODEL_DB << "BLAH after"}
238
225
  end
239
226
  end
@@ -242,11 +229,7 @@ describe "Model#before_update && Model#after_update" do
242
229
  @c.before_update {MODEL_DB << "BLAH before"}
243
230
  m = @c.load(:id => 2233, :x=>123)
244
231
  m.save
245
- MODEL_DB.sqls.should == [
246
- 'BLAH before',
247
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
248
- 'BLAH after'
249
- ]
232
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
250
233
  end
251
234
 
252
235
  specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
@@ -268,8 +251,7 @@ describe "Model#before_save && Model#after_save" do
268
251
  before do
269
252
  MODEL_DB.reset
270
253
 
271
- @c = Class.new(Sequel::Model(:items))
272
- @c.class_eval do
254
+ @c = model_class.call(Sequel::Model(:items)) do
273
255
  columns :x
274
256
  after_save {MODEL_DB << "BLAH after"}
275
257
  end
@@ -279,22 +261,14 @@ describe "Model#before_save && Model#after_save" do
279
261
  @c.before_save {MODEL_DB << "BLAH before"}
280
262
  m = @c.load(:id => 2233, :x=>123)
281
263
  m.save
282
- MODEL_DB.sqls.should == [
283
- 'BLAH before',
284
- 'UPDATE items SET x = 123 WHERE (id = 2233)',
285
- 'BLAH after'
286
- ]
264
+ MODEL_DB.sqls.should == ['BLAH before', 'UPDATE items SET x = 123 WHERE (id = 2233)', 'BLAH after']
287
265
  end
288
266
 
289
267
  specify "should be called around record creation" do
290
268
  @c.before_save {MODEL_DB << "BLAH before"}
291
269
  @c.no_primary_key
292
270
  @c.create(:x => 2)
293
- MODEL_DB.sqls.should == [
294
- 'BLAH before',
295
- 'INSERT INTO items (x) VALUES (2)',
296
- 'BLAH after'
297
- ]
271
+ MODEL_DB.sqls.should == ['BLAH before', 'INSERT INTO items (x) VALUES (2)', 'BLAH after']
298
272
  end
299
273
 
300
274
  specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
@@ -316,13 +290,8 @@ describe "Model#before_destroy && Model#after_destroy" do
316
290
  before do
317
291
  MODEL_DB.reset
318
292
 
319
- @c = Class.new(Sequel::Model(:items))
320
- @c.class_eval do
293
+ @c = model_class.call(Sequel::Model(:items)) do
321
294
  after_destroy {MODEL_DB << "BLAH after"}
322
-
323
- def delete
324
- MODEL_DB << "DELETE BLAH"
325
- end
326
295
  end
327
296
  end
328
297
 
@@ -330,11 +299,7 @@ describe "Model#before_destroy && Model#after_destroy" do
330
299
  @c.before_destroy {MODEL_DB << "BLAH before"}
331
300
  m = @c.load(:id => 2233)
332
301
  m.destroy
333
- MODEL_DB.sqls.should == [
334
- 'BLAH before',
335
- 'DELETE BLAH',
336
- 'BLAH after'
337
- ]
302
+ MODEL_DB.sqls.should == ['BLAH before', "DELETE FROM items WHERE id = 2233", 'BLAH after']
338
303
  end
339
304
 
340
305
  specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
@@ -355,8 +320,8 @@ describe "Model#before_validation && Model#after_validation" do
355
320
  before do
356
321
  MODEL_DB.reset
357
322
 
358
- @c = Class.new(Sequel::Model(:items))
359
- @c.class_eval do
323
+ @c = model_class.call(Sequel::Model(:items)) do
324
+ plugin :validation_class_methods
360
325
  after_validation{MODEL_DB << "BLAH after"}
361
326
 
362
327
  def self.validate(o)
@@ -408,7 +373,7 @@ end
408
373
 
409
374
  describe "Model.has_hooks?" do
410
375
  before do
411
- @c = Class.new(Sequel::Model(:items))
376
+ @c = model_class.call(Sequel::Model(:items))
412
377
  end
413
378
 
414
379
  specify "should return false if no hooks are defined" do
@@ -428,7 +393,8 @@ end
428
393
 
429
394
  describe "Model#add_hook_type" do
430
395
  before do
431
- class Foo < Sequel::Model(:items)
396
+ class ::Foo < Sequel::Model(:items)
397
+ plugin :hook_class_methods
432
398
  add_hook_type :before_bar, :after_bar
433
399
 
434
400
  def bar
@@ -439,6 +405,9 @@ describe "Model#add_hook_type" do
439
405
  end
440
406
  @f = Class.new(Foo)
441
407
  end
408
+ after do
409
+ Object.send(:remove_const, :Foo)
410
+ end
442
411
 
443
412
  specify "should have before_bar and after_bar class methods" do
444
413
  @f.should respond_to(:before_bar)
@@ -5,13 +5,14 @@ describe "Sequel::Plugins::IdentityMap" do
5
5
  class ::IdentityMapModel < Sequel::Model
6
6
  plugin :identity_map
7
7
  attr_accessor :foo
8
- ds = dataset
9
- def ds.fetch_rows(sql)
10
- c = @opts[:where].args.first
11
- c = c.column if c.is_a?(Sequel::SQL::QualifiedIdentifier)
12
- h = {c=>@opts[:where].args.last}
13
- execute(sql)
14
- yield h
8
+ dataset._fetch = proc do |sql|
9
+ sql =~ /WHERE \(?(\w+\.)?(\w+) = (\d)\)?/
10
+ {$2.to_sym=>$3.to_i}
11
+ end
12
+ def self.waw_identity_map(&block) # with and without
13
+ with_identity_map(&block)
14
+ db.reset
15
+ yield
15
16
  end
16
17
  end
17
18
  class ::IdentityMapAlbum < ::IdentityMapModel
@@ -54,8 +55,17 @@ describe "Sequel::Plugins::IdentityMap" do
54
55
  @c.identity_map_key(1).should_not == @c.identity_map_key(2)
55
56
  end
56
57
 
57
- it "#identity_map_key should be different if the pk is nil" do
58
- @c.identity_map_key(nil).should_not == @c.identity_map_key(nil)
58
+ it "#identity_map_key should be nil for an empty pk values" do
59
+ @c.identity_map_key(nil).should == nil
60
+ @c.identity_map_key([]).should == nil
61
+ @c.identity_map_key([nil]).should == nil
62
+ end
63
+
64
+ it "#load should work even if model doesn't have a primary key" do
65
+ c = Class.new(@c)
66
+ c.no_primary_key
67
+ proc{c.with_identity_map{c.load({})}}.should_not raise_error
68
+ c.with_identity_map{c.load({}).should_not equal(c.load({}))}
59
69
  end
60
70
 
61
71
  it "#load should return an object if there is no current identity map" do
@@ -105,9 +115,9 @@ describe "Sequel::Plugins::IdentityMap" do
105
115
  MODEL_DB.sqls.length.should == 1
106
116
  o.foo = 1
107
117
  @c[1].foo.should == o.foo
108
- MODEL_DB.sqls.length.should == 1
118
+ MODEL_DB.sqls.length.should == 0
109
119
  @c[2].foo.should_not == o.foo
110
- MODEL_DB.sqls.length.should == 2
120
+ MODEL_DB.sqls.length.should == 1
111
121
  end
112
122
  end
113
123
 
@@ -118,22 +128,22 @@ describe "Sequel::Plugins::IdentityMap" do
118
128
  MODEL_DB.sqls.length.should == 1
119
129
  o.foo = 1
120
130
  @c[1].should == o
121
- MODEL_DB.sqls.length.should == 1
131
+ MODEL_DB.sqls.length.should == 0
122
132
  o.destroy
123
- MODEL_DB.sqls.length.should == 2
133
+ MODEL_DB.sqls.length.should == 1
124
134
  @c[1].foo.should_not == o.foo
125
- MODEL_DB.sqls.length.should == 3
135
+ MODEL_DB.sqls.length.should == 1
126
136
 
127
137
  MODEL_DB.reset
128
138
  o = @c[2]
129
139
  MODEL_DB.sqls.length.should == 1
130
140
  o.foo = 1
131
141
  @c[2].should == o
132
- MODEL_DB.sqls.length.should == 1
142
+ MODEL_DB.sqls.length.should == 0
133
143
  o.delete
134
- MODEL_DB.sqls.length.should == 2
144
+ MODEL_DB.sqls.length.should == 1
135
145
  @c[2].foo.should_not == o.foo
136
- MODEL_DB.sqls.length.should == 3
146
+ MODEL_DB.sqls.length.should == 1
137
147
  end
138
148
  end
139
149
 
@@ -148,10 +158,10 @@ describe "Sequel::Plugins::IdentityMap" do
148
158
  MODEL_DB.sqls.length.should == 1
149
159
  o = @c1.load(:id=>1, :another_id=>2, :artist_id=>2)
150
160
  o.artist.should == a
151
- MODEL_DB.sqls.length.should == 1
161
+ MODEL_DB.sqls.length.should == 0
152
162
  o = @c1.load(:id=>3, :another_id=>3, :artist_id=>3)
153
163
  o.artist.should_not == a
154
- MODEL_DB.sqls.length.should == 2
164
+ MODEL_DB.sqls.length.should == 1
155
165
  end
156
166
  end
157
167
 
@@ -165,10 +175,10 @@ describe "Sequel::Plugins::IdentityMap" do
165
175
  MODEL_DB.sqls.length.should == 1
166
176
  o = @c1.load(:id=>2, :artist_id=>2)
167
177
  o.artist.should == a
168
- MODEL_DB.sqls.length.should == 1
178
+ MODEL_DB.sqls.length.should == 0
169
179
  o = @c1.load(:id=>3, :artist_id=>3)
170
180
  o.artist.should_not == a
171
- MODEL_DB.sqls.length.should == 2
181
+ MODEL_DB.sqls.length.should == 1
172
182
  end
173
183
  end
174
184
 
@@ -182,9 +192,9 @@ describe "Sequel::Plugins::IdentityMap" do
182
192
  a.should be_a_kind_of(@c1)
183
193
  MODEL_DB.sqls.length.should == 1
184
194
  o.reload
185
- MODEL_DB.sqls.length.should == 2
195
+ MODEL_DB.sqls.length.should == 1
186
196
  o.artist.should == a
187
- MODEL_DB.sqls.length.should == 3
197
+ MODEL_DB.sqls.length.should == 1
188
198
  end
189
199
  end
190
200
 
@@ -199,7 +209,7 @@ describe "Sequel::Plugins::IdentityMap" do
199
209
  MODEL_DB.sqls.length.should == 1
200
210
  o = @c1.load(:id=>2, :artist_id=>2)
201
211
  o.artist.should == a
202
- MODEL_DB.sqls.length.should == 2
212
+ MODEL_DB.sqls.length.should == 1
203
213
  end
204
214
  end
205
215
 
@@ -213,7 +223,115 @@ describe "Sequel::Plugins::IdentityMap" do
213
223
  MODEL_DB.sqls.length.should == 1
214
224
  o = @c1.load(:id=>2, :artist_id=>2)
215
225
  o.artist.should == a
226
+ MODEL_DB.sqls.length.should == 1
227
+ end
228
+ end
229
+
230
+ it "should not use the identity map as a lookup cache if a dynamic callback is used" do
231
+ @c1.many_to_one :artist, :class=>@c2
232
+ @c.with_identity_map do
233
+ MODEL_DB.sqls.length.should == 0
234
+ o = @c1.load(:id=>1, :artist_id=>2)
235
+ a = o.artist
236
+ a.should be_a_kind_of(@c2)
237
+ MODEL_DB.sqls.length.should == 1
238
+ o = @c1.load(:id=>2, :artist_id=>2)
239
+ o.artist.should == a
240
+ MODEL_DB.sqls.length.should == 0
241
+ o = @c1.load(:id=>3, :artist_id=>3)
242
+ o.artist.should_not == a
243
+ MODEL_DB.sqls.length.should == 1
244
+ end
245
+ end
246
+
247
+ it "should not override custom :eager_loaders for many_to_many associations" do
248
+ @c1.columns :id
249
+ @c2.columns :id
250
+ c = @c2
251
+ @c1.many_to_many :artists, :class=>@c2, :left_key=>:album_id, :right_key=>:artist_id, :join_table=>:aa, :eager_loader=>(proc do |eo|
252
+ eo[:rows].each{|object| object.associations[:artists] = [c.load(:id=>object.id)]}
253
+ end)
254
+ @c1.dataset._fetch = [{:id=>1}, {:id=>2}, {:id=>3}]
255
+
256
+ @c.waw_identity_map do
257
+ MODEL_DB.sqls.length.should == 0
258
+ a = @c1.eager(:artists).all
259
+ MODEL_DB.sqls.length.should == 1
260
+ a.should == [@c1.load(:id=>1), @c1.load(:id=>2), @c1.load(:id=>3)]
261
+ a.map{|x| x.artists}.should == [[@c2.load(:id=>1)], [@c2.load(:id=>2)], [@c2.load(:id=>3)]]
262
+ MODEL_DB.sqls.length.should == 0
263
+ end
264
+ end
265
+
266
+ it "should work correctly when eagerly loading many_to_many associations" do
267
+ @c1.columns :id
268
+ @c2.columns :id
269
+ @c1.many_to_many :artists, :class=>@c2, :left_key=>:album_id, :right_key=>:artist_id, :join_table=>:aa
270
+ @c1.dataset._fetch = [{:id=>1}, {:id=>2}, {:id=>3}]
271
+ @c2.dataset._fetch = [{:id=>1, :x_foreign_key_x=>1}, {:id=>1, :x_foreign_key_x=>2}, {:id=>2, :x_foreign_key_x=>1}, {:id=>2, :x_foreign_key_x=>2}, {:id=>3, :x_foreign_key_x=>1}, {:id=>3, :x_foreign_key_x=>1}]
272
+
273
+ @c.waw_identity_map do
274
+ MODEL_DB.sqls.length.should == 0
275
+ a = @c1.eager(:artists).all
216
276
  MODEL_DB.sqls.length.should == 2
277
+ a.should == [@c1.load(:id=>1), @c1.load(:id=>2), @c1.load(:id=>3)]
278
+ a.map{|x| x.artists}.should == [[@c2.load(:id=>1), @c2.load(:id=>2), @c2.load(:id=>3), @c2.load(:id=>3)], [@c2.load(:id=>1), @c2.load(:id=>2)], []]
279
+ MODEL_DB.sqls.length.should == 0
280
+ end
281
+ end
282
+
283
+ it "should work correctly when eagerly loading many_to_many associations with composite keys" do
284
+ @c1.columns :id, :id2
285
+ @c2.columns :id
286
+ @c1.set_primary_key :id, :id2
287
+ @c1.many_to_many :artists, :class=>@c2, :left_key=>[:album_id1, :album_id2], :right_key=>:artist_id, :join_table=>:aa
288
+ @c1.dataset._fetch = [{:id=>1, :id2=>4}, {:id=>2, :id2=>5}, {:id=>3, :id2=>6}]
289
+ @c2.dataset._fetch = [ {:id=>1, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>1, :x_foreign_key_0_x=>2, :x_foreign_key_1_x=>5}, {:id=>2, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>2, :x_foreign_key_0_x=>2, :x_foreign_key_1_x=>5}, {:id=>3, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>3, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}]
290
+
291
+ @c.waw_identity_map do
292
+ MODEL_DB.sqls.length.should == 0
293
+ a = @c1.eager(:artists).all
294
+ MODEL_DB.sqls.length.should == 2
295
+ a.should == [@c1.load(:id=>1, :id2=>4), @c1.load(:id=>2, :id2=>5), @c1.load(:id=>3, :id2=>6)]
296
+ a.map{|x| x.artists}.should == [[@c2.load(:id=>1), @c2.load(:id=>2), @c2.load(:id=>3), @c2.load(:id=>3)], [@c2.load(:id=>1), @c2.load(:id=>2)], []]
297
+ MODEL_DB.sqls.length.should == 0
298
+ end
299
+ end
300
+
301
+ it "should work correctly when eagerly loading many_through_many associations" do
302
+ @c1.columns :id
303
+ @c2.columns :id
304
+ @c1.plugin :many_through_many
305
+ @c1.many_through_many :artists, [[:aa, :album_id, :artist_id]], :class=>@c2
306
+ @c1.dataset._fetch = [{:id=>1}, {:id=>2}, {:id=>3}]
307
+ @c2.dataset._fetch = [{:id=>1, :x_foreign_key_x=>1}, {:id=>1, :x_foreign_key_x=>2}, {:id=>2, :x_foreign_key_x=>1}, {:id=>2, :x_foreign_key_x=>2}, {:id=>3, :x_foreign_key_x=>1}, {:id=>3, :x_foreign_key_x=>1}]
308
+
309
+ @c.waw_identity_map do
310
+ MODEL_DB.sqls.length.should == 0
311
+ a = @c1.eager(:artists).all
312
+ MODEL_DB.sqls.length.should == 2
313
+ a.should == [@c1.load(:id=>1), @c1.load(:id=>2), @c1.load(:id=>3)]
314
+ a.map{|x| x.artists}.should == [[@c2.load(:id=>1), @c2.load(:id=>2), @c2.load(:id=>3), @c2.load(:id=>3)], [@c2.load(:id=>1), @c2.load(:id=>2)], []]
315
+ MODEL_DB.sqls.length.should == 0
316
+ end
317
+ end
318
+
319
+ it "should work correctly when eagerly loading many_to_many associations with composite keys" do
320
+ @c1.columns :id, :id2
321
+ @c2.columns :id
322
+ @c1.set_primary_key :id, :id2
323
+ @c1.plugin :many_through_many
324
+ @c1.many_through_many :artists, [[:aa, [:album_id1, :album_id2], :artist_id]], :class=>@c2
325
+ @c1.dataset._fetch = [{:id=>1, :id2=>4}, {:id=>2, :id2=>5}, {:id=>3, :id2=>6}]
326
+ @c2.dataset._fetch = [ {:id=>1, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>1, :x_foreign_key_0_x=>2, :x_foreign_key_1_x=>5}, {:id=>2, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>2, :x_foreign_key_0_x=>2, :x_foreign_key_1_x=>5}, {:id=>3, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}, {:id=>3, :x_foreign_key_0_x=>1, :x_foreign_key_1_x=>4}]
327
+
328
+ @c.waw_identity_map do
329
+ MODEL_DB.sqls.length.should == 0
330
+ a = @c1.eager(:artists).all
331
+ MODEL_DB.sqls.length.should == 2
332
+ a.should == [@c1.load(:id=>1, :id2=>4), @c1.load(:id=>2, :id2=>5), @c1.load(:id=>3, :id2=>6)]
333
+ a.map{|x| x.artists}.should == [[@c2.load(:id=>1), @c2.load(:id=>2), @c2.load(:id=>3), @c2.load(:id=>3)], [@c2.load(:id=>1), @c2.load(:id=>2)], []]
334
+ MODEL_DB.sqls.length.should == 0
217
335
  end
218
336
  end
219
337
  end
@@ -1,8 +1,5 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
2
 
3
- if defined?(ActiveSupport::Inflector)
4
- skip_warn "inflector extension: active_support inflector loaded"
5
- else
6
3
  describe String do
7
4
  it "#camelize and #camelcase should transform the word to CamelCase" do
8
5
  "egg_and_hams".camelize.should == "EggAndHams"
@@ -182,4 +179,3 @@ describe 'Default inflections' do
182
179
  end
183
180
  end
184
181
  end
185
- end