sequel 4.26.0 → 5.37.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 (692) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +405 -5656
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +232 -157
  5. data/bin/sequel +32 -9
  6. data/doc/advanced_associations.rdoc +252 -188
  7. data/doc/association_basics.rdoc +231 -273
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +75 -48
  10. data/doc/code_order.rdoc +28 -10
  11. data/doc/core_extensions.rdoc +104 -63
  12. data/doc/dataset_basics.rdoc +12 -21
  13. data/doc/dataset_filtering.rdoc +99 -86
  14. data/doc/extensions.rdoc +3 -10
  15. data/doc/mass_assignment.rdoc +74 -31
  16. data/doc/migration.rdoc +72 -46
  17. data/doc/model_dataset_method_design.rdoc +129 -0
  18. data/doc/model_hooks.rdoc +15 -25
  19. data/doc/model_plugins.rdoc +12 -12
  20. data/doc/mssql_stored_procedures.rdoc +3 -3
  21. data/doc/object_model.rdoc +59 -69
  22. data/doc/opening_databases.rdoc +84 -94
  23. data/doc/postgresql.rdoc +268 -38
  24. data/doc/prepared_statements.rdoc +29 -24
  25. data/doc/querying.rdoc +184 -164
  26. data/doc/reflection.rdoc +5 -6
  27. data/doc/release_notes/5.0.0.txt +159 -0
  28. data/doc/release_notes/5.1.0.txt +31 -0
  29. data/doc/release_notes/5.10.0.txt +84 -0
  30. data/doc/release_notes/5.11.0.txt +83 -0
  31. data/doc/release_notes/5.12.0.txt +141 -0
  32. data/doc/release_notes/5.13.0.txt +27 -0
  33. data/doc/release_notes/5.14.0.txt +63 -0
  34. data/doc/release_notes/5.15.0.txt +39 -0
  35. data/doc/release_notes/5.16.0.txt +110 -0
  36. data/doc/release_notes/5.17.0.txt +31 -0
  37. data/doc/release_notes/5.18.0.txt +69 -0
  38. data/doc/release_notes/5.19.0.txt +28 -0
  39. data/doc/release_notes/5.2.0.txt +33 -0
  40. data/doc/release_notes/5.20.0.txt +89 -0
  41. data/doc/release_notes/5.21.0.txt +87 -0
  42. data/doc/release_notes/5.22.0.txt +48 -0
  43. data/doc/release_notes/5.23.0.txt +56 -0
  44. data/doc/release_notes/5.24.0.txt +56 -0
  45. data/doc/release_notes/5.25.0.txt +32 -0
  46. data/doc/release_notes/5.26.0.txt +35 -0
  47. data/doc/release_notes/5.27.0.txt +21 -0
  48. data/doc/release_notes/5.28.0.txt +16 -0
  49. data/doc/release_notes/5.29.0.txt +22 -0
  50. data/doc/release_notes/5.3.0.txt +121 -0
  51. data/doc/release_notes/5.30.0.txt +20 -0
  52. data/doc/release_notes/5.31.0.txt +148 -0
  53. data/doc/release_notes/5.32.0.txt +46 -0
  54. data/doc/release_notes/5.33.0.txt +24 -0
  55. data/doc/release_notes/5.34.0.txt +40 -0
  56. data/doc/release_notes/5.35.0.txt +56 -0
  57. data/doc/release_notes/5.36.0.txt +60 -0
  58. data/doc/release_notes/5.37.0.txt +30 -0
  59. data/doc/release_notes/5.4.0.txt +80 -0
  60. data/doc/release_notes/5.5.0.txt +61 -0
  61. data/doc/release_notes/5.6.0.txt +31 -0
  62. data/doc/release_notes/5.7.0.txt +108 -0
  63. data/doc/release_notes/5.8.0.txt +170 -0
  64. data/doc/release_notes/5.9.0.txt +99 -0
  65. data/doc/schema_modification.rdoc +102 -77
  66. data/doc/security.rdoc +160 -87
  67. data/doc/sharding.rdoc +74 -47
  68. data/doc/sql.rdoc +135 -122
  69. data/doc/testing.rdoc +34 -18
  70. data/doc/thread_safety.rdoc +2 -4
  71. data/doc/transactions.rdoc +101 -19
  72. data/doc/validations.rdoc +64 -51
  73. data/doc/virtual_rows.rdoc +90 -109
  74. data/lib/sequel.rb +3 -1
  75. data/lib/sequel/adapters/ado.rb +154 -22
  76. data/lib/sequel/adapters/ado/access.rb +21 -21
  77. data/lib/sequel/adapters/ado/mssql.rb +8 -15
  78. data/lib/sequel/adapters/amalgalite.rb +17 -25
  79. data/lib/sequel/adapters/ibmdb.rb +52 -58
  80. data/lib/sequel/adapters/jdbc.rb +149 -127
  81. data/lib/sequel/adapters/jdbc/db2.rb +32 -40
  82. data/lib/sequel/adapters/jdbc/derby.rb +56 -58
  83. data/lib/sequel/adapters/jdbc/h2.rb +40 -30
  84. data/lib/sequel/adapters/jdbc/hsqldb.rb +22 -33
  85. data/lib/sequel/adapters/jdbc/jtds.rb +4 -10
  86. data/lib/sequel/adapters/jdbc/mssql.rb +6 -12
  87. data/lib/sequel/adapters/jdbc/mysql.rb +17 -18
  88. data/lib/sequel/adapters/jdbc/oracle.rb +25 -19
  89. data/lib/sequel/adapters/jdbc/postgresql.rb +90 -69
  90. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +14 -24
  91. data/lib/sequel/adapters/jdbc/sqlite.rb +50 -12
  92. data/lib/sequel/adapters/jdbc/sqlserver.rb +36 -9
  93. data/lib/sequel/adapters/jdbc/transactions.rb +25 -39
  94. data/lib/sequel/adapters/mock.rb +104 -113
  95. data/lib/sequel/adapters/mysql.rb +42 -61
  96. data/lib/sequel/adapters/mysql2.rb +126 -35
  97. data/lib/sequel/adapters/odbc.rb +21 -28
  98. data/lib/sequel/adapters/odbc/db2.rb +3 -1
  99. data/lib/sequel/adapters/odbc/mssql.rb +11 -15
  100. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  101. data/lib/sequel/adapters/oracle.rb +62 -68
  102. data/lib/sequel/adapters/postgres.rb +257 -311
  103. data/lib/sequel/adapters/postgresql.rb +3 -1
  104. data/lib/sequel/adapters/shared/access.rb +75 -79
  105. data/lib/sequel/adapters/shared/db2.rb +96 -74
  106. data/lib/sequel/adapters/shared/mssql.rb +258 -213
  107. data/lib/sequel/adapters/shared/mysql.rb +284 -216
  108. data/lib/sequel/adapters/shared/oracle.rb +175 -60
  109. data/lib/sequel/adapters/shared/postgres.rb +829 -383
  110. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -127
  111. data/lib/sequel/adapters/shared/sqlite.rb +382 -159
  112. data/lib/sequel/adapters/sqlanywhere.rb +53 -38
  113. data/lib/sequel/adapters/sqlite.rb +111 -105
  114. data/lib/sequel/adapters/tinytds.rb +38 -46
  115. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +8 -9
  116. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +7 -5
  117. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  118. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  119. data/lib/sequel/adapters/utils/replace.rb +3 -4
  120. data/lib/sequel/adapters/utils/split_alter_table.rb +2 -0
  121. data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
  122. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  123. data/lib/sequel/ast_transformer.rb +13 -89
  124. data/lib/sequel/connection_pool.rb +54 -26
  125. data/lib/sequel/connection_pool/sharded_single.rb +19 -12
  126. data/lib/sequel/connection_pool/sharded_threaded.rb +160 -111
  127. data/lib/sequel/connection_pool/single.rb +21 -12
  128. data/lib/sequel/connection_pool/threaded.rb +137 -119
  129. data/lib/sequel/core.rb +352 -320
  130. data/lib/sequel/database.rb +19 -2
  131. data/lib/sequel/database/connecting.rb +70 -55
  132. data/lib/sequel/database/dataset.rb +15 -5
  133. data/lib/sequel/database/dataset_defaults.rb +20 -102
  134. data/lib/sequel/database/features.rb +20 -4
  135. data/lib/sequel/database/logging.rb +25 -7
  136. data/lib/sequel/database/misc.rb +132 -118
  137. data/lib/sequel/database/query.rb +51 -28
  138. data/lib/sequel/database/schema_generator.rb +188 -75
  139. data/lib/sequel/database/schema_methods.rb +161 -92
  140. data/lib/sequel/database/transactions.rb +260 -58
  141. data/lib/sequel/dataset.rb +28 -12
  142. data/lib/sequel/dataset/actions.rb +354 -170
  143. data/lib/sequel/dataset/dataset_module.rb +46 -0
  144. data/lib/sequel/dataset/features.rb +81 -34
  145. data/lib/sequel/dataset/graph.rb +82 -58
  146. data/lib/sequel/dataset/misc.rb +139 -47
  147. data/lib/sequel/dataset/placeholder_literalizer.rb +66 -26
  148. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  149. data/lib/sequel/dataset/query.rb +428 -214
  150. data/lib/sequel/dataset/sql.rb +446 -339
  151. data/lib/sequel/deprecated.rb +14 -2
  152. data/lib/sequel/exceptions.rb +48 -16
  153. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  154. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  155. data/lib/sequel/extensions/_pretty_table.rb +10 -9
  156. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  157. data/lib/sequel/extensions/arbitrary_servers.rb +15 -11
  158. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  159. data/lib/sequel/extensions/blank.rb +2 -0
  160. data/lib/sequel/extensions/caller_logging.rb +79 -0
  161. data/lib/sequel/extensions/columns_introspection.rb +9 -4
  162. data/lib/sequel/extensions/connection_expiration.rb +99 -0
  163. data/lib/sequel/extensions/connection_validator.rb +26 -13
  164. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  165. data/lib/sequel/extensions/constraint_validations.rb +93 -38
  166. data/lib/sequel/extensions/core_extensions.rb +45 -53
  167. data/lib/sequel/extensions/core_refinements.rb +44 -46
  168. data/lib/sequel/extensions/current_datetime_timestamp.rb +5 -4
  169. data/lib/sequel/extensions/dataset_source_alias.rb +4 -0
  170. data/lib/sequel/extensions/date_arithmetic.rb +42 -16
  171. data/lib/sequel/extensions/datetime_parse_to_time.rb +37 -0
  172. data/lib/sequel/extensions/duplicate_columns_handler.rb +94 -0
  173. data/lib/sequel/extensions/empty_array_consider_nulls.rb +7 -3
  174. data/lib/sequel/extensions/error_sql.rb +7 -3
  175. data/lib/sequel/extensions/escaped_like.rb +100 -0
  176. data/lib/sequel/extensions/eval_inspect.rb +14 -15
  177. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  178. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  179. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  180. data/lib/sequel/extensions/from_block.rb +2 -31
  181. data/lib/sequel/extensions/graph_each.rb +19 -6
  182. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  183. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  184. data/lib/sequel/extensions/index_caching.rb +109 -0
  185. data/lib/sequel/extensions/inflector.rb +8 -4
  186. data/lib/sequel/extensions/integer64.rb +32 -0
  187. data/lib/sequel/extensions/looser_typecasting.rb +19 -9
  188. data/lib/sequel/extensions/migration.rb +132 -80
  189. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +4 -0
  190. data/lib/sequel/extensions/named_timezones.rb +88 -23
  191. data/lib/sequel/extensions/no_auto_literal_strings.rb +4 -0
  192. data/lib/sequel/extensions/null_dataset.rb +12 -8
  193. data/lib/sequel/extensions/pagination.rb +35 -28
  194. data/lib/sequel/extensions/pg_array.rb +227 -316
  195. data/lib/sequel/extensions/pg_array_ops.rb +19 -7
  196. data/lib/sequel/extensions/pg_enum.rb +69 -24
  197. data/lib/sequel/extensions/pg_extended_date_support.rb +250 -0
  198. data/lib/sequel/extensions/pg_hstore.rb +50 -59
  199. data/lib/sequel/extensions/pg_hstore_ops.rb +9 -3
  200. data/lib/sequel/extensions/pg_inet.rb +34 -15
  201. data/lib/sequel/extensions/pg_inet_ops.rb +5 -1
  202. data/lib/sequel/extensions/pg_interval.rb +26 -26
  203. data/lib/sequel/extensions/pg_json.rb +422 -141
  204. data/lib/sequel/extensions/pg_json_ops.rb +248 -9
  205. data/lib/sequel/extensions/pg_loose_count.rb +5 -1
  206. data/lib/sequel/extensions/pg_range.rb +162 -146
  207. data/lib/sequel/extensions/pg_range_ops.rb +10 -5
  208. data/lib/sequel/extensions/pg_row.rb +53 -87
  209. data/lib/sequel/extensions/pg_row_ops.rb +36 -13
  210. data/lib/sequel/extensions/pg_static_cache_updater.rb +6 -2
  211. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  212. data/lib/sequel/extensions/pretty_table.rb +4 -0
  213. data/lib/sequel/extensions/query.rb +12 -7
  214. data/lib/sequel/extensions/round_timestamps.rb +6 -9
  215. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  216. data/lib/sequel/extensions/s.rb +59 -0
  217. data/lib/sequel/extensions/schema_caching.rb +14 -1
  218. data/lib/sequel/extensions/schema_dumper.rb +83 -55
  219. data/lib/sequel/extensions/select_remove.rb +8 -4
  220. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  221. data/lib/sequel/extensions/server_block.rb +50 -17
  222. data/lib/sequel/extensions/server_logging.rb +61 -0
  223. data/lib/sequel/extensions/split_array_nil.rb +8 -4
  224. data/lib/sequel/extensions/sql_comments.rb +96 -0
  225. data/lib/sequel/extensions/sql_expr.rb +4 -1
  226. data/lib/sequel/extensions/string_agg.rb +181 -0
  227. data/lib/sequel/extensions/string_date_time.rb +2 -0
  228. data/lib/sequel/extensions/symbol_aref.rb +53 -0
  229. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  230. data/lib/sequel/extensions/symbol_as.rb +23 -0
  231. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  232. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  233. data/lib/sequel/extensions/thread_local_timezones.rb +4 -0
  234. data/lib/sequel/extensions/to_dot.rb +15 -5
  235. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  236. data/lib/sequel/model.rb +36 -126
  237. data/lib/sequel/model/associations.rb +850 -257
  238. data/lib/sequel/model/base.rb +652 -764
  239. data/lib/sequel/model/dataset_module.rb +13 -10
  240. data/lib/sequel/model/default_inflections.rb +3 -1
  241. data/lib/sequel/model/errors.rb +3 -3
  242. data/lib/sequel/model/exceptions.rb +12 -12
  243. data/lib/sequel/model/inflections.rb +8 -19
  244. data/lib/sequel/model/plugins.rb +111 -0
  245. data/lib/sequel/plugins/accessed_columns.rb +2 -0
  246. data/lib/sequel/plugins/active_model.rb +32 -7
  247. data/lib/sequel/plugins/after_initialize.rb +3 -1
  248. data/lib/sequel/plugins/association_dependencies.rb +27 -18
  249. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  250. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  251. data/lib/sequel/plugins/association_pks.rb +181 -83
  252. data/lib/sequel/plugins/association_proxies.rb +33 -9
  253. data/lib/sequel/plugins/auto_validations.rb +58 -23
  254. data/lib/sequel/plugins/before_after_save.rb +8 -0
  255. data/lib/sequel/plugins/blacklist_security.rb +23 -12
  256. data/lib/sequel/plugins/boolean_readers.rb +9 -6
  257. data/lib/sequel/plugins/boolean_subsets.rb +64 -0
  258. data/lib/sequel/plugins/caching.rb +27 -16
  259. data/lib/sequel/plugins/class_table_inheritance.rb +192 -94
  260. data/lib/sequel/plugins/column_conflicts.rb +18 -3
  261. data/lib/sequel/plugins/column_select.rb +9 -5
  262. data/lib/sequel/plugins/columns_updated.rb +42 -0
  263. data/lib/sequel/plugins/composition.rb +36 -24
  264. data/lib/sequel/plugins/constraint_validations.rb +37 -16
  265. data/lib/sequel/plugins/csv_serializer.rb +58 -35
  266. data/lib/sequel/plugins/dataset_associations.rb +60 -18
  267. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  268. data/lib/sequel/plugins/defaults_setter.rb +74 -13
  269. data/lib/sequel/plugins/delay_add_association.rb +4 -1
  270. data/lib/sequel/plugins/dirty.rb +65 -24
  271. data/lib/sequel/plugins/eager_each.rb +27 -3
  272. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  273. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  274. data/lib/sequel/plugins/error_splitter.rb +19 -12
  275. data/lib/sequel/plugins/finder.rb +246 -0
  276. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  277. data/lib/sequel/plugins/force_encoding.rb +9 -12
  278. data/lib/sequel/plugins/hook_class_methods.rb +39 -54
  279. data/lib/sequel/plugins/input_transformer.rb +20 -10
  280. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  281. data/lib/sequel/plugins/insert_returning_select.rb +4 -2
  282. data/lib/sequel/plugins/instance_filters.rb +12 -8
  283. data/lib/sequel/plugins/instance_hooks.rb +36 -17
  284. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  285. data/lib/sequel/plugins/inverted_subsets.rb +24 -13
  286. data/lib/sequel/plugins/json_serializer.rb +123 -47
  287. data/lib/sequel/plugins/lazy_attributes.rb +20 -14
  288. data/lib/sequel/plugins/list.rb +40 -26
  289. data/lib/sequel/plugins/many_through_many.rb +28 -12
  290. data/lib/sequel/plugins/modification_detection.rb +17 -5
  291. data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -5
  292. data/lib/sequel/plugins/nested_attributes.rb +55 -28
  293. data/lib/sequel/plugins/optimistic_locking.rb +5 -3
  294. data/lib/sequel/plugins/pg_array_associations.rb +52 -18
  295. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +348 -0
  296. data/lib/sequel/plugins/pg_row.rb +7 -51
  297. data/lib/sequel/plugins/prepared_statements.rb +53 -72
  298. data/lib/sequel/plugins/prepared_statements_safe.rb +13 -5
  299. data/lib/sequel/plugins/rcte_tree.rb +43 -63
  300. data/lib/sequel/plugins/serialization.rb +37 -44
  301. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -1
  302. data/lib/sequel/plugins/sharding.rb +17 -10
  303. data/lib/sequel/plugins/single_table_inheritance.rb +62 -28
  304. data/lib/sequel/plugins/singular_table_names.rb +2 -0
  305. data/lib/sequel/plugins/skip_create_refresh.rb +5 -3
  306. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  307. data/lib/sequel/plugins/split_values.rb +13 -6
  308. data/lib/sequel/plugins/static_cache.rb +79 -53
  309. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  310. data/lib/sequel/plugins/string_stripper.rb +5 -3
  311. data/lib/sequel/plugins/subclasses.rb +20 -2
  312. data/lib/sequel/plugins/subset_conditions.rb +48 -0
  313. data/lib/sequel/plugins/table_select.rb +4 -2
  314. data/lib/sequel/plugins/tactical_eager_loading.rb +120 -6
  315. data/lib/sequel/plugins/throw_failures.rb +110 -0
  316. data/lib/sequel/plugins/timestamps.rb +22 -8
  317. data/lib/sequel/plugins/touch.rb +21 -8
  318. data/lib/sequel/plugins/tree.rb +57 -30
  319. data/lib/sequel/plugins/typecast_on_load.rb +14 -4
  320. data/lib/sequel/plugins/unlimited_update.rb +3 -7
  321. data/lib/sequel/plugins/update_or_create.rb +6 -4
  322. data/lib/sequel/plugins/update_primary_key.rb +3 -1
  323. data/lib/sequel/plugins/update_refresh.rb +28 -15
  324. data/lib/sequel/plugins/uuid.rb +70 -0
  325. data/lib/sequel/plugins/validate_associated.rb +20 -0
  326. data/lib/sequel/plugins/validation_class_methods.rb +40 -19
  327. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  328. data/lib/sequel/plugins/validation_helpers.rb +49 -31
  329. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  330. data/lib/sequel/plugins/xml_serializer.rb +31 -30
  331. data/lib/sequel/sql.rb +479 -329
  332. data/lib/sequel/timezones.rb +62 -32
  333. data/lib/sequel/version.rb +10 -3
  334. metadata +177 -477
  335. data/Rakefile +0 -165
  336. data/doc/active_record.rdoc +0 -912
  337. data/doc/release_notes/1.0.txt +0 -38
  338. data/doc/release_notes/1.1.txt +0 -143
  339. data/doc/release_notes/1.3.txt +0 -101
  340. data/doc/release_notes/1.4.0.txt +0 -53
  341. data/doc/release_notes/1.5.0.txt +0 -155
  342. data/doc/release_notes/2.0.0.txt +0 -298
  343. data/doc/release_notes/2.1.0.txt +0 -271
  344. data/doc/release_notes/2.10.0.txt +0 -328
  345. data/doc/release_notes/2.11.0.txt +0 -215
  346. data/doc/release_notes/2.12.0.txt +0 -534
  347. data/doc/release_notes/2.2.0.txt +0 -253
  348. data/doc/release_notes/2.3.0.txt +0 -88
  349. data/doc/release_notes/2.4.0.txt +0 -106
  350. data/doc/release_notes/2.5.0.txt +0 -137
  351. data/doc/release_notes/2.6.0.txt +0 -157
  352. data/doc/release_notes/2.7.0.txt +0 -166
  353. data/doc/release_notes/2.8.0.txt +0 -171
  354. data/doc/release_notes/2.9.0.txt +0 -97
  355. data/doc/release_notes/3.0.0.txt +0 -221
  356. data/doc/release_notes/3.1.0.txt +0 -406
  357. data/doc/release_notes/3.10.0.txt +0 -286
  358. data/doc/release_notes/3.11.0.txt +0 -254
  359. data/doc/release_notes/3.12.0.txt +0 -304
  360. data/doc/release_notes/3.13.0.txt +0 -210
  361. data/doc/release_notes/3.14.0.txt +0 -118
  362. data/doc/release_notes/3.15.0.txt +0 -78
  363. data/doc/release_notes/3.16.0.txt +0 -45
  364. data/doc/release_notes/3.17.0.txt +0 -58
  365. data/doc/release_notes/3.18.0.txt +0 -120
  366. data/doc/release_notes/3.19.0.txt +0 -67
  367. data/doc/release_notes/3.2.0.txt +0 -268
  368. data/doc/release_notes/3.20.0.txt +0 -41
  369. data/doc/release_notes/3.21.0.txt +0 -87
  370. data/doc/release_notes/3.22.0.txt +0 -39
  371. data/doc/release_notes/3.23.0.txt +0 -172
  372. data/doc/release_notes/3.24.0.txt +0 -420
  373. data/doc/release_notes/3.25.0.txt +0 -88
  374. data/doc/release_notes/3.26.0.txt +0 -88
  375. data/doc/release_notes/3.27.0.txt +0 -82
  376. data/doc/release_notes/3.28.0.txt +0 -304
  377. data/doc/release_notes/3.29.0.txt +0 -459
  378. data/doc/release_notes/3.3.0.txt +0 -192
  379. data/doc/release_notes/3.30.0.txt +0 -135
  380. data/doc/release_notes/3.31.0.txt +0 -146
  381. data/doc/release_notes/3.32.0.txt +0 -202
  382. data/doc/release_notes/3.33.0.txt +0 -157
  383. data/doc/release_notes/3.34.0.txt +0 -671
  384. data/doc/release_notes/3.35.0.txt +0 -144
  385. data/doc/release_notes/3.36.0.txt +0 -245
  386. data/doc/release_notes/3.37.0.txt +0 -338
  387. data/doc/release_notes/3.38.0.txt +0 -234
  388. data/doc/release_notes/3.39.0.txt +0 -237
  389. data/doc/release_notes/3.4.0.txt +0 -325
  390. data/doc/release_notes/3.40.0.txt +0 -73
  391. data/doc/release_notes/3.41.0.txt +0 -155
  392. data/doc/release_notes/3.42.0.txt +0 -74
  393. data/doc/release_notes/3.43.0.txt +0 -105
  394. data/doc/release_notes/3.44.0.txt +0 -152
  395. data/doc/release_notes/3.45.0.txt +0 -179
  396. data/doc/release_notes/3.46.0.txt +0 -122
  397. data/doc/release_notes/3.47.0.txt +0 -270
  398. data/doc/release_notes/3.48.0.txt +0 -477
  399. data/doc/release_notes/3.5.0.txt +0 -510
  400. data/doc/release_notes/3.6.0.txt +0 -366
  401. data/doc/release_notes/3.7.0.txt +0 -179
  402. data/doc/release_notes/3.8.0.txt +0 -151
  403. data/doc/release_notes/3.9.0.txt +0 -233
  404. data/doc/release_notes/4.0.0.txt +0 -262
  405. data/doc/release_notes/4.1.0.txt +0 -85
  406. data/doc/release_notes/4.10.0.txt +0 -226
  407. data/doc/release_notes/4.11.0.txt +0 -147
  408. data/doc/release_notes/4.12.0.txt +0 -105
  409. data/doc/release_notes/4.13.0.txt +0 -169
  410. data/doc/release_notes/4.14.0.txt +0 -68
  411. data/doc/release_notes/4.15.0.txt +0 -56
  412. data/doc/release_notes/4.16.0.txt +0 -36
  413. data/doc/release_notes/4.17.0.txt +0 -38
  414. data/doc/release_notes/4.18.0.txt +0 -36
  415. data/doc/release_notes/4.19.0.txt +0 -45
  416. data/doc/release_notes/4.2.0.txt +0 -129
  417. data/doc/release_notes/4.20.0.txt +0 -79
  418. data/doc/release_notes/4.21.0.txt +0 -94
  419. data/doc/release_notes/4.22.0.txt +0 -72
  420. data/doc/release_notes/4.23.0.txt +0 -65
  421. data/doc/release_notes/4.24.0.txt +0 -99
  422. data/doc/release_notes/4.25.0.txt +0 -181
  423. data/doc/release_notes/4.26.0.txt +0 -44
  424. data/doc/release_notes/4.3.0.txt +0 -40
  425. data/doc/release_notes/4.4.0.txt +0 -92
  426. data/doc/release_notes/4.5.0.txt +0 -34
  427. data/doc/release_notes/4.6.0.txt +0 -30
  428. data/doc/release_notes/4.7.0.txt +0 -103
  429. data/doc/release_notes/4.8.0.txt +0 -175
  430. data/doc/release_notes/4.9.0.txt +0 -190
  431. data/lib/sequel/adapters/cubrid.rb +0 -142
  432. data/lib/sequel/adapters/do.rb +0 -156
  433. data/lib/sequel/adapters/do/mysql.rb +0 -64
  434. data/lib/sequel/adapters/do/postgres.rb +0 -42
  435. data/lib/sequel/adapters/do/sqlite3.rb +0 -40
  436. data/lib/sequel/adapters/jdbc/as400.rb +0 -82
  437. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -62
  438. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -34
  439. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -31
  440. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -31
  441. data/lib/sequel/adapters/odbc/progress.rb +0 -8
  442. data/lib/sequel/adapters/shared/cubrid.rb +0 -243
  443. data/lib/sequel/adapters/shared/firebird.rb +0 -245
  444. data/lib/sequel/adapters/shared/informix.rb +0 -52
  445. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -150
  446. data/lib/sequel/adapters/shared/progress.rb +0 -38
  447. data/lib/sequel/adapters/swift.rb +0 -158
  448. data/lib/sequel/adapters/swift/mysql.rb +0 -47
  449. data/lib/sequel/adapters/swift/postgres.rb +0 -45
  450. data/lib/sequel/adapters/swift/sqlite.rb +0 -47
  451. data/lib/sequel/adapters/utils/pg_types.rb +0 -68
  452. data/lib/sequel/dataset/mutation.rb +0 -109
  453. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -3
  454. data/lib/sequel/extensions/filter_having.rb +0 -59
  455. data/lib/sequel/extensions/hash_aliases.rb +0 -45
  456. data/lib/sequel/extensions/meta_def.rb +0 -31
  457. data/lib/sequel/extensions/query_literals.rb +0 -80
  458. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -22
  459. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -118
  460. data/lib/sequel/extensions/set_overrides.rb +0 -72
  461. data/lib/sequel/no_core_ext.rb +0 -1
  462. data/lib/sequel/plugins/association_autoreloading.rb +0 -7
  463. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -7
  464. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -78
  465. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -117
  466. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -59
  467. data/lib/sequel/plugins/schema.rb +0 -80
  468. data/lib/sequel/plugins/scissors.rb +0 -33
  469. data/spec/adapters/db2_spec.rb +0 -160
  470. data/spec/adapters/firebird_spec.rb +0 -411
  471. data/spec/adapters/informix_spec.rb +0 -100
  472. data/spec/adapters/mssql_spec.rb +0 -706
  473. data/spec/adapters/mysql_spec.rb +0 -1287
  474. data/spec/adapters/oracle_spec.rb +0 -313
  475. data/spec/adapters/postgres_spec.rb +0 -3725
  476. data/spec/adapters/spec_helper.rb +0 -43
  477. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  478. data/spec/adapters/sqlite_spec.rb +0 -653
  479. data/spec/bin_spec.rb +0 -254
  480. data/spec/core/connection_pool_spec.rb +0 -1016
  481. data/spec/core/database_spec.rb +0 -2531
  482. data/spec/core/dataset_spec.rb +0 -5098
  483. data/spec/core/deprecated_spec.rb +0 -70
  484. data/spec/core/expression_filters_spec.rb +0 -1243
  485. data/spec/core/mock_adapter_spec.rb +0 -462
  486. data/spec/core/object_graph_spec.rb +0 -303
  487. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  488. data/spec/core/schema_generator_spec.rb +0 -179
  489. data/spec/core/schema_spec.rb +0 -1659
  490. data/spec/core/spec_helper.rb +0 -34
  491. data/spec/core/version_spec.rb +0 -7
  492. data/spec/core_extensions_spec.rb +0 -699
  493. data/spec/extensions/accessed_columns_spec.rb +0 -51
  494. data/spec/extensions/active_model_spec.rb +0 -123
  495. data/spec/extensions/after_initialize_spec.rb +0 -24
  496. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  497. data/spec/extensions/association_dependencies_spec.rb +0 -117
  498. data/spec/extensions/association_pks_spec.rb +0 -365
  499. data/spec/extensions/association_proxies_spec.rb +0 -86
  500. data/spec/extensions/auto_validations_spec.rb +0 -192
  501. data/spec/extensions/blacklist_security_spec.rb +0 -88
  502. data/spec/extensions/blank_spec.rb +0 -69
  503. data/spec/extensions/boolean_readers_spec.rb +0 -93
  504. data/spec/extensions/caching_spec.rb +0 -270
  505. data/spec/extensions/class_table_inheritance_spec.rb +0 -420
  506. data/spec/extensions/column_conflicts_spec.rb +0 -60
  507. data/spec/extensions/column_select_spec.rb +0 -108
  508. data/spec/extensions/columns_introspection_spec.rb +0 -91
  509. data/spec/extensions/composition_spec.rb +0 -242
  510. data/spec/extensions/connection_validator_spec.rb +0 -120
  511. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -274
  512. data/spec/extensions/constraint_validations_spec.rb +0 -325
  513. data/spec/extensions/core_refinements_spec.rb +0 -519
  514. data/spec/extensions/csv_serializer_spec.rb +0 -173
  515. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  516. data/spec/extensions/dataset_associations_spec.rb +0 -311
  517. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  518. data/spec/extensions/date_arithmetic_spec.rb +0 -150
  519. data/spec/extensions/defaults_setter_spec.rb +0 -101
  520. data/spec/extensions/delay_add_association_spec.rb +0 -52
  521. data/spec/extensions/dirty_spec.rb +0 -180
  522. data/spec/extensions/eager_each_spec.rb +0 -42
  523. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  524. data/spec/extensions/error_splitter_spec.rb +0 -18
  525. data/spec/extensions/error_sql_spec.rb +0 -20
  526. data/spec/extensions/eval_inspect_spec.rb +0 -73
  527. data/spec/extensions/filter_having_spec.rb +0 -40
  528. data/spec/extensions/force_encoding_spec.rb +0 -114
  529. data/spec/extensions/from_block_spec.rb +0 -21
  530. data/spec/extensions/graph_each_spec.rb +0 -109
  531. data/spec/extensions/hash_aliases_spec.rb +0 -24
  532. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  533. data/spec/extensions/inflector_spec.rb +0 -183
  534. data/spec/extensions/input_transformer_spec.rb +0 -54
  535. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  536. data/spec/extensions/instance_filters_spec.rb +0 -79
  537. data/spec/extensions/instance_hooks_spec.rb +0 -276
  538. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  539. data/spec/extensions/json_serializer_spec.rb +0 -291
  540. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  541. data/spec/extensions/list_spec.rb +0 -267
  542. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  543. data/spec/extensions/many_through_many_spec.rb +0 -2172
  544. data/spec/extensions/meta_def_spec.rb +0 -21
  545. data/spec/extensions/migration_spec.rb +0 -712
  546. data/spec/extensions/modification_detection_spec.rb +0 -80
  547. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  548. data/spec/extensions/named_timezones_spec.rb +0 -108
  549. data/spec/extensions/nested_attributes_spec.rb +0 -697
  550. data/spec/extensions/null_dataset_spec.rb +0 -85
  551. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  552. data/spec/extensions/pagination_spec.rb +0 -118
  553. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  554. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  555. data/spec/extensions/pg_array_spec.rb +0 -395
  556. data/spec/extensions/pg_enum_spec.rb +0 -92
  557. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  558. data/spec/extensions/pg_hstore_spec.rb +0 -206
  559. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  560. data/spec/extensions/pg_inet_spec.rb +0 -52
  561. data/spec/extensions/pg_interval_spec.rb +0 -76
  562. data/spec/extensions/pg_json_ops_spec.rb +0 -229
  563. data/spec/extensions/pg_json_spec.rb +0 -218
  564. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  565. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  566. data/spec/extensions/pg_range_spec.rb +0 -404
  567. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  568. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  569. data/spec/extensions/pg_row_spec.rb +0 -360
  570. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  571. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  572. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  573. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  574. data/spec/extensions/prepared_statements_spec.rb +0 -103
  575. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  576. data/spec/extensions/pretty_table_spec.rb +0 -92
  577. data/spec/extensions/query_literals_spec.rb +0 -183
  578. data/spec/extensions/query_spec.rb +0 -102
  579. data/spec/extensions/rcte_tree_spec.rb +0 -392
  580. data/spec/extensions/round_timestamps_spec.rb +0 -43
  581. data/spec/extensions/schema_caching_spec.rb +0 -41
  582. data/spec/extensions/schema_dumper_spec.rb +0 -789
  583. data/spec/extensions/schema_spec.rb +0 -117
  584. data/spec/extensions/scissors_spec.rb +0 -26
  585. data/spec/extensions/select_remove_spec.rb +0 -38
  586. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  587. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  588. data/spec/extensions/serialization_spec.rb +0 -362
  589. data/spec/extensions/server_block_spec.rb +0 -90
  590. data/spec/extensions/set_overrides_spec.rb +0 -61
  591. data/spec/extensions/sharding_spec.rb +0 -198
  592. data/spec/extensions/shared_caching_spec.rb +0 -175
  593. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  594. data/spec/extensions/singular_table_names_spec.rb +0 -22
  595. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  596. data/spec/extensions/spec_helper.rb +0 -71
  597. data/spec/extensions/split_array_nil_spec.rb +0 -24
  598. data/spec/extensions/split_values_spec.rb +0 -22
  599. data/spec/extensions/sql_expr_spec.rb +0 -60
  600. data/spec/extensions/static_cache_spec.rb +0 -361
  601. data/spec/extensions/string_date_time_spec.rb +0 -95
  602. data/spec/extensions/string_stripper_spec.rb +0 -68
  603. data/spec/extensions/subclasses_spec.rb +0 -66
  604. data/spec/extensions/table_select_spec.rb +0 -71
  605. data/spec/extensions/tactical_eager_loading_spec.rb +0 -82
  606. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  607. data/spec/extensions/timestamps_spec.rb +0 -175
  608. data/spec/extensions/to_dot_spec.rb +0 -154
  609. data/spec/extensions/touch_spec.rb +0 -203
  610. data/spec/extensions/tree_spec.rb +0 -274
  611. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  612. data/spec/extensions/unlimited_update_spec.rb +0 -20
  613. data/spec/extensions/update_or_create_spec.rb +0 -87
  614. data/spec/extensions/update_primary_key_spec.rb +0 -100
  615. data/spec/extensions/update_refresh_spec.rb +0 -53
  616. data/spec/extensions/validate_associated_spec.rb +0 -52
  617. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  618. data/spec/extensions/validation_helpers_spec.rb +0 -541
  619. data/spec/extensions/xml_serializer_spec.rb +0 -207
  620. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  621. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  622. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  623. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  624. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  625. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  626. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  627. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  628. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  629. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  630. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  631. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  632. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  633. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  634. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  635. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  636. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  637. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  638. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  639. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  640. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  641. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  642. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  643. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  644. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  645. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  646. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  647. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  648. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  649. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  650. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  651. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  652. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  653. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  654. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  655. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  656. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  657. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  658. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  659. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  660. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  661. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  662. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  663. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  664. data/spec/guards_helper.rb +0 -55
  665. data/spec/integration/associations_test.rb +0 -2454
  666. data/spec/integration/database_test.rb +0 -113
  667. data/spec/integration/dataset_test.rb +0 -1808
  668. data/spec/integration/eager_loader_test.rb +0 -687
  669. data/spec/integration/migrator_test.rb +0 -240
  670. data/spec/integration/model_test.rb +0 -226
  671. data/spec/integration/plugin_test.rb +0 -2240
  672. data/spec/integration/prepared_statement_test.rb +0 -467
  673. data/spec/integration/schema_test.rb +0 -817
  674. data/spec/integration/spec_helper.rb +0 -48
  675. data/spec/integration/timezone_test.rb +0 -86
  676. data/spec/integration/transaction_test.rb +0 -374
  677. data/spec/integration/type_test.rb +0 -133
  678. data/spec/model/association_reflection_spec.rb +0 -525
  679. data/spec/model/associations_spec.rb +0 -4426
  680. data/spec/model/base_spec.rb +0 -759
  681. data/spec/model/class_dataset_methods_spec.rb +0 -146
  682. data/spec/model/dataset_methods_spec.rb +0 -149
  683. data/spec/model/eager_loading_spec.rb +0 -2137
  684. data/spec/model/hooks_spec.rb +0 -604
  685. data/spec/model/inflector_spec.rb +0 -26
  686. data/spec/model/model_spec.rb +0 -982
  687. data/spec/model/plugins_spec.rb +0 -299
  688. data/spec/model/record_spec.rb +0 -2147
  689. data/spec/model/spec_helper.rb +0 -46
  690. data/spec/model/validations_spec.rb +0 -193
  691. data/spec/sequel_coverage.rb +0 -15
  692. data/spec/spec_config.rb +0 -10
@@ -1,80 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
- require 'yaml'
3
-
4
- describe "serialization_modification_detection plugin" do
5
- before do
6
- @ds = Sequel.mock(:fetch=>{:id=>1, :a=>'a', :b=>1, :c=>['a'], :d=>{'b'=>'c'}}, :numrows=>1, :autoid=>1)[:items]
7
- @c = Class.new(Sequel::Model(@ds))
8
- @c.plugin :modification_detection
9
- @c.columns :a, :b, :c, :d
10
- @o = @c.first
11
- @ds.db.sqls
12
- end
13
-
14
- it "should only detect columns that have been changed" do
15
- @o.changed_columns.must_equal []
16
- @o.a << 'b'
17
- @o.changed_columns.must_equal [:a]
18
- @o.a.replace('a')
19
- @o.changed_columns.must_equal []
20
-
21
- @o.values[:b] = 2
22
- @o.changed_columns.must_equal [:b]
23
- @o.values[:b] = 1
24
- @o.changed_columns.must_equal []
25
-
26
- @o.c[0] << 'b'
27
- @o.d['b'] << 'b'
28
- @o.changed_columns.sort_by{|c| c.to_s}.must_equal [:c, :d]
29
- @o.c[0] = 'a'
30
- @o.changed_columns.must_equal [:d]
31
- @o.d['b'] = 'c'
32
- @o.changed_columns.must_equal []
33
- end
34
-
35
- it "should not list a column twice" do
36
- @o.a = 'b'
37
- @o.a << 'a'
38
- @o.changed_columns.must_equal [:a]
39
- end
40
-
41
- it "should report correct changed_columns after updating" do
42
- @o.a << 'a'
43
- @o.save_changes
44
- @o.changed_columns.must_equal []
45
-
46
- @o.values[:b] = 2
47
- @o.save_changes
48
- @o.changed_columns.must_equal []
49
-
50
- @o.c[0] << 'b'
51
- @o.save_changes
52
- @o.changed_columns.must_equal []
53
-
54
- @o.d['b'] << 'a'
55
- @o.save_changes
56
- @o.changed_columns.must_equal []
57
-
58
- @ds.db.sqls.must_equal ["UPDATE items SET a = 'aa' WHERE (id = 1)",
59
- "UPDATE items SET b = 2 WHERE (id = 1)",
60
- "UPDATE items SET c = ('ab') WHERE (id = 1)",
61
- "UPDATE items SET d = ('b' = 'ca') WHERE (id = 1)"]
62
- end
63
-
64
- it "should report correct changed_columns after creating new object" do
65
- o = @c.create
66
- o.changed_columns.must_equal []
67
- o.a << 'a'
68
- o.changed_columns.must_equal [:a]
69
- @ds.db.sqls.must_equal ["INSERT INTO items DEFAULT VALUES", "SELECT * FROM items WHERE (id = 1) LIMIT 1"]
70
- end
71
-
72
- it "should report correct changed_columns after refreshing existing object" do
73
- @o.a << 'a'
74
- @o.changed_columns.must_equal [:a]
75
- @o.refresh
76
- @o.changed_columns.must_equal []
77
- @o.a << 'a'
78
- @o.changed_columns.must_equal [:a]
79
- end
80
- end
@@ -1,91 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
-
3
- describe "MSSSQL optimistic locking plugin" do
4
- before do
5
- @db = Sequel.mock(:host=>'mssql')
6
- @c = Class.new(Sequel::Model(@db[:items]))
7
- @c.columns :id, :name, :timestamp
8
- @c.plugin :mssql_optimistic_locking
9
- @o = @c.load(:id=>1, :name=>'a', :timestamp=>'1234')
10
- @db.sqls
11
- end
12
-
13
- it "should not include the lock column when updating" do
14
- @db.fetch = [[{:timestamp=>'2345'}]]
15
- @o.save
16
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x31323334))"]
17
- end
18
-
19
- it "should automatically update lock column using new value from database" do
20
- @db.fetch = [[{:timestamp=>'2345'}]]
21
- @o.save
22
- @o.timestamp.must_equal '2345'
23
- end
24
-
25
- it "should raise error when updating stale object" do
26
- @db.fetch = []
27
- @o.timestamp = '2345'
28
- proc{@o.save}.must_raise(Sequel::NoExistingObject)
29
- @o.timestamp.must_equal '2345'
30
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x32333435))"]
31
- end
32
-
33
- it "should raise error when destroying stale object" do
34
- @db.numrows = 0
35
- @o.timestamp = '2345'
36
- proc{@o.destroy}.must_raise(Sequel::NoExistingObject)
37
- @db.sqls.must_equal ["DELETE FROM items WHERE ((id = 1) AND (timestamp = 0x32333435))"]
38
- end
39
-
40
- it "should allow refresh after failed save" do
41
- @db.fetch = []
42
- @o.timestamp = '2345'
43
- proc{@o.save}.must_raise(Sequel::NoExistingObject)
44
- @db.fetch = {:id=>1, :name=>'a', :timestamp=>'2345'}
45
- @o.refresh
46
- @db.sqls
47
- @o.save
48
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x32333435))"]
49
- end
50
-
51
- it "should allow changing the lock column via model.lock_column=" do
52
- @c = Class.new(Sequel::Model(@db[:items]))
53
- @c.columns :id, :name, :lv
54
- @c.plugin :mssql_optimistic_locking
55
- @c.lock_column = :lv
56
- @o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
57
- @db.sqls
58
- @db.fetch = []
59
- proc{@o.save}.must_raise(Sequel::NoExistingObject)
60
- @o.lv.must_equal '1234'
61
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.lv WHERE ((id = 1) AND (lv = 0x31323334))"]
62
- @o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
63
- @db.fetch = {:lv=>'2345'}
64
- @o.save
65
- @o.lv.must_equal '2345'
66
- end
67
-
68
- it "should allow changing the lock column via plugin option" do
69
- @c = Class.new(Sequel::Model(@db[:items]))
70
- @c.columns :id, :name, :lv
71
- @c.plugin :mssql_optimistic_locking, :lock_column=>:lv
72
- @o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
73
- @db.sqls
74
- @db.fetch = []
75
- proc{@o.save}.must_raise(Sequel::NoExistingObject)
76
- @o.lv.must_equal '1234'
77
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.lv WHERE ((id = 1) AND (lv = 0x31323334))"]
78
- @o = @c.load(:id=>1, :name=>'a', :lv=>'1234')
79
- @db.fetch = {:lv=>'2345'}
80
- @o.save
81
- @o.lv.must_equal '2345'
82
- end
83
-
84
- it "should work when subclassing" do
85
- c = Class.new(@c)
86
- o = c.load(:id=>1, :name=>'a', :timestamp=>'1234')
87
- @db.fetch = [[{:timestamp=>'2345'}]]
88
- o.save
89
- @db.sqls.must_equal ["UPDATE TOP (1) items SET name = 'a' OUTPUT inserted.timestamp WHERE ((id = 1) AND (timestamp = 0x31323334))"]
90
- end
91
- end
@@ -1,108 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- begin
4
- require 'tzinfo'
5
- rescue LoadError => e
6
- skip_warn "named_timezones_spec: can't load tzinfo (#{e.class}: #{e})"
7
- else
8
- Sequel.extension :thread_local_timezones
9
- Sequel.extension :named_timezones
10
- Sequel.datetime_class = Time
11
-
12
- describe "Sequel named_timezones extension" do
13
- before do
14
- @tz_in = TZInfo::Timezone.get('America/Los_Angeles')
15
- @tz_out = TZInfo::Timezone.get('America/New_York')
16
- @db = Sequel.mock
17
- @dt = DateTime.civil(2009,6,1,10,20,30,0)
18
- Sequel.application_timezone = 'America/Los_Angeles'
19
- Sequel.database_timezone = 'America/New_York'
20
- Sequel.datetime_class = DateTime
21
- end
22
- after do
23
- Sequel.tzinfo_disambiguator = nil
24
- Sequel.default_timezone = nil
25
- Sequel.datetime_class = Time
26
- end
27
-
28
- it "should convert string arguments to *_timezone= to TZInfo::Timezone instances" do
29
- Sequel.application_timezone.must_equal @tz_in
30
- Sequel.database_timezone.must_equal @tz_out
31
- end
32
-
33
- it "should convert string arguments for Database#timezone= to TZInfo::Timezone instances for database-specific timezones" do
34
- @db.extension :named_timezones
35
- @db.timezone = 'America/Los_Angeles'
36
- @db.timezone.must_equal @tz_in
37
- end
38
-
39
- it "should accept TZInfo::Timezone instances in *_timezone=" do
40
- Sequel.application_timezone = @tz_in
41
- Sequel.database_timezone = @tz_out
42
- Sequel.application_timezone.must_equal @tz_in
43
- Sequel.database_timezone.must_equal @tz_out
44
- end
45
-
46
- it "should convert datetimes going into the database to named database_timezone" do
47
- ds = @db[:a]
48
- def ds.supports_timestamp_timezones?; true; end
49
- def ds.supports_timestamp_usecs?; false; end
50
- ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
51
- @db.sqls.must_equal ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
52
- end
53
-
54
- it "should convert datetimes coming out of the database from database_timezone to application_timezone" do
55
- dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30-0400')
56
- dt.must_equal @dt
57
- dt.offset.must_equal(-7/24.0)
58
-
59
- dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30+0000')
60
- dt.must_equal @dt
61
- dt.offset.must_equal(-7/24.0)
62
- end
63
-
64
- it "should raise an error for ambiguous timezones by default" do
65
- proc{Sequel.database_to_application_timestamp('2004-10-31T01:30:00')}.must_raise(Sequel::InvalidValue)
66
- end
67
-
68
- it "should support tzinfo_disambiguator= to handle ambiguous timezones automatically" do
69
- Sequel.tzinfo_disambiguator = proc{|datetime, periods| periods.first}
70
- Sequel.database_to_application_timestamp('2004-10-31T01:30:00').must_equal DateTime.parse('2004-10-30T22:30:00-07:00')
71
- end
72
-
73
- it "should assume datetimes coming out of the database that don't have an offset as coming from database_timezone" do
74
- dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30')
75
- dt.must_equal @dt
76
- dt.offset.must_equal(-7/24.0)
77
-
78
- dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30')
79
- dt.must_equal @dt + 1/6.0
80
- dt.offset.must_equal(-7/24.0)
81
- end
82
-
83
- it "should work with the thread_local_timezones extension" do
84
- q, q1, q2 = Queue.new, Queue.new, Queue.new
85
- tz1, tz2 = nil, nil
86
- t1 = Thread.new do
87
- Sequel.thread_application_timezone = 'America/New_York'
88
- q2.push nil
89
- q.pop
90
- tz1 = Sequel.application_timezone
91
- end
92
- t2 = Thread.new do
93
- Sequel.thread_application_timezone = 'America/Los_Angeles'
94
- q2.push nil
95
- q1.pop
96
- tz2 = Sequel.application_timezone
97
- end
98
- q2.pop
99
- q2.pop
100
- q.push nil
101
- q1.push nil
102
- t1.join
103
- t2.join
104
- tz1.must_equal @tz_out
105
- tz2.must_equal @tz_in
106
- end
107
- end
108
- end
@@ -1,697 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- describe "NestedAttributes plugin" do
4
- def check_sqls(should, is)
5
- if should.is_a?(Array)
6
- should.must_include(is)
7
- else
8
- is.must_equal should
9
- end
10
- end
11
-
12
- def check_sql_array(*shoulds)
13
- sqls = @db.sqls
14
- sqls.length.must_equal shoulds.length
15
- shoulds.zip(sqls){|s, i| check_sqls(s, i)}
16
- end
17
-
18
- before do
19
- @db = Sequel.mock(:autoid=>1, :numrows=>1)
20
- @c = Class.new(Sequel::Model(@db))
21
- @c.plugin :nested_attributes
22
- @Artist = Class.new(@c).set_dataset(:artists)
23
- @Album = Class.new(@c).set_dataset(:albums)
24
- @Tag = Class.new(@c).set_dataset(:tags)
25
- @Concert = Class.new(@c).set_dataset(:concerts)
26
- @Artist.plugin :skip_create_refresh
27
- @Album.plugin :skip_create_refresh
28
- @Tag.plugin :skip_create_refresh
29
- @Concert.plugin :skip_create_refresh
30
- @Artist.columns :id, :name
31
- @Album.columns :id, :name, :artist_id
32
- @Tag.columns :id, :name
33
- @Concert.columns :tour, :date, :artist_id, :playlist
34
- @Concert.set_primary_key([:tour, :date])
35
- @Concert.unrestrict_primary_key
36
- @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
37
- @Artist.one_to_many :concerts, :class=>@Concert, :key=>:artist_id
38
- @Artist.one_to_one :first_album, :class=>@Album, :key=>:artist_id
39
- @Artist.one_to_one :first_concert, :class=>@Concert, :key=>:artist_id
40
- @Concert.one_to_many :albums, :class=>@Album, :key=>:artist_id, :primary_key=>:artist_id
41
- @Album.many_to_one :artist, :class=>@Artist, :reciprocal=>:albums
42
- @Album.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at
43
- @Tag.many_to_many :albums, :class=>@Album, :left_key=>:tag_id, :right_key=>:album_id, :join_table=>:at
44
- @Artist.nested_attributes :albums, :first_album, :destroy=>true, :remove=>true
45
- @Artist.nested_attributes :concerts, :destroy=>true, :remove=>true
46
- @Album.nested_attributes :artist, :tags, :destroy=>true, :remove=>true
47
- @Artist.nested_attributes :first_concert
48
- @Concert.nested_attributes :albums
49
- @db.sqls
50
- end
51
-
52
- it "should support creating new many_to_one objects" do
53
- a = @Album.new({:name=>'Al', :artist_attributes=>{:name=>'Ar'}})
54
- @db.sqls.must_equal []
55
- a.save
56
- check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
57
- ["INSERT INTO albums (name, artist_id) VALUES ('Al', 1)", "INSERT INTO albums (artist_id, name) VALUES (1, 'Al')"])
58
- end
59
-
60
- it "should support creating new one_to_one objects" do
61
- a = @Artist.new(:name=>'Ar')
62
- a.id = 1
63
- a.first_album_attributes = {:name=>'Al'}
64
- @db.sqls.must_equal []
65
- a.save
66
- check_sql_array(["INSERT INTO artists (name, id) VALUES ('Ar', 1)", "INSERT INTO artists (id, name) VALUES (1, 'Ar')"],
67
- "UPDATE albums SET artist_id = NULL WHERE (artist_id = 1)",
68
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
69
- end
70
-
71
- it "should support creating new one_to_many objects" do
72
- a = @Artist.new({:name=>'Ar', :albums_attributes=>[{:name=>'Al'}]})
73
- @db.sqls.must_equal []
74
- a.save
75
- check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
76
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
77
- end
78
-
79
- it "should support creating new one_to_many and one_to_one objects with presence validations on the foreign key" do
80
- @Album.class_eval do
81
- plugin :validation_helpers
82
- def validate
83
- validates_integer :artist_id
84
- super
85
- end
86
- end
87
- a = @Artist.new({:name=>'Ar', :albums_attributes=>[{:name=>'Al'}]})
88
- @db.sqls.must_equal []
89
- a.save
90
- check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
91
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
92
-
93
- a = @Artist.new(:name=>'Ar')
94
- a.id = 1
95
- a.first_album_attributes = {:name=>'Al'}
96
- @db.sqls.must_equal []
97
- a.save
98
- check_sql_array(["INSERT INTO artists (name, id) VALUES ('Ar', 1)", "INSERT INTO artists (id, name) VALUES (1, 'Ar')"],
99
- "UPDATE albums SET artist_id = NULL WHERE (artist_id = 1)",
100
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
101
- end
102
-
103
- it "should support creating new one_to_many and one_to_one objects with composite keys with presence validations on the foreign key" do
104
- insert = nil
105
- @Album.class_eval do
106
- plugin :validation_helpers
107
- def validate
108
- validates_integer :artist_id
109
- super
110
- end
111
- end
112
- @Concert.class_eval do
113
- define_method :_insert do
114
- insert = values.dup
115
- end
116
- def before_create # Have to define the CPK somehow.
117
- self.tour = 'To'
118
- self.date = '2004-04-05'
119
- super
120
- end
121
- def after_create
122
- super
123
- self.artist_id = 3
124
- end
125
- end
126
-
127
- c = @Concert.new(:playlist=>'Pl')
128
- @db.sqls.must_equal []
129
- c.albums_attributes = [{:name=>'Al'}]
130
- c.save
131
- insert.must_equal(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
132
- check_sql_array(["INSERT INTO albums (name, artist_id) VALUES ('Al', 3)", "INSERT INTO albums (artist_id, name) VALUES (3, 'Al')"])
133
-
134
- @Concert.class_eval do
135
- plugin :validation_helpers
136
- def validate
137
- validates_integer :artist_id
138
- super
139
- end
140
- end
141
-
142
- a = @Artist.new(:name=>'Ar')
143
- a.id = 1
144
- a.first_concert_attributes = {:playlist=>'Pl'}
145
- @db.sqls.must_equal []
146
- a.save
147
- check_sql_array(["INSERT INTO artists (name, id) VALUES ('Ar', 1)", "INSERT INTO artists (id, name) VALUES (1, 'Ar')"],
148
- "UPDATE concerts SET artist_id = NULL WHERE (artist_id = 1)")
149
- insert.must_equal(:tour=>'To', :date=>'2004-04-05', :artist_id=>1, :playlist=>'Pl')
150
- end
151
-
152
- it "should should not remove existing values from object when validating" do
153
- @Artist.one_to_one :first_album, :class=>@Album, :key=>:id
154
- @Artist.nested_attributes :first_album
155
- @db.fetch = {:id=>1}
156
- a = @Artist.load(:id=>1)
157
- a.set(:first_album_attributes=>{:id=>1, :name=>'Ar'})
158
- a.first_album.values.must_equal(:id=>1, :name=>'Ar')
159
- @db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.id = 1) LIMIT 1"]
160
- a.save_changes
161
- check_sql_array("UPDATE albums SET name = 'Ar' WHERE (id = 1)")
162
- end
163
-
164
- it "should support creating new many_to_many objects" do
165
- a = @Album.new({:name=>'Al', :tags_attributes=>[{:name=>'T'}]})
166
- @db.sqls.must_equal []
167
- a.save
168
- check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
169
- "INSERT INTO tags (name) VALUES ('T')",
170
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"])
171
- end
172
-
173
- it "should add new objects to the cached association array as soon as the *_attributes= method is called" do
174
- a = @Artist.new({:name=>'Ar', :first_album_attributes=>{:name=>'B'}, :albums_attributes=>[{:name=>'Al', :tags_attributes=>[{:name=>'T'}]}]})
175
- a.albums.must_equal [@Album.new(:name=>'Al')]
176
- a.albums.first.artist.must_equal a
177
- a.albums.first.tags.must_equal [@Tag.new(:name=>'T')]
178
- a.first_album.must_equal @Album.new(:name=>'B')
179
- a.first_album.artist.must_equal a
180
- end
181
-
182
- it "should support creating new objects with composite primary keys" do
183
- insert = nil
184
- @Concert.class_eval do
185
- define_method :_insert do
186
- insert = values.dup
187
- end
188
- def before_create # Have to define the CPK somehow.
189
- self.tour = 'To'
190
- self.date = '2004-04-05'
191
- super
192
- end
193
- end
194
- a = @Artist.new({:name=>'Ar', :concerts_attributes=>[{:playlist=>'Pl'}]})
195
- @db.sqls.must_equal []
196
- a.save
197
- @db.sqls.must_equal ["INSERT INTO artists (name) VALUES ('Ar')"]
198
- insert.must_equal(:tour=>'To', :date=>'2004-04-05', :artist_id=>1, :playlist=>'Pl')
199
- end
200
-
201
- it "should support creating new objects with specific primary keys if :unmatched_pk => :create is set" do
202
- @Artist.nested_attributes :albums, :unmatched_pk=>:create
203
- insert = nil
204
- @Album.class_eval do
205
- unrestrict_primary_key
206
- define_method :_insert do
207
- insert = values.dup
208
- end
209
- end
210
- a = @Artist.new({:name=>'Ar', :albums_attributes=>[{:id=>7, :name=>'Al'}]})
211
- @db.sqls.must_equal []
212
- a.save
213
- @db.sqls.must_equal ["INSERT INTO artists (name) VALUES ('Ar')"]
214
- insert.must_equal(:artist_id=>1, :name=>'Al', :id=>7)
215
- end
216
-
217
- it "should support creating new objects with specific composite primary keys if :unmatched_pk => :create is set" do
218
- insert = nil
219
- @Artist.nested_attributes :concerts, :unmatched_pk=>:create
220
- @Concert.class_eval do
221
- define_method :_insert do
222
- insert = values.dup
223
- end
224
- end
225
- a = @Artist.new({:name=>'Ar', :concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl'}]})
226
- @db.sqls.must_equal []
227
- a.save
228
- @db.sqls.must_equal ["INSERT INTO artists (name) VALUES ('Ar')"]
229
- insert.must_equal(:tour=>'To', :date=>'2004-04-05', :artist_id=>1, :playlist=>'Pl')
230
- end
231
-
232
- it "should support updating many_to_one objects" do
233
- al = @Album.load(:id=>10, :name=>'Al')
234
- ar = @Artist.load(:id=>20, :name=>'Ar')
235
- al.associations[:artist] = ar
236
- al.set(:artist_attributes=>{:id=>'20', :name=>'Ar2'})
237
- @db.sqls.must_equal []
238
- al.save
239
- @db.sqls.must_equal ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE artists SET name = 'Ar2' WHERE (id = 20)"]
240
- end
241
-
242
- it "should support updating one_to_one objects" do
243
- al = @Album.load(:id=>10, :name=>'Al')
244
- ar = @Artist.load(:id=>20, :name=>'Ar')
245
- ar.associations[:first_album] = al
246
- ar.set(:first_album_attributes=>{:id=>10, :name=>'Al2'})
247
- @db.sqls.must_equal []
248
- ar.save
249
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
250
- end
251
-
252
- it "should support updating one_to_many objects" do
253
- al = @Album.load(:id=>10, :name=>'Al')
254
- ar = @Artist.load(:id=>20, :name=>'Ar')
255
- ar.associations[:albums] = [al]
256
- ar.set(:albums_attributes=>[{:id=>10, :name=>'Al2'}])
257
- @db.sqls.must_equal []
258
- ar.save
259
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
260
- end
261
-
262
- it "should support updating one_to_many objects with _delete/_remove flags set to false" do
263
- al = @Album.load(:id=>10, :name=>'Al')
264
- ar = @Artist.load(:id=>20, :name=>'Ar')
265
- ar.associations[:albums] = [al]
266
- ar.set(:albums_attributes=>[{:id=>10, :name=>'Al2', :_delete => 'f', :_remove => '0'}])
267
- @db.sqls.must_equal []
268
- ar.save
269
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "UPDATE albums SET name = 'Al2' WHERE (id = 10)"]
270
- end
271
-
272
- it "should support updating many_to_many objects" do
273
- a = @Album.load(:id=>10, :name=>'Al')
274
- t = @Tag.load(:id=>20, :name=>'T')
275
- a.associations[:tags] = [t]
276
- a.set(:tags_attributes=>[{:id=>20, :name=>'T2'}])
277
- @db.sqls.must_equal []
278
- a.save
279
- @db.sqls.must_equal ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE tags SET name = 'T2' WHERE (id = 20)"]
280
- end
281
-
282
- it "should support updating many_to_many objects with _delete/_remove flags set to false" do
283
- a = @Album.load(:id=>10, :name=>'Al')
284
- t = @Tag.load(:id=>20, :name=>'T')
285
- a.associations[:tags] = [t]
286
- a.set(:tags_attributes=>[{:id=>20, :name=>'T2', '_delete' => false, '_remove' => 'F'}])
287
- @db.sqls.must_equal []
288
- a.save
289
- @db.sqls.must_equal ["UPDATE albums SET name = 'Al' WHERE (id = 10)", "UPDATE tags SET name = 'T2' WHERE (id = 20)"]
290
- end
291
-
292
- it "should support updating objects with composite primary keys" do
293
- ar = @Artist.load(:id=>10, :name=>'Ar')
294
- co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
295
- ar.associations[:concerts] = [co]
296
- ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl2'}])
297
- @db.sqls.must_equal []
298
- ar.save
299
- check_sql_array("UPDATE artists SET name = 'Ar' WHERE (id = 10)", ["UPDATE concerts SET playlist = 'Pl2' WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET playlist = 'Pl2' WHERE ((date = '2004-04-05') AND (tour = 'To'))"])
300
- end
301
-
302
- it "should support removing many_to_one objects" do
303
- al = @Album.load(:id=>10, :name=>'Al')
304
- ar = @Artist.load(:id=>20, :name=>'Ar')
305
- al.associations[:artist] = ar
306
- al.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})
307
- @db.sqls.must_equal []
308
- al.save
309
- check_sql_array(["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"])
310
- end
311
-
312
- it "should support removing one_to_one objects" do
313
- al = @Album.load(:id=>10, :name=>'Al')
314
- ar = @Artist.load(:id=>20, :name=>'Ar')
315
- ar.associations[:first_album] = al
316
- ar.set(:first_album_attributes=>{:id=>10, :_remove=>'t'})
317
- @db.sqls.must_equal []
318
- ar.save
319
- @db.sqls.must_equal ["UPDATE albums SET artist_id = NULL WHERE (artist_id = 20)", "UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
320
- end
321
-
322
- it "should support removing one_to_many objects" do
323
- al = @Album.load(:id=>10, :name=>'Al')
324
- ar = @Artist.load(:id=>20, :name=>'Ar')
325
- ar.associations[:albums] = [al]
326
- ar.set(:albums_attributes=>[{:id=>10, :_remove=>'t'}])
327
- ar.associations[:albums].must_equal []
328
- @db.sqls.must_equal []
329
- @Album.dataset._fetch = {:id=>1}
330
- ar.save
331
- check_sql_array("SELECT 1 AS one FROM albums WHERE ((albums.artist_id = 20) AND (id = 10)) LIMIT 1",
332
- ["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"],
333
- "UPDATE artists SET name = 'Ar' WHERE (id = 20)")
334
- end
335
-
336
- it "should support removing many_to_many objects" do
337
- a = @Album.load(:id=>10, :name=>'Al')
338
- t = @Tag.load(:id=>20, :name=>'T')
339
- a.associations[:tags] = [t]
340
- a.set(:tags_attributes=>[{:id=>20, :_remove=>true}])
341
- a.associations[:tags].must_equal []
342
- @db.sqls.must_equal []
343
- a.save
344
- @db.sqls.must_equal ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)"]
345
- end
346
-
347
- it "should support removing objects with composite primary keys" do
348
- ar = @Artist.load(:id=>10, :name=>'Ar')
349
- co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
350
- ar.associations[:concerts] = [co]
351
- ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_remove=>'t'}])
352
- @db.sqls.must_equal []
353
- @Concert.dataset._fetch = {:id=>1}
354
- ar.save
355
- check_sql_array(["SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (tour = 'To') AND (date = '2004-04-05')) LIMIT 1", "SELECT 1 AS one FROM concerts WHERE ((concerts.artist_id = 10) AND (date = '2004-04-05') AND (tour = 'To')) LIMIT 1"],
356
- ["UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((tour = 'To') AND (date = '2004-04-05'))", "UPDATE concerts SET artist_id = NULL, playlist = 'Pl' WHERE ((date = '2004-04-05') AND (tour = 'To'))", "UPDATE concerts SET playlist = 'Pl', artist_id = NULL WHERE ((date = '2004-04-05') AND (tour = 'To'))"],
357
- "UPDATE artists SET name = 'Ar' WHERE (id = 10)")
358
- end
359
-
360
- it "should support destroying many_to_one objects" do
361
- al = @Album.load(:id=>10, :name=>'Al')
362
- ar = @Artist.load(:id=>20, :name=>'Ar')
363
- al.associations[:artist] = ar
364
- al.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})
365
- @db.sqls.must_equal []
366
- al.save
367
- check_sql_array(["UPDATE albums SET artist_id = NULL, name = 'Al' WHERE (id = 10)", "UPDATE albums SET name = 'Al', artist_id = NULL WHERE (id = 10)"],
368
- "DELETE FROM artists WHERE (id = 20)")
369
- end
370
-
371
- it "should support destroying one_to_one objects" do
372
- al = @Album.load(:id=>10, :name=>'Al')
373
- ar = @Artist.load(:id=>20, :name=>'Ar')
374
- ar.associations[:first_album] = al
375
- ar.set(:first_album_attributes=>{:id=>10, :_delete=>'t'})
376
- @db.sqls.must_equal []
377
- ar.save
378
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
379
- end
380
-
381
- it "should support destroying one_to_many objects" do
382
- al = @Album.load(:id=>10, :name=>'Al')
383
- ar = @Artist.load(:id=>20, :name=>'Ar')
384
- ar.associations[:albums] = [al]
385
- ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
386
- @db.sqls.must_equal []
387
- ar.save
388
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)", "DELETE FROM albums WHERE (id = 10)"]
389
- end
390
-
391
- it "should support destroying many_to_many objects" do
392
- a = @Album.load(:id=>10, :name=>'Al')
393
- t = @Tag.load(:id=>20, :name=>'T')
394
- a.associations[:tags] = [t]
395
- a.set(:tags_attributes=>[{:id=>20, :_delete=>true}])
396
- @db.sqls.must_equal []
397
- a.save
398
- @db.sqls.must_equal ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
399
- end
400
-
401
- it "should support destroying objects with composite primary keys" do
402
- ar = @Artist.load(:id=>10, :name=>'Ar')
403
- co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
404
- ar.associations[:concerts] = [co]
405
- ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])
406
- @db.sqls.must_equal []
407
- ar.save
408
- check_sql_array("UPDATE artists SET name = 'Ar' WHERE (id = 10)", ["DELETE FROM concerts WHERE ((tour = 'To') AND (date = '2004-04-05'))", "DELETE FROM concerts WHERE ((date = '2004-04-05') AND (tour = 'To'))"])
409
- end
410
-
411
- it "should support both string and symbol keys in nested attribute hashes" do
412
- a = @Album.load(:id=>10, :name=>'Al')
413
- t = @Tag.load(:id=>20, :name=>'T')
414
- a.associations[:tags] = [t]
415
- a.set('tags_attributes'=>[{'id'=>20, '_delete'=>true}])
416
- @db.sqls.must_equal []
417
- a.save
418
- @db.sqls.must_equal ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
419
- end
420
-
421
- it "should support using a hash instead of an array for to_many nested attributes" do
422
- a = @Album.load(:id=>10, :name=>'Al')
423
- t = @Tag.load(:id=>20, :name=>'T')
424
- a.associations[:tags] = [t]
425
- a.set('tags_attributes'=>{'1'=>{'id'=>20, '_delete'=>true}})
426
- @db.sqls.must_equal []
427
- a.save
428
- @db.sqls.must_equal ["DELETE FROM at WHERE ((album_id = 10) AND (tag_id = 20))", "UPDATE albums SET name = 'Al' WHERE (id = 10)", "DELETE FROM tags WHERE (id = 20)"]
429
- end
430
-
431
- it "should only allow destroying associated objects if :destroy option is used in the nested_attributes call" do
432
- a = @Album.load(:id=>10, :name=>'Al')
433
- ar = @Artist.load(:id=>20, :name=>'Ar')
434
- a.associations[:artist] = ar
435
- @Album.nested_attributes :artist
436
- proc{a.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})}.must_raise(Sequel::MassAssignmentRestriction)
437
- @Album.nested_attributes :artist, :destroy=>true
438
- a.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})
439
- end
440
-
441
- it "should only allow removing associated objects if :remove option is used in the nested_attributes call" do
442
- a = @Album.load(:id=>10, :name=>'Al')
443
- ar = @Artist.load(:id=>20, :name=>'Ar')
444
- a.associations[:artist] = ar
445
- @Album.nested_attributes :artist
446
- proc{a.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})}.must_raise(Sequel::MassAssignmentRestriction)
447
- @Album.nested_attributes :artist, :remove=>true
448
- a.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})
449
- end
450
-
451
- it "should raise an Error if a primary key is given in a nested attribute hash, but no matching associated object exists" do
452
- al = @Album.load(:id=>10, :name=>'Al')
453
- ar = @Artist.load(:id=>20, :name=>'Ar')
454
- ar.associations[:albums] = [al]
455
- proc{ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])}.must_raise(Sequel::Error)
456
- ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])
457
- end
458
-
459
- it "should not raise an Error if an unmatched primary key is given, if the :strict=>false option is used" do
460
- @Artist.nested_attributes :albums, :strict=>false
461
- al = @Album.load(:id=>10, :name=>'Al')
462
- ar = @Artist.load(:id=>20, :name=>'Ar')
463
- ar.associations[:albums] = [al]
464
- ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])
465
- @db.sqls.must_equal []
466
- ar.save
467
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
468
- end
469
-
470
- it "should not raise an Error if an unmatched primary key is given, if the :unmatched_pk=>:ignore option is used" do
471
- @Artist.nested_attributes :albums, :unmatched_pk=>:ignore
472
- al = @Album.load(:id=>10, :name=>'Al')
473
- ar = @Artist.load(:id=>20, :name=>'Ar')
474
- ar.associations[:albums] = [al]
475
- ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])
476
- @db.sqls.must_equal []
477
- ar.save
478
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 20)"]
479
- end
480
-
481
- it "should raise an Error if a composite primary key is given in a nested attribute hash, but no matching associated object exists" do
482
- ar = @Artist.load(:id=>10, :name=>'Ar')
483
- co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
484
- ar.associations[:concerts] = [co]
485
- proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-04', :_delete=>'t'}])}.must_raise(Sequel::Error)
486
- ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])
487
- end
488
-
489
- it "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
490
- @Artist.nested_attributes :concerts, :strict=>false
491
- ar = @Artist.load(:id=>10, :name=>'Ar')
492
- co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
493
- ar.associations[:concerts] = [co]
494
- ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-06', :_delete=>'t'}])
495
- @db.sqls.must_equal []
496
- ar.save
497
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar' WHERE (id = 10)"]
498
- end
499
-
500
- it "should not save if nested attribute is not valid and should include nested attribute validation errors in the main object's validation errors" do
501
- @Artist.class_eval do
502
- def validate
503
- super
504
- errors.add(:name, 'cannot be Ar') if name == 'Ar'
505
- end
506
- end
507
- a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
508
- @db.sqls.must_equal []
509
- proc{a.save}.must_raise(Sequel::ValidationFailed)
510
- a.errors.full_messages.must_equal ['artist name cannot be Ar']
511
- @db.sqls.must_equal []
512
- # Should preserve attributes
513
- a.artist.name.must_equal 'Ar'
514
- end
515
-
516
- it "should not attempt to validate nested attributes if the :validate=>false association option is used" do
517
- @Album.many_to_one :artist, :class=>@Artist, :validate=>false, :reciprocal=>nil
518
- @Album.nested_attributes :artist, :tags, :destroy=>true, :remove=>true
519
- @Artist.class_eval do
520
- def validate
521
- super
522
- errors.add(:name, 'cannot be Ar') if name == 'Ar'
523
- end
524
- end
525
- a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
526
- @db.sqls.must_equal []
527
- a.save
528
- check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
529
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
530
- end
531
-
532
- it "should not attempt to validate nested attributes if the :validate=>false option is passed to save" do
533
- @Artist.class_eval do
534
- def validate
535
- super
536
- errors.add(:name, 'cannot be Ar') if name == 'Ar'
537
- end
538
- end
539
- a = @Album.new(:name=>'Al', :artist_attributes=>{:name=>'Ar'})
540
- @db.sqls.must_equal []
541
- a.save(:validate=>false)
542
- check_sql_array("INSERT INTO artists (name) VALUES ('Ar')",
543
- ["INSERT INTO albums (artist_id, name) VALUES (1, 'Al')", "INSERT INTO albums (name, artist_id) VALUES ('Al', 1)"])
544
- end
545
-
546
- it "should not accept nested attributes unless explicitly specified" do
547
- @Artist.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at
548
- proc{@Artist.create({:name=>'Ar', :tags_attributes=>[{:name=>'T'}]})}.must_raise(Sequel::MassAssignmentRestriction)
549
- @db.sqls.must_equal []
550
- end
551
-
552
- it "should save when save_changes or update is called if nested attribute associated objects changed but there are no changes to the main object" do
553
- al = @Album.load(:id=>10, :name=>'Al')
554
- ar = @Artist.load(:id=>20, :name=>'Ar')
555
- al.associations[:artist] = ar
556
- @db.sqls.must_equal []
557
- al.update(:artist_attributes=>{:id=>'20', :name=>'Ar2'})
558
- @db.sqls.must_equal ["UPDATE artists SET name = 'Ar2' WHERE (id = 20)"]
559
- end
560
-
561
- it "should have a :limit option limiting the amount of entries" do
562
- @Album.nested_attributes :tags, :limit=>2
563
- arr = [{:name=>'T'}]
564
- proc{@Album.new({:name=>'Al', :tags_attributes=>arr*3})}.must_raise(Sequel::Error)
565
- a = @Album.new({:name=>'Al', :tags_attributes=>arr*2})
566
- @db.sqls.must_equal []
567
- a.save
568
- check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
569
- "INSERT INTO tags (name) VALUES ('T')",
570
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
571
- "INSERT INTO tags (name) VALUES ('T')",
572
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
573
- end
574
-
575
- it "should accept a block that each hash gets passed to determine if it should be processed" do
576
- @Album.nested_attributes(:tags){|h| h[:name].empty?}
577
- a = @Album.new({:name=>'Al', :tags_attributes=>[{:name=>'T'}, {:name=>''}, {:name=>'T2'}]})
578
- @db.sqls.must_equal []
579
- a.save
580
- check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
581
- "INSERT INTO tags (name) VALUES ('T')",
582
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
583
- "INSERT INTO tags (name) VALUES ('T2')",
584
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
585
- end
586
-
587
- it "should accept a :transform block that returns a changed attributes hash" do
588
- @Album.nested_attributes :tags, :transform=>proc{|parent, hash| hash[:name] << parent.name; hash }
589
- a = @Album.new(:name => 'Al')
590
- a.set(:tags_attributes=>[{:name=>'T'}, {:name=>'T2'}])
591
- @db.sqls.must_equal []
592
- a.save
593
- check_sql_array("INSERT INTO albums (name) VALUES ('Al')",
594
- "INSERT INTO tags (name) VALUES ('TAl')",
595
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 2)", "INSERT INTO at (tag_id, album_id) VALUES (2, 1)"],
596
- "INSERT INTO tags (name) VALUES ('T2Al')",
597
- ["INSERT INTO at (album_id, tag_id) VALUES (1, 4)", "INSERT INTO at (tag_id, album_id) VALUES (4, 1)"])
598
- end
599
-
600
- it "should return objects created/modified in the internal methods" do
601
- @Album.nested_attributes :tags, :remove=>true, :strict=>false
602
- objs = []
603
- @Album.class_eval do
604
- define_method(:nested_attributes_create){|*a| objs << [super(*a), :create]}
605
- define_method(:nested_attributes_remove){|*a| objs << [super(*a), :remove]}
606
- define_method(:nested_attributes_update){|*a| objs << [super(*a), :update]}
607
- end
608
- a = @Album.new(:name=>'Al')
609
- a.associations[:tags] = [@Tag.load(:id=>6, :name=>'A'), @Tag.load(:id=>7, :name=>'A2')]
610
- a.tags_attributes = [{:id=>6, :name=>'T'}, {:id=>7, :name=>'T2', :_remove=>true}, {:name=>'T3'}, {:id=>8, :name=>'T4'}, {:id=>9, :name=>'T5', :_remove=>true}]
611
- objs.must_equal [[@Tag.load(:id=>6, :name=>'T'), :update], [@Tag.load(:id=>7, :name=>'A2'), :remove], [@Tag.new(:name=>'T3'), :create]]
612
- end
613
-
614
- it "should raise an error if updating modifies the associated objects keys" do
615
- @Artist.columns :id, :name, :artist_id
616
- @Album.columns :id, :name, :artist_id
617
- @Tag.columns :id, :name, :tag_id
618
- @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :primary_key=>:artist_id
619
- @Album.many_to_one :artist, :class=>@Artist, :primary_key=>:artist_id
620
- @Album.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at, :right_primary_key=>:tag_id
621
- @Artist.nested_attributes :albums, :destroy=>true, :remove=>true
622
- @Album.nested_attributes :artist, :tags, :destroy=>true, :remove=>true
623
-
624
- al = @Album.load(:id=>10, :name=>'Al', :artist_id=>25)
625
- ar = @Artist.load(:id=>20, :name=>'Ar', :artist_id=>25)
626
- t = @Tag.load(:id=>30, :name=>'T', :tag_id=>15)
627
- al.associations[:artist] = ar
628
- al.associations[:tags] = [t]
629
- ar.associations[:albums] = [al]
630
- proc{ar.set(:albums_attributes=>[{:id=>10, :name=>'Al2', :artist_id=>'3'}])}.must_raise(Sequel::Error)
631
- proc{al.set(:artist_attributes=>{:id=>20, :name=>'Ar2', :artist_id=>'3'})}.must_raise(Sequel::Error)
632
- proc{al.set(:tags_attributes=>[{:id=>30, :name=>'T2', :tag_id=>'3'}])}.must_raise(Sequel::Error)
633
- end
634
-
635
- it "should accept a :fields option and only allow modification of those fields" do
636
- @Tag.columns :id, :name, :number
637
- @Album.nested_attributes :tags, :destroy=>true, :remove=>true, :fields=>[:name]
638
-
639
- al = @Album.load(:id=>10, :name=>'Al')
640
- t = @Tag.load(:id=>30, :name=>'T', :number=>10)
641
- al.associations[:tags] = [t]
642
- al.set(:tags_attributes=>[{:id=>30, :name=>'T2'}, {:name=>'T3'}])
643
- @db.sqls.must_equal []
644
- al.save
645
- check_sql_array("UPDATE albums SET name = 'Al' WHERE (id = 10)",
646
- "UPDATE tags SET name = 'T2' WHERE (id = 30)",
647
- "INSERT INTO tags (name) VALUES ('T3')",
648
- ["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
649
- proc{al.set(:tags_attributes=>[{:id=>30, :name=>'T2', :number=>3}])}.must_raise(Sequel::MassAssignmentRestriction)
650
- proc{al.set(:tags_attributes=>[{:name=>'T2', :number=>3}])}.must_raise(Sequel::MassAssignmentRestriction)
651
- end
652
-
653
- it "should accept a proc for the :fields option that accepts the associated object and returns an array of fields" do
654
- @Tag.columns :id, :name, :number
655
- @Album.nested_attributes :tags, :destroy=>true, :remove=>true, :fields=>proc{|object| object.is_a?(@Tag) ? [:name] : []}
656
-
657
- al = @Album.load(:id=>10, :name=>'Al')
658
- t = @Tag.load(:id=>30, :name=>'T', :number=>10)
659
- al.associations[:tags] = [t]
660
- al.set(:tags_attributes=>[{:id=>30, :name=>'T2'}, {:name=>'T3'}])
661
- @db.sqls.must_equal []
662
- al.save
663
- check_sql_array("UPDATE albums SET name = 'Al' WHERE (id = 10)",
664
- "UPDATE tags SET name = 'T2' WHERE (id = 30)",
665
- "INSERT INTO tags (name) VALUES ('T3')",
666
- ["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
667
- proc{al.set(:tags_attributes=>[{:id=>30, :name=>'T2', :number=>3}])}.must_raise(Sequel::MassAssignmentRestriction)
668
- proc{al.set(:tags_attributes=>[{:name=>'T2', :number=>3}])}.must_raise(Sequel::MassAssignmentRestriction)
669
- end
670
-
671
- it "should allow per-call options via the set_nested_attributes method" do
672
- @Tag.columns :id, :name, :number
673
- @Album.nested_attributes :tags
674
-
675
- al = @Album.load(:id=>10, :name=>'Al')
676
- t = @Tag.load(:id=>30, :name=>'T', :number=>10)
677
- al.associations[:tags] = [t]
678
- al.set_nested_attributes(:tags, [{:id=>30, :name=>'T2'}, {:name=>'T3'}], :fields=>[:name])
679
- @db.sqls.must_equal []
680
- al.save
681
- check_sql_array("UPDATE albums SET name = 'Al' WHERE (id = 10)",
682
- "UPDATE tags SET name = 'T2' WHERE (id = 30)",
683
- "INSERT INTO tags (name) VALUES ('T3')",
684
- ["INSERT INTO at (album_id, tag_id) VALUES (10, 1)", "INSERT INTO at (tag_id, album_id) VALUES (1, 10)"])
685
- proc{al.set_nested_attributes(:tags, [{:id=>30, :name=>'T2', :number=>3}], :fields=>[:name])}.must_raise(Sequel::MassAssignmentRestriction)
686
- proc{al.set_nested_attributes(:tags, [{:name=>'T2', :number=>3}], :fields=>[:name])}.must_raise(Sequel::MassAssignmentRestriction)
687
- end
688
-
689
- it "should have set_nested_attributes method raise error if called with a bad association" do
690
- proc{@Album.load(:id=>10, :name=>'Al').set_nested_attributes(:tags2, [{:id=>30, :name=>'T2', :number=>3}], :fields=>[:name])}.must_raise(Sequel::Error)
691
- end
692
-
693
- it "should have set_nested_attributes method raise error if called with an association that doesn't support nested attributes" do
694
- @Tag.columns :id, :name, :number
695
- proc{@Album.load(:id=>10, :name=>'Al').set_nested_attributes(:tags, [{:id=>30, :name=>'T2', :number=>3}], :fields=>[:name])}.must_raise(Sequel::Error)
696
- end
697
- end