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,2240 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
-
3
- describe "Class Table Inheritance Plugin" do
4
- before(:all) do
5
- @db = DB
6
- @db.instance_variable_set(:@schemas, {})
7
- @db.drop_table?(:staff, :executives, :managers, :employees)
8
- @db.create_table(:employees) do
9
- primary_key :id
10
- String :name
11
- String :kind
12
- end
13
- @db.create_table(:managers) do
14
- foreign_key :id, :employees, :primary_key=>true
15
- Integer :num_staff
16
- end
17
- @db.create_table(:executives) do
18
- foreign_key :id, :managers, :primary_key=>true
19
- Integer :num_managers
20
- end
21
- @db.create_table(:staff) do
22
- foreign_key :id, :employees, :primary_key=>true
23
- foreign_key :manager_id, :managers
24
- end
25
- end
26
- before do
27
- [:staff, :executives, :managers, :employees].each{|t| @db[t].delete}
28
- class ::Employee < Sequel::Model(@db)
29
- plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
30
- end
31
- class ::Manager < Employee
32
- one_to_many :staff_members, :class=>:Staff
33
- end
34
- class ::Executive < Manager
35
- end
36
- class ::Ceo < Executive
37
- end
38
- class ::Staff < Employee
39
- many_to_one :manager
40
- end
41
-
42
-
43
- @i1 = @db[:employees].insert(:name=>'E', :kind=>'Employee')
44
- @i2 = @db[:employees].insert(:name=>'S', :kind=>'Staff')
45
- @i3 = @db[:employees].insert(:name=>'M', :kind=>'Manager')
46
- @db[:managers].insert(:id=>@i3, :num_staff=>7)
47
- @i4 = @db[:employees].insert(:name=>'Ex', :kind=>'Executive')
48
- @db[:managers].insert(:id=>@i4, :num_staff=>5)
49
- @db[:executives].insert(:id=>@i4, :num_managers=>6)
50
- @i5 = @db[:employees].insert(:name=>'C', :kind=>'Ceo')
51
- @db[:managers].insert(:id=>@i5, :num_staff=>2)
52
- @db[:executives].insert(:id=>@i5, :num_managers=>1)
53
- @db[:staff].insert(:id=>@i2, :manager_id=>@i4)
54
- end
55
- after do
56
- [:Ceo, :Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
57
- end
58
- after(:all) do
59
- @db.drop_table? :staff, :executives, :managers, :employees
60
- end
61
-
62
- it "should return rows as subclass instances" do
63
- Employee.order(:id).all.must_equal [
64
- Employee.load(:id=>@i1, :name=>'E', :kind=>'Employee'),
65
- Staff.load(:id=>@i2, :name=>'S', :kind=>'Staff'),
66
- Manager.load(:id=>@i3, :name=>'M', :kind=>'Manager'),
67
- Executive.load(:id=>@i4, :name=>'Ex', :kind=>'Executive'),
68
- Ceo.load(:id=>@i5, :name=>'C', :kind=>'Ceo')
69
- ]
70
- end
71
-
72
- it "should lazily load columns in subclass tables" do
73
- Employee[@i2][:manager_id].must_equal nil
74
- Employee[@i2].manager_id.must_equal @i4
75
- Employee[@i3][:num_staff].must_equal nil
76
- Employee[@i3].num_staff.must_equal 7
77
- Employee[@i4][:num_staff].must_equal nil
78
- Employee[@i4].num_staff.must_equal 5
79
- Employee[@i4][:num_managers].must_equal nil
80
- Employee[@i4].num_managers.must_equal 6
81
- Employee[@i5][:num_managers].must_equal nil
82
- Employee[@i5].num_managers.must_equal 1
83
- end
84
-
85
- it "should eagerly load columns in subclass tables when retrieving multiple objects" do
86
- a = Employee.order(:id).all
87
- a[1][:manager_id].must_equal nil
88
- a[1].manager_id.must_equal @i4
89
- a[2][:num_staff].must_equal nil
90
- a[2].num_staff.must_equal 7
91
- a[3][:num_staff].must_equal 5 # eagerly loaded by previous call
92
- a[3].num_staff.must_equal 5
93
- a[3][:num_managers].must_equal nil
94
- a[3].num_managers.must_equal 6
95
- a[4][:num_managers].must_equal 1
96
- a[4].num_managers.must_equal 1
97
- end
98
-
99
- it "should include schema for columns for tables for ancestor classes" do
100
- Employee.db_schema.keys.sort_by{|x| x.to_s}.must_equal [:id, :kind, :name]
101
- Staff.db_schema.keys.sort_by{|x| x.to_s}.must_equal [:id, :kind, :manager_id, :name]
102
- Manager.db_schema.keys.sort_by{|x| x.to_s}.must_equal [:id, :kind, :name, :num_staff]
103
- Executive.db_schema.keys.sort_by{|x| x.to_s}.must_equal [:id, :kind, :name, :num_managers, :num_staff]
104
- Ceo.db_schema.keys.sort_by{|x| x.to_s}.must_equal [:id, :kind, :name, :num_managers, :num_staff]
105
- end
106
-
107
- it "should include columns for tables for ancestor classes" do
108
- Employee.columns.must_equal [:id, :name, :kind]
109
- Staff.columns.must_equal [:id, :name, :kind, :manager_id]
110
- Manager.columns.must_equal [:id, :name, :kind, :num_staff]
111
- Executive.columns.must_equal [:id, :name, :kind, :num_staff, :num_managers]
112
- Ceo.columns.must_equal [:id, :name, :kind, :num_staff, :num_managers]
113
- end
114
-
115
- it "should delete rows from all tables" do
116
- e = Ceo.first
117
- i = e.id
118
- e.staff_members_dataset.destroy
119
- e.destroy
120
- @db[:executives][:id=>i].must_equal nil
121
- @db[:managers][:id=>i].must_equal nil
122
- @db[:employees][:id=>i].must_equal nil
123
- end
124
-
125
- it "should handle associations only defined in subclasses" do
126
- Employee.filter(:employees__id=>@i2).all.first.manager.id.must_equal @i4
127
- end
128
-
129
- it "should insert rows into all tables" do
130
- e = Ceo.create(:name=>'Ex2', :num_managers=>8, :num_staff=>9)
131
- i = e.id
132
- @db[:employees][:id=>i].must_equal(:id=>i, :name=>'Ex2', :kind=>'Ceo')
133
- @db[:managers][:id=>i].must_equal(:id=>i, :num_staff=>9)
134
- @db[:executives][:id=>i].must_equal(:id=>i, :num_managers=>8)
135
- end
136
-
137
- it "should update rows in all tables" do
138
- Executive.first.update(:name=>'Ex2', :num_managers=>8, :num_staff=>9)
139
- @db[:employees][:id=>@i4].must_equal(:id=>@i4, :name=>'Ex2', :kind=>'Executive')
140
- @db[:managers][:id=>@i4].must_equal(:id=>@i4, :num_staff=>9)
141
- @db[:executives][:id=>@i4].must_equal(:id=>@i4, :num_managers=>8)
142
- end
143
-
144
- it "should handle many_to_one relationships" do
145
- m = Staff.first.manager
146
- m.must_equal Manager[@i4]
147
- m.must_be_kind_of(Executive)
148
- end
149
-
150
- it "should handle eagerly loading many_to_one relationships" do
151
- Staff.limit(1).eager(:manager).all.map{|x| x.manager}.must_equal [Manager[@i4]]
152
- end
153
-
154
- it "should handle eagerly graphing many_to_one relationships" do
155
- ss = Staff.eager_graph(:manager).all
156
- ss.must_equal [Staff[@i2]]
157
- ss.map{|x| x.manager}.must_equal [Manager[@i4]]
158
- end
159
-
160
- it "should handle one_to_many relationships" do
161
- Executive.first.staff_members.must_equal [Staff[@i2]]
162
- end
163
-
164
- it "should handle eagerly loading one_to_many relationships" do
165
- Executive.limit(1).eager(:staff_members).first.staff_members.must_equal [Staff[@i2]]
166
- end
167
-
168
- it "should handle eagerly graphing one_to_many relationships" do
169
- es = Executive.limit(1).eager_graph(:staff_members).all
170
- es.must_equal [Executive[@i4]]
171
- es.map{|x| x.staff_members}.must_equal [[Staff[@i2]]]
172
- end
173
- end
174
-
175
- describe "Many Through Many Plugin" do
176
- before(:all) do
177
- @db = DB
178
- @db.instance_variable_set(:@schemas, {})
179
- @db.drop_table?(:albums_artists, :albums, :artists)
180
- @db.create_table(:albums) do
181
- primary_key :id
182
- String :name
183
- end
184
- @db.create_table(:artists) do
185
- primary_key :id
186
- String :name
187
- end
188
- @db.create_table(:albums_artists) do
189
- foreign_key :album_id, :albums
190
- foreign_key :artist_id, :artists
191
- end
192
- end
193
- before do
194
- [:albums_artists, :albums, :artists].each{|t| @db[t].delete}
195
- class ::Album < Sequel::Model(@db)
196
- many_to_many :artists
197
- end
198
- class ::Artist < Sequel::Model(@db)
199
- plugin :many_through_many
200
- end
201
-
202
- @artist1 = Artist.create(:name=>'1')
203
- @artist2 = Artist.create(:name=>'2')
204
- @artist3 = Artist.create(:name=>'3')
205
- @artist4 = Artist.create(:name=>'4')
206
- @album1 = Album.create(:name=>'A')
207
- @album1.add_artist(@artist1)
208
- @album1.add_artist(@artist2)
209
- @album2 = Album.create(:name=>'B')
210
- @album2.add_artist(@artist3)
211
- @album2.add_artist(@artist4)
212
- @album3 = Album.create(:name=>'C')
213
- @album3.add_artist(@artist2)
214
- @album3.add_artist(@artist3)
215
- @album4 = Album.create(:name=>'D')
216
- @album4.add_artist(@artist1)
217
- @album4.add_artist(@artist4)
218
- end
219
- after do
220
- [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
221
- end
222
- after(:all) do
223
- @db.drop_table? :albums_artists, :albums, :artists
224
- end
225
- def around
226
- DB.transaction(:rollback=>:always){super}
227
- end
228
-
229
- def self_join(c)
230
- c.join(Sequel.as(c.table_name, :b), Array(c.primary_key).zip(Array(c.primary_key))).select_all(c.table_name)
231
- end
232
-
233
- it "should handle super simple case with 1 join table" do
234
- Artist.many_through_many :albums, [[:albums_artists, :artist_id, :album_id]]
235
- Artist[@artist1.id].albums.map{|x| x.name}.sort.must_equal %w'A D'
236
- Artist[@artist2.id].albums.map{|x| x.name}.sort.must_equal %w'A C'
237
- Artist[@artist3.id].albums.map{|x| x.name}.sort.must_equal %w'B C'
238
- Artist[@artist4.id].albums.map{|x| x.name}.sort.must_equal %w'B D'
239
-
240
- Artist.plugin :prepared_statements_associations
241
- Artist[@artist1.id].albums.map{|x| x.name}.sort.must_equal %w'A D'
242
- Artist[@artist2.id].albums.map{|x| x.name}.sort.must_equal %w'A C'
243
- Artist[@artist3.id].albums.map{|x| x.name}.sort.must_equal %w'B C'
244
- Artist[@artist4.id].albums.map{|x| x.name}.sort.must_equal %w'B D'
245
-
246
- Artist.filter(:id=>@artist1.id).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'A D'
247
- Artist.filter(:id=>@artist2.id).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'A C'
248
- Artist.filter(:id=>@artist3.id).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'B C'
249
- Artist.filter(:id=>@artist4.id).eager(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'B D'
250
-
251
- Artist.filter(:artists__id=>@artist1.id).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'A D'
252
- Artist.filter(:artists__id=>@artist2.id).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'A C'
253
- Artist.filter(:artists__id=>@artist3.id).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'B C'
254
- Artist.filter(:artists__id=>@artist4.id).eager_graph(:albums).all.map{|x| x.albums.map{|a| a.name}}.flatten.sort.must_equal %w'B D'
255
-
256
- Artist.filter(:albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'1 2'
257
- Artist.filter(:albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'3 4'
258
- Artist.filter(:albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'2 3'
259
- Artist.filter(:albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'1 4'
260
-
261
- Artist.exclude(:albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'3 4'
262
- Artist.exclude(:albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'1 2'
263
- Artist.exclude(:albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'1 4'
264
- Artist.exclude(:albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'2 3'
265
-
266
- Artist.filter(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
267
- Artist.filter(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w'1 3 4'
268
-
269
- Artist.exclude(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'4'
270
- Artist.exclude(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w'2'
271
-
272
- Artist.filter(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
273
- Artist.exclude(:albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'4'
274
-
275
- c = self_join(Artist)
276
- c.filter(:albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'1 2'
277
- c.filter(:albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'3 4'
278
- c.filter(:albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'2 3'
279
- c.filter(:albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'1 4'
280
-
281
- c.exclude(:albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'3 4'
282
- c.exclude(:albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'1 2'
283
- c.exclude(:albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'1 4'
284
- c.exclude(:albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'2 3'
285
-
286
- c.filter(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
287
- c.filter(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w'1 3 4'
288
-
289
- c.exclude(:albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'4'
290
- c.exclude(:albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w'2'
291
-
292
- c.filter(:albums=>self_join(Album).filter(:albums__id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
293
- c.exclude(:albums=>self_join(Album).filter(:albums__id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'4'
294
- end
295
-
296
- it "should handle typical case with 3 join tables" do
297
- Artist.many_through_many :related_artists, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id]], :class=>Artist, :distinct=>true
298
- Artist[@artist1.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 2 4'
299
- Artist[@artist2.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 2 3'
300
- Artist[@artist3.id].related_artists.map{|x| x.name}.sort.must_equal %w'2 3 4'
301
- Artist[@artist4.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 3 4'
302
-
303
- Artist.plugin :prepared_statements_associations
304
- Artist[@artist1.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 2 4'
305
- Artist[@artist2.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 2 3'
306
- Artist[@artist3.id].related_artists.map{|x| x.name}.sort.must_equal %w'2 3 4'
307
- Artist[@artist4.id].related_artists.map{|x| x.name}.sort.must_equal %w'1 3 4'
308
-
309
- Artist.filter(:id=>@artist1.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 2 4'
310
- Artist.filter(:id=>@artist2.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 2 3'
311
- Artist.filter(:id=>@artist3.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'2 3 4'
312
- Artist.filter(:id=>@artist4.id).eager(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 3 4'
313
-
314
- Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 2 4'
315
- Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 2 3'
316
- Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'2 3 4'
317
- Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_artists).all.map{|x| x.related_artists.map{|a| a.name}}.flatten.sort.must_equal %w'1 3 4'
318
-
319
- Artist.filter(:related_artists=>@artist1).all.map{|a| a.name}.sort.must_equal %w'1 2 4'
320
- Artist.filter(:related_artists=>@artist2).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
321
- Artist.filter(:related_artists=>@artist3).all.map{|a| a.name}.sort.must_equal %w'2 3 4'
322
- Artist.filter(:related_artists=>@artist4).all.map{|a| a.name}.sort.must_equal %w'1 3 4'
323
-
324
- Artist.exclude(:related_artists=>@artist1).all.map{|a| a.name}.sort.must_equal %w'3'
325
- Artist.exclude(:related_artists=>@artist2).all.map{|a| a.name}.sort.must_equal %w'4'
326
- Artist.exclude(:related_artists=>@artist3).all.map{|a| a.name}.sort.must_equal %w'1'
327
- Artist.exclude(:related_artists=>@artist4).all.map{|a| a.name}.sort.must_equal %w'2'
328
-
329
- Artist.filter(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
330
- Artist.exclude(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.must_equal %w''
331
-
332
- Artist.filter(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.must_equal %w'1 2 4'
333
- Artist.exclude(:related_artists=>Artist.filter(:id=>@artist1.id)).all.map{|a| a.name}.sort.must_equal %w'3'
334
-
335
- c = self_join(Artist)
336
- c.filter(:related_artists=>@artist1).all.map{|a| a.name}.sort.must_equal %w'1 2 4'
337
- c.filter(:related_artists=>@artist2).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
338
- c.filter(:related_artists=>@artist3).all.map{|a| a.name}.sort.must_equal %w'2 3 4'
339
- c.filter(:related_artists=>@artist4).all.map{|a| a.name}.sort.must_equal %w'1 3 4'
340
-
341
- c.exclude(:related_artists=>@artist1).all.map{|a| a.name}.sort.must_equal %w'3'
342
- c.exclude(:related_artists=>@artist2).all.map{|a| a.name}.sort.must_equal %w'4'
343
- c.exclude(:related_artists=>@artist3).all.map{|a| a.name}.sort.must_equal %w'1'
344
- c.exclude(:related_artists=>@artist4).all.map{|a| a.name}.sort.must_equal %w'2'
345
-
346
- c.filter(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
347
- c.exclude(:related_artists=>[@artist1, @artist4]).all.map{|a| a.name}.sort.must_equal %w''
348
-
349
- c.filter(:related_artists=>c.filter(:artists__id=>@artist1.id)).all.map{|a| a.name}.sort.must_equal %w'1 2 4'
350
- c.exclude(:related_artists=>c.filter(:artists__id=>@artist1.id)).all.map{|a| a.name}.sort.must_equal %w'3'
351
- end
352
-
353
- it "should handle extreme case with 5 join tables" do
354
- Artist.many_through_many :related_albums, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_artists, :album_id, :artist_id], [:artists, :id, :id], [:albums_artists, :artist_id, :album_id]], :class=>Album, :distinct=>true
355
- @db[:albums_artists].delete
356
- @album1.add_artist(@artist1)
357
- @album1.add_artist(@artist2)
358
- @album2.add_artist(@artist2)
359
- @album2.add_artist(@artist3)
360
- @album3.add_artist(@artist1)
361
- @album4.add_artist(@artist3)
362
- @album4.add_artist(@artist4)
363
-
364
- Artist[@artist1.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B C'
365
- Artist[@artist2.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B C D'
366
- Artist[@artist3.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B D'
367
- Artist[@artist4.id].related_albums.map{|x| x.name}.sort.must_equal %w'B D'
368
-
369
- Artist.plugin :prepared_statements_associations
370
- Artist[@artist1.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B C'
371
- Artist[@artist2.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B C D'
372
- Artist[@artist3.id].related_albums.map{|x| x.name}.sort.must_equal %w'A B D'
373
- Artist[@artist4.id].related_albums.map{|x| x.name}.sort.must_equal %w'B D'
374
-
375
- Artist.filter(:id=>@artist1.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B C'
376
- Artist.filter(:id=>@artist2.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B C D'
377
- Artist.filter(:id=>@artist3.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B D'
378
- Artist.filter(:id=>@artist4.id).eager(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'B D'
379
-
380
- Artist.filter(:artists__id=>@artist1.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B C'
381
- Artist.filter(:artists__id=>@artist2.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B C D'
382
- Artist.filter(:artists__id=>@artist3.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'A B D'
383
- Artist.filter(:artists__id=>@artist4.id).eager_graph(:related_albums).all.map{|x| x.related_albums.map{|a| a.name}}.flatten.sort.must_equal %w'B D'
384
-
385
- Artist.filter(:related_albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
386
- Artist.filter(:related_albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
387
- Artist.filter(:related_albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'1 2'
388
- Artist.filter(:related_albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'2 3 4'
389
-
390
- Artist.exclude(:related_albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'4'
391
- Artist.exclude(:related_albums=>@album2).all.map{|a| a.name}.sort.must_equal %w''
392
- Artist.exclude(:related_albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'3 4'
393
- Artist.exclude(:related_albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'1'
394
-
395
- Artist.filter(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
396
- Artist.filter(:related_albums=>[@album3, @album4]).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
397
-
398
- Artist.exclude(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'4'
399
- Artist.exclude(:related_albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w''
400
-
401
- Artist.filter(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
402
- Artist.exclude(:related_albums=>Album.filter(:id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'4'
403
-
404
- c = self_join(Artist)
405
- c.filter(:related_albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
406
- c.filter(:related_albums=>@album2).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
407
- c.filter(:related_albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'1 2'
408
- c.filter(:related_albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'2 3 4'
409
-
410
- c.exclude(:related_albums=>@album1).all.map{|a| a.name}.sort.must_equal %w'4'
411
- c.exclude(:related_albums=>@album2).all.map{|a| a.name}.sort.must_equal %w''
412
- c.exclude(:related_albums=>@album3).all.map{|a| a.name}.sort.must_equal %w'3 4'
413
- c.exclude(:related_albums=>@album4).all.map{|a| a.name}.sort.must_equal %w'1'
414
-
415
- c.filter(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
416
- c.filter(:related_albums=>[@album3, @album4]).all.map{|a| a.name}.sort.must_equal %w'1 2 3 4'
417
-
418
- c.exclude(:related_albums=>[@album1, @album3]).all.map{|a| a.name}.sort.must_equal %w'4'
419
- c.exclude(:related_albums=>[@album2, @album4]).all.map{|a| a.name}.sort.must_equal %w''
420
-
421
- c.filter(:related_albums=>self_join(Album).filter(:albums__id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'1 2 3'
422
- c.exclude(:related_albums=>self_join(Album).filter(:albums__id=>[@album1.id, @album3.id])).all.map{|a| a.name}.sort.must_equal %w'4'
423
- end
424
- end
425
-
426
- describe "Lazy Attributes plugin" do
427
- before(:all) do
428
- @db = DB
429
- @db.create_table!(:items) do
430
- primary_key :id
431
- String :name
432
- Integer :num
433
- end
434
- @db[:items].delete
435
- class ::Item < Sequel::Model(@db)
436
- plugin :lazy_attributes, :num
437
- end
438
- Item.create(:name=>'J', :num=>1)
439
- end
440
- after(:all) do
441
- @db.drop_table?(:items)
442
- Object.send(:remove_const, :Item)
443
- end
444
-
445
- it "should not include lazy attribute columns by default" do
446
- Item.first.must_equal Item.load(:id=>1, :name=>'J')
447
- end
448
-
449
- it "should load lazy attribute on access" do
450
- Item.first.num.must_equal 1
451
- end
452
-
453
- it "should typecast lazy attribute in setter" do
454
- i = Item.new
455
- i.num = '1'
456
- i.num.must_equal 1
457
- end
458
-
459
- it "should load lazy attribute for all items returned when accessing any item if using identity map " do
460
- Item.create(:name=>'K', :num=>2)
461
- a = Item.order(:name).all
462
- a.must_equal [Item.load(:id=>1, :name=>'J'), Item.load(:id=>2, :name=>'K')]
463
- a.map{|x| x[:num]}.must_equal [nil, nil]
464
- a.first.num.must_equal 1
465
- a.map{|x| x[:num]}.must_equal [1, 2]
466
- a.last.num.must_equal 2
467
- end
468
- end
469
-
470
- describe "Tactical Eager Loading Plugin" do
471
- before(:all) do
472
- @db = DB
473
- @db.instance_variable_set(:@schemas, {})
474
- @db.drop_table?(:albums_artists)
475
- @db.create_table!(:artists) do
476
- primary_key :id
477
- String :name
478
- end
479
- @db.create_table!(:albums) do
480
- primary_key :id
481
- String :name
482
- foreign_key :artist_id, :artists
483
- end
484
- end
485
- before do
486
- @db[:albums].delete
487
- @db[:artists].delete
488
- class ::Album < Sequel::Model(@db)
489
- plugin :tactical_eager_loading
490
- many_to_one :artist
491
- end
492
- class ::Artist < Sequel::Model(@db)
493
- plugin :tactical_eager_loading
494
- one_to_many :albums, :order=>:name
495
- end
496
-
497
- @artist1 = Artist.create(:name=>'1')
498
- @artist2 = Artist.create(:name=>'2')
499
- @artist3 = Artist.create(:name=>'3')
500
- @artist4 = Artist.create(:name=>'4')
501
- @album1 = Album.create(:name=>'A', :artist=>@artist1)
502
- @album2 = Album.create(:name=>'B', :artist=>@artist1)
503
- @album3 = Album.create(:name=>'C', :artist=>@artist2)
504
- @album4 = Album.create(:name=>'D', :artist=>@artist3)
505
- end
506
- after do
507
- [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
508
- end
509
- after(:all) do
510
- @db.drop_table? :albums, :artists
511
- end
512
-
513
- it "should eagerly load associations for all items when accessing any item" do
514
- a = Artist.order(:name).all
515
- a.map{|x| x.associations}.must_equal [{}, {}, {}, {}]
516
- a.first.albums.must_equal [@album1, @album2]
517
- a.map{|x| x.associations}.must_equal [{:albums=>[@album1, @album2]}, {:albums=>[@album3]}, {:albums=>[@album4]}, {:albums=>[]}]
518
-
519
- a = Album.order(:name).all
520
- a.map{|x| x.associations}.must_equal [{}, {}, {}, {}]
521
- a.first.artist.must_equal @artist1
522
- a.map{|x| x.associations}.must_equal [{:artist=>@artist1}, {:artist=>@artist1}, {:artist=>@artist2}, {:artist=>@artist3}]
523
- end
524
- end
525
-
526
- describe "Touch plugin" do
527
- before(:all) do
528
- @db = DB
529
- @db.drop_table? :albums_artists, :albums, :artists
530
- @db.create_table(:artists) do
531
- primary_key :id
532
- String :name
533
- DateTime :updated_at
534
- end
535
- @db.create_table(:albums) do
536
- primary_key :id
537
- String :name
538
- foreign_key :artist_id, :artists
539
- DateTime :updated_at
540
- end
541
- @db.create_join_table({:album_id=>:albums, :artist_id=>:artists}, :no_index=>true)
542
- end
543
- before do
544
- @db[:albums].delete
545
- @db[:artists].delete
546
- class ::Album < Sequel::Model(@db)
547
- end
548
- class ::Artist < Sequel::Model(@db)
549
- end
550
-
551
- @artist = Artist.create(:name=>'1')
552
- @album = Album.create(:name=>'A', :artist_id=>@artist.id)
553
- end
554
- after do
555
- [:Album, :Artist].each{|s| Object.send(:remove_const, s)}
556
- end
557
- after(:all) do
558
- @db.drop_table? :albums_artists, :albums, :artists
559
- end
560
- def around
561
- DB.transaction(:rollback=>:always){super}
562
- end
563
-
564
- it "should update the timestamp column when touching the record" do
565
- Album.plugin :touch
566
- @album.updated_at.must_equal nil
567
- @album.touch
568
- @album.updated_at.to_i.must_be_close_to Time.now.to_i, 2
569
- end
570
-
571
- cspecify "should update the timestamp column for many_to_one associated records when the record is updated or destroyed", [:do, :sqlite], [:jdbc, :sqlite], [:swift] do
572
- Album.many_to_one :artist
573
- Album.plugin :touch, :associations=>:artist
574
- @artist.updated_at.must_equal nil
575
- @album.update(:name=>'B')
576
- ua = @artist.reload.updated_at
577
- if ua.is_a?(Time)
578
- ua.to_i.must_be_close_to Time.now.to_i, 60
579
- else
580
- (DateTime.now - ua).must_be_close_to 0, 60.0/86400
581
- end
582
- @artist.update(:updated_at=>nil)
583
- @album.destroy
584
- if ua.is_a?(Time)
585
- ua.to_i.must_be_close_to Time.now.to_i, 60
586
- else
587
- (DateTime.now - ua).must_be_close_to 0, 60.0/86400
588
- end
589
- end
590
-
591
- cspecify "should update the timestamp column for one_to_many associated records when the record is updated", [:do, :sqlite], [:jdbc, :sqlite], [:swift] do
592
- Artist.one_to_many :albums
593
- Artist.plugin :touch, :associations=>:albums
594
- @album.updated_at.must_equal nil
595
- @artist.update(:name=>'B')
596
- ua = @album.reload.updated_at
597
- if ua.is_a?(Time)
598
- ua.to_i.must_be_close_to Time.now.to_i, 60
599
- else
600
- (DateTime.now - ua).must_be_close_to 0, 60.0/86400
601
- end
602
- end
603
-
604
- cspecify "should update the timestamp column for many_to_many associated records when the record is updated", [:do, :sqlite], [:jdbc, :sqlite], [:swift] do
605
- Artist.many_to_many :albums
606
- Artist.plugin :touch, :associations=>:albums
607
- @artist.add_album(@album)
608
- @album.updated_at.must_equal nil
609
- @artist.update(:name=>'B')
610
- ua = @album.reload.updated_at
611
- if ua.is_a?(Time)
612
- ua.to_i.must_be_close_to Time.now.to_i, 60
613
- else
614
- (DateTime.now - ua).must_be_close_to 0, 60.0/86400
615
- end
616
- end
617
- end
618
-
619
- describe "Serialization plugin" do
620
- before do
621
- @db = DB
622
- @db.create_table!(:items) do
623
- primary_key :id
624
- String :stuff
625
- end
626
- class ::Item < Sequel::Model(@db)
627
- plugin :serialization, :marshal, :stuff
628
- end
629
- end
630
- after do
631
- @db.drop_table?(:items)
632
- Object.send(:remove_const, :Item)
633
- end
634
-
635
- it "should serialize and deserialize items as needed" do
636
- i = Item.create(:stuff=>{:a=>1})
637
- i.stuff.must_equal(:a=>1)
638
- i.stuff = [1, 2, 3]
639
- i.save
640
- Item.first.stuff.must_equal [1, 2, 3]
641
- i.update(:stuff=>Item.new)
642
- Item.first.stuff.must_equal Item.new
643
- end
644
- end
645
-
646
- describe "OptimisticLocking plugin" do
647
- before(:all) do
648
- @db = DB
649
- @db.create_table!(:people) do
650
- primary_key :id
651
- String :name
652
- Integer :lock_version, :default=>0, :null=>false
653
- end
654
- class ::Person < Sequel::Model(@db)
655
- plugin :optimistic_locking
656
- end
657
- end
658
- before do
659
- @db[:people].delete
660
- @p = Person.create(:name=>'John')
661
- end
662
- after(:all) do
663
- @db.drop_table?(:people)
664
- Object.send(:remove_const, :Person)
665
- end
666
-
667
- it "should raise an error when updating a stale record" do
668
- p1 = Person[@p.id]
669
- p2 = Person[@p.id]
670
- p1.update(:name=>'Jim')
671
- proc{p2.update(:name=>'Bob')}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
672
- end
673
-
674
- it "should raise an error when destroying a stale record" do
675
- p1 = Person[@p.id]
676
- p2 = Person[@p.id]
677
- p1.update(:name=>'Jim')
678
- proc{p2.destroy}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
679
- end
680
-
681
- it "should not raise an error when updating the same record twice" do
682
- p1 = Person[@p.id]
683
- p1.update(:name=>'Jim')
684
- p1.update(:name=>'Bob')
685
- end
686
- end
687
-
688
- describe "Composition plugin" do
689
- before do
690
- @db = DB
691
- @db.create_table!(:events) do
692
- primary_key :id
693
- Integer :year
694
- Integer :month
695
- Integer :day
696
- end
697
- class ::Event < Sequel::Model(@db)
698
- plugin :composition
699
- composition :date, :composer=>proc{Date.new(year, month, day) if year && month && day}, :decomposer=>(proc do
700
- if date
701
- self.year = date.year
702
- self.month = date.month
703
- self.day = date.day
704
- else
705
- self.year, self.month, self.day = nil
706
- end
707
- end)
708
- composition :date, :mapping=>[:year, :month, :day]
709
- end
710
- @e1 = Event.create(:year=>2010, :month=>2, :day=>15)
711
- @e2 = Event.create(:year=>nil)
712
- end
713
- after do
714
- @db.drop_table?(:events)
715
- Object.send(:remove_const, :Event)
716
- end
717
-
718
- it "should return a composed object if the underlying columns have a value" do
719
- @e1.date.must_equal Date.civil(2010, 2, 15)
720
- @e2.date.must_equal nil
721
- end
722
-
723
- it "should decompose the object when saving the record" do
724
- @e1.date = Date.civil(2009, 1, 2)
725
- @e1.save
726
- @e1.year.must_equal 2009
727
- @e1.month.must_equal 1
728
- @e1.day.must_equal 2
729
- end
730
-
731
- it "should save all columns when saving changes" do
732
- @e2.date = Date.civil(2009, 10, 2)
733
- @e2.save_changes
734
- @e2.reload
735
- @e2.year.must_equal 2009
736
- @e2.month.must_equal 10
737
- @e2.day.must_equal 2
738
- end
739
- end
740
-
741
- describe "RcteTree Plugin" do
742
- RcteTreePluginSpecs = shared_description do
743
- it "should load all standard (not-CTE) methods correctly" do
744
- @a.children.must_equal [@aa, @ab]
745
- @b.children.must_equal [@ba, @bb]
746
- @aa.children.must_equal [@aaa, @aab]
747
- @ab.children.must_equal [@aba, @abb]
748
- @ba.children.must_equal []
749
- @bb.children.must_equal []
750
- @aaa.children.must_equal [@aaaa, @aaab]
751
- @aab.children.must_equal []
752
- @aba.children.must_equal []
753
- @abb.children.must_equal []
754
- @aaaa.children.must_equal [@aaaaa]
755
- @aaab.children.must_equal []
756
- @aaaaa.children.must_equal []
757
-
758
- @a.parent.must_equal nil
759
- @b.parent.must_equal nil
760
- @aa.parent.must_equal @a
761
- @ab.parent.must_equal @a
762
- @ba.parent.must_equal @b
763
- @bb.parent.must_equal @b
764
- @aaa.parent.must_equal @aa
765
- @aab.parent.must_equal @aa
766
- @aba.parent.must_equal @ab
767
- @abb.parent.must_equal @ab
768
- @aaaa.parent.must_equal @aaa
769
- @aaab.parent.must_equal @aaa
770
- @aaaaa.parent.must_equal @aaaa
771
- end
772
-
773
- it "should load all ancestors and descendants lazily for a given instance" do
774
- @a.descendants.must_equal [@aa, @aaa, @aaaa, @aaaaa, @aaab, @aab, @ab, @aba, @abb]
775
- @b.descendants.must_equal [@ba, @bb]
776
- @aa.descendants.must_equal [@aaa, @aaaa, @aaaaa, @aaab, @aab]
777
- @ab.descendants.must_equal [@aba, @abb]
778
- @ba.descendants.must_equal []
779
- @bb.descendants.must_equal []
780
- @aaa.descendants.must_equal [@aaaa, @aaaaa, @aaab]
781
- @aab.descendants.must_equal []
782
- @aba.descendants.must_equal []
783
- @abb.descendants.must_equal []
784
- @aaaa.descendants.must_equal [@aaaaa]
785
- @aaab.descendants.must_equal []
786
- @aaaaa.descendants.must_equal []
787
-
788
- @a.ancestors.must_equal []
789
- @b.ancestors.must_equal []
790
- @aa.ancestors.must_equal [@a]
791
- @ab.ancestors.must_equal [@a]
792
- @ba.ancestors.must_equal [@b]
793
- @bb.ancestors.must_equal [@b]
794
- @aaa.ancestors.must_equal [@a, @aa]
795
- @aab.ancestors.must_equal [@a, @aa]
796
- @aba.ancestors.must_equal [@a, @ab]
797
- @abb.ancestors.must_equal [@a, @ab]
798
- @aaaa.ancestors.must_equal [@a, @aa, @aaa]
799
- @aaab.ancestors.must_equal [@a, @aa, @aaa]
800
- @aaaaa.ancestors.must_equal [@a, @aa, @aaa, @aaaa]
801
- end
802
-
803
- it "should eagerly load all ancestors and descendants for a dataset" do
804
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:ancestors, :descendants).all
805
- nodes.must_equal [@a, @aaa, @b]
806
- nodes[0].descendants.must_equal [@aa, @aaa, @aaaa, @aaaaa, @aaab, @aab, @ab, @aba, @abb]
807
- nodes[1].descendants.must_equal [@aaaa, @aaaaa, @aaab]
808
- nodes[2].descendants.must_equal [@ba, @bb]
809
- nodes[0].ancestors.must_equal []
810
- nodes[1].ancestors.must_equal [@a, @aa]
811
- nodes[2].ancestors.must_equal []
812
- end
813
-
814
- it "should eagerly load descendants to a given level" do
815
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>1).all
816
- nodes.must_equal [@a, @aaa, @b]
817
- nodes[0].descendants.must_equal [@aa, @ab]
818
- nodes[1].descendants.must_equal [@aaaa, @aaab]
819
- nodes[2].descendants.must_equal [@ba, @bb]
820
-
821
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>2).all
822
- nodes.must_equal [@a, @aaa, @b]
823
- nodes[0].descendants.must_equal [@aa, @aaa, @aab, @ab, @aba, @abb]
824
- nodes[1].descendants.must_equal [@aaaa, @aaaaa, @aaab]
825
- nodes[2].descendants.must_equal [@ba, @bb]
826
- end
827
-
828
- it "should populate all :children associations when eagerly loading descendants for a dataset" do
829
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants).all
830
- nodes[0].associations[:children].must_equal [@aa, @ab]
831
- nodes[1].associations[:children].must_equal [@aaaa, @aaab]
832
- nodes[2].associations[:children].must_equal [@ba, @bb]
833
- nodes[0].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaa, @aab], [@aba, @abb]]
834
- nodes[1].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaaaa], []]
835
- nodes[2].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[], []]
836
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[[@aaaa, @aaab], []], [[], []]]
837
- nodes[1].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[[]], []]
838
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children].map{|c3| c3.associations[:children]}}}.must_equal [[[[@aaaaa], []], []], [[], []]]
839
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children].map{|c3| c3.associations[:children].map{|c4| c4.associations[:children]}}}}.must_equal [[[[[]], []], []], [[], []]]
840
- end
841
-
842
- it "should not populate :children associations for final level when loading descendants to a given level" do
843
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>1).all
844
- nodes[0].associations[:children].must_equal [@aa, @ab]
845
- nodes[0].associations[:children].map{|c1| c1.associations[:children]}.must_equal [nil, nil]
846
- nodes[1].associations[:children].must_equal [@aaaa, @aaab]
847
- nodes[1].associations[:children].map{|c1| c1.associations[:children]}.must_equal [nil, nil]
848
- nodes[2].associations[:children].must_equal [@ba, @bb]
849
- nodes[2].associations[:children].map{|c1| c1.associations[:children]}.must_equal [nil, nil]
850
-
851
- nodes[0].associations[:children].map{|c1| c1.children}.must_equal [[@aaa, @aab], [@aba, @abb]]
852
- nodes[1].associations[:children].map{|c1| c1.children}.must_equal [[@aaaaa], []]
853
- nodes[2].associations[:children].map{|c1| c1.children}.must_equal [[], []]
854
-
855
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @b.pk, @aaa.pk]).order(:name).eager(:descendants=>2).all
856
- nodes[0].associations[:children].must_equal [@aa, @ab]
857
- nodes[0].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaa, @aab], [@aba, @abb]]
858
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[[@aaaa, @aaab], nil], [nil, nil]]
859
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| (cc2 = c2.associations[:children]) ? cc2.map{|c3| c3.associations[:children]} : nil}}.must_equal [[[[@aaaaa], []], nil], [nil, nil]]
860
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| (cc2 = c2.associations[:children]) ? cc2.map{|c3| (cc3 = c3.associations[:children]) ? cc3.map{|c4| c4.associations[:children]} : nil} : nil}}.must_equal [[[[nil], []], nil], [nil, nil]]
861
-
862
- nodes[1].associations[:children].must_equal [@aaaa, @aaab]
863
- nodes[1].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaaaa], []]
864
- nodes[1].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[nil], []]
865
-
866
- nodes[2].associations[:children].must_equal [@ba, @bb]
867
- nodes[2].associations[:children].map{|c1| c1.associations[:children]}.must_equal [[], []]
868
-
869
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.children}}.must_equal [[[@aaaa, @aaab], []], [[], []]]
870
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.children.map{|c3| c3.children}}}.must_equal [[[[@aaaaa], []], []], [[], []]]
871
- nodes[0].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.children.map{|c3| c3.children.map{|c4| c4.children}}}}.must_equal [[[[[]], []], []], [[], []]]
872
- nodes[1].associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.children}}.must_equal [[[]], []]
873
- end
874
-
875
- it "should populate all :children associations when lazily loading descendants" do
876
- @a.descendants
877
- @a.associations[:children].must_equal [@aa, @ab]
878
- @a.associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaa, @aab], [@aba, @abb]]
879
- @a.associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[[@aaaa, @aaab], []], [[], []]]
880
- @a.associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children].map{|c3| c3.associations[:children]}}}.must_equal [[[[@aaaaa], []], []], [[], []]]
881
- @a.associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children].map{|c3| c3.associations[:children].map{|c4| c4.associations[:children]}}}}.must_equal [[[[[]], []], []], [[], []]]
882
-
883
- @b.descendants
884
- @b.associations[:children].must_equal [@ba, @bb]
885
- @b.associations[:children].map{|c1| c1.associations[:children]}.must_equal [[], []]
886
-
887
- @aaa.descendants
888
- @aaa.associations[:children].map{|c1| c1.associations[:children]}.must_equal [[@aaaaa], []]
889
- @aaa.associations[:children].map{|c1| c1.associations[:children].map{|c2| c2.associations[:children]}}.must_equal [[[]], []]
890
- end
891
-
892
- it "should populate all :parent associations when eagerly loading ancestors for a dataset" do
893
- nodes = @Node.filter(@Node.primary_key=>[@a.pk, @ba.pk, @aaa.pk, @aaaaa.pk]).order(:name).eager(:ancestors).all
894
- nodes[0].associations.fetch(:parent, 1).must_equal nil
895
- nodes[1].associations[:parent].must_equal @aa
896
- nodes[1].associations[:parent].associations[:parent].must_equal @a
897
- nodes[1].associations[:parent].associations[:parent].associations.fetch(:parent, 1).must_equal nil
898
- nodes[2].associations[:parent].must_equal @aaaa
899
- nodes[2].associations[:parent].associations[:parent].must_equal @aaa
900
- nodes[2].associations[:parent].associations[:parent].associations[:parent].must_equal @aa
901
- nodes[2].associations[:parent].associations[:parent].associations[:parent].associations[:parent].must_equal @a
902
- nodes[2].associations[:parent].associations[:parent].associations[:parent].associations[:parent].associations.fetch(:parent, 1).must_equal nil
903
- nodes[3].associations[:parent].must_equal @b
904
- nodes[3].associations[:parent].associations.fetch(:parent, 1).must_equal nil
905
- end
906
-
907
- it "should populate all :parent associations when lazily loading ancestors" do
908
- @a.reload
909
- @a.ancestors
910
- @a.associations[:parent].must_equal nil
911
-
912
- @ba.reload
913
- @ba.ancestors
914
- @ba.associations[:parent].must_equal @b
915
- @ba.associations[:parent].associations.fetch(:parent, 1).must_equal nil
916
-
917
- @ba.reload
918
- @aaaaa.ancestors
919
- @aaaaa.associations[:parent].must_equal @aaaa
920
- @aaaaa.associations[:parent].associations[:parent].must_equal @aaa
921
- @aaaaa.associations[:parent].associations[:parent].associations[:parent].must_equal @aa
922
- @aaaaa.associations[:parent].associations[:parent].associations[:parent].associations[:parent].must_equal @a
923
- @aaaaa.associations[:parent].associations[:parent].associations[:parent].associations[:parent].associations.fetch(:parent, 1).must_equal nil
924
- end
925
- end
926
-
927
- before do
928
- @nodes.each{|n| n.associations.clear}
929
- end
930
-
931
- describe "with single key" do
932
- before(:all) do
933
- @db = DB
934
- @db.create_table!(:nodes) do
935
- primary_key :id
936
- Integer :parent_id
937
- String :name
938
- end
939
- @Node = Class.new(Sequel::Model(@db[:nodes]))
940
- @Node.plugin :rcte_tree, :order=>:name
941
- @nodes = []
942
- @nodes << @a = @Node.create(:name=>'a')
943
- @nodes << @b = @Node.create(:name=>'b')
944
- @nodes << @aa = @Node.create(:name=>'aa', :parent=>@a)
945
- @nodes << @ab = @Node.create(:name=>'ab', :parent=>@a)
946
- @nodes << @ba = @Node.create(:name=>'ba', :parent=>@b)
947
- @nodes << @bb = @Node.create(:name=>'bb', :parent=>@b)
948
- @nodes << @aaa = @Node.create(:name=>'aaa', :parent=>@aa)
949
- @nodes << @aab = @Node.create(:name=>'aab', :parent=>@aa)
950
- @nodes << @aba = @Node.create(:name=>'aba', :parent=>@ab)
951
- @nodes << @abb = @Node.create(:name=>'abb', :parent=>@ab)
952
- @nodes << @aaaa = @Node.create(:name=>'aaaa', :parent=>@aaa)
953
- @nodes << @aaab = @Node.create(:name=>'aaab', :parent=>@aaa)
954
- @nodes << @aaaaa = @Node.create(:name=>'aaaaa', :parent=>@aaaa)
955
- end
956
- after(:all) do
957
- @db.drop_table? :nodes
958
- end
959
-
960
- include RcteTreePluginSpecs
961
-
962
- it "should work correctly if not all columns are selected" do
963
- c = Class.new(Sequel::Model(@db[:nodes]))
964
- c.plugin :rcte_tree, :order=>:name
965
- c.plugin :lazy_attributes, :name
966
- c[:name=>'aaaa'].descendants.must_equal [c.load(:parent_id=>11, :id=>13)]
967
- c[:name=>'aa'].ancestors.must_equal [c.load(:parent_id=>nil, :id=>1)]
968
- nodes = c.filter(:id=>[@a.id, @b.id, @aaa.id]).order(:name).eager(:ancestors, :descendants).all
969
- nodes.must_equal [{:parent_id=>nil, :id=>1}, {:parent_id=>3, :id=>7}, {:parent_id=>nil, :id=>2}].map{|x| c.load(x)}
970
- nodes[2].descendants.must_equal [{:parent_id=>2, :id=>5}, {:parent_id=>2, :id=>6}].map{|x| c.load(x)}
971
- nodes[1].ancestors.must_equal [{:parent_id=>nil, :id=>1}, {:parent_id=>1, :id=>3}].map{|x| c.load(x)}
972
- end
973
- end
974
-
975
- describe "with composite keys" do
976
- before(:all) do
977
- @db = DB
978
- @db.create_table!(:nodes) do
979
- Integer :id
980
- Integer :id2
981
- Integer :parent_id
982
- Integer :parent_id2
983
- String :name
984
- primary_key [:id, :id2]
985
- end
986
- @Node = Class.new(Sequel::Model(@db[:nodes]))
987
- @Node.plugin :rcte_tree, :order=>:name, :key=>[:parent_id, :parent_id2]
988
- @Node.unrestrict_primary_key
989
- @nodes = []
990
- @nodes << @a = @Node.create(:id=>1, :id2=>1, :name=>'a')
991
- @nodes << @b = @Node.create(:id=>1, :id2=>2, :name=>'b')
992
- @nodes << @aa = @Node.create(:id=>2, :id2=>1, :name=>'aa', :parent=>@a)
993
- @nodes << @ab = @Node.create(:id=>2, :id2=>2, :name=>'ab', :parent=>@a)
994
- @nodes << @ba = @Node.create(:id=>3, :id2=>1, :name=>'ba', :parent=>@b)
995
- @nodes << @bb = @Node.create(:id=>3, :id2=>2, :name=>'bb', :parent=>@b)
996
- @nodes << @aaa = @Node.create(:id=>3, :id2=>3, :name=>'aaa', :parent=>@aa)
997
- @nodes << @aab = @Node.create(:id=>1, :id2=>3, :name=>'aab', :parent=>@aa)
998
- @nodes << @aba = @Node.create(:id=>2, :id2=>3, :name=>'aba', :parent=>@ab)
999
- @nodes << @abb = @Node.create(:id=>4, :id2=>1, :name=>'abb', :parent=>@ab)
1000
- @nodes << @aaaa = @Node.create(:id=>1, :id2=>4, :name=>'aaaa', :parent=>@aaa)
1001
- @nodes << @aaab = @Node.create(:id=>2, :id2=>4, :name=>'aaab', :parent=>@aaa)
1002
- @nodes << @aaaaa = @Node.create(:id=>3, :id2=>4, :name=>'aaaaa', :parent=>@aaaa)
1003
- end
1004
- after(:all) do
1005
- @db.drop_table? :nodes
1006
- end
1007
-
1008
- include RcteTreePluginSpecs
1009
- end
1010
- end if DB.dataset.supports_cte? and !Sequel.guarded?(:db2)
1011
-
1012
- describe "Instance Filters plugin" do
1013
- before(:all) do
1014
- @db = DB
1015
- @db.create_table!(:items) do
1016
- primary_key :id
1017
- String :name
1018
- Integer :cost
1019
- Integer :number
1020
- end
1021
- class ::Item < Sequel::Model(@db)
1022
- plugin :instance_filters
1023
- end
1024
- end
1025
- before do
1026
- @db[:items].delete
1027
- @i = Item.create(:name=>'J', :number=>1, :cost=>2)
1028
- @i.instance_filter(:number=>1)
1029
- @i.set(:name=>'K')
1030
- end
1031
- after(:all) do
1032
- @db.drop_table?(:items)
1033
- Object.send(:remove_const, :Item)
1034
- end
1035
-
1036
- it "should not raise an error if saving only updates one row" do
1037
- @i.save
1038
- @i.refresh.name.must_equal 'K'
1039
- end
1040
-
1041
- it "should raise error if saving doesn't update a row" do
1042
- @i.this.update(:number=>2)
1043
- proc{@i.save}.must_raise(Sequel::NoExistingObject)
1044
- end
1045
-
1046
- it "should apply all instance filters" do
1047
- @i.instance_filter{cost <= 2}
1048
- @i.this.update(:number=>2)
1049
- proc{@i.save}.must_raise(Sequel::NoExistingObject)
1050
- @i.this.update(:number=>1, :cost=>3)
1051
- proc{@i.save}.must_raise(Sequel::NoExistingObject)
1052
- @i.this.update(:cost=>2)
1053
- @i.save
1054
- @i.refresh.name.must_equal 'K'
1055
- end
1056
-
1057
- it "should clear instance filters after successful save" do
1058
- @i.save
1059
- @i.this.update(:number=>2)
1060
- @i.update(:name=>'L')
1061
- @i.refresh.name.must_equal 'L'
1062
- end
1063
-
1064
- it "should not raise an error if deleting only deletes one row" do
1065
- @i.destroy
1066
- proc{@i.refresh}.must_raise(Sequel::Error, 'Record not found')
1067
- end
1068
-
1069
- it "should raise error if destroying doesn't delete a row" do
1070
- @i.this.update(:number=>2)
1071
- proc{@i.destroy}.must_raise(Sequel::NoExistingObject)
1072
- end
1073
- end
1074
-
1075
- describe "UpdatePrimaryKey plugin" do
1076
- before(:all) do
1077
- @db = DB
1078
- @db.create_table!(:t) do
1079
- Integer :a, :primary_key=>true
1080
- Integer :b
1081
- end
1082
- @ds = @db[:t]
1083
- @c = Class.new(Sequel::Model(@ds))
1084
- @c.set_primary_key(:a)
1085
- @c.unrestrict_primary_key
1086
- @c.plugin :update_primary_key
1087
- end
1088
- before do
1089
- @ds.delete
1090
- @ds.insert(:a=>1, :b=>3)
1091
- end
1092
- after(:all) do
1093
- @db.drop_table?(:t)
1094
- end
1095
-
1096
- it "should handle regular updates" do
1097
- @c.first.update(:b=>4)
1098
- @db[:t].all.must_equal [{:a=>1, :b=>4}]
1099
- @c.first.set(:b=>5).save
1100
- @db[:t].all.must_equal [{:a=>1, :b=>5}]
1101
- @c.first.set(:b=>6).save(:columns=>:b)
1102
- @db[:t].all.must_equal [{:a=>1, :b=>6}]
1103
- end
1104
-
1105
- it "should handle updating the primary key field with another field" do
1106
- @c.first.update(:a=>2, :b=>4)
1107
- @db[:t].all.must_equal [{:a=>2, :b=>4}]
1108
- end
1109
-
1110
- it "should handle updating just the primary key field when saving changes" do
1111
- @c.first.update(:a=>2)
1112
- @db[:t].all.must_equal [{:a=>2, :b=>3}]
1113
- @c.first.set(:a=>3).save(:columns=>:a)
1114
- @db[:t].all.must_equal [{:a=>3, :b=>3}]
1115
- end
1116
-
1117
- it "should handle saving after modifying the primary key field with another field" do
1118
- @c.first.set(:a=>2, :b=>4).save
1119
- @db[:t].all.must_equal [{:a=>2, :b=>4}]
1120
- end
1121
-
1122
- it "should handle saving after modifying just the primary key field" do
1123
- @c.first.set(:a=>2).save
1124
- @db[:t].all.must_equal [{:a=>2, :b=>3}]
1125
- end
1126
-
1127
- it "should handle saving after updating the primary key" do
1128
- @c.first.update(:a=>2).update(:b=>4).set(:b=>5).save
1129
- @db[:t].all.must_equal [{:a=>2, :b=>5}]
1130
- end
1131
- end
1132
-
1133
- describe "AssociationPks plugin" do
1134
- before(:all) do
1135
- @db = DB
1136
- @db.drop_table?(:albums_tags, :albums_vocalists, :vocalists_instruments, :vocalists_hits, :hits, :instruments, :vocalists, :tags, :albums, :artists)
1137
- @db.create_table(:artists) do
1138
- primary_key :id
1139
- String :name
1140
- end
1141
- @db.create_table(:albums) do
1142
- primary_key :id
1143
- String :name
1144
- foreign_key :artist_id, :artists
1145
- end
1146
- @db.create_table(:tags) do
1147
- primary_key :id
1148
- String :name
1149
- end
1150
- @db.create_table(:albums_tags) do
1151
- foreign_key :album_id, :albums
1152
- foreign_key :tag_id, :tags
1153
- end
1154
- @db.create_table(:vocalists) do
1155
- String :first
1156
- String :last
1157
- primary_key [:first, :last]
1158
- foreign_key :album_id, :albums
1159
- end
1160
- @db.create_table(:albums_vocalists) do
1161
- foreign_key :album_id, :albums
1162
- String :first
1163
- String :last
1164
- foreign_key [:first, :last], :vocalists
1165
- end
1166
- @db.create_table(:instruments) do
1167
- primary_key :id
1168
- String :first
1169
- String :last
1170
- foreign_key [:first, :last], :vocalists
1171
- end
1172
- @db.create_table(:vocalists_instruments) do
1173
- String :first
1174
- String :last
1175
- foreign_key [:first, :last], :vocalists
1176
- foreign_key :instrument_id, :instruments
1177
- end
1178
- @db.create_table(:hits) do
1179
- Integer :year
1180
- Integer :week
1181
- primary_key [:year, :week]
1182
- String :first
1183
- String :last
1184
- foreign_key [:first, :last], :vocalists
1185
- end
1186
- @db.create_table(:vocalists_hits) do
1187
- String :first
1188
- String :last
1189
- foreign_key [:first, :last], :vocalists
1190
- Integer :year
1191
- Integer :week
1192
- foreign_key [:year, :week], :hits
1193
- end
1194
- class ::Artist < Sequel::Model
1195
- plugin :association_pks
1196
- one_to_many :albums, :order=>:id
1197
- end
1198
- class ::Album < Sequel::Model
1199
- plugin :association_pks
1200
- many_to_many :tags, :order=>:id
1201
- end
1202
- class ::Tag < Sequel::Model
1203
- end
1204
- class ::Vocalist < Sequel::Model
1205
- set_primary_key [:first, :last]
1206
- plugin :association_pks
1207
- end
1208
- class ::Instrument < Sequel::Model
1209
- plugin :association_pks
1210
- end
1211
- class ::Hit < Sequel::Model
1212
- set_primary_key [:year, :week]
1213
- end
1214
- end
1215
- before do
1216
- [:albums_tags, :albums_vocalists, :vocalists_instruments, :vocalists_hits, :hits, :instruments, :vocalists, :tags, :albums, :artists].each{|t| @db[t].delete}
1217
- @ar1 =@db[:artists].insert(:name=>'YJM')
1218
- @ar2 =@db[:artists].insert(:name=>'AS')
1219
- @al1 =@db[:albums].insert(:name=>'RF', :artist_id=>@ar1)
1220
- @al2 =@db[:albums].insert(:name=>'MO', :artist_id=>@ar1)
1221
- @al3 =@db[:albums].insert(:name=>'T', :artist_id=>@ar1)
1222
- @t1 = @db[:tags].insert(:name=>'A')
1223
- @t2 = @db[:tags].insert(:name=>'B')
1224
- @t3 = @db[:tags].insert(:name=>'C')
1225
- {@al1=>[@t1, @t2, @t3], @al2=>[@t2]}.each do |aid, tids|
1226
- tids.each{|tid| @db[:albums_tags].insert([aid, tid])}
1227
- end
1228
- @v1 = ['F1', 'L1']
1229
- @v2 = ['F2', 'L2']
1230
- @v3 = ['F3', 'L3']
1231
- @db[:vocalists].insert(@v1 + [@al1])
1232
- @db[:vocalists].insert(@v2 + [@al1])
1233
- @db[:vocalists].insert(@v3 + [@al1])
1234
- @i1 = @db[:instruments].insert([:first, :last], @v1)
1235
- @i2 = @db[:instruments].insert([:first, :last], @v1)
1236
- @i3 = @db[:instruments].insert([:first, :last], @v1)
1237
- @h1 = [1997, 1]
1238
- @h2 = [1997, 2]
1239
- @h3 = [1997, 3]
1240
- @db[:hits].insert(@h1 + @v1)
1241
- @db[:hits].insert(@h2 + @v1)
1242
- @db[:hits].insert(@h3 + @v1)
1243
- {@al1=>[@v1, @v2, @v3], @al2=>[@v2]}.each do |aid, vids|
1244
- vids.each{|vid| @db[:albums_vocalists].insert([aid] + vid)}
1245
- end
1246
- {@v1=>[@i1, @i2, @i3], @v2=>[@i2]}.each do |vid, iids|
1247
- iids.each{|iid| @db[:vocalists_instruments].insert(vid + [iid])}
1248
- end
1249
- {@v1=>[@h1, @h2, @h3], @v2=>[@h2]}.each do |vid, hids|
1250
- hids.each{|hid| @db[:vocalists_hits].insert(vid + hid)}
1251
- end
1252
- end
1253
- after(:all) do
1254
- @db.drop_table? :albums_tags, :albums_vocalists, :vocalists_instruments, :vocalists_hits, :hits, :instruments, :vocalists, :tags, :albums, :artists
1255
- [:Artist, :Album, :Tag, :Vocalist, :Instrument, :Hit].each{|s| Object.send(:remove_const, s)}
1256
- end
1257
-
1258
- it "should return correct associated pks for one_to_many associations" do
1259
- Artist.order(:id).all.map{|a| a.album_pks}.must_equal [[@al1, @al2, @al3], []]
1260
- end
1261
-
1262
- it "should return correct associated pks for many_to_many associations" do
1263
- Album.order(:id).all.map{|a| a.tag_pks.sort}.must_equal [[@t1, @t2, @t3], [@t2], []]
1264
- end
1265
-
1266
- it "should return correct associated right-side cpks for one_to_many associations" do
1267
- Album.one_to_many :vocalists, :order=>:first
1268
- Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [], []]
1269
- end
1270
-
1271
- it "should return correct associated right-side cpks for many_to_many associations" do
1272
- Album.many_to_many :vocalists, :join_table=>:albums_vocalists, :right_key=>[:first, :last], :order=>:first
1273
- Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [@v2], []]
1274
- end
1275
-
1276
- it "should return correct associated pks for left-side cpks for one_to_many associations" do
1277
- Vocalist.one_to_many :instruments, :key=>[:first, :last], :order=>:id
1278
- Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [], []]
1279
- end
1280
-
1281
- it "should return correct associated pks for left-side cpks for many_to_many associations" do
1282
- Vocalist.many_to_many :instruments, :join_table=>:vocalists_instruments, :left_key=>[:first, :last], :order=>:id
1283
- Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [@i2], []]
1284
- end
1285
-
1286
- it "should return correct associated right-side cpks for left-side cpks for one_to_many associations" do
1287
- Vocalist.one_to_many :hits, :key=>[:first, :last], :order=>:week
1288
- Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [], []]
1289
- end
1290
-
1291
- it "should return correct associated right-side cpks for left-side cpks for many_to_many associations" do
1292
- Vocalist.many_to_many :hits, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :order=>:week
1293
- Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [@h2], []]
1294
- end
1295
-
1296
- it "should handle :delay association option for new instances" do
1297
- album_class = Class.new(Album)
1298
- album_class.many_to_many :tags, :clone=>:tags, :delay_pks=>true, :join_table=>:albums_tags, :left_key=>:album_id
1299
- album = album_class.new(:name=>'test album')
1300
- album.tag_pks.must_equal []
1301
- album.tag_pks = [@t1, @t2]
1302
- album.tag_pks.must_equal [@t1, @t2]
1303
- album.save
1304
- album_class.with_pk!(album.pk).tag_pks.sort.must_equal [@t1, @t2]
1305
- end
1306
-
1307
- it "should handle :delay=>:all association option for existing instances" do
1308
- album_class = Class.new(Album)
1309
- album_class.many_to_many :tags, :clone=>:tags, :delay_pks=>:always, :join_table=>:albums_tags, :left_key=>:album_id
1310
- album = album_class.with_pk!(@al1)
1311
- album.tag_pks.sort.must_equal [@t1, @t2, @t3]
1312
- album.tag_pks = [@t1, @t2]
1313
- album.tag_pks.must_equal [@t1, @t2]
1314
- album.save_changes
1315
- album_class.with_pk!(album.pk).tag_pks.sort.must_equal [@t1, @t2]
1316
- end
1317
-
1318
- it "should set associated pks correctly for a one_to_many association" do
1319
- Artist.use_transactions = true
1320
- Album.order(:id).select_map(:artist_id).must_equal [@ar1, @ar1, @ar1]
1321
-
1322
- Artist[@ar2].album_pks = [@al1, @al3]
1323
- Artist[@ar1].album_pks.must_equal [@al2]
1324
- Album.order(:id).select_map(:artist_id).must_equal [@ar2, @ar1, @ar2]
1325
-
1326
- Artist[@ar1].album_pks = [@al1]
1327
- Artist[@ar2].album_pks.must_equal [@al3]
1328
- Album.order(:id).select_map(:artist_id).must_equal [@ar1, nil, @ar2]
1329
-
1330
- Artist[@ar1].album_pks = [@al1, @al2]
1331
- Artist[@ar2].album_pks.must_equal [@al3]
1332
- Album.order(:id).select_map(:artist_id).must_equal [@ar1, @ar1, @ar2]
1333
- end
1334
-
1335
- it "should set associated pks correctly for a many_to_many association" do
1336
- Artist.use_transactions = true
1337
- @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).must_equal [@t1, @t2, @t3]
1338
- Album[@al1].tag_pks = [@t1, @t3]
1339
- @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).must_equal [@t1, @t3]
1340
- Album[@al1].tag_pks = []
1341
- @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).must_equal []
1342
-
1343
- @db[:albums_tags].filter(:album_id=>@al2).select_order_map(:tag_id).must_equal [@t2]
1344
- Album[@al2].tag_pks = [@t1, @t2]
1345
- @db[:albums_tags].filter(:album_id=>@al2).select_order_map(:tag_id).must_equal [@t1, @t2]
1346
- Album[@al2].tag_pks = []
1347
- @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).must_equal []
1348
-
1349
- @db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).must_equal []
1350
- Album[@al3].tag_pks = [@t1, @t3]
1351
- @db[:albums_tags].filter(:album_id=>@al3).select_order_map(:tag_id).must_equal [@t1, @t3]
1352
- Album[@al3].tag_pks = []
1353
- @db[:albums_tags].filter(:album_id=>@al1).select_order_map(:tag_id).must_equal []
1354
- end
1355
-
1356
- it "should set associated right-side cpks correctly for a one_to_many association" do
1357
- Album.use_transactions = true
1358
- Album.one_to_many :vocalists, :order=>:first
1359
- Album.order(:id).all.map{|a| a.vocalist_pks.sort}.must_equal [[@v1, @v2, @v3], [], []]
1360
-
1361
- Album[@al2].vocalist_pks = [@v1, @v3]
1362
- Album[@al1].vocalist_pks.must_equal [@v2]
1363
- Vocalist.order(:first, :last).select_map(:album_id).must_equal [@al2, @al1, @al2]
1364
-
1365
- Album[@al1].vocalist_pks = [@v1]
1366
- Album[@al2].vocalist_pks.must_equal [@v3]
1367
- Vocalist.order(:first, :last).select_map(:album_id).must_equal [@al1, nil, @al2]
1368
-
1369
- Album[@al1].vocalist_pks = [@v1, @v2]
1370
- Album[@al2].vocalist_pks.must_equal [@v3]
1371
- Vocalist.order(:first, :last).select_map(:album_id).must_equal [@al1, @al1, @al2]
1372
- end
1373
-
1374
- it "should set associated right-side cpks correctly for a many_to_many association" do
1375
- Album.use_transactions = true
1376
- Album.many_to_many :vocalists, :join_table=>:albums_vocalists, :right_key=>[:first, :last], :order=>:first
1377
-
1378
- @db[:albums_vocalists].filter(:album_id=>@al1).select_order_map([:first, :last]).must_equal [@v1, @v2, @v3]
1379
- Album[@al1].vocalist_pks = [@v1, @v3]
1380
- @db[:albums_vocalists].filter(:album_id=>@al1).select_order_map([:first, :last]).must_equal [@v1, @v3]
1381
- Album[@al1].vocalist_pks = []
1382
- @db[:albums_vocalists].filter(:album_id=>@al1).select_order_map([:first, :last]).must_equal []
1383
-
1384
- @db[:albums_vocalists].filter(:album_id=>@al2).select_order_map([:first, :last]).must_equal [@v2]
1385
- Album[@al2].vocalist_pks = [@v1, @v2]
1386
- @db[:albums_vocalists].filter(:album_id=>@al2).select_order_map([:first, :last]).must_equal [@v1, @v2]
1387
- Album[@al2].vocalist_pks = []
1388
- @db[:albums_vocalists].filter(:album_id=>@al1).select_order_map([:first, :last]).must_equal []
1389
-
1390
- @db[:albums_vocalists].filter(:album_id=>@al3).select_order_map([:first, :last]).must_equal []
1391
- Album[@al3].vocalist_pks = [@v1, @v3]
1392
- @db[:albums_vocalists].filter(:album_id=>@al3).select_order_map([:first, :last]).must_equal [@v1, @v3]
1393
- Album[@al3].vocalist_pks = []
1394
- @db[:albums_vocalists].filter(:album_id=>@al1).select_order_map([:first, :last]).must_equal []
1395
- end
1396
-
1397
- it "should set associated pks correctly with left-side cpks for a one_to_many association" do
1398
- Vocalist.use_transactions = true
1399
- Vocalist.one_to_many :instruments, :key=>[:first, :last], :order=>:id
1400
- Vocalist.order(:first, :last).all.map{|a| a.instrument_pks.sort}.must_equal [[@i1, @i2, @i3], [], []]
1401
-
1402
- Vocalist[@v2].instrument_pks = [@i1, @i3]
1403
- Vocalist[@v1].instrument_pks.must_equal [@i2]
1404
- Instrument.order(:id).select_map([:first, :last]).must_equal [@v2, @v1, @v2]
1405
-
1406
- Vocalist[@v1].instrument_pks = [@i1]
1407
- Vocalist[@v2].instrument_pks.must_equal [@i3]
1408
- Instrument.order(:id).select_map([:first, :last]).must_equal [@v1, [nil, nil], @v2]
1409
-
1410
- Vocalist[@v1].instrument_pks = [@i1, @i2]
1411
- Vocalist[@v2].instrument_pks.must_equal [@i3]
1412
- Instrument.order(:id).select_map([:first, :last]).must_equal [@v1, @v1, @v2]
1413
- end
1414
-
1415
- it "should set associated pks correctly with left-side cpks for a many_to_many association" do
1416
- Vocalist.use_transactions = true
1417
- Vocalist.many_to_many :instruments, :join_table=>:vocalists_instruments, :left_key=>[:first, :last], :order=>:id
1418
-
1419
- @db[:vocalists_instruments].filter([:first, :last]=>[@v1]).select_order_map(:instrument_id).must_equal [@i1, @i2, @i3]
1420
- Vocalist[@v1].instrument_pks = [@i1, @i3]
1421
- @db[:vocalists_instruments].filter([:first, :last]=>[@v1]).select_order_map(:instrument_id).must_equal [@i1, @i3]
1422
- Vocalist[@v1].instrument_pks = []
1423
- @db[:vocalists_instruments].filter([:first, :last]=>[@v1]).select_order_map(:instrument_id).must_equal []
1424
-
1425
- @db[:vocalists_instruments].filter([:first, :last]=>[@v2]).select_order_map(:instrument_id).must_equal [@i2]
1426
- Vocalist[@v2].instrument_pks = [@i1, @i2]
1427
- @db[:vocalists_instruments].filter([:first, :last]=>[@v2]).select_order_map(:instrument_id).must_equal [@i1, @i2]
1428
- Vocalist[@v2].instrument_pks = []
1429
- @db[:vocalists_instruments].filter([:first, :last]=>[@v1]).select_order_map(:instrument_id).must_equal []
1430
-
1431
- @db[:vocalists_instruments].filter([:first, :last]=>[@v3]).select_order_map(:instrument_id).must_equal []
1432
- Vocalist[@v3].instrument_pks = [@i1, @i3]
1433
- @db[:vocalists_instruments].filter([:first, :last]=>[@v3]).select_order_map(:instrument_id).must_equal [@i1, @i3]
1434
- Vocalist[@v3].instrument_pks = []
1435
- @db[:vocalists_instruments].filter([:first, :last]=>[@v1]).select_order_map(:instrument_id).must_equal []
1436
- end
1437
-
1438
- it "should set associated right-side cpks correctly with left-side cpks for a one_to_many association" do
1439
- Vocalist.use_transactions = true
1440
- Vocalist.one_to_many :hits, :key=>[:first, :last], :order=>:week
1441
- Vocalist.order(:first, :last).all.map{|a| a.hit_pks.sort}.must_equal [[@h1, @h2, @h3], [], []]
1442
-
1443
- Vocalist[@v2].hit_pks = [@h1, @h3]
1444
- Vocalist[@v1].hit_pks.must_equal [@h2]
1445
- Hit.order(:year, :week).select_map([:first, :last]).must_equal [@v2, @v1, @v2]
1446
-
1447
- Vocalist[@v1].hit_pks = [@h1]
1448
- Vocalist[@v2].hit_pks.must_equal [@h3]
1449
- Hit.order(:year, :week).select_map([:first, :last]).must_equal [@v1, [nil, nil], @v2]
1450
-
1451
- Vocalist[@v1].hit_pks = [@h1, @h2]
1452
- Vocalist[@v2].hit_pks.must_equal [@h3]
1453
- Hit.order(:year, :week).select_map([:first, :last]).must_equal [@v1, @v1, @v2]
1454
- end
1455
-
1456
- it "should set associated right-side cpks correctly with left-side cpks for a many_to_many association" do
1457
- Vocalist.use_transactions = true
1458
- Vocalist.many_to_many :hits, :join_table=>:vocalists_hits, :left_key=>[:first, :last], :right_key=>[:year, :week], :order=>:week
1459
-
1460
- @db[:vocalists_hits].filter([:first, :last]=>[@v1]).select_order_map([:year, :week]).must_equal [@h1, @h2, @h3]
1461
- Vocalist[@v1].hit_pks = [@h1, @h3]
1462
- @db[:vocalists_hits].filter([:first, :last]=>[@v1]).select_order_map([:year, :week]).must_equal [@h1, @h3]
1463
- Vocalist[@v1].hit_pks = []
1464
- @db[:vocalists_hits].filter([:first, :last]=>[@v1]).select_order_map([:year, :week]).must_equal []
1465
-
1466
- @db[:vocalists_hits].filter([:first, :last]=>[@v2]).select_order_map([:year, :week]).must_equal [@h2]
1467
- Vocalist[@v2].hit_pks = [@h1, @h2]
1468
- @db[:vocalists_hits].filter([:first, :last]=>[@v2]).select_order_map([:year, :week]).must_equal [@h1, @h2]
1469
- Vocalist[@v2].hit_pks = []
1470
- @db[:vocalists_hits].filter([:first, :last]=>[@v1]).select_order_map([:year, :week]).must_equal []
1471
-
1472
- @db[:vocalists_hits].filter([:first, :last]=>[@v3]).select_order_map([:year, :week]).must_equal []
1473
- Vocalist[@v3].hit_pks = [@h1, @h3]
1474
- @db[:vocalists_hits].filter([:first, :last]=>[@v3]).select_order_map([:year, :week]).must_equal [@h1, @h3]
1475
- Vocalist[@v3].hit_pks = []
1476
- @db[:vocalists_hits].filter([:first, :last]=>[@v1]).select_order_map([:year, :week]).must_equal []
1477
- end
1478
- end
1479
-
1480
- describe "List plugin without a scope" do
1481
- before(:all) do
1482
- @db = DB
1483
- @db.create_table!(:sites) do
1484
- primary_key :id
1485
- String :name
1486
- Integer :position
1487
- end
1488
-
1489
- @c = Class.new(Sequel::Model(@db[:sites]))
1490
- @c.plugin :list
1491
- end
1492
- before do
1493
- @c.dataset.delete
1494
- @c.create :name => "abc"
1495
- @c.create :name => "def"
1496
- @c.create :name => "hig"
1497
- end
1498
- after(:all) do
1499
- @db.drop_table?(:sites)
1500
- end
1501
-
1502
- it "should return rows in order of position" do
1503
- @c.map(:position).must_equal [1,2,3]
1504
- @c.map(:name).must_equal %w[ abc def hig ]
1505
- end
1506
-
1507
- it "should define prev and next" do
1508
- i = @c[:name => "abc"]
1509
- i.prev.must_equal nil
1510
- i = @c[:name => "def"]
1511
- i.prev.must_equal @c[:name => "abc"]
1512
- i.next.must_equal @c[:name => "hig"]
1513
- i = @c[:name => "hig"]
1514
- i.next.must_equal nil
1515
- end
1516
-
1517
- it "should define move_to" do
1518
- @c[:name => "def"].move_to(1)
1519
- @c.map(:name).must_equal %w[ def abc hig ]
1520
-
1521
- @c[:name => "abc"].move_to(3)
1522
- @c.map(:name).must_equal %w[ def hig abc ]
1523
-
1524
- @c[:name => "abc"].move_to(-1)
1525
- @c.map(:name).must_equal %w[ abc def hig ]
1526
- @c[:name => "abc"].move_to(10)
1527
- @c.map(:name).must_equal %w[ def hig abc ]
1528
- end
1529
-
1530
- it "should define move_to_top and move_to_bottom" do
1531
- @c[:name => "def"].move_to_top
1532
- @c.map(:name).must_equal %w[ def abc hig ]
1533
-
1534
- @c[:name => "def"].move_to_bottom
1535
- @c.map(:name).must_equal %w[ abc hig def ]
1536
- end
1537
-
1538
- it "should define move_up and move_down" do
1539
- @c[:name => "def"].move_up
1540
- @c.map(:name).must_equal %w[ def abc hig ]
1541
-
1542
- @c[:name => "abc"].move_down
1543
- @c.map(:name).must_equal %w[ def hig abc ]
1544
-
1545
- @c[:name => "abc"].move_up(2)
1546
- @c.map(:name).must_equal %w[ abc def hig ]
1547
-
1548
- @c[:name => "abc"].move_down(2)
1549
- @c.map(:name).must_equal %w[ def hig abc ]
1550
-
1551
- @c[:name => "abc"].move_up(10)
1552
- @c.map(:name).must_equal %w[ abc def hig ]
1553
- @c[:name => "abc"].move_down(10)
1554
- @c.map(:name).must_equal %w[ def hig abc ]
1555
- end
1556
-
1557
- it "should update positions on destroy" do
1558
- @c[:name => "def"].destroy
1559
- @c.select_map([:position, :name]).must_equal [[1, 'abc'], [2, 'hig']]
1560
- end
1561
- end
1562
-
1563
- describe "List plugin with a scope" do
1564
- before(:all) do
1565
- @db = DB
1566
- @db.create_table!(:pages) do
1567
- primary_key :id
1568
- String :name
1569
- Integer :pos
1570
- Integer :parent_id
1571
- end
1572
-
1573
- @c = Class.new(Sequel::Model(@db[:pages]))
1574
- @c.plugin :list, :field => :pos, :scope => :parent_id
1575
- end
1576
- before do
1577
- @c.dataset.delete
1578
- p1 = @c.create :name => "Hm", :parent_id => 0
1579
- p2 = @c.create :name => "Ps", :parent_id => p1.id
1580
- @c.create :name => "P1", :parent_id => p2.id
1581
- @c.create :name => "P2", :parent_id => p2.id
1582
- @c.create :name => "P3", :parent_id => p2.id
1583
- @c.create :name => "Au", :parent_id => p1.id
1584
- end
1585
- after(:all) do
1586
- @db.drop_table?(:pages)
1587
- end
1588
-
1589
- it "should return rows in order of position" do
1590
- @c.map(:name).must_equal %w[ Hm Ps Au P1 P2 P3 ]
1591
- end
1592
-
1593
- it "should define prev and next" do
1594
- @c[:name => "Ps"].next.name.must_equal 'Au'
1595
- @c[:name => "Au"].prev.name.must_equal 'Ps'
1596
- @c[:name => "P1"].next.name.must_equal 'P2'
1597
- @c[:name => "P2"].prev.name.must_equal 'P1'
1598
-
1599
- @c[:name => "P1"].next(2).name.must_equal 'P3'
1600
- @c[:name => "P2"].next(-1).name.must_equal 'P1'
1601
- @c[:name => "P3"].prev(2).name.must_equal 'P1'
1602
- @c[:name => "P2"].prev(-1).name.must_equal 'P3'
1603
-
1604
- @c[:name => "Ps"].prev.must_equal nil
1605
- @c[:name => "Au"].next.must_equal nil
1606
- @c[:name => "P1"].prev.must_equal nil
1607
- @c[:name => "P3"].next.must_equal nil
1608
- end
1609
-
1610
- it "should define move_to" do
1611
- @c[:name => "P2"].move_to(1)
1612
- @c.map(:name).must_equal %w[ Hm Ps Au P2 P1 P3 ]
1613
-
1614
- @c[:name => "P2"].move_to(3)
1615
- @c.map(:name).must_equal %w[ Hm Ps Au P1 P3 P2 ]
1616
-
1617
- @c[:name => "P2"].move_to(-1)
1618
- @c.map(:name).must_equal %w[ Hm Ps Au P2 P1 P3 ]
1619
- @c[:name => "P2"].move_to(10)
1620
- @c.map(:name).must_equal %w[ Hm Ps Au P1 P3 P2 ]
1621
- end
1622
-
1623
- it "should define move_to_top and move_to_bottom" do
1624
- @c[:name => "Au"].move_to_top
1625
- @c.map(:name).must_equal %w[ Hm Au Ps P1 P2 P3 ]
1626
-
1627
- @c[:name => "Au"].move_to_bottom
1628
- @c.map(:name).must_equal %w[ Hm Ps Au P1 P2 P3 ]
1629
- end
1630
-
1631
- it "should define move_up and move_down" do
1632
- @c[:name => "P2"].move_up
1633
- @c.map(:name).must_equal %w[ Hm Ps Au P2 P1 P3 ]
1634
-
1635
- @c[:name => "P1"].move_down
1636
- @c.map(:name).must_equal %w[ Hm Ps Au P2 P3 P1 ]
1637
-
1638
- @c[:name => "P1"].move_up(10)
1639
- @c.map(:name).must_equal %w[ Hm Ps Au P1 P2 P3 ]
1640
- @c[:name => "P1"].move_down(10)
1641
- @c.map(:name).must_equal %w[ Hm Ps Au P2 P3 P1 ]
1642
- end
1643
-
1644
- it "should update positions on destroy" do
1645
- @c[:name => "P2"].destroy
1646
- @c.select_order_map([:pos, :name]).must_equal [[1, "Hm"], [1, "P1"], [1, "Ps"], [2, "Au"], [2, "P3"]]
1647
- end
1648
- end
1649
-
1650
- describe "Sequel::Plugins::Tree" do
1651
- TreePluginSpecs = shared_description do
1652
- it "should instantiate" do
1653
- @Node.all.size.must_equal 12
1654
- end
1655
-
1656
- it "should find all descendants of a node" do
1657
- @Node.find(:name => 'two').descendants.map{|m| m.name}.must_equal %w'two.one two.two two.three two.two.one'
1658
- end
1659
-
1660
- it "should find all ancestors of a node" do
1661
- @Node.find(:name => "two.two.one").ancestors.map{|m| m.name}.must_equal %w'two.two two'
1662
- end
1663
-
1664
- it "should find all siblings of a node, excepting self" do
1665
- @Node.find(:name=>"two.one").siblings.map{|m| m.name}.must_equal %w'two.two two.three'
1666
- end
1667
-
1668
- it "should find all siblings of a node, including self" do
1669
- @Node.find(:name=>"two.one").self_and_siblings.map{|m| m.name}.must_equal %w'two.one two.two two.three'
1670
- end
1671
-
1672
- it "should find siblings for root nodes" do
1673
- @Node.find(:name=>'three').self_and_siblings.map{|m| m.name}.must_equal %w'one two three four five'
1674
- end
1675
-
1676
- it "should find correct root for a node" do
1677
- @Node.find(:name=>"two.two.one").root.name.must_equal 'two'
1678
- @Node.find(:name=>"three").root.name.must_equal 'three'
1679
- @Node.find(:name=>"five.one").root.name.must_equal 'five'
1680
- end
1681
-
1682
- it "iterate top-level nodes in order" do
1683
- @Node.roots_dataset.count.must_equal 5
1684
- @Node.roots.map{|p| p.name}.must_equal %w'one two three four five'
1685
- end
1686
-
1687
- it "should have children" do
1688
- @Node.find(:name=>'one').children.map{|m| m.name}.must_equal %w'one.one one.two'
1689
- end
1690
- end
1691
-
1692
- describe "with simple key" do
1693
- before(:all) do
1694
- @db = DB
1695
- @db.create_table!(:nodes) do
1696
- Integer :id, :primary_key=>true
1697
- String :name
1698
- Integer :parent_id
1699
- Integer :position
1700
- end
1701
-
1702
- @nodes = [{:id => 1, :name => 'one', :parent_id => nil, :position => 1},
1703
- {:id => 2, :name => 'two', :parent_id => nil, :position => 2},
1704
- {:id => 3, :name => 'three', :parent_id => nil, :position => 3},
1705
- {:id => 4, :name => "two.one", :parent_id => 2, :position => 1},
1706
- {:id => 5, :name => "two.two", :parent_id => 2, :position => 2},
1707
- {:id => 6, :name => "two.two.one", :parent_id => 5, :position => 1},
1708
- {:id => 7, :name => "one.two", :parent_id => 1, :position => 2},
1709
- {:id => 8, :name => "one.one", :parent_id => 1, :position => 1},
1710
- {:id => 9, :name => "five", :parent_id => nil, :position => 5},
1711
- {:id => 10, :name => "four", :parent_id => nil, :position => 4},
1712
- {:id => 11, :name => "five.one", :parent_id => 9, :position => 1},
1713
- {:id => 12, :name => "two.three", :parent_id => 2, :position => 3}]
1714
- @nodes.each{|node| @db[:nodes].insert(node)}
1715
-
1716
- @Node = Class.new(Sequel::Model(:nodes))
1717
- @Node.plugin :tree, :order=>:position
1718
- end
1719
- after(:all) do
1720
- @db.drop_table?(:nodes)
1721
- end
1722
-
1723
- include TreePluginSpecs
1724
- end
1725
-
1726
- describe "with composite key" do
1727
- before(:all) do
1728
- @db = DB
1729
- @db.create_table!(:nodes) do
1730
- Integer :id
1731
- Integer :id2
1732
- String :name
1733
- Integer :parent_id
1734
- Integer :parent_id2
1735
- Integer :position
1736
- primary_key [:id, :id2]
1737
- end
1738
-
1739
- @nodes = [{:id => 1, :id2=> 1, :name => 'one', :parent_id => nil, :parent_id2 => nil, :position => 1},
1740
- {:id => 2, :id2=> 1, :name => 'two', :parent_id => nil, :parent_id2 => nil, :position => 2},
1741
- {:id => 1, :id2=> 2, :name => 'three', :parent_id => nil, :parent_id2 => nil, :position => 3},
1742
- {:id => 2, :id2=> 2, :name => "two.one", :parent_id => 2, :parent_id2 => 1, :position => 1},
1743
- {:id => 3, :id2=> 1, :name => "two.two", :parent_id => 2, :parent_id2 => 1, :position => 2},
1744
- {:id => 3, :id2=> 2, :name => "two.two.one", :parent_id => 3, :parent_id2 => 1, :position => 1},
1745
- {:id => 3, :id2=> 3, :name => "one.two", :parent_id => 1, :parent_id2 => 1, :position => 2},
1746
- {:id => 1, :id2=> 3, :name => "one.one", :parent_id => 1, :parent_id2 => 1, :position => 1},
1747
- {:id => 2, :id2=> 3, :name => "five", :parent_id => nil, :parent_id2 => nil, :position => 5},
1748
- {:id => 4, :id2=> 1, :name => "four", :parent_id => nil, :parent_id2 => nil, :position => 4},
1749
- {:id => 1, :id2=> 4, :name => "five.one", :parent_id => 2, :parent_id2 => 3, :position => 1},
1750
- {:id => 2, :id2=> 4, :name => "two.three", :parent_id => 2, :parent_id2 => 1, :position => 3}]
1751
- @nodes.each{|node| @db[:nodes].insert(node)}
1752
-
1753
- @Node = Class.new(Sequel::Model(:nodes))
1754
- @Node.plugin :tree, :order=>:position, :key=>[:parent_id, :parent_id2]
1755
- end
1756
- after(:all) do
1757
- @db.drop_table?(:nodes)
1758
- end
1759
-
1760
- include TreePluginSpecs
1761
- end
1762
- end
1763
-
1764
- describe "Sequel::Plugins::UpdateRefresh" do
1765
- before(:all) do
1766
- @db = DB
1767
- @db.create_table!(:tests) do
1768
- primary_key :id
1769
- String :name
1770
- Integer :i
1771
- end
1772
- @c = Class.new(Sequel::Model(@db[:tests]))
1773
- @c.plugin :update_refresh
1774
- end
1775
- before do
1776
- @c.dataset.delete
1777
- @foo = @c.create(:name=>'foo', :i=>10)
1778
- end
1779
- after(:all) do
1780
- @db.drop_table?(:tests)
1781
- end
1782
-
1783
- it "should refresh when updating" do
1784
- @foo.this.update(:i=>20)
1785
- @foo.update(:name=>'bar')
1786
- @foo.name.must_equal 'bar'
1787
- @foo.i.must_equal 20
1788
- end
1789
- end
1790
-
1791
- describe "Sequel::Plugins::PreparedStatements" do
1792
- before(:all) do
1793
- @db = DB
1794
- @db.create_table!(:ps_test) do
1795
- primary_key :id
1796
- String :name
1797
- Integer :i
1798
- end
1799
- @c = Class.new(Sequel::Model(@db[:ps_test]))
1800
- @c.plugin :prepared_statements_with_pk
1801
- end
1802
- before do
1803
- @c.dataset.delete
1804
- @foo = @c.create(:name=>'foo', :i=>10)
1805
- @bar = @c.create(:name=>'bar', :i=>20)
1806
- end
1807
- after(:all) do
1808
- @db.drop_table?(:ps_test)
1809
- end
1810
-
1811
- it "should work with looking up using Model.[]" do
1812
- @c[@foo.id].must_equal @foo
1813
- @c[@bar.id].must_equal @bar
1814
- @c[0].must_equal nil
1815
- @c[nil].must_equal nil
1816
- end
1817
-
1818
- it "should work with looking up using Dataset#with_pk" do
1819
- @c.dataset.with_pk(@foo.id).must_equal @foo
1820
- @c.dataset.with_pk(@bar.id).must_equal @bar
1821
- @c.dataset.with_pk(0).must_equal nil
1822
- @c.dataset.with_pk(nil).must_equal nil
1823
-
1824
- @c.dataset.filter(:i=>0).with_pk(@foo.id).must_equal nil
1825
- @c.dataset.filter(:i=>10).with_pk(@foo.id).must_equal @foo
1826
- @c.dataset.filter(:i=>20).with_pk(@bar.id).must_equal @bar
1827
- @c.dataset.filter(:i=>10).with_pk(nil).must_equal nil
1828
- @c.dataset.filter(:name=>'foo').with_pk(@foo.id).must_equal @foo
1829
- @c.dataset.filter(:name=>'bar').with_pk(@bar.id).must_equal @bar
1830
- @c.dataset.filter(:name=>'baz').with_pk(@bar.id).must_equal nil
1831
- @c.dataset.filter(:name=>'bar').with_pk(nil).must_equal nil
1832
- end
1833
-
1834
- it "should work with Model#destroy" do
1835
- @foo.destroy
1836
- @bar.destroy
1837
- @c[@foo.id].must_equal nil
1838
- @c[@bar.id].must_equal nil
1839
- end
1840
-
1841
- it "should work with Model#update" do
1842
- @foo.update(:name=>'foo2', :i=>30)
1843
- @c[@foo.id].must_equal @c.load(:id=>@foo.id, :name=>'foo2', :i=>30)
1844
- @foo.update(:name=>'foo3')
1845
- @c[@foo.id].must_equal @c.load(:id=>@foo.id, :name=>'foo3', :i=>30)
1846
- @foo.update(:i=>40)
1847
- @c[@foo.id].must_equal @c.load(:id=>@foo.id, :name=>'foo3', :i=>40)
1848
- @foo.update(:i=>nil)
1849
- @c[@foo.id].must_equal @c.load(:id=>@foo.id, :name=>'foo3', :i=>nil)
1850
- end
1851
-
1852
- it "should work with Model#create" do
1853
- o = @c.create(:name=>'foo2', :i=>30)
1854
- @c[o.id].must_equal @c.load(:id=>o.id, :name=>'foo2', :i=>30)
1855
- o = @c.create(:name=>'foo2')
1856
- @c[o.id].must_equal @c.load(:id=>o.id, :name=>'foo2', :i=>nil)
1857
- o = @c.create(:i=>30)
1858
- @c[o.id].must_equal @c.load(:id=>o.id, :name=>nil, :i=>30)
1859
- o = @c.create(:name=>nil, :i=>40)
1860
- @c[o.id].must_equal @c.load(:id=>o.id, :name=>nil, :i=>40)
1861
- end
1862
- end
1863
-
1864
- describe "Sequel::Plugins::PreparedStatements with schema changes" do
1865
- before do
1866
- @db = DB
1867
- @db.create_table!(:ps_test) do
1868
- primary_key :id
1869
- String :name
1870
- end
1871
- @c = Class.new(Sequel::Model(@db[:ps_test]))
1872
- @c.many_to_one :ps_test, :key=>:id, :class=>@c
1873
- @c.one_to_many :ps_tests, :key=>:id, :class=>@c
1874
- @c.many_to_many :mps_tests, :left_key=>:id, :right_key=>:id, :class=>@c, :join_table=>:ps_test___x
1875
- @c.plugin :prepared_statements
1876
- @c.plugin :prepared_statements_associations
1877
- end
1878
- after do
1879
- @db.drop_table?(:ps_test)
1880
- end
1881
-
1882
- it "should handle added columns" do
1883
- foo = @c.create(:name=>'foo')
1884
- @c[foo.id].name.must_equal 'foo'
1885
- foo.ps_test.name.must_equal 'foo'
1886
- foo.ps_tests.map{|x| x.name}.must_equal %w'foo'
1887
- foo.mps_tests.map{|x| x.name}.must_equal %w'foo'
1888
- foo.update(:name=>'foo2')
1889
- @c[foo.id].name.must_equal 'foo2'
1890
- foo.delete
1891
- foo.exists?.must_equal false
1892
-
1893
- @db.alter_table(:ps_test){add_column :i, Integer}
1894
-
1895
- foo = @c.create(:name=>'foo')
1896
- @c[foo.id].name.must_equal 'foo'
1897
- foo.ps_test.name.must_equal 'foo'
1898
- foo.ps_tests.map{|x| x.name}.must_equal %w'foo'
1899
- foo.mps_tests.map{|x| x.name}.must_equal %w'foo'
1900
- foo.update(:name=>'foo2')
1901
- @c[foo.id].name.must_equal 'foo2'
1902
- foo.delete
1903
- foo.exists?.must_equal false
1904
- end
1905
- end
1906
-
1907
- describe "Caching plugins" do
1908
- before(:all) do
1909
- @db = DB
1910
- @db.drop_table?(:albums, :artists)
1911
- @db.create_table(:artists) do
1912
- primary_key :id
1913
- end
1914
- @db.create_table(:albums) do
1915
- primary_key :id
1916
- foreign_key :artist_id, :artists
1917
- end
1918
- @db[:artists].insert
1919
- @db[:albums].insert(:artist_id=>1)
1920
- end
1921
- before do
1922
- @Album = Class.new(Sequel::Model(@db[:albums]))
1923
- @Album.plugin :many_to_one_pk_lookup
1924
- end
1925
- after(:all) do
1926
- @db.drop_table?(:albums, :artists)
1927
- end
1928
-
1929
- CachingPluginSpecs = shared_description do
1930
- it "should work with looking up using Model.[]" do
1931
- @Artist[1].must_be_same_as(@Artist[1])
1932
- @Artist[:id=>1].must_equal @Artist[1]
1933
- @Artist[0].must_equal nil
1934
- @Artist[nil].must_equal nil
1935
- end
1936
-
1937
- it "should work with lookup up many_to_one associated objects" do
1938
- a = @Artist[1]
1939
- @Album.first.artist.must_be_same_as(a)
1940
- end
1941
- end
1942
-
1943
- describe "caching plugin" do
1944
- before do
1945
- @cache_class = Class.new(Hash) do
1946
- def set(k, v, ttl) self[k] = v end
1947
- alias get []
1948
- end
1949
- @cache = @cache_class.new
1950
-
1951
- @Artist = Class.new(Sequel::Model(@db[:artists]))
1952
- @Artist.plugin :caching, @cache
1953
- @Album.many_to_one :artist, :class=>@Artist
1954
- end
1955
-
1956
- include CachingPluginSpecs
1957
- end
1958
-
1959
- describe "static_cache plugin" do
1960
- before do
1961
- @Artist = Class.new(Sequel::Model(@db[:artists]))
1962
- @Artist.plugin :static_cache
1963
- @Album.many_to_one :artist, :class=>@Artist
1964
- end
1965
-
1966
- include CachingPluginSpecs
1967
- end
1968
- end
1969
-
1970
- describe "Sequel::Plugins::ConstraintValidations" do
1971
- before(:all) do
1972
- @db = DB
1973
- @db.extension(:constraint_validations)
1974
- @db.drop_table?(:sequel_constraint_validations)
1975
- @db.create_constraint_validations_table
1976
- @ds = @db[:cv_test]
1977
- @regexp = regexp = @db.dataset.supports_regexp?
1978
- @validation_opts = {}
1979
- opts_proc = proc{@validation_opts}
1980
- @validate_block = proc do |opts|
1981
- opts = opts_proc.call
1982
- presence :pre, opts.merge(:name=>:p)
1983
- exact_length 5, :exactlen, opts.merge(:name=>:el)
1984
- min_length 5, :minlen, opts.merge(:name=>:minl)
1985
- max_length 5, :maxlen, opts.merge(:name=>:maxl)
1986
- length_range 3..5, :lenrange, opts.merge(:name=>:lr)
1987
- if regexp
1988
- format(/^foo\d+/, :form, opts.merge(:name=>:f))
1989
- end
1990
- like 'foo%', :lik, opts.merge(:name=>:l)
1991
- ilike 'foo%', :ilik, opts.merge(:name=>:il)
1992
- includes %w'abc def', :inc, opts.merge(:name=>:i)
1993
- unique :uniq, opts.merge(:name=>:u)
1994
- max_length 6, :minlen, opts.merge(:name=>:maxl2)
1995
- end
1996
- @valid_row = {:pre=>'a', :exactlen=>'12345', :minlen=>'12345', :maxlen=>'12345', :lenrange=>'1234', :lik=>'fooabc', :ilik=>'FooABC', :inc=>'abc', :uniq=>'u'}
1997
- @violations = [
1998
- [:pre, [nil, '', ' ']],
1999
- [:exactlen, [nil, '', '1234', '123456']],
2000
- [:minlen, [nil, '', '1234']],
2001
- [:maxlen, [nil, '123456']],
2002
- [:lenrange, [nil, '', '12', '123456']],
2003
- [:lik, [nil, '', 'fo', 'fotabc', 'FOOABC']],
2004
- [:ilik, [nil, '', 'fo', 'fotabc']],
2005
- [:inc, [nil, '', 'ab', 'abcd']],
2006
- ]
2007
-
2008
- if @regexp
2009
- @valid_row[:form] = 'foo1'
2010
- @violations << [:form, [nil, '', 'foo', 'fooa']]
2011
- end
2012
- end
2013
- after(:all) do
2014
- @db.drop_constraint_validations_table
2015
- end
2016
-
2017
- ConstraintValidationsSpecs = shared_description do
2018
- cspecify "should set up constraints that work even outside the model", :mysql do
2019
- @ds.insert(@valid_row)
2020
-
2021
- # Test for unique constraint
2022
- proc{@ds.insert(@valid_row)}.must_raise(Sequel::DatabaseError, Sequel::UniqueConstraintViolation, Sequel::ConstraintViolation)
2023
-
2024
- @ds.delete
2025
- @violations.each do |col, vals|
2026
- try = @valid_row.dup
2027
- vals += ['1234567'] if col == :minlen
2028
- vals.each do |val|
2029
- next if val.nil? && @validation_opts[:allow_nil]
2030
- next if val == '' && @validation_opts[:allow_nil] && @db.database_type == :oracle
2031
- try[col] = val
2032
- proc{@ds.insert(try)}.must_raise(Sequel::DatabaseError, Sequel::CheckConstraintViolation, Sequel::ConstraintViolation)
2033
- end
2034
- end
2035
-
2036
- # Test for dropping of constraint
2037
- @db.alter_table(:cv_test){validate{drop :maxl2}}
2038
- @ds.insert(@valid_row.merge(:minlen=>'1234567'))
2039
- end
2040
-
2041
- it "should set up automatic validations inside the model" do
2042
- c = Class.new(Sequel::Model(@ds))
2043
- c.plugin :constraint_validations
2044
- c.dataset.delete
2045
- c.create(@valid_row)
2046
-
2047
- # Test for unique validation
2048
- c.new(@valid_row).wont_be :valid?
2049
-
2050
- c.dataset.delete
2051
- @violations.each do |col, vals|
2052
- try = @valid_row.dup
2053
- vals.each do |val|
2054
- next if val.nil? && @validation_opts[:allow_nil]
2055
- try[col] = val
2056
- c.new(try).wont_be :valid?
2057
- end
2058
- end
2059
- c.db.constraint_validations = nil
2060
- end
2061
- end
2062
-
2063
- describe "via create_table" do
2064
- before(:all) do
2065
- @table_block = proc do
2066
- regexp = @regexp
2067
- validate_block = @validate_block
2068
- @db.create_table!(:cv_test) do
2069
- primary_key :id
2070
- String :pre
2071
- String :exactlen
2072
- String :minlen
2073
- String :maxlen
2074
- String :lenrange
2075
- if regexp
2076
- String :form
2077
- end
2078
- String :lik
2079
- String :ilik
2080
- String :inc
2081
- String :uniq, :null=>false
2082
- validate(&validate_block)
2083
- end
2084
- end
2085
- end
2086
- after(:all) do
2087
- @db.drop_table?(:cv_test)
2088
- @db.drop_constraint_validations_for(:table=>:cv_test)
2089
- end
2090
-
2091
- describe "with :allow_nil=>true" do
2092
- before(:all) do
2093
- @validation_opts = {:allow_nil=>true}
2094
- @table_block.call
2095
- end
2096
- include ConstraintValidationsSpecs
2097
- end
2098
- describe "with :allow_nil=>false" do
2099
- before(:all) do
2100
- @table_block.call
2101
- end
2102
- include ConstraintValidationsSpecs
2103
- end
2104
- end
2105
-
2106
- describe "via alter_table" do
2107
- before(:all) do
2108
- @table_block = proc do
2109
- regexp = @regexp
2110
- validate_block = @validate_block
2111
- @db.create_table!(:cv_test) do
2112
- primary_key :id
2113
- String :lik
2114
- String :ilik
2115
- String :inc
2116
- String :uniq, :null=>false
2117
- end
2118
- @db.alter_table(:cv_test) do
2119
- add_column :pre, String
2120
- add_column :exactlen, String
2121
- add_column :minlen, String
2122
- add_column :maxlen, String
2123
- add_column :lenrange, String
2124
- if regexp
2125
- add_column :form, String
2126
- end
2127
- validate(&validate_block)
2128
- end
2129
- end
2130
- end
2131
- after(:all) do
2132
- @db.drop_table?(:cv_test)
2133
- @db.drop_constraint_validations_for(:table=>:cv_test)
2134
- end
2135
-
2136
- describe "with :allow_nil=>true" do
2137
- before(:all) do
2138
- @validation_opts = {:allow_nil=>true}
2139
- @table_block.call
2140
- end
2141
- include ConstraintValidationsSpecs
2142
- end
2143
- describe "with :allow_nil=>false" do
2144
- before(:all) do
2145
- @table_block.call
2146
- end
2147
- include ConstraintValidationsSpecs
2148
- end
2149
- end
2150
- end
2151
-
2152
- describe "date_arithmetic extension" do
2153
- asd = begin
2154
- require 'active_support/duration'
2155
- require 'active_support/inflector'
2156
- require 'active_support/core_ext/string/inflections'
2157
- true
2158
- rescue LoadError
2159
- false
2160
- end
2161
-
2162
- before(:all) do
2163
- @db = DB
2164
- @db.extension(:date_arithmetic)
2165
- if @db.database_type == :sqlite
2166
- @db.use_timestamp_timezones = false
2167
- end
2168
- @date = Date.civil(2010, 7, 12)
2169
- @dt = Time.local(2010, 7, 12)
2170
- if asd
2171
- @d0 = ActiveSupport::Duration.new(0, [[:days, 0]])
2172
- @d1 = ActiveSupport::Duration.new(1, [[:days, 1]])
2173
- @d2 = ActiveSupport::Duration.new(1, [[:years, 1], [:months, 1], [:days, 1], [:minutes, 61], [:seconds, 1]])
2174
- end
2175
- @h0 = {:days=>0}
2176
- @h1 = {:days=>1, :years=>nil, :hours=>0}
2177
- @h2 = {:years=>1, :months=>1, :days=>1, :hours=>1, :minutes=>1, :seconds=>1}
2178
- @a1 = Time.local(2010, 7, 13)
2179
- @a2 = Time.local(2011, 8, 13, 1, 1, 1)
2180
- @s1 = Time.local(2010, 7, 11)
2181
- @s2 = Time.local(2009, 6, 10, 22, 58, 59)
2182
- @check = lambda do |meth, in_date, in_interval, should|
2183
- output = @db.get(Sequel.send(meth, in_date, in_interval))
2184
- output = Time.parse(output.to_s) unless output.is_a?(Time) || output.is_a?(DateTime)
2185
- output.year.must_equal should.year
2186
- output.month.must_equal should.month
2187
- output.day.must_equal should.day
2188
- output.hour.must_equal should.hour
2189
- output.min.must_equal should.min
2190
- output.sec.must_equal should.sec
2191
- end
2192
- end
2193
- after(:all) do
2194
- if @db.database_type == :sqlite
2195
- @db.use_timestamp_timezones = true
2196
- end
2197
- end
2198
-
2199
- if asd
2200
- it "be able to use Sequel.date_add to add ActiveSupport::Duration objects to dates and datetimes" do
2201
- @check.call(:date_add, @date, @d0, @dt)
2202
- @check.call(:date_add, @date, @d1, @a1)
2203
- @check.call(:date_add, @date, @d2, @a2)
2204
-
2205
- @check.call(:date_add, @dt, @d0, @dt)
2206
- @check.call(:date_add, @dt, @d1, @a1)
2207
- @check.call(:date_add, @dt, @d2, @a2)
2208
- end
2209
-
2210
- it "be able to use Sequel.date_sub to subtract ActiveSupport::Duration objects from dates and datetimes" do
2211
- @check.call(:date_sub, @date, @d0, @dt)
2212
- @check.call(:date_sub, @date, @d1, @s1)
2213
- @check.call(:date_sub, @date, @d2, @s2)
2214
-
2215
- @check.call(:date_sub, @dt, @d0, @dt)
2216
- @check.call(:date_sub, @dt, @d1, @s1)
2217
- @check.call(:date_sub, @dt, @d2, @s2)
2218
- end
2219
- end
2220
-
2221
- it "be able to use Sequel.date_add to add interval hashes to dates and datetimes" do
2222
- @check.call(:date_add, @date, @h0, @dt)
2223
- @check.call(:date_add, @date, @h1, @a1)
2224
- @check.call(:date_add, @date, @h2, @a2)
2225
-
2226
- @check.call(:date_add, @dt, @h0, @dt)
2227
- @check.call(:date_add, @dt, @h1, @a1)
2228
- @check.call(:date_add, @dt, @h2, @a2)
2229
- end
2230
-
2231
- it "be able to use Sequel.date_sub to subtract interval hashes from dates and datetimes" do
2232
- @check.call(:date_sub, @date, @h0, @dt)
2233
- @check.call(:date_sub, @date, @h1, @s1)
2234
- @check.call(:date_sub, @date, @h2, @s2)
2235
-
2236
- @check.call(:date_sub, @dt, @h0, @dt)
2237
- @check.call(:date_sub, @dt, @h1, @s1)
2238
- @check.call(:date_sub, @dt, @h2, @s2)
2239
- end
2240
- end