sequel 5.29.0 → 5.34.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 (387) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +70 -1922
  3. data/README.rdoc +1 -1
  4. data/doc/advanced_associations.rdoc +4 -4
  5. data/doc/association_basics.rdoc +3 -3
  6. data/doc/code_order.rdoc +12 -2
  7. data/doc/model_dataset_method_design.rdoc +1 -1
  8. data/doc/postgresql.rdoc +71 -0
  9. data/doc/release_notes/5.30.0.txt +20 -0
  10. data/doc/release_notes/5.31.0.txt +148 -0
  11. data/doc/release_notes/5.32.0.txt +46 -0
  12. data/doc/release_notes/5.33.0.txt +24 -0
  13. data/doc/release_notes/5.34.0.txt +40 -0
  14. data/doc/testing.rdoc +1 -1
  15. data/lib/sequel/adapters/shared/access.rb +6 -6
  16. data/lib/sequel/adapters/shared/mssql.rb +5 -5
  17. data/lib/sequel/adapters/shared/mysql.rb +9 -9
  18. data/lib/sequel/adapters/shared/oracle.rb +16 -16
  19. data/lib/sequel/adapters/shared/postgres.rb +169 -14
  20. data/lib/sequel/adapters/shared/sqlanywhere.rb +9 -9
  21. data/lib/sequel/adapters/shared/sqlite.rb +32 -5
  22. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  23. data/lib/sequel/connection_pool/sharded_threaded.rb +12 -12
  24. data/lib/sequel/connection_pool/single.rb +1 -1
  25. data/lib/sequel/connection_pool/threaded.rb +2 -2
  26. data/lib/sequel/core.rb +318 -314
  27. data/lib/sequel/database/connecting.rb +1 -1
  28. data/lib/sequel/database/misc.rb +16 -10
  29. data/lib/sequel/database/query.rb +3 -1
  30. data/lib/sequel/database/schema_generator.rb +0 -1
  31. data/lib/sequel/database/schema_methods.rb +15 -16
  32. data/lib/sequel/database/transactions.rb +12 -13
  33. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  34. data/lib/sequel/dataset/query.rb +4 -3
  35. data/lib/sequel/deprecated.rb +2 -0
  36. data/lib/sequel/exceptions.rb +2 -0
  37. data/lib/sequel/extensions/connection_expiration.rb +2 -2
  38. data/lib/sequel/extensions/connection_validator.rb +2 -2
  39. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  40. data/lib/sequel/extensions/index_caching.rb +9 -7
  41. data/lib/sequel/extensions/integer64.rb +2 -0
  42. data/lib/sequel/extensions/migration.rb +1 -1
  43. data/lib/sequel/extensions/pg_enum.rb +5 -2
  44. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  45. data/lib/sequel/extensions/pg_inet.rb +13 -5
  46. data/lib/sequel/extensions/pg_interval.rb +2 -0
  47. data/lib/sequel/extensions/pg_range.rb +2 -0
  48. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  49. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  50. data/lib/sequel/extensions/schema_dumper.rb +10 -4
  51. data/lib/sequel/extensions/server_block.rb +3 -3
  52. data/lib/sequel/model.rb +2 -0
  53. data/lib/sequel/model/associations.rb +30 -18
  54. data/lib/sequel/model/base.rb +64 -55
  55. data/lib/sequel/model/plugins.rb +3 -3
  56. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  57. data/lib/sequel/plugins/association_multi_add_remove.rb +2 -0
  58. data/lib/sequel/plugins/association_pks.rb +57 -16
  59. data/lib/sequel/plugins/association_proxies.rb +2 -0
  60. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  61. data/lib/sequel/plugins/class_table_inheritance.rb +26 -26
  62. data/lib/sequel/plugins/dirty.rb +13 -13
  63. data/lib/sequel/plugins/forbid_lazy_load.rb +214 -0
  64. data/lib/sequel/plugins/json_serializer.rb +3 -7
  65. data/lib/sequel/plugins/rcte_tree.rb +2 -2
  66. data/lib/sequel/plugins/single_table_inheritance.rb +15 -15
  67. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  68. data/lib/sequel/plugins/subclasses.rb +2 -0
  69. data/lib/sequel/timezones.rb +6 -4
  70. data/lib/sequel/version.rb +1 -1
  71. metadata +17 -368
  72. data/Rakefile +0 -151
  73. data/doc/release_notes/4.0.0.txt +0 -262
  74. data/doc/release_notes/4.1.0.txt +0 -85
  75. data/doc/release_notes/4.10.0.txt +0 -226
  76. data/doc/release_notes/4.11.0.txt +0 -147
  77. data/doc/release_notes/4.12.0.txt +0 -105
  78. data/doc/release_notes/4.13.0.txt +0 -169
  79. data/doc/release_notes/4.14.0.txt +0 -68
  80. data/doc/release_notes/4.15.0.txt +0 -56
  81. data/doc/release_notes/4.16.0.txt +0 -36
  82. data/doc/release_notes/4.17.0.txt +0 -38
  83. data/doc/release_notes/4.18.0.txt +0 -36
  84. data/doc/release_notes/4.19.0.txt +0 -45
  85. data/doc/release_notes/4.2.0.txt +0 -129
  86. data/doc/release_notes/4.20.0.txt +0 -79
  87. data/doc/release_notes/4.21.0.txt +0 -94
  88. data/doc/release_notes/4.22.0.txt +0 -72
  89. data/doc/release_notes/4.23.0.txt +0 -65
  90. data/doc/release_notes/4.24.0.txt +0 -99
  91. data/doc/release_notes/4.25.0.txt +0 -181
  92. data/doc/release_notes/4.26.0.txt +0 -44
  93. data/doc/release_notes/4.27.0.txt +0 -78
  94. data/doc/release_notes/4.28.0.txt +0 -57
  95. data/doc/release_notes/4.29.0.txt +0 -41
  96. data/doc/release_notes/4.3.0.txt +0 -40
  97. data/doc/release_notes/4.30.0.txt +0 -37
  98. data/doc/release_notes/4.31.0.txt +0 -57
  99. data/doc/release_notes/4.32.0.txt +0 -132
  100. data/doc/release_notes/4.33.0.txt +0 -88
  101. data/doc/release_notes/4.34.0.txt +0 -86
  102. data/doc/release_notes/4.35.0.txt +0 -130
  103. data/doc/release_notes/4.36.0.txt +0 -116
  104. data/doc/release_notes/4.37.0.txt +0 -50
  105. data/doc/release_notes/4.38.0.txt +0 -67
  106. data/doc/release_notes/4.39.0.txt +0 -127
  107. data/doc/release_notes/4.4.0.txt +0 -92
  108. data/doc/release_notes/4.40.0.txt +0 -179
  109. data/doc/release_notes/4.41.0.txt +0 -77
  110. data/doc/release_notes/4.42.0.txt +0 -221
  111. data/doc/release_notes/4.43.0.txt +0 -87
  112. data/doc/release_notes/4.44.0.txt +0 -125
  113. data/doc/release_notes/4.45.0.txt +0 -370
  114. data/doc/release_notes/4.46.0.txt +0 -404
  115. data/doc/release_notes/4.47.0.txt +0 -56
  116. data/doc/release_notes/4.48.0.txt +0 -293
  117. data/doc/release_notes/4.49.0.txt +0 -222
  118. data/doc/release_notes/4.5.0.txt +0 -34
  119. data/doc/release_notes/4.6.0.txt +0 -30
  120. data/doc/release_notes/4.7.0.txt +0 -103
  121. data/doc/release_notes/4.8.0.txt +0 -175
  122. data/doc/release_notes/4.9.0.txt +0 -190
  123. data/spec/adapter_spec.rb +0 -4
  124. data/spec/adapters/db2_spec.rb +0 -170
  125. data/spec/adapters/mssql_spec.rb +0 -828
  126. data/spec/adapters/mysql_spec.rb +0 -1060
  127. data/spec/adapters/oracle_spec.rb +0 -371
  128. data/spec/adapters/postgres_spec.rb +0 -4476
  129. data/spec/adapters/spec_helper.rb +0 -44
  130. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  131. data/spec/adapters/sqlite_spec.rb +0 -652
  132. data/spec/bin_spec.rb +0 -278
  133. data/spec/core/connection_pool_spec.rb +0 -1250
  134. data/spec/core/database_spec.rb +0 -2915
  135. data/spec/core/dataset_spec.rb +0 -5544
  136. data/spec/core/deprecated_spec.rb +0 -70
  137. data/spec/core/expression_filters_spec.rb +0 -1498
  138. data/spec/core/mock_adapter_spec.rb +0 -722
  139. data/spec/core/object_graph_spec.rb +0 -336
  140. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  141. data/spec/core/schema_generator_spec.rb +0 -214
  142. data/spec/core/schema_spec.rb +0 -1844
  143. data/spec/core/spec_helper.rb +0 -24
  144. data/spec/core/version_spec.rb +0 -14
  145. data/spec/core_extensions_spec.rb +0 -763
  146. data/spec/core_model_spec.rb +0 -2
  147. data/spec/core_spec.rb +0 -1
  148. data/spec/deprecation_helper.rb +0 -30
  149. data/spec/extensions/accessed_columns_spec.rb +0 -51
  150. data/spec/extensions/active_model_spec.rb +0 -99
  151. data/spec/extensions/after_initialize_spec.rb +0 -28
  152. data/spec/extensions/any_not_empty_spec.rb +0 -23
  153. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  154. data/spec/extensions/association_dependencies_spec.rb +0 -125
  155. data/spec/extensions/association_multi_add_remove_spec.rb +0 -1041
  156. data/spec/extensions/association_pks_spec.rb +0 -423
  157. data/spec/extensions/association_proxies_spec.rb +0 -100
  158. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  159. data/spec/extensions/auto_validations_spec.rb +0 -229
  160. data/spec/extensions/blacklist_security_spec.rb +0 -95
  161. data/spec/extensions/blank_spec.rb +0 -69
  162. data/spec/extensions/boolean_readers_spec.rb +0 -93
  163. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  164. data/spec/extensions/caching_spec.rb +0 -273
  165. data/spec/extensions/caller_logging_spec.rb +0 -52
  166. data/spec/extensions/class_table_inheritance_spec.rb +0 -750
  167. data/spec/extensions/column_conflicts_spec.rb +0 -75
  168. data/spec/extensions/column_select_spec.rb +0 -129
  169. data/spec/extensions/columns_introspection_spec.rb +0 -90
  170. data/spec/extensions/columns_updated_spec.rb +0 -35
  171. data/spec/extensions/composition_spec.rb +0 -248
  172. data/spec/extensions/connection_expiration_spec.rb +0 -151
  173. data/spec/extensions/connection_validator_spec.rb +0 -144
  174. data/spec/extensions/constant_sql_override_spec.rb +0 -24
  175. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  176. data/spec/extensions/constraint_validations_spec.rb +0 -439
  177. data/spec/extensions/core_refinements_spec.rb +0 -528
  178. data/spec/extensions/csv_serializer_spec.rb +0 -183
  179. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  180. data/spec/extensions/dataset_associations_spec.rb +0 -365
  181. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  182. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  183. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  184. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  185. data/spec/extensions/defaults_setter_spec.rb +0 -150
  186. data/spec/extensions/delay_add_association_spec.rb +0 -73
  187. data/spec/extensions/dirty_spec.rb +0 -222
  188. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  189. data/spec/extensions/eager_each_spec.rb +0 -62
  190. data/spec/extensions/eager_graph_eager_spec.rb +0 -100
  191. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  192. data/spec/extensions/empty_failure_backtraces_spec.rb +0 -60
  193. data/spec/extensions/error_splitter_spec.rb +0 -18
  194. data/spec/extensions/error_sql_spec.rb +0 -20
  195. data/spec/extensions/escaped_like_spec.rb +0 -40
  196. data/spec/extensions/eval_inspect_spec.rb +0 -81
  197. data/spec/extensions/exclude_or_null_spec.rb +0 -15
  198. data/spec/extensions/finder_spec.rb +0 -260
  199. data/spec/extensions/force_encoding_spec.rb +0 -126
  200. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  201. data/spec/extensions/graph_each_spec.rb +0 -113
  202. data/spec/extensions/hook_class_methods_spec.rb +0 -402
  203. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  204. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  205. data/spec/extensions/index_caching_spec.rb +0 -66
  206. data/spec/extensions/inflector_spec.rb +0 -183
  207. data/spec/extensions/input_transformer_spec.rb +0 -69
  208. data/spec/extensions/insert_conflict_spec.rb +0 -103
  209. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  210. data/spec/extensions/instance_filters_spec.rb +0 -79
  211. data/spec/extensions/instance_hooks_spec.rb +0 -246
  212. data/spec/extensions/integer64_spec.rb +0 -22
  213. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  214. data/spec/extensions/json_serializer_spec.rb +0 -346
  215. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  216. data/spec/extensions/list_spec.rb +0 -291
  217. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  218. data/spec/extensions/many_through_many_spec.rb +0 -2177
  219. data/spec/extensions/migration_spec.rb +0 -864
  220. data/spec/extensions/modification_detection_spec.rb +0 -93
  221. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  222. data/spec/extensions/named_timezones_spec.rb +0 -218
  223. data/spec/extensions/nested_attributes_spec.rb +0 -815
  224. data/spec/extensions/null_dataset_spec.rb +0 -85
  225. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  226. data/spec/extensions/pagination_spec.rb +0 -116
  227. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  228. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  229. data/spec/extensions/pg_array_spec.rb +0 -398
  230. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -209
  231. data/spec/extensions/pg_enum_spec.rb +0 -118
  232. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  233. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  234. data/spec/extensions/pg_hstore_spec.rb +0 -219
  235. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  236. data/spec/extensions/pg_inet_spec.rb +0 -72
  237. data/spec/extensions/pg_interval_spec.rb +0 -103
  238. data/spec/extensions/pg_json_ops_spec.rb +0 -356
  239. data/spec/extensions/pg_json_spec.rb +0 -451
  240. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  241. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  242. data/spec/extensions/pg_range_spec.rb +0 -600
  243. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  244. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  245. data/spec/extensions/pg_row_spec.rb +0 -363
  246. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  247. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  248. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  249. data/spec/extensions/prepared_statements_spec.rb +0 -177
  250. data/spec/extensions/pretty_table_spec.rb +0 -123
  251. data/spec/extensions/query_spec.rb +0 -94
  252. data/spec/extensions/rcte_tree_spec.rb +0 -387
  253. data/spec/extensions/round_timestamps_spec.rb +0 -39
  254. data/spec/extensions/s_spec.rb +0 -60
  255. data/spec/extensions/schema_caching_spec.rb +0 -64
  256. data/spec/extensions/schema_dumper_spec.rb +0 -870
  257. data/spec/extensions/select_remove_spec.rb +0 -38
  258. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  259. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  260. data/spec/extensions/serialization_spec.rb +0 -365
  261. data/spec/extensions/server_block_spec.rb +0 -135
  262. data/spec/extensions/server_logging_spec.rb +0 -45
  263. data/spec/extensions/sharding_spec.rb +0 -197
  264. data/spec/extensions/shared_caching_spec.rb +0 -151
  265. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  266. data/spec/extensions/singular_table_names_spec.rb +0 -22
  267. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  268. data/spec/extensions/spec_helper.rb +0 -70
  269. data/spec/extensions/split_array_nil_spec.rb +0 -24
  270. data/spec/extensions/split_values_spec.rb +0 -57
  271. data/spec/extensions/sql_comments_spec.rb +0 -33
  272. data/spec/extensions/sql_expr_spec.rb +0 -59
  273. data/spec/extensions/static_cache_cache_spec.rb +0 -35
  274. data/spec/extensions/static_cache_spec.rb +0 -471
  275. data/spec/extensions/string_agg_spec.rb +0 -90
  276. data/spec/extensions/string_date_time_spec.rb +0 -95
  277. data/spec/extensions/string_stripper_spec.rb +0 -68
  278. data/spec/extensions/subclasses_spec.rb +0 -79
  279. data/spec/extensions/subset_conditions_spec.rb +0 -38
  280. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  281. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  282. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  283. data/spec/extensions/table_select_spec.rb +0 -83
  284. data/spec/extensions/tactical_eager_loading_spec.rb +0 -402
  285. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  286. data/spec/extensions/throw_failures_spec.rb +0 -74
  287. data/spec/extensions/timestamps_spec.rb +0 -209
  288. data/spec/extensions/to_dot_spec.rb +0 -153
  289. data/spec/extensions/touch_spec.rb +0 -226
  290. data/spec/extensions/tree_spec.rb +0 -334
  291. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  292. data/spec/extensions/unlimited_update_spec.rb +0 -21
  293. data/spec/extensions/update_or_create_spec.rb +0 -83
  294. data/spec/extensions/update_primary_key_spec.rb +0 -105
  295. data/spec/extensions/update_refresh_spec.rb +0 -59
  296. data/spec/extensions/uuid_spec.rb +0 -101
  297. data/spec/extensions/validate_associated_spec.rb +0 -52
  298. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  299. data/spec/extensions/validation_contexts_spec.rb +0 -31
  300. data/spec/extensions/validation_helpers_spec.rb +0 -525
  301. data/spec/extensions/whitelist_security_spec.rb +0 -157
  302. data/spec/extensions/xml_serializer_spec.rb +0 -213
  303. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  304. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  305. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  306. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  307. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  308. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  309. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  310. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  311. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  312. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  313. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  314. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  315. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  316. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  317. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  318. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  319. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  320. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  321. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  322. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  323. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  324. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  325. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  326. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  327. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  328. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  329. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  330. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  331. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  332. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  333. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  334. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  335. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  336. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  337. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  338. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  339. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  340. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  341. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  342. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  343. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  344. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  345. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  346. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  347. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  348. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  349. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  350. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  351. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  352. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  353. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  354. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  355. data/spec/guards_helper.rb +0 -59
  356. data/spec/integration/associations_test.rb +0 -2597
  357. data/spec/integration/database_test.rb +0 -113
  358. data/spec/integration/dataset_test.rb +0 -2037
  359. data/spec/integration/eager_loader_test.rb +0 -687
  360. data/spec/integration/migrator_test.rb +0 -262
  361. data/spec/integration/model_test.rb +0 -203
  362. data/spec/integration/plugin_test.rb +0 -2423
  363. data/spec/integration/prepared_statement_test.rb +0 -405
  364. data/spec/integration/schema_test.rb +0 -903
  365. data/spec/integration/spec_helper.rb +0 -71
  366. data/spec/integration/timezone_test.rb +0 -86
  367. data/spec/integration/transaction_test.rb +0 -603
  368. data/spec/integration/type_test.rb +0 -127
  369. data/spec/model/association_reflection_spec.rb +0 -803
  370. data/spec/model/associations_spec.rb +0 -4738
  371. data/spec/model/base_spec.rb +0 -875
  372. data/spec/model/class_dataset_methods_spec.rb +0 -146
  373. data/spec/model/dataset_methods_spec.rb +0 -198
  374. data/spec/model/eager_loading_spec.rb +0 -2377
  375. data/spec/model/hooks_spec.rb +0 -370
  376. data/spec/model/inflector_spec.rb +0 -26
  377. data/spec/model/model_spec.rb +0 -956
  378. data/spec/model/plugins_spec.rb +0 -429
  379. data/spec/model/record_spec.rb +0 -2118
  380. data/spec/model/spec_helper.rb +0 -46
  381. data/spec/model/validations_spec.rb +0 -220
  382. data/spec/model_no_assoc_spec.rb +0 -1
  383. data/spec/model_spec.rb +0 -1
  384. data/spec/plugin_spec.rb +0 -1
  385. data/spec/sequel_coverage.rb +0 -15
  386. data/spec/sequel_warning.rb +0 -5
  387. data/spec/spec_config.rb +0 -12
@@ -1,1041 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "association_multi_add_remove plugin - one_to_many" do
4
- before do
5
- @c1 = Class.new(Sequel::Model(:attributes)) do
6
- unrestrict_primary_key
7
- columns :id, :node_id, :y, :z
8
- end
9
-
10
- @c2 = Class.new(Sequel::Model(:nodes)) do
11
- plugin :association_multi_add_remove
12
-
13
- def _refresh(ds); end
14
- unrestrict_primary_key
15
- attr_accessor :xxx
16
-
17
- def self.name; 'Node'; end
18
- def self.to_s; 'Node'; end
19
-
20
- columns :id, :x
21
- end
22
- @dataset = @c2.dataset = @c2.dataset.with_fetch({})
23
- @c1.dataset = @c1.dataset.with_fetch(proc { |sql| sql =~ /SELECT 1/ ? { a: 1 } : {} })
24
- DB.reset
25
- end
26
-
27
- it "should define an add_*s method that works on existing records" do
28
- @c2.one_to_many :attributes, class: @c1
29
-
30
- n = @c2.load(id: 1234)
31
- a1 = @c1.load(id: 2345)
32
- a2 = @c1.load(id: 3456)
33
- [a1, a2].must_equal n.add_attributes([a1, a2])
34
- a1.values.must_equal(:node_id => 1234, id: 2345)
35
- a2.values.must_equal(:node_id => 1234, id: 3456)
36
- DB.sqls.must_equal [
37
- 'BEGIN',
38
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 2345)',
39
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 3456)',
40
- 'COMMIT'
41
- ]
42
- end
43
-
44
- it "should not define add/remove methods with the same name as the ones defined by default " do
45
- @c2.one_to_many :sheep, class: @c1, :key=>:node_id
46
-
47
- n = @c2.load(id: 1234)
48
- a1 = @c1.load(id: 2345)
49
- a1.must_be_same_as n.add_sheep(a1)
50
- a1.values.must_equal(:node_id => 1234, id: 2345)
51
- DB.sqls.must_equal ['UPDATE attributes SET node_id = 1234 WHERE (id = 2345)']
52
- a1.must_be_same_as n.remove_sheep(a1)
53
- a1.values.must_equal(:node_id => nil, id: 2345)
54
- DB.sqls.must_equal [
55
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1",
56
- 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)',
57
- ]
58
- n.respond_to?(:sheep=).must_equal false
59
- end
60
-
61
- it "should support :multi_add_method" do
62
- @c2.one_to_many :attributes, class: @c1, :multi_add_method=>:add_multiple_attributes
63
-
64
- n = @c2.load(id: 1234)
65
- a1 = @c1.load(id: 2345)
66
- a2 = @c1.load(id: 3456)
67
- [a1, a2].must_equal n.add_multiple_attributes([a1, a2])
68
- a1.values.must_equal(:node_id => 1234, id: 2345)
69
- a2.values.must_equal(:node_id => 1234, id: 3456)
70
- DB.sqls.must_equal [
71
- 'BEGIN',
72
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 2345)',
73
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 3456)',
74
- 'COMMIT'
75
- ]
76
- end
77
-
78
- it "should define an add_*s method that works on new records" do
79
- @c2.one_to_many :attributes, :class => @c1
80
-
81
- n = @c2.load(:id => 1234)
82
- a1 = @c1.new(:id => 234)
83
- a2 = @c1.new(:id => 345)
84
- @c1.dataset = @c1.dataset.with_fetch([
85
- [{ :id=>234, :node_id=>1234 }], [{ :id=>345, :node_id=>1234 }]
86
- ])
87
- [a1, a2].must_equal n.add_attributes([a1, a2])
88
- DB.sqls.must_equal [
89
- 'BEGIN',
90
- "INSERT INTO attributes (id, node_id) VALUES (234, 1234)",
91
- "SELECT * FROM attributes WHERE id = 234",
92
- "INSERT INTO attributes (id, node_id) VALUES (345, 1234)",
93
- "SELECT * FROM attributes WHERE id = 345",
94
- 'COMMIT'
95
- ]
96
- a1.values.must_equal(:node_id => 1234, :id => 234)
97
- a2.values.must_equal(:node_id => 1234, :id => 345)
98
- end
99
-
100
- it "should define a remove_*s method that works on existing records" do
101
- @c2.one_to_many :attributes, :class => @c1
102
-
103
- n = @c2.load(:id => 1234)
104
- a1 = @c1.load(:id => 2345, :node_id => 1234)
105
- a2 = @c1.load(:id => 3456, :node_id => 1234)
106
- [a1, a2].must_equal n.remove_attributes([a1, a2])
107
- a1.values.must_equal(:node_id => nil, :id => 2345)
108
- a2.values.must_equal(:node_id => nil, :id => 3456)
109
- DB.sqls.must_equal [
110
- 'BEGIN',
111
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1",
112
- 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)',
113
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 3456)) LIMIT 1",
114
- 'UPDATE attributes SET node_id = NULL WHERE (id = 3456)',
115
- 'COMMIT'
116
- ]
117
- end
118
-
119
- it "should support :multi_remove_method" do
120
- @c2.one_to_many :attributes, :class => @c1, :multi_remove_method=>:remove_multiple_attributes
121
-
122
- n = @c2.load(:id => 1234)
123
- a1 = @c1.load(:id => 2345, :node_id => 1234)
124
- a2 = @c1.load(:id => 3456, :node_id => 1234)
125
- [a1, a2].must_equal n.remove_multiple_attributes([a1, a2])
126
- a1.values.must_equal(:node_id => nil, :id => 2345)
127
- a2.values.must_equal(:node_id => nil, :id => 3456)
128
- DB.sqls.must_equal [
129
- 'BEGIN',
130
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1",
131
- 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)',
132
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 3456)) LIMIT 1",
133
- 'UPDATE attributes SET node_id = NULL WHERE (id = 3456)',
134
- 'COMMIT'
135
- ]
136
- end
137
-
138
- it "should have the remove_*s method raise an error if the passed objects are not already associated" do
139
- @c2.one_to_many :attributes, :class => @c1
140
-
141
- n = @c2.new(:id => 1234)
142
- a1 = @c1.load(:id => 2345, :node_id => 1234)
143
- a2 = @c1.load(:id => 3456, :node_id => 1234)
144
- @c1.dataset = @c1.dataset.with_fetch([])
145
- proc{n.remove_attributes([a1, a2])}.must_raise(Sequel::Error)
146
- DB.sqls.must_equal [
147
- 'BEGIN',
148
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1",
149
- 'ROLLBACK'
150
- ]
151
- end
152
-
153
- it "should accept hashes for the add_*s method and create a new records" do
154
- @c2.one_to_many :attributes, :class => @c1
155
- n = @c2.new(:id => 1234)
156
- DB.reset
157
- @c1.dataset = @c1.dataset.with_fetch([
158
- [{ :node_id => 1234, :id => 234 }], [{ :node_id => 1234, :id => 345 }]
159
- ])
160
- n.add_attributes([{ :id => 234 }, { :id => 345 }]).must_equal [
161
- @c1.load(:node_id => 1234, :id => 234),
162
- @c1.load(:node_id => 1234, :id => 345)
163
- ]
164
- DB.sqls.must_equal [
165
- 'BEGIN',
166
- "INSERT INTO attributes (id, node_id) VALUES (234, 1234)",
167
- "SELECT * FROM attributes WHERE id = 234",
168
- "INSERT INTO attributes (id, node_id) VALUES (345, 1234)",
169
- "SELECT * FROM attributes WHERE id = 345",
170
- 'COMMIT'
171
- ]
172
- end
173
-
174
- it "should accept primary keys for the add_*s method" do
175
- @c2.one_to_many :attributes, :class => @c1
176
- n = @c2.new(:id => 1234)
177
- @c1.dataset = @c1.dataset.with_fetch([
178
- [{ :node_id => nil, :id => 234 }], [{ :node_id => nil, :id => 345 }]
179
- ])
180
- n.add_attributes([234, 345]).must_equal [
181
- @c1.load(:node_id => 1234, :id => 234),
182
- @c1.load(:node_id => 1234, :id => 345)
183
- ]
184
- DB.sqls.must_equal [
185
- 'BEGIN',
186
- "SELECT * FROM attributes WHERE id = 234",
187
- "UPDATE attributes SET node_id = 1234 WHERE (id = 234)",
188
- "SELECT * FROM attributes WHERE id = 345",
189
- "UPDATE attributes SET node_id = 1234 WHERE (id = 345)",
190
- 'COMMIT'
191
- ]
192
- end
193
-
194
- it "should raise an error if the primary key passed to the add_*s method does not match an existing record" do
195
- @c2.one_to_many :attributes, :class => @c1
196
- n = @c2.new(:id => 1234)
197
- @c1.dataset = @c1.dataset.with_fetch([])
198
- proc{n.add_attributes([234, 345])}.must_raise(Sequel::NoMatchingRow)
199
- DB.sqls.must_equal [
200
- 'BEGIN',
201
- "SELECT * FROM attributes WHERE id = 234",
202
- 'ROLLBACK'
203
- ]
204
- end
205
-
206
- it "should raise an error in the add_*s method if the passed associated objects are not of the correct type" do
207
- @c2.one_to_many :attributes, :class => @c1
208
- proc{@c2.new(:id => 1234).add_attributes([@c2.new, @c2.new])}.must_raise(Sequel::Error)
209
- end
210
-
211
- it "should accept primary keys for the remove_*s method and remove existing records" do
212
- @c2.one_to_many :attributes, :class => @c1
213
- n = @c2.new(:id => 1234)
214
- @c1.dataset = @c1.dataset.with_fetch([
215
- [{ :id=>234, :node_id=>1234 }], [{ :id=>345, :node_id=>1234 }]
216
- ])
217
- n.remove_attributes([234, 345]).must_equal [
218
- @c1.load(:node_id => nil, :id => 234),
219
- @c1.load(:node_id => nil, :id => 345)
220
- ]
221
- DB.sqls.must_equal [
222
- 'BEGIN',
223
- 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.id = 234)) LIMIT 1',
224
- 'UPDATE attributes SET node_id = NULL WHERE (id = 234)',
225
- 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.id = 345)) LIMIT 1',
226
- 'UPDATE attributes SET node_id = NULL WHERE (id = 345)',
227
- 'COMMIT'
228
- ]
229
- end
230
-
231
- it "should raise an error in the remove_*s method if the passed associated objects are not of the correct type" do
232
- @c2.one_to_many :attributes, :class => @c1
233
- proc{@c2.new(:id => 1234).remove_attributes([@c2.new, @c2.new])}.must_raise(Sequel::Error)
234
- end
235
-
236
- it "should have add_*s method respect the :primary_key option" do
237
- @c2.one_to_many :attributes, :class => @c1, :primary_key=>:xxx
238
-
239
- n = @c2.new(:id => 1234, :xxx=>5)
240
- a1 = @c1.load(:id => 2345)
241
- a2 = @c1.load(:id => 3456)
242
- n.add_attributes([a1, a2]).must_equal [a1, a2]
243
- DB.sqls.must_equal [
244
- 'BEGIN',
245
- 'UPDATE attributes SET node_id = 5 WHERE (id = 2345)',
246
- 'UPDATE attributes SET node_id = 5 WHERE (id = 3456)',
247
- 'COMMIT'
248
- ]
249
- end
250
-
251
- it "should have add_*s method not add the same objects to the cached association array if the objects are already in the array" do
252
- @c2.one_to_many :attributes, :class => @c1
253
-
254
- n = @c2.new(:id => 1234)
255
- a1 = @c1.load(:id => 2345)
256
- a2 = @c1.load(:id => 3456)
257
- n.associations[:attributes] = []
258
- [a1, a2].must_equal n.add_attributes([a1, a2])
259
- [a1, a2].must_equal n.add_attributes([a1, a2])
260
- a1.values.must_equal(:node_id => 1234, :id => 2345)
261
- a2.values.must_equal(:node_id => 1234, :id => 3456)
262
- n.attributes.must_equal [a1, a2]
263
- DB.sqls.must_equal [
264
- 'BEGIN',
265
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 2345)',
266
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 3456)',
267
- 'COMMIT'
268
- ] * 2
269
- end
270
-
271
- it "should have add_*s method respect composite keys" do
272
- @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
273
-
274
- n = @c2.load(:id => 1234, :x=>5)
275
- a1 = @c1.load(:id => 2345)
276
- a2 = @c1.load(:id => 3456)
277
- n.add_attributes([a1, a2]).must_equal [a1, a2]
278
- DB.sqls.must_equal [
279
- 'BEGIN',
280
- "UPDATE attributes SET node_id = 1234, y = 5 WHERE (id = 2345)",
281
- "UPDATE attributes SET node_id = 1234, y = 5 WHERE (id = 3456)",
282
- 'COMMIT'
283
- ]
284
- end
285
-
286
- it "should have add_*s method accept composite keys" do
287
- @c1.dataset = @c1.dataset.with_fetch([
288
- [{ :id=>2345, :node_id=>1234, :z=>8, :y=>5 }],
289
- [{ :id=>3456, :node_id=>1234, :z=>9, :y=>5 }]
290
- ])
291
- @c1.set_primary_key [:id, :z]
292
- @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
293
-
294
- n = @c2.load(:id => 1234, :x=>5)
295
- a1 = @c1.load(:id => 2345, :z => 8, :node_id => 1234, :y=>5)
296
- a2 = @c1.load(:id => 3456, :z => 9, :node_id => 1234, :y=>5)
297
- n.add_attributes([[2345, 8], [3456, 9]]).must_equal [a1, a2]
298
- DB.sqls.must_equal [
299
- 'BEGIN',
300
- "SELECT * FROM attributes WHERE ((id = 2345) AND (z = 8)) LIMIT 1",
301
- "UPDATE attributes SET node_id = 1234, y = 5 WHERE ((id = 2345) AND (z = 8))",
302
- "SELECT * FROM attributes WHERE ((id = 3456) AND (z = 9)) LIMIT 1",
303
- "UPDATE attributes SET node_id = 1234, y = 5 WHERE ((id = 3456) AND (z = 9))",
304
- 'COMMIT'
305
- ]
306
- end
307
-
308
- it "should have remove_*s method respect composite keys" do
309
- @c2.one_to_many :attributes, :class => @c1, :key =>[:node_id, :y], :primary_key=>[:id, :x]
310
-
311
- n = @c2.load(:id => 1234, :x=>5)
312
- a1 = @c1.load(:id => 2345, :node_id=>1234, :y=>5)
313
- a2 = @c1.load(:id => 3456, :node_id=>1234, :y=>5)
314
- n.remove_attributes([a1, a2]).must_equal [a1, a2]
315
- DB.sqls.must_equal [
316
- 'BEGIN',
317
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.y = 5) AND (id = 2345)) LIMIT 1",
318
- "UPDATE attributes SET node_id = NULL, y = NULL WHERE (id = 2345)",
319
- "SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (attributes.y = 5) AND (id = 3456)) LIMIT 1",
320
- "UPDATE attributes SET node_id = NULL, y = NULL WHERE (id = 3456)",
321
- 'COMMIT'
322
- ]
323
- end
324
-
325
- it "should accept a array of composite primary keys values for the remove_*s method and remove existing records" do
326
- @c1.dataset = @c1.dataset.with_fetch([
327
- [{ :id=>234, :node_id=>123, :y=>5 }], [{ :id=>345, :node_id=>123, :y=>6 }]
328
- ])
329
- @c1.set_primary_key [:id, :y]
330
- @c2.one_to_many :attributes, :class => @c1, :key=>:node_id, :primary_key=>:id
331
- n = @c2.new(:id => 123)
332
- n.remove_attributes([[234, 5], [345, 6]]).must_equal [
333
- @c1.load(:node_id => nil, :y => 5, :id => 234),
334
- @c1.load(:node_id => nil, :y => 6, :id => 345)
335
- ]
336
- DB.sqls.must_equal [
337
- 'BEGIN',
338
- "SELECT * FROM attributes WHERE ((attributes.node_id = 123) AND (attributes.id = 234) AND (attributes.y = 5)) LIMIT 1",
339
- "UPDATE attributes SET node_id = NULL WHERE ((id = 234) AND (y = 5))",
340
- "SELECT * FROM attributes WHERE ((attributes.node_id = 123) AND (attributes.id = 345) AND (attributes.y = 6)) LIMIT 1",
341
- "UPDATE attributes SET node_id = NULL WHERE ((id = 345) AND (y = 6))",
342
- 'COMMIT'
343
- ]
344
- end
345
-
346
- it "should raise an error in add_*s and remove_*s if the passed objects return false to save (are not valid)" do
347
- @c2.one_to_many :attributes, :class => @c1
348
- n = @c2.new(:id => 1234)
349
- a1 = @c1.new(:id => 2345)
350
- a2 = @c1.new(:id => 3456)
351
- def a1.validate() errors.add(:id, 'foo') end
352
- def a2.validate() errors.add(:id, 'bar') end
353
- proc{n.add_attributes([a1, a2])}.must_raise(Sequel::ValidationFailed)
354
- proc{n.remove_attributes([a1, a2])}.must_raise(Sequel::ValidationFailed)
355
- end
356
-
357
- it "should not validate the associated objects in add_*s and remove_*s if the :validate=>false option is used" do
358
- @c2.one_to_many :attributes, :class => @c1, :validate=>false
359
- n = @c2.new(:id => 1234)
360
- a1 = @c1.new(:id => 2345)
361
- a2 = @c1.new(:id => 3456)
362
- def a1.validate() errors.add(:id, 'foo') end
363
- def a2.validate() errors.add(:id, 'bar') end
364
- n.add_attributes([a1, a2]).must_equal [a1, a2]
365
- n.remove_attributes([a1, a2]).must_equal [a1, a2]
366
- end
367
-
368
- it "should not raise exception in add_*s and remove_*s if the :raise_on_save_failure=>false option is used" do
369
- @c2.one_to_many :attributes, :class => @c1, :raise_on_save_failure=>false
370
- n = @c2.new(:id => 1234)
371
- a1 = @c1.new(:id => 2345)
372
- a2 = @c1.new(:id => 3456)
373
- def a1.validate() errors.add(:id, 'foo') end
374
- def a2.validate() errors.add(:id, 'bar') end
375
- n.associations[:attributes] = []
376
- n.add_attributes([a1, a2]).must_equal []
377
- n.associations[:attributes].must_equal []
378
- n.remove_attributes([a1, a2]).must_equal []
379
- n.associations[:attributes].must_equal []
380
- end
381
-
382
- it "should add item to cache if it exists when calling add_*s" do
383
- @c2.one_to_many :attributes, :class => @c1
384
- n = @c2.new(:id => 123)
385
- a1 = @c1.load(:id => 234)
386
- a2 = @c1.load(:id => 345)
387
- arr = []
388
- n.associations[:attributes] = arr
389
- n.add_attributes([a1, a2])
390
- arr.must_equal [a1, a2]
391
- end
392
-
393
- it "should set object to item's reciprocal cache when calling add_*s" do
394
- @c2.one_to_many :attributes, :class => @c1
395
- @c1.many_to_one :node, :class => @c2
396
-
397
- n = @c2.new(:id => 123)
398
- a1 = @c1.new(:id => 234)
399
- a2 = @c1.new(:id => 345)
400
- n.add_attributes([a1, a2])
401
- a1.node.must_equal n
402
- a2.node.must_equal n
403
- end
404
-
405
- it "should remove item from cache if it exists when calling remove_*s" do
406
- @c2.one_to_many :attributes, :class => @c1
407
-
408
- n = @c2.load(:id => 123)
409
- a1 = @c1.load(:id => 234)
410
- a2 = @c1.load(:id => 345)
411
- arr = [a1, a2]
412
- n.associations[:attributes] = arr
413
- n.remove_attributes([a1, a2])
414
- arr.must_equal []
415
- end
416
-
417
- it "should remove item's reciprocal cache calling remove_*s" do
418
- @c2.one_to_many :attributes, :class => @c1
419
- @c1.many_to_one :node, :class => @c2
420
-
421
- n = @c2.new(:id => 123)
422
- a1 = @c1.new(:id => 234)
423
- a2 = @c1.new(:id => 345)
424
- a1.associations[:node] = n
425
- a2.associations[:node] = n
426
- a1.node.must_equal n
427
- a2.node.must_equal n
428
- n.remove_attributes([a1, a2])
429
- a1.node.must_be_nil
430
- a2.node.must_be_nil
431
- end
432
-
433
- it "should not create the add_*s or remove_*s methods if :read_only option is used" do
434
- @c2.one_to_many :attributes, :class => @c1, :read_only=>true
435
- im = @c2.instance_methods
436
- im.wont_include(:add_attributes)
437
- im.wont_include(:remove_attributes)
438
- end
439
-
440
- it "should not add associations methods directly to class" do
441
- @c2.one_to_many :attributes, :class => @c1
442
- im = @c2.instance_methods
443
- im.must_include(:add_attributes)
444
- im.must_include(:remove_attributes)
445
- im2 = @c2.instance_methods(false)
446
- im2.wont_include(:add_attributes)
447
- im2.wont_include(:remove_attributes)
448
- end
449
-
450
- it "should call an _add_ method internally to add attributes" do
451
- @c2.one_to_many :attributes, :class => @c1
452
- @c2.private_instance_methods.must_include(:_add_attribute)
453
- p = @c2.load(:id=>10)
454
- c1 = @c1.load(:id=>123)
455
- c2 = @c1.load(:id=>234)
456
- def p._add_attribute(x)
457
- (@x ||= []) << x
458
- end
459
- def c1._node_id=; raise; end
460
- def c2._node_id=; raise; end
461
- p.add_attributes([c1, c2])
462
- p.instance_variable_get(:@x).must_equal [c1, c2]
463
- end
464
-
465
- it "should allow additional arguments given to the add_*s method and pass them onwards to the _add_ method" do
466
- @c2.one_to_many :attributes, :class => @c1
467
- p = @c2.load(:id=>10)
468
- c1 = @c1.load(:id=>123)
469
- c2 = @c1.load(:id=>234)
470
- def p._add_attribute(x,*y)
471
- (@x ||= []) << x
472
- (@y ||= []) << y
473
- end
474
- def c1._node_id=; raise; end
475
- def c2._node_id=; raise; end
476
- p.add_attributes([c1, c2], :foo, :bar=>:baz)
477
- p.instance_variable_get(:@x).must_equal [c1, c2]
478
- p.instance_variable_get(:@y).must_equal [
479
- [:foo,{:bar=>:baz}], [:foo,{:bar=>:baz}]
480
- ]
481
- end
482
-
483
- it "should call a _remove_ method internally to remove attributes" do
484
- @c2.one_to_many :attributes, :class => @c1
485
- @c2.private_instance_methods.must_include(:_remove_attribute)
486
- p = @c2.load(:id=>10)
487
- c1 = @c1.load(:id=>123)
488
- c2 = @c1.load(:id=>234)
489
- def p._remove_attribute(x)
490
- (@x ||= []) << x
491
- end
492
- def c1._node_id=; raise; end
493
- def c2._node_id=; raise; end
494
- p.remove_attributes([c1, c2])
495
- p.instance_variable_get(:@x).must_equal [c1, c2]
496
- end
497
-
498
- it "should allow additional arguments given to the remove_*s method and pass them onwards to the _remove_ method" do
499
- @c2.one_to_many :attributes, :class => @c1, :reciprocal=>nil
500
- p = @c2.load(:id=>10)
501
- c1 = @c1.load(:id=>123)
502
- c2 = @c1.load(:id=>234)
503
- def p._remove_attribute(x,*y)
504
- (@x ||= []) << x
505
- (@y ||= []) << y
506
- end
507
- def c1._node_id=; raise; end
508
- def c2._node_id=; raise; end
509
- p.remove_attributes([c1, c2], :foo, :bar=>:baz)
510
- p.instance_variable_get(:@x).must_equal [c1, c2]
511
- p.instance_variable_get(:@y).must_equal [
512
- [:foo,{:bar=>:baz}], [:foo,{:bar=>:baz}]
513
- ]
514
- end
515
-
516
- it "should support (before|after)_(add|remove) callbacks for (add|remove)_*s methods" do
517
- h = []
518
- @c2.one_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
519
- @c2.class_eval do
520
- self::Foo = h
521
- def _add_attribute(v)
522
- model::Foo << 4
523
- end
524
- def _remove_attribute(v)
525
- model::Foo << 5
526
- end
527
- def blah(x)
528
- model::Foo << x.pk
529
- end
530
- def blahr(x)
531
- model::Foo << 6
532
- end
533
- end
534
- p = @c2.load(:id=>10)
535
- c1 = @c1.load(:id=>123)
536
- c2 = @c1.load(:id=>234)
537
- h.must_equal []
538
- p.add_attributes([c1, c2])
539
- h.must_equal [
540
- 10, -123, 123, 4, 3,
541
- 10, -234, 234, 4, 3
542
- ]
543
- p.remove_attributes([c1, c2])
544
- h.must_equal [
545
- 10, -123, 123, 4, 3,
546
- 10, -234, 234, 4, 3,
547
- 123, 5, 6,
548
- 234, 5, 6
549
- ]
550
- end
551
-
552
- it "should raise error and not call internal add_*s or remove_*s method if before callback calls cancel_action if raise_on_save_failure is true" do
553
- p = @c2.load(:id=>10)
554
- c1 = @c1.load(:id=>123)
555
- c2 = @c1.load(:id=>234)
556
- @c2.one_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
557
- def p.ba(o); cancel_action; end
558
- def p._add_attribute; raise; end
559
- def p._remove_attribute; raise; end
560
- p.associations[:attributes] = []
561
- proc{p.add_attributes([c1, c2])}.must_raise(Sequel::HookFailed)
562
- p.attributes.must_equal []
563
- p.associations[:attributes] = [c1, c2]
564
- def p.br(o); cancel_action; end
565
- proc{p.remove_attributes([c1, c2])}.must_raise(Sequel::HookFailed)
566
- p.attributes.must_equal [c1, c2]
567
- end
568
-
569
- it "should return nil and not call internal add_*s or remove_*s method if before callback calls cancel_action if raise_on_save_failure is false" do
570
- p = @c2.load(:id=>10)
571
- c1 = @c1.load(:id=>123)
572
- c2 = @c1.load(:id=>234)
573
- p.raise_on_save_failure = false
574
- @c2.one_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
575
- def p.ba(o); cancel_action; end
576
- def p._add_attribute; raise; end
577
- def p._remove_attribute; raise; end
578
- p.associations[:attributes] = []
579
- p.add_attributes([c1, c2]).must_equal []
580
- p.attributes.must_equal []
581
- p.associations[:attributes] = [c1, c2]
582
- def p.br(o); cancel_action; end
583
- p.remove_attributes([c1, c2]).must_equal []
584
- p.attributes.must_equal [c1, c2]
585
- end
586
-
587
- it "should define a setter that works on existing records" do
588
- @c2.one_to_many :attributes, class: @c1
589
-
590
- n = @c2.load(id: 1234)
591
- a1 = @c1.load(id: 2345, node_id: 1234)
592
- a2 = @c1.load(id: 3456, node_id: 1234)
593
- a3 = @c1.load(id: 4567)
594
-
595
- n.associations[:attributes] = [a1, a2]
596
-
597
- [a2, a3].must_equal(n.attributes = [a2, a3])
598
- a1.values.must_equal(node_id: nil, id: 2345)
599
- a2.values.must_equal(node_id: 1234, id: 3456)
600
- a3.values.must_equal(node_id: 1234, id: 4567)
601
- DB.sqls.must_equal [
602
- 'BEGIN',
603
- 'SELECT 1 AS one FROM attributes WHERE ((attributes.node_id = 1234) AND (id = 2345)) LIMIT 1',
604
- 'UPDATE attributes SET node_id = NULL WHERE (id = 2345)',
605
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 4567)',
606
- 'COMMIT'
607
- ]
608
- end
609
- end
610
-
611
- describe "association_multi_add_remove plugin - many_to_many" do
612
- before do
613
- @c1 = Class.new(Sequel::Model(:attributes)) do
614
- unrestrict_primary_key
615
- attr_accessor :yyy
616
- def self.name; 'Attribute'; end
617
- def self.to_s; 'Attribute'; end
618
- columns :id, :y, :z
619
- end
620
-
621
- @c2 = Class.new(Sequel::Model(:nodes)) do
622
- unrestrict_primary_key
623
-
624
- plugin :association_multi_add_remove
625
-
626
- attr_accessor :xxx
627
-
628
- def self.name; 'Node'; end
629
- def self.to_s; 'Node'; end
630
- columns :id, :x
631
- end
632
- @dataset = @c2.dataset
633
- @c1.dataset = @c1.dataset.with_autoid(1)
634
-
635
- [@c1, @c2].each{|c| c.dataset = c.dataset.with_fetch({})}
636
- DB.reset
637
- end
638
-
639
- it "should define an add_*s method that works on existing records" do
640
- @c2.many_to_many :attributes, :class => @c1
641
-
642
- n = @c2.load(:id => 1234)
643
- a1 = @c1.load(:id => 2345)
644
- a2 = @c1.load(:id => 3456)
645
- n.add_attributes([a1, a2]).must_equal [a1, a2]
646
- DB.sqls.must_equal [
647
- 'BEGIN',
648
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)",
649
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 3456)",
650
- 'COMMIT'
651
- ]
652
- end
653
-
654
- it "should define an add_*s method that works with a primary key" do
655
- @c2.many_to_many :attributes, :class => @c1
656
-
657
- n = @c2.load(:id => 1234)
658
- a1 = @c1.load(:id => 2345)
659
- a2 = @c1.load(:id => 3456)
660
- @c1.dataset = @c1.dataset.with_fetch([[{ :id=>2345 }], [{ :id=>3456 }]])
661
- n.add_attributes([2345, 3456]).must_equal [a1, a2]
662
- DB.sqls.must_equal [
663
- 'BEGIN',
664
- "SELECT * FROM attributes WHERE id = 2345",
665
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2345)",
666
- "SELECT * FROM attributes WHERE id = 3456",
667
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 3456)",
668
- 'COMMIT'
669
- ]
670
- end
671
-
672
- it "should allow passing hashes to the add_*s method which creates new records" do
673
- @c2.many_to_many :attributes, :class => @c1
674
-
675
- n = @c2.load(:id => 1234)
676
- @c1.dataset = @c1.dataset.with_fetch([[{ :id=>1 }], [{ :id=>2 }]])
677
- n.add_attributes([{ :id => 1 }, { :id => 2 }]).must_equal [
678
- @c1.load(:id => 1), @c1.load(:id => 2)
679
- ]
680
- DB.sqls.must_equal [
681
- 'BEGIN',
682
- 'INSERT INTO attributes (id) VALUES (1)',
683
- "SELECT * FROM attributes WHERE id = 1",
684
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 1)",
685
- 'INSERT INTO attributes (id) VALUES (2)',
686
- "SELECT * FROM attributes WHERE id = 2",
687
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 2)",
688
- 'COMMIT'
689
- ]
690
- end
691
-
692
- it "should define a remove_*s method that works on existing records" do
693
- @c2.many_to_many :attributes, :class => @c1
694
-
695
- n = @c2.new(:id => 1234)
696
- a1 = @c1.new(:id => 2345)
697
- a2 = @c1.new(:id => 3456)
698
- n.remove_attributes([a1, a2]).must_equal [a1, a2]
699
- DB.sqls.must_equal [
700
- 'BEGIN',
701
- 'DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 2345))',
702
- 'DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 3456))',
703
- 'COMMIT'
704
- ]
705
- end
706
-
707
- it "should accept primary keys for the remove_*s method and remove existing records" do
708
- @c2.many_to_many :attributes, :class => @c1
709
- n = @c2.new(:id => 1234)
710
- @c1.dataset = @c1.dataset.with_fetch([[{ :id=>234 }], [{ :id=>345 }]])
711
- n.remove_attributes([234, 345]).must_equal [
712
- @c1.load(:id => 234), @c1.load(:id => 345)
713
- ]
714
- DB.sqls.must_equal [
715
- 'BEGIN',
716
- "SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((attributes_nodes.node_id = 1234) AND (attributes.id = 234)) LIMIT 1",
717
- "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))",
718
- "SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((attributes_nodes.node_id = 1234) AND (attributes.id = 345)) LIMIT 1",
719
- "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 345))",
720
- 'COMMIT'
721
- ]
722
- end
723
-
724
- it "should have the add_*s method respect the :left_primary_key and :right_primary_key options" do
725
- @c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx, :right_primary_key=>:yyy
726
-
727
- n = @c2.load(:id => 1234).set(:xxx=>5)
728
- a1 = @c1.load(:id => 2345).set(:yyy=>8)
729
- a2 = @c1.load(:id => 3456).set(:yyy=>9)
730
- n.add_attributes([a1, a2]).must_equal [a1, a2]
731
- DB.sqls.must_equal [
732
- 'BEGIN',
733
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (5, 8)",
734
- "INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (5, 9)",
735
- 'COMMIT'
736
- ]
737
- end
738
-
739
- it "should have the add_*s method respect composite keys" do
740
- @c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
741
- @c1.dataset = @c1.dataset.with_fetch([
742
- [{ :id=>2345, :z=>8 }], [{ :id=>3456, :z=>9 }]
743
- ])
744
- @c1.set_primary_key [:id, :z]
745
- n = @c2.load(:id => 1234, :x=>5)
746
- a1 = @c1.load(:id => 2345, :z=>8)
747
- a2 = @c1.load(:id => 3456, :z=>9)
748
- n.add_attributes([[2345, 8], [3456, 9]]).must_equal [a1, a2]
749
- DB.sqls.must_equal [
750
- 'BEGIN',
751
- "SELECT * FROM attributes WHERE ((id = 2345) AND (z = 8)) LIMIT 1",
752
- "INSERT INTO attributes_nodes (l1, l2, r1, r2) VALUES (1234, 5, 2345, 8)",
753
- "SELECT * FROM attributes WHERE ((id = 3456) AND (z = 9)) LIMIT 1",
754
- "INSERT INTO attributes_nodes (l1, l2, r1, r2) VALUES (1234, 5, 3456, 9)",
755
- 'COMMIT'
756
- ]
757
- end
758
-
759
- it "should have the remove_*s method respect the :left_primary_key and :right_primary_key options" do
760
- @c2.many_to_many :attributes, :class => @c1, :left_primary_key=>:xxx, :right_primary_key=>:yyy
761
-
762
- n = @c2.new(:id => 1234, :xxx=>5)
763
- a1 = @c1.new(:id => 2345, :yyy=>8)
764
- a2 = @c1.new(:id => 3456, :yyy=>9)
765
- n.remove_attributes([a1, a2]).must_equal [a1, a2]
766
- DB.sqls.must_equal [
767
- 'BEGIN',
768
- 'DELETE FROM attributes_nodes WHERE ((node_id = 5) AND (attribute_id = 8))',
769
- 'DELETE FROM attributes_nodes WHERE ((node_id = 5) AND (attribute_id = 9))',
770
- 'COMMIT'
771
- ]
772
- end
773
-
774
- it "should have the remove_*s method respect composite keys" do
775
- @c2.many_to_many :attributes, :class => @c1, :left_key=>[:l1, :l2], :right_key=>[:r1, :r2], :left_primary_key=>[:id, :x], :right_primary_key=>[:id, :z]
776
- n = @c2.load(:id => 1234, :x=>5)
777
- a1 = @c1.load(:id => 2345, :z=>8)
778
- a2 = @c1.load(:id => 3456, :z=>9)
779
- [a1, a2].must_equal n.remove_attributes([a1, a2])
780
- DB.sqls.must_equal [
781
- 'BEGIN',
782
- "DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5) AND (r1 = 2345) AND (r2 = 8))",
783
- "DELETE FROM attributes_nodes WHERE ((l1 = 1234) AND (l2 = 5) AND (r1 = 3456) AND (r2 = 9))",
784
- 'COMMIT'
785
- ]
786
- end
787
-
788
- it "should accept an array of arrays of composite primary key values for the remove_*s method and remove existing records" do
789
- @c1.dataset = @c1.dataset.with_fetch([
790
- [{ :id=>234, :y=>8 }], [{ :id=>345, :y=>9 }]
791
- ])
792
- @c1.set_primary_key [:id, :y]
793
- @c2.many_to_many :attributes, :class => @c1
794
- n = @c2.new(:id => 1234)
795
- n.remove_attributes([[234, 8], [345, 9]]).must_equal [
796
- @c1.load(:id => 234, :y=>8), @c1.load(:id => 345, :y=>9)
797
- ]
798
- DB.sqls.must_equal [
799
- 'BEGIN',
800
- "SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((attributes_nodes.node_id = 1234) AND (attributes.id = 234) AND (attributes.y = 8)) LIMIT 1",
801
- "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 234))",
802
- "SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON (attributes_nodes.attribute_id = attributes.id) WHERE ((attributes_nodes.node_id = 1234) AND (attributes.id = 345) AND (attributes.y = 9)) LIMIT 1",
803
- "DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 345))",
804
- 'COMMIT'
805
- ]
806
- end
807
-
808
- it "should raise an error if trying to remove model objects that don't have valid primary keys" do
809
- @c2.many_to_many :attributes, :class => @c1
810
- n = @c2.new
811
- a1 = @c1.load(:id=>123)
812
- a2 = @c1.load(:id=>234)
813
- proc { n.remove_attributes([a1, a2]) }.must_raise(Sequel::Error)
814
- end
815
-
816
- it "should remove items from cache if they exist when calling remove_*s" do
817
- @c2.many_to_many :attributes, :class => @c1
818
-
819
- n = @c2.new(:id => 1234)
820
- a1 = @c1.load(:id => 345)
821
- a2 = @c1.load(:id => 456)
822
- arr = [a1, a2]
823
- n.associations[:attributes] = arr
824
- n.remove_attributes([a1, a2])
825
- arr.must_equal []
826
- end
827
-
828
- it "should remove items from reciprocal's if they exist when calling remove_*s" do
829
- @c2.many_to_many :attributes, :class => @c1
830
- @c1.many_to_many :nodes, :class => @c2
831
-
832
- n = @c2.new(:id => 1234)
833
- a1 = @c1.new(:id => 345)
834
- a2 = @c1.new(:id => 456)
835
- a1.associations[:nodes] = [n]
836
- a2.associations[:nodes] = [n]
837
- n.remove_attributes([a1, a2])
838
- a1.nodes.must_equal []
839
- a2.nodes.must_equal []
840
- end
841
-
842
- it "should not create the add_*s or remove_*s methods if :read_only option is used" do
843
- @c2.many_to_many :attributes, :class => @c1, :read_only=>true
844
- im = @c2.instance_methods
845
- im.wont_include(:add_attributes)
846
- im.wont_include(:remove_attributes)
847
- end
848
-
849
- it "should not add associations methods directly to class" do
850
- @c2.many_to_many :attributes, :class => @c1
851
- im = @c2.instance_methods
852
- im.must_include(:add_attributes)
853
- im.must_include(:remove_attributes)
854
- im2 = @c2.instance_methods(false)
855
- im2.wont_include(:add_attributes)
856
- im2.wont_include(:remove_attributes)
857
- end
858
-
859
- it "should call a _remove_*s method internally to remove attributes" do
860
- @c2.many_to_many :attributes, :class => @c1
861
- @c2.private_instance_methods.must_include(:_remove_attribute)
862
- p = @c2.load(:id=>10)
863
- c1 = @c1.load(:id=>123)
864
- c2 = @c1.load(:id=>234)
865
- def p._remove_attribute(x)
866
- (@x ||= []) << x
867
- end
868
- p.remove_attributes([c1, c2])
869
- p.instance_variable_get(:@x).must_equal [c1, c2]
870
- DB.sqls.must_equal ['BEGIN', 'COMMIT']
871
- end
872
-
873
- it "should support a :remover option for defining the _remove_*s method" do
874
- @c2.many_to_many :attributes, :class => @c1,
875
- :remover=>proc { |x| (@x ||= []) << x }
876
- p = @c2.load(:id=>10)
877
- c1 = @c1.load(:id=>123)
878
- c2 = @c1.load(:id=>234)
879
- p.remove_attributes([c1, c2])
880
- p.instance_variable_get(:@x).must_equal [c1, c2]
881
- DB.sqls.must_equal ['BEGIN', 'COMMIT']
882
- end
883
-
884
- it "should allow additional arguments given to the remove_*s method and pass them onwards to the _remove_ method" do
885
- @c2.many_to_many :attributes, :class => @c1
886
- p = @c2.load(:id=>10)
887
- c1 = @c1.load(:id=>123)
888
- c2 = @c1.load(:id=>234)
889
- def p._remove_attribute(x,*y)
890
- (@x ||= []) << x
891
- (@y ||= []) << y
892
- end
893
- p.remove_attributes([c1, c2], :foo, :bar=>:baz)
894
- p.instance_variable_get(:@x).must_equal [c1, c2]
895
- p.instance_variable_get(:@y).must_equal [
896
- [:foo, { :bar=>:baz }], [:foo, { :bar=>:baz }]
897
- ]
898
- end
899
-
900
- it "should raise an error in the remove_*s method if the passed associated objects are not of the correct type" do
901
- @c2.many_to_many :attributes, :class => @c1
902
- proc do
903
- @c2.new(:id => 1234).remove_attributes([@c2.new, @c2.new])
904
- end
905
- .must_raise(Sequel::Error)
906
- end
907
-
908
- it "should support (before|after)_(add|remove) callbacks for (add|remove)_* methods" do
909
- h = []
910
- @c2.many_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
911
- @c2.class_eval do
912
- self::Foo = h
913
- def _add_attribute(v)
914
- model::Foo << 4
915
- end
916
- def _remove_attribute(v)
917
- model::Foo << 5
918
- end
919
- def blah(x)
920
- model::Foo << x.pk
921
- end
922
- def blahr(x)
923
- model::Foo << 6
924
- end
925
- end
926
- p = @c2.load(:id=>10)
927
- c1 = @c1.load(:id=>123)
928
- c2 = @c1.load(:id=>234)
929
- h.must_equal []
930
- p.add_attributes([c1, c2])
931
- h.must_equal [
932
- 10, -123, 123, 4, 3,
933
- 10, -234, 234, 4, 3
934
- ]
935
- p.remove_attributes([c1, c2])
936
- h.must_equal [
937
- 10, -123, 123, 4, 3,
938
- 10, -234, 234, 4, 3,
939
- 123, 5, 6,
940
- 234, 5, 6
941
- ]
942
- end
943
-
944
- it "should raise error and not call internal add_*s or remove_*s method if before callback calls cancel_action if raise_on_save_failure is true" do
945
- p = @c2.load(:id=>10)
946
- c1 = @c1.load(:id=>123)
947
- c2 = @c1.load(:id=>234)
948
- @c2.many_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
949
- def p.ba(o) cancel_action end
950
- def p._add_attribute; raise; end
951
- def p._remove_attribute; raise; end
952
- p.associations[:attributes] = []
953
- p.raise_on_save_failure = true
954
- proc{p.add_attributes([c1, c2])}.must_raise(Sequel::HookFailed)
955
- p.attributes.must_equal []
956
- p.associations[:attributes] = [c1, c2]
957
- def p.br(o) cancel_action end
958
- proc { p.remove_attributes([c1, c2]) }.must_raise(Sequel::HookFailed)
959
- p.attributes.must_equal [c1, c2]
960
- end
961
-
962
- it "should return nil and not call internal add_*s or remove_*s method if before callback calls cancel_action if raise_on_save_failure is false" do
963
- p = @c2.load(:id=>10)
964
- c1 = @c1.load(:id=>123)
965
- c2 = @c1.load(:id=>234)
966
- p.raise_on_save_failure = false
967
- @c2.many_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
968
- def p.ba(o) cancel_action end
969
- def p._add_attribute; raise; end
970
- def p._remove_attribute; raise; end
971
- p.associations[:attributes] = []
972
- p.add_attributes([c1, c2]).must_equal []
973
- p.attributes.must_equal []
974
- p.associations[:attributes] = [c1, c2]
975
- def p.br(o) cancel_action end
976
- p.remove_attributes([c1, c2]).must_equal []
977
- p.attributes.must_equal [c1, c2]
978
- end
979
-
980
- it "should define a setter that works on existing records" do
981
- @c2.many_to_many :attributes, class: @c1
982
-
983
- n = @c2.load(id: 1234)
984
- a1 = @c1.load(id: 2345)
985
- a2 = @c1.load(id: 3456)
986
- a3 = @c1.load(id: 4567)
987
-
988
- n.associations[:attributes] = [a1, a2]
989
-
990
- [a2, a3].must_equal(n.attributes = [a2, a3])
991
- DB.sqls.must_equal [
992
- 'BEGIN',
993
- 'DELETE FROM attributes_nodes WHERE ((node_id = 1234) AND (attribute_id = 2345))',
994
- 'INSERT INTO attributes_nodes (node_id, attribute_id) VALUES (1234, 4567)',
995
- 'COMMIT'
996
- ]
997
- end
998
- end
999
-
1000
- describe "association_multi_add_remove plugin - sharding" do
1001
- before do
1002
- @db = Sequel.mock(:servers=>{:a=>{}}, :numrows=>1)
1003
- @c1 = Class.new(Sequel::Model(@db[:attributes])) do
1004
- unrestrict_primary_key
1005
- columns :id, :node_id, :y, :z
1006
- end
1007
-
1008
- @c2 = Class.new(Sequel::Model(@db[:nodes])) do
1009
- plugin :association_multi_add_remove
1010
-
1011
- def _refresh(ds); end
1012
- unrestrict_primary_key
1013
- attr_accessor :xxx
1014
-
1015
- def self.name; 'Node'; end
1016
- def self.to_s; 'Node'; end
1017
-
1018
- columns :id, :x
1019
- end
1020
- @dataset = @c2.dataset = @c2.dataset.with_fetch({})
1021
- @c1.dataset = @c1.dataset.with_fetch(proc { |sql| sql =~ /SELECT 1/ ? { a: 1 } : {} })
1022
- @db.sqls
1023
- end
1024
-
1025
- it "should handle servers correctly" do
1026
- @c2.one_to_many :attributes, class: @c1
1027
-
1028
- n = @c2.load(id: 1234).set_server(:a)
1029
- a1 = @c1.load(id: 2345).set_server(:a)
1030
- a2 = @c1.load(id: 3456).set_server(:a)
1031
- [a1, a2].must_equal n.add_attributes([a1, a2])
1032
- a1.values.must_equal(:node_id => 1234, id: 2345)
1033
- a2.values.must_equal(:node_id => 1234, id: 3456)
1034
- @db.sqls.must_equal [
1035
- 'BEGIN -- a',
1036
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 2345) -- a',
1037
- 'UPDATE attributes SET node_id = 1234 WHERE (id = 3456) -- a',
1038
- 'COMMIT -- a'
1039
- ]
1040
- end
1041
- end