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,85 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- describe "null_dataset extension" do
4
- before do
5
- @db = Sequel::mock(:fetch=>{:id=>1}, :autoid=>1, :numrows=>1, :columns=>[:id]).extension(:null_dataset)
6
- @ds = @db[:table].nullify
7
- @i = 0
8
- @pr = proc{|*a| @i += 1}
9
- end
10
- after do
11
- @db.sqls.must_equal [] unless @skip_check
12
- end
13
-
14
- it "should make each be a noop" do
15
- @ds.each(&@pr).must_be_same_as(@ds)
16
- @i.must_equal 0
17
- end
18
-
19
- it "should make fetch_rows be a noop" do
20
- @ds.fetch_rows("SELECT 1", &@pr).must_equal nil
21
- @i.must_equal 0
22
- end
23
-
24
- it "should make insert be a noop" do
25
- @ds.insert(1).must_equal nil
26
- end
27
-
28
- it "should make update be a noop" do
29
- @ds.update(:a=>1).must_equal 0
30
- end
31
-
32
- it "should make delete be a noop" do
33
- @ds.delete.must_equal 0
34
- end
35
-
36
- it "should make truncate be a noop" do
37
- @ds.truncate.must_equal nil
38
- end
39
-
40
- it "should make execute_* be a noop" do
41
- @ds.send(:execute_ddl,'FOO').must_equal nil
42
- @ds.send(:execute_insert,'FOO').must_equal nil
43
- @ds.send(:execute_dui,'FOO').must_equal nil
44
- @ds.send(:execute,'FOO').must_equal nil
45
- end
46
-
47
- it "should have working columns" do
48
- @skip_check = true
49
- @ds.columns.must_equal [:id]
50
- @db.sqls.must_equal ['SELECT * FROM table LIMIT 1']
51
- end
52
-
53
- it "should have count return 0" do
54
- @ds.count.must_equal 0
55
- end
56
-
57
- it "should have empty return true" do
58
- @ds.empty?.must_equal true
59
- end
60
-
61
- it "should make import a noop" do
62
- @ds.import([:id], [[1], [2], [3]]).must_equal nil
63
- end
64
-
65
- it "should have nullify method returned modified receiver" do
66
- @skip_check = true
67
- ds = @db[:table]
68
- ds.nullify.wont_be_same_as(ds)
69
- ds.each(&@pr)
70
- @db.sqls.must_equal ['SELECT * FROM table']
71
- @i.must_equal 1
72
- end
73
-
74
- it "should have nullify! method modify receiver" do
75
- ds = @db[:table]
76
- ds.nullify!.must_be_same_as(ds)
77
- ds.each(&@pr)
78
- @i.must_equal 0
79
- end
80
-
81
- it "should work with method chaining" do
82
- @ds.where(:a=>1).select(:b).each(&@pr)
83
- @i.must_equal 0
84
- end
85
- end
@@ -1,128 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- describe "optimistic_locking plugin" do
4
- before do
5
- @c = Class.new(Sequel::Model(:people)) do
6
- end
7
- h = {1=>{:id=>1, :name=>'John', :lock_version=>2}}
8
- lv = @lv = "lock_version"
9
- @c.instance_dataset.numrows = @c.dataset.numrows = proc do |sql|
10
- case sql
11
- when /UPDATE people SET (name|#{lv}) = ('Jim'|'Bob'|\d+), (?:name|#{lv}) = ('Jim'|'Bob'|\d+) WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
12
- name, nlv = $1 == 'name' ? [$2, $3] : [$3, $2]
13
- m = h[$4.to_i]
14
- if m && m[:lock_version] == $5.to_i
15
- m.merge!(:name=>name.gsub("'", ''), :lock_version=>nlv.to_i)
16
- 1
17
- else
18
- 0
19
- end
20
- when /UPDATE people SET #{lv} = (\d+) WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
21
- m = h[$2.to_i]
22
- if m && m[:lock_version] == $3.to_i
23
- m.merge!(:lock_version=>$1.to_i)
24
- 1
25
- else
26
- 0
27
- end
28
- when /DELETE FROM people WHERE \(\(id = (\d+)\) AND \(#{lv} = (\d+)\)\)/
29
- m = h[$1.to_i]
30
- if m && m[lv.to_sym] == $2.to_i
31
- h.delete[$1.to_i]
32
- 1
33
- else
34
- 0
35
- end
36
- else
37
- puts sql
38
- end
39
- end
40
- @c.instance_dataset._fetch = @c.dataset._fetch = proc do |sql|
41
- m = h[1].dup
42
- v = m.delete(:lock_version)
43
- m[lv.to_sym] = v
44
- m
45
- end
46
- @c.columns :id, :name, :lock_version
47
- @c.plugin :optimistic_locking
48
- end
49
-
50
- it "should raise an error when updating a stale record" do
51
- p1 = @c[1]
52
- p2 = @c[1]
53
- p1.update(:name=>'Jim')
54
- proc{p2.update(:name=>'Bob')}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
55
- end
56
-
57
- it "should raise an error when destroying a stale record" do
58
- p1 = @c[1]
59
- p2 = @c[1]
60
- p1.update(:name=>'Jim')
61
- proc{p2.destroy}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
62
- end
63
-
64
- it "should not raise an error when updating the same record twice" do
65
- p1 = @c[1]
66
- p1.update(:name=>'Jim')
67
- p1.update(:name=>'Bob')
68
- end
69
-
70
- it "should allow changing the lock column via model.lock_column=" do
71
- @lv.replace('lv')
72
- @c.columns :id, :name, :lv
73
- @c.lock_column = :lv
74
- p1 = @c[1]
75
- p2 = @c[1]
76
- p1.update(:name=>'Jim')
77
- proc{p2.update(:name=>'Bob')}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
78
- end
79
-
80
- it "should allow changing the lock column via plugin option" do
81
- @lv.replace('lv')
82
- @c.columns :id, :name, :lv
83
- @c.plugin :optimistic_locking, :lock_column=>:lv
84
- p1 = @c[1]
85
- p2 = @c[1]
86
- p1.update(:name=>'Jim')
87
- proc{p2.destroy}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
88
- end
89
-
90
- it "should work when subclassing" do
91
- c = Class.new(@c)
92
- p1 = c[1]
93
- p2 = c[1]
94
- p1.update(:name=>'Jim')
95
- proc{p2.update(:name=>'Bob')}.must_raise(Sequel::Plugins::OptimisticLocking::Error)
96
- end
97
-
98
- it "should work correctly if attempting to refresh and save again after a failed save" do
99
- p1 = @c[1]
100
- p2 = @c[1]
101
- p1.update(:name=>'Jim')
102
- begin
103
- p2.update(:name=>'Bob')
104
- rescue Sequel::Plugins::OptimisticLocking::Error
105
- p2.refresh
106
- @c.db.sqls
107
- p2.update(:name=>'Bob')
108
- end
109
- @c.db.sqls.first.must_match(/UPDATE people SET (name = 'Bob', lock_version = 4|lock_version = 4, name = 'Bob') WHERE \(\(id = 1\) AND \(lock_version = 3\)\)/)
110
- end
111
-
112
- it "should increment the lock column when #modified! even if no columns are changed" do
113
- p1 = @c[1]
114
- p1.modified!
115
- lv = p1.lock_version
116
- p1.save_changes
117
- p1.lock_version.must_equal lv + 1
118
- end
119
-
120
- it "should not increment the lock column when the update fails" do
121
- @c.instance_dataset.meta_def(:update) {|_| raise }
122
- p1 = @c[1]
123
- p1.modified!
124
- lv = p1.lock_version
125
- proc{p1.save_changes}.must_raise(RuntimeError)
126
- p1.lock_version.must_equal lv
127
- end
128
- end
@@ -1,118 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- describe "A paginated dataset" do
4
- before do
5
- @d = Sequel.mock.dataset.extension(:pagination)
6
- @d.meta_def(:count) {153}
7
-
8
- @paginated = @d.paginate(1, 20)
9
- end
10
-
11
- it "should raise an error if the dataset already has a limit" do
12
- proc{@d.limit(10).paginate(1,10)}.must_raise(Sequel::Error)
13
- proc{@paginated.paginate(2,20)}.must_raise(Sequel::Error)
14
- proc{@d.limit(10).each_page(10){|ds|}}.must_raise(Sequel::Error)
15
- proc{@d.limit(10).each_page(10)}.must_raise(Sequel::Error)
16
- end
17
-
18
- it "should set the limit and offset options correctly" do
19
- @paginated.opts[:limit].must_equal 20
20
- @paginated.opts[:offset].must_equal 0
21
- end
22
-
23
- it "should set the page count correctly" do
24
- @paginated.page_count.must_equal 8
25
- @d.paginate(1, 50).page_count.must_equal 4
26
-
27
- @d.meta_def(:count) {0}
28
- @d.paginate(1, 50).page_count.must_equal 1
29
- end
30
-
31
- it "should set the current page number correctly" do
32
- @paginated.current_page.must_equal 1
33
- @d.paginate(3, 50).current_page.must_equal 3
34
- end
35
-
36
- it "should return the next page number or nil if we're on the last" do
37
- @paginated.next_page.must_equal 2
38
- @d.paginate(4, 50).next_page.must_equal nil
39
- end
40
-
41
- it "should return the previous page number or nil if we're on the first" do
42
- @paginated.prev_page.must_equal nil
43
- @d.paginate(4, 50).prev_page.must_equal 3
44
- end
45
-
46
- it "should return the page range" do
47
- @paginated.page_range.must_equal(1..8)
48
- @d.paginate(4, 50).page_range.must_equal(1..4)
49
- end
50
-
51
- it "should return the record range for the current page" do
52
- @paginated.current_page_record_range.must_equal(1..20)
53
- @d.paginate(4, 50).current_page_record_range.must_equal(151..153)
54
- @d.paginate(5, 50).current_page_record_range.must_equal(0..0)
55
- end
56
-
57
- it "should return the record count for the current page" do
58
- @paginated.current_page_record_count.must_equal 20
59
- @d.paginate(3, 50).current_page_record_count.must_equal 50
60
- @d.paginate(4, 50).current_page_record_count.must_equal 3
61
- @d.paginate(5, 50).current_page_record_count.must_equal 0
62
- end
63
-
64
- it "should know if current page is last page" do
65
- @paginated.last_page?.must_equal false
66
- @d.paginate(2, 20).last_page?.must_equal false
67
- @d.paginate(5, 30).last_page?.must_equal false
68
- @d.paginate(6, 30).last_page?.must_equal true
69
-
70
- @d.meta_def(:count) {0}
71
- @d.paginate(1, 30).last_page?.must_equal true
72
- @d.paginate(2, 30).last_page?.must_equal false
73
- end
74
-
75
- it "should know if current page is first page" do
76
- @paginated.first_page?.must_equal true
77
- @d.paginate(1, 20).first_page?.must_equal true
78
- @d.paginate(2, 20).first_page?.must_equal false
79
- end
80
-
81
- it "should work with fixed sql" do
82
- ds = @d.clone(:sql => 'select * from blah')
83
- ds.meta_def(:count) {150}
84
- ds.paginate(2, 50).sql.must_equal 'SELECT * FROM (select * from blah) AS t1 LIMIT 50 OFFSET 50'
85
- end
86
- end
87
-
88
- describe "Dataset#each_page" do
89
- before do
90
- @d = Sequel.mock.dataset.from(:items).extension(:pagination)
91
- @d.meta_def(:count) {153}
92
- end
93
-
94
- it "should raise an error if the dataset already has a limit" do
95
- proc{@d.limit(10).each_page(10){}}.must_raise(Sequel::Error)
96
- end
97
-
98
- it "should iterate over each page in the resultset as a paginated dataset" do
99
- a = []
100
- @d.each_page(50) {|p| a << p}
101
- a.map {|p| p.sql}.must_equal [
102
- 'SELECT * FROM items LIMIT 50 OFFSET 0',
103
- 'SELECT * FROM items LIMIT 50 OFFSET 50',
104
- 'SELECT * FROM items LIMIT 50 OFFSET 100',
105
- 'SELECT * FROM items LIMIT 50 OFFSET 150',
106
- ]
107
- end
108
-
109
- it "should return an enumerator if no block is given" do
110
- enum = @d.each_page(50)
111
- enum.map {|p| p.sql}.must_equal [
112
- 'SELECT * FROM items LIMIT 50 OFFSET 0',
113
- 'SELECT * FROM items LIMIT 50 OFFSET 50',
114
- 'SELECT * FROM items LIMIT 50 OFFSET 100',
115
- 'SELECT * FROM items LIMIT 50 OFFSET 150',
116
- ]
117
- end
118
- end
@@ -1,736 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
-
3
- describe Sequel::Model, "pg_array_associations" do
4
- before do
5
- @db = Sequel.mock(:numrows=>1)
6
- class ::Artist < Sequel::Model(@db)
7
- attr_accessor :yyy
8
- columns :id, :tag_ids
9
- plugin :pg_array_associations
10
- pg_array_to_many :tags
11
- pg_array_to_many :a_tags, :clone=>:tags, :conditions=>{:name=>'A'}, :key=>:tag_ids
12
- end
13
- class ::Tag < Sequel::Model(@db)
14
- columns :id
15
- plugin :pg_array_associations
16
- many_to_pg_array :artists
17
- many_to_pg_array :a_artists, :clone=>:artists, :conditions=>{:name=>'A'}
18
- def id3
19
- id*3
20
- end
21
- end
22
- @c1 = Artist
23
- @c2 = Tag
24
- @c1.dataset._fetch = {:id=>1, :tag_ids=>Sequel.pg_array([1,2,3])}
25
- @c2.dataset._fetch = {:id=>2}
26
- @o1 = @c1.first
27
- @o2 = @c2.first
28
- @n1 = @c1.new
29
- @n2 = @c2.new
30
- @db.sqls
31
- end
32
- after do
33
- Object.send(:remove_const, :Artist)
34
- Object.send(:remove_const, :Tag)
35
- end
36
-
37
- it "should populate :key_hash and :id_map option correctly for custom eager loaders" do
38
- khs = []
39
- pr = proc{|h| khs << [h[:key_hash], h[:id_map]]}
40
- @c1.pg_array_to_many :tags, :clone=>:tags, :eager_loader=>pr
41
- @c2.many_to_pg_array :artists, :clone=>:artists, :eager_loader=>pr
42
- @c1.eager(:tags).all
43
- @c2.eager(:artists).all
44
- khs.must_equal [[{}, nil], [{:id=>{2=>[Tag.load(:id=>2)]}}, {2=>[Tag.load(:id=>2)]}]]
45
- end
46
-
47
- it "should not issue queries if the object cannot have associated objects" do
48
- @n1.tags.must_equal []
49
- @c1.load(:tag_ids=>[]).tags.must_equal []
50
- @n2.artists.must_equal []
51
- @db.sqls.must_equal []
52
- end
53
-
54
- it "should use correct SQL when loading associations lazily" do
55
- @o1.tags.must_equal [@o2]
56
- @o2.artists.must_equal [@o1]
57
- @db.sqls.must_equal ["SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))", "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[])"]
58
- end
59
-
60
- it "should accept :primary_key option for primary keys to use in current and associated table" do
61
- @c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>Sequel./(:id, 3)
62
- @c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>:id3
63
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE ((tags.id / 3) IN (1, 2, 3))"
64
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[6]::integer[])"
65
- end
66
-
67
- it "should allowing filtering by associations" do
68
- @c1.filter(:tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[])"
69
- @c2.filter(:artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))"
70
- end
71
-
72
- it "should allowing filtering by associations with :conditions" do
73
- @c1.filter(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), 'f')"
74
- @c2.filter(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1))))"
75
- end
76
-
77
- it "should allowing excluding by associations" do
78
- @c1.exclude(:tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT (artists.tag_ids @> ARRAY[2]::integer[]) OR (artists.tag_ids IS NULL))"
79
- @c2.exclude(:artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (1, 2, 3)) OR (tags.id IS NULL))"
80
- end
81
-
82
- it "should allowing excluding by associations with :conditions" do
83
- @c1.exclude(:a_tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id = 2)))), 'f') OR (artists.tag_ids IS NULL))"
84
- @c2.exclude(:a_artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id = 1)))) OR (tags.id IS NULL))"
85
- end
86
-
87
- it "should allowing filtering by multiple associations" do
88
- @c1.filter(:tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[1,2]::integer[])"
89
- @c2.filter(:artists=>[@c1.load(:tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (3, 4, 5))"
90
- end
91
-
92
- it "should allowing filtering by multiple associations with :conditions" do
93
- @c1.filter(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), 'f')"
94
- @c2.filter(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8)))))"
95
- end
96
-
97
- it "should allowing excluding by multiple associations" do
98
- @c1.exclude(:tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT (artists.tag_ids && ARRAY[1,2]::integer[]) OR (artists.tag_ids IS NULL))"
99
- @c2.exclude(:artists=>[@c1.load(:tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (3, 4, 5)) OR (tags.id IS NULL))"
100
- end
101
-
102
- it "should allowing excluding by multiple associations with :conditions" do
103
- @c1.exclude(:a_tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (1, 2))))), 'f') OR (artists.tag_ids IS NULL))"
104
- @c2.exclude(:a_artists=>[@c1.load(:id=>7, :tag_ids=>Sequel.pg_array([3, 4])), @c1.load(:id=>8, :tag_ids=>Sequel.pg_array([4, 5]))]).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (7, 8))))) OR (tags.id IS NULL))"
105
- end
106
-
107
- it "should allowing filtering/excluding associations with NULL or empty values" do
108
- @c1.filter(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE \'f\''
109
- @c1.exclude(:tags=>@c2.new).sql.must_equal 'SELECT * FROM artists WHERE \'t\''
110
- @c2.filter(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE \'f\''
111
- @c2.exclude(:artists=>@c1.new).sql.must_equal 'SELECT * FROM tags WHERE \'t\''
112
-
113
- @c2.filter(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE \'f\''
114
- @c2.exclude(:artists=>@c1.load(:tag_ids=>[])).sql.must_equal 'SELECT * FROM tags WHERE \'t\''
115
-
116
- @c1.filter(:tags=>[@c2.new, @c2.load(:id=>2)]).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"
117
- @c2.filter(:artists=>[@c1.load(:tag_ids=>Sequel.pg_array([3, 4])), @c1.new]).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (3, 4))"
118
- end
119
-
120
- it "should allowing filtering by association datasets" do
121
- @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), 'f')"
122
- @c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1)))"
123
- end
124
-
125
- it "should allowing filtering by association datasets with :conditions" do
126
- @c1.filter(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), 'f')"
127
- @c2.filter(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1))))))"
128
- end
129
-
130
- it "should allowing excluding by association datasets" do
131
- @c1.exclude(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE (id = 1))), 'f') OR (artists.tag_ids IS NULL))"
132
- @c2.exclude(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE (id = 1))) OR (tags.id IS NULL))"
133
- end
134
-
135
- it "should allowing excluding by association datasets with :conditions" do
136
- @c1.exclude(:a_tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE (NOT coalesce((artists.tag_ids && (SELECT array_agg(tags.id) FROM tags WHERE ((name = 'A') AND (tags.id IS NOT NULL) AND (tags.id IN (SELECT tags.id FROM tags WHERE (id = 1)))))), 'f') OR (artists.tag_ids IS NULL))"
137
- @c2.exclude(:a_artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id NOT IN (SELECT unnest(artists.tag_ids) FROM artists WHERE ((name = 'A') AND (artists.tag_ids IS NOT NULL) AND (artists.id IN (SELECT artists.id FROM artists WHERE (id = 1)))))) OR (tags.id IS NULL))"
138
- end
139
-
140
- it "filter by associations should respect key options" do
141
- @c1.class_eval{def tag3_ids; tag_ids.map{|x| x*3} end}
142
- @c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>Sequel.*(:id, 3), :primary_key_method=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
143
- @c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>Sequel.*(:id, 3), :primary_key_method=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
144
-
145
- @c1.filter(:tags=>@o2).sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids[1:2] @> ARRAY[6]::integer[])"
146
- @c2.filter(:artists=>@o1).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (3, 6, 9))"
147
- @c1.filter(:tags=>@c2.where(:id=>1)).sql.must_equal "SELECT * FROM artists WHERE coalesce((artists.tag_ids[1:2] && (SELECT array_agg((tags.id * 3)) FROM tags WHERE (id = 1))), 'f')"
148
- @c2.filter(:artists=>@c1.where(:id=>1)).sql.must_equal "SELECT * FROM tags WHERE ((tags.id * 3) IN (SELECT unnest(artists.tag_ids[1:2]) FROM artists WHERE (id = 1)))"
149
- end
150
-
151
- it "should raise an error if associated model does not have a primary key, and :primary_key is not specified" do
152
- @c1.no_primary_key
153
- @c2.no_primary_key
154
- @c1.pg_array_to_many :tags, :clone=>:tags
155
- proc{@o1.tags}.must_raise(Sequel::Error)
156
- proc{@c2.many_to_pg_array :artists, :clone=>:artists}.must_raise(Sequel::Error)
157
- @db.sqls.must_equal []
158
- end
159
-
160
- it "should support a :key option" do
161
- @c1.pg_array_to_many :tags, :clone=>:tags, :key=>:tag2_ids
162
- @c2.many_to_pg_array :artists, :clone=>:artists, :key=>:tag2_ids
163
- @c1.class_eval{def tag2_ids; tag_ids.map{|x| x * 2} end}
164
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (2, 4, 6))"
165
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag2_ids @> ARRAY[2]::integer[])"
166
- end
167
-
168
- it "should support a :key_column option" do
169
- @c2.many_to_pg_array :artists, :clone=>:artists, :key_column=>Sequel.pg_array(:tag_ids)[1..2], :key=>:tag2_ids
170
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids[1:2] @> ARRAY[2]::integer[])"
171
- end
172
-
173
- it "should support a :primary_key option" do
174
- @c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>:id2
175
- @c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>:id2
176
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE (tags.id2 IN (1, 2, 3))"
177
- @c2.class_eval{def id2; id*2 end}
178
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[4]::integer[])"
179
- end
180
-
181
- it "should support a :conditions option" do
182
- @c1.pg_array_to_many :tags, :clone=>:tags, :conditions=>{:a=>1}
183
- @c2.many_to_pg_array :artists, :clone=>:artists, :conditions=>{:a=>1}
184
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE ((a = 1) AND (tags.id IN (1, 2, 3)))"
185
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE ((a = 1) AND (artists.tag_ids @> ARRAY[2]::integer[]))"
186
- end
187
-
188
- it "should support an :order option" do
189
- @c1.pg_array_to_many :tags, :clone=>:tags, :order=>[:a, :b]
190
- @c2.many_to_pg_array :artists, :clone=>:artists, :order=>[:a, :b]
191
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (1, 2, 3)) ORDER BY a, b"
192
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[]) ORDER BY a, b"
193
- end
194
-
195
- it "should support a select option" do
196
- @c1.pg_array_to_many :tags, :clone=>:tags, :select=>[:a, :b]
197
- @c2.many_to_pg_array :artists, :clone=>:artists, :select=>[:a, :b]
198
- @c1.load(:tag_ids=>Sequel.pg_array([1,2,3])).tags_dataset.sql.must_equal "SELECT a, b FROM tags WHERE (tags.id IN (1, 2, 3))"
199
- @c2.load(:id=>1).artists_dataset.sql.must_equal "SELECT a, b FROM artists WHERE (artists.tag_ids @> ARRAY[1]::integer[])"
200
- end
201
-
202
- it "should accept a block" do
203
- @c1.pg_array_to_many :tags, :clone=>:tags do |ds| ds.filter(:yyy=>@yyy) end
204
- @c2.many_to_pg_array :artists, :clone=>:artists do |ds| ds.filter(:a=>1) end
205
- @c1.new(:yyy=>6, :tag_ids=>Sequel.pg_array([1,2,3])).tags_dataset.sql.must_equal "SELECT * FROM tags WHERE ((tags.id IN (1, 2, 3)) AND (yyy = 6))"
206
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE ((artists.tag_ids @> ARRAY[2]::integer[]) AND (a = 1))"
207
- end
208
-
209
- it "should support a :dataset option that is used instead of the default" do
210
- @c1.pg_array_to_many :tags, :clone=>:tags, :dataset=>proc{Tag.where(:id=>tag_ids.map{|x| x*2})}
211
- @c2.many_to_pg_array :artists, :clone=>:artists, :dataset=>proc{Artist.where(Sequel.pg_array(Sequel.pg_array(:tag_ids)[1..2]).contains([id]))}
212
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE (id IN (2, 4, 6))"
213
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (tag_ids[1:2] @> ARRAY[2])"
214
- end
215
-
216
- it "should support a :limit option" do
217
- @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>[2, 3]
218
- @c2.many_to_pg_array :artists, :clone=>:artists, :limit=>[3, 2]
219
- @o1.tags_dataset.sql.must_equal "SELECT * FROM tags WHERE (tags.id IN (1, 2, 3)) LIMIT 2 OFFSET 3"
220
- @o2.artists_dataset.sql.must_equal "SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[]) LIMIT 3 OFFSET 2"
221
- end
222
-
223
- it "should support a :uniq option that removes duplicates from the association" do
224
- @c1.pg_array_to_many :tags, :clone=>:tags, :uniq=>true
225
- @c2.many_to_pg_array :artists, :clone=>:artists, :uniq=>true
226
- @c1.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
227
- @c2.dataset._fetch = [{:id=>20}, {:id=>30}, {:id=>20}, {:id=>30}]
228
- @o1.tags.must_equal [@c2.load(:id=>20), @c2.load(:id=>30)]
229
- @o2.artists.must_equal [@c1.load(:id=>20), @c1.load(:id=>30)]
230
- end
231
-
232
- it "reflection associated_object_keys should return correct values" do
233
- @c1.association_reflection(:tags).associated_object_keys.must_equal [:id]
234
- @c2.association_reflection(:artists).associated_object_keys.must_equal [:tag_ids]
235
- end
236
-
237
- it "reflection remove_before_destroy? should return correct values" do
238
- @c1.association_reflection(:tags).remove_before_destroy?.must_equal true
239
- @c2.association_reflection(:artists).remove_before_destroy?.must_equal false
240
- end
241
-
242
- it "reflection reciprocal should be correct" do
243
- @c1.association_reflection(:tags).reciprocal.must_equal :artists
244
- @c2.association_reflection(:artists).reciprocal.must_equal :tags
245
- end
246
-
247
- it "should eagerly load correctly" do
248
- a = @c1.eager(:tags).all
249
- a.must_equal [@o1]
250
- sqls = @db.sqls
251
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
252
- sqls.must_equal ["SELECT * FROM artists"]
253
- a.first.tags.must_equal [@o2]
254
- @db.sqls.must_equal []
255
-
256
- a = @c2.eager(:artists).all
257
- a.must_equal [@o2]
258
- @db.sqls.must_equal ['SELECT * FROM tags', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
259
- a.first.artists.must_equal [@o1]
260
- @db.sqls.must_equal []
261
- end
262
-
263
- it "should support using custom key options when eager loading associations" do
264
- @c1.class_eval{def tag3_ids; tag_ids.map{|x| x*3} end}
265
- @c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>Sequel.*(:id, 3), :primary_key_method=>:id3, :key=>:tag3_ids
266
- @c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
267
-
268
- a = @c1.eager(:tags).all
269
- a.must_equal [@o1]
270
- sqls = @db.sqls
271
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(\(tags\.id \* 3\) IN \([369], [369], [369]\)\)/)
272
- sqls.must_equal ["SELECT * FROM artists"]
273
- a.first.tags.must_equal [@o2]
274
- @db.sqls.must_equal []
275
-
276
- a = @c2.eager(:artists).all
277
- a.must_equal [@o2]
278
- @db.sqls.must_equal ["SELECT * FROM tags", "SELECT * FROM artists WHERE (artists.tag_ids[1:2] && ARRAY[6]::integer[])"]
279
- a.first.artists.must_equal [@o1]
280
- @db.sqls.must_equal []
281
- end
282
-
283
- it "should allow cascading of eager loading for associations of associated models" do
284
- a = @c1.eager(:tags=>:artists).all
285
- a.must_equal [@o1]
286
- sqls = @db.sqls
287
- sqls.slice!(1).must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
288
- sqls.must_equal ['SELECT * FROM artists', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
289
- a.first.tags.must_equal [@o2]
290
- a.first.tags.first.artists.must_equal [@o1]
291
- @db.sqls.must_equal []
292
- end
293
-
294
- it "should respect :eager when lazily loading an association" do
295
- @c1.pg_array_to_many :tags2, :clone=>:tags, :eager=>:artists, :key=>:tag_ids
296
- @c2.many_to_pg_array :artists2, :clone=>:artists, :eager=>:tags
297
-
298
- @o1.tags2.must_equal [@o2]
299
- @db.sqls.must_equal ["SELECT * FROM tags WHERE (tags.id IN (1, 2, 3))", "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
300
- @o1.tags2.first.artists.must_equal [@o1]
301
- @db.sqls.must_equal []
302
-
303
- @o2.artists2.must_equal [@o1]
304
- sqls = @db.sqls
305
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
306
- sqls.must_equal ["SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[2]::integer[])"]
307
- @o2.artists2.first.tags.must_equal [@o2]
308
- @db.sqls.must_equal []
309
- end
310
-
311
- it "should cascade eagerly loading when the :eager_graph association option is used" do
312
- @c1.pg_array_to_many :tags2, :clone=>:tags, :eager_graph=>:artists, :key=>:tag_ids
313
- @c2.many_to_pg_array :artists2, :clone=>:artists, :eager_graph=>:tags
314
-
315
- @c2.dataset._fetch = {:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3])}
316
- @c1.dataset._fetch = {:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3])}
317
-
318
- @o1.tags2.must_equal [@o2]
319
- @db.sqls.first.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
320
- @o1.tags2.first.artists.must_equal [@o1]
321
- @db.sqls.must_equal []
322
-
323
- @o2.artists2.must_equal [@o1]
324
- @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (artists.tag_ids @> ARRAY[2]::integer[])"]
325
- @o2.artists2.first.tags.must_equal [@o2]
326
- @db.sqls.must_equal []
327
-
328
- @c2.dataset._fetch = {:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3])}
329
- @c1.dataset._fetch = {:id=>1, :tag_ids=>Sequel.pg_array([1,2,3])}
330
-
331
- a = @c1.eager(:tags2).all
332
- sqls = @db.sqls
333
- sqls.pop.must_match(/SELECT tags\.id, artists\.id AS artists_id, artists\.tag_ids FROM tags LEFT OUTER JOIN artists ON \(artists.tag_ids @> ARRAY\[tags.id\]\) WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
334
- sqls.must_equal ["SELECT * FROM artists"]
335
- a.must_equal [@o1]
336
- a.first.tags2.must_equal [@o2]
337
- a.first.tags2.first.artists.must_equal [@o1]
338
- @db.sqls.must_equal []
339
-
340
- @c2.dataset._fetch = {:id=>2}
341
- @c1.dataset._fetch = {:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3])}
342
-
343
- a = @c2.eager(:artists2).all
344
- @db.sqls.must_equal ["SELECT * FROM tags", "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
345
- a.must_equal [@o2]
346
- a.first.artists2.must_equal [@o1]
347
- a.first.artists2.first.tags.must_equal [@o2]
348
- @db.sqls.must_equal []
349
- end
350
-
351
- it "should respect the :limit option when eager loading" do
352
- @c2.dataset._fetch = [{:id=>1},{:id=>2}, {:id=>3}]
353
-
354
- @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>2
355
- a = @c1.eager(:tags).all
356
- a.must_equal [@o1]
357
- sqls = @db.sqls
358
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
359
- sqls.must_equal ["SELECT * FROM artists"]
360
- a.first.tags.must_equal [@c2.load(:id=>1), @c2.load(:id=>2)]
361
- @db.sqls.must_equal []
362
-
363
- @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>[1, 1]
364
- a = @c1.eager(:tags).all
365
- a.must_equal [@o1]
366
- sqls = @db.sqls
367
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
368
- sqls.must_equal ["SELECT * FROM artists"]
369
- a.first.tags.must_equal [@c2.load(:id=>2)]
370
- @db.sqls.must_equal []
371
-
372
- @c1.pg_array_to_many :tags, :clone=>:tags, :limit=>[nil, 1]
373
- a = @c1.eager(:tags).all
374
- a.must_equal [@o1]
375
- sqls = @db.sqls
376
- sqls.pop.must_match(/SELECT \* FROM tags WHERE \(tags\.id IN \([123], [123], [123]\)\)/)
377
- sqls.must_equal ["SELECT * FROM artists"]
378
- a.first.tags.must_equal [@c2.load(:id=>2), @c2.load(:id=>3)]
379
- @db.sqls.length.must_equal 0
380
-
381
- @c2.dataset._fetch = [{:id=>2}]
382
- @c1.dataset._fetch = [{:id=>5, :tag_ids=>Sequel.pg_array([1,2,3])},{:id=>6, :tag_ids=>Sequel.pg_array([2,3])}, {:id=>7, :tag_ids=>Sequel.pg_array([1,2])}]
383
-
384
- @c2.many_to_pg_array :artists, :clone=>:artists, :limit=>2
385
- a = @c2.eager(:artists).all
386
- a.must_equal [@o2]
387
- @db.sqls.must_equal ['SELECT * FROM tags', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
388
- a.first.artists.must_equal [@c1.load(:id=>5, :tag_ids=>Sequel.pg_array([1,2,3])), @c1.load(:id=>6, :tag_ids=>Sequel.pg_array([2,3]))]
389
- @db.sqls.must_equal []
390
-
391
- @c2.many_to_pg_array :artists, :clone=>:artists, :limit=>[1, 1]
392
- a = @c2.eager(:artists).all
393
- a.must_equal [@o2]
394
- @db.sqls.must_equal ['SELECT * FROM tags', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
395
- a.first.artists.must_equal [@c1.load(:id=>6, :tag_ids=>Sequel.pg_array([2,3]))]
396
- @db.sqls.must_equal []
397
-
398
- @c2.many_to_pg_array :artists, :clone=>:artists, :limit=>[nil, 1]
399
- a = @c2.eager(:artists).all
400
- a.must_equal [@o2]
401
- @db.sqls.must_equal ['SELECT * FROM tags', "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::integer[])"]
402
- a.first.artists.must_equal [@c1.load(:id=>6, :tag_ids=>Sequel.pg_array([2,3])), @c1.load(:id=>7, :tag_ids=>Sequel.pg_array([1,2]))]
403
- @db.sqls.must_equal []
404
- end
405
-
406
- it "should support association_join" do
407
- @c1.association_join(:tags).sql.must_equal "SELECT * FROM artists INNER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"
408
- @c2.association_join(:artists).sql.must_equal "SELECT * FROM tags INNER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id])"
409
- end
410
-
411
- it "should support custom selects when using association_join" do
412
- @c1.select{a(b)}.association_join(:tags).sql.must_equal "SELECT a(b) FROM artists INNER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"
413
- @c2.select{a(b)}.association_join(:artists).sql.must_equal "SELECT a(b) FROM tags INNER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id])"
414
- end
415
-
416
- it "should eagerly graph associations" do
417
- @c2.dataset._fetch = {:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3])}
418
- @c1.dataset._fetch = {:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3])}
419
-
420
- a = @c1.eager_graph(:tags).all
421
- @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
422
- a.must_equal [@o1]
423
- a.first.tags.must_equal [@o2]
424
- @db.sqls.must_equal []
425
-
426
- a = @c2.eager_graph(:artists).all
427
- @db.sqls.must_equal ["SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id])"]
428
- a.must_equal [@o2]
429
- a.first.artists.must_equal [@o1]
430
- @db.sqls.must_equal []
431
- end
432
-
433
- it "should allow cascading of eager graphing for associations of associated models" do
434
- @c2.dataset._fetch = {:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2}
435
- @c1.dataset._fetch = {:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3])}
436
-
437
- a = @c1.eager_graph(:tags=>:artists).all
438
- @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id, artists_0.id AS artists_0_id, artists_0.tag_ids AS artists_0_tag_ids FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id]) LEFT OUTER JOIN artists AS artists_0 ON (artists_0.tag_ids @> ARRAY[tags.id])"]
439
- a.must_equal [@o1]
440
- a.first.tags.must_equal [@o2]
441
- a.first.tags.first.artists.must_equal [@o1]
442
- @db.sqls.must_equal []
443
-
444
- a = @c2.eager_graph(:artists=>:tags).all
445
- @db.sqls.must_equal ["SELECT tags.id, artists.id AS artists_id, artists.tag_ids, tags_0.id AS tags_0_id FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id]) LEFT OUTER JOIN tags AS tags_0 ON (artists.tag_ids @> ARRAY[tags_0.id])"]
446
- a.must_equal [@o2]
447
- a.first.artists.must_equal [@o1]
448
- a.first.artists.first.tags.must_equal [@o2]
449
- @db.sqls.must_equal []
450
- end
451
-
452
- it "eager graphing should respect key options" do
453
- @c1.class_eval{def tag3_ids; tag_ids.map{|x| x*3} end}
454
- @c1.pg_array_to_many :tags, :clone=>:tags, :primary_key=>Sequel.*(:id, 3), :primary_key_method=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
455
- @c2.many_to_pg_array :artists, :clone=>:artists, :primary_key=>:id3, :key=>:tag3_ids, :key_column=>Sequel.pg_array(:tag_ids)[1..2]
456
-
457
- @c2.dataset._fetch = {:id=>2, :artists_id=>1, :tag_ids=>Sequel.pg_array([1,2,3]), :tags_0_id=>2}
458
- @c1.dataset._fetch = {:id=>1, :tags_id=>2, :tag_ids=>Sequel.pg_array([1,2,3]), :artists_0_id=>1, :artists_0_tag_ids=>Sequel.pg_array([1,2,3])}
459
-
460
- a = @c1.eager_graph(:tags).all
461
- a.must_equal [@o1]
462
- @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids[1:2] @> ARRAY[(tags.id * 3)])"]
463
- a.first.tags.must_equal [@o2]
464
- @db.sqls.must_equal []
465
-
466
- a = @c2.eager_graph(:artists).all
467
- a.must_equal [@o2]
468
- @db.sqls.must_equal ["SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids[1:2] @> ARRAY[tags.id3])"]
469
- a.first.artists.must_equal [@o1]
470
- @db.sqls.must_equal []
471
- end
472
-
473
- it "should respect the association's :graph_select option" do
474
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_select=>:id2
475
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_select=>:id
476
-
477
- @c2.dataset._fetch = {:id=>2, :artists_id=>1}
478
- @c1.dataset._fetch = {:id=>1, :id2=>2, :tag_ids=>Sequel.pg_array([1,2,3])}
479
-
480
- a = @c1.eager_graph(:tags).all
481
- @db.sqls.must_equal ["SELECT artists.id, artists.tag_ids, tags.id2 FROM artists LEFT OUTER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"]
482
- a.must_equal [@o1]
483
- a.first.tags.must_equal [@c2.load(:id2=>2)]
484
- @db.sqls.must_equal []
485
-
486
- a = @c2.eager_graph(:artists).all
487
- @db.sqls.must_equal ["SELECT tags.id, artists.id AS artists_id FROM tags LEFT OUTER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id])"]
488
- a.must_equal [@o2]
489
- a.first.artists.must_equal [@c1.load(:id=>1)]
490
- @db.sqls.must_equal []
491
- end
492
-
493
- it "should respect the association's :graph_join_type option" do
494
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_join_type=>:inner
495
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_join_type=>:inner
496
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists INNER JOIN tags ON (artists.tag_ids @> ARRAY[tags.id])"
497
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags INNER JOIN artists ON (artists.tag_ids @> ARRAY[tags.id])"
498
- end
499
-
500
- it "should respect the association's :conditions option" do
501
- @c1.pg_array_to_many :tags, :clone=>:tags, :conditions=>{:a=>1}
502
- @c2.many_to_pg_array :artists, :clone=>:artists, :conditions=>{:a=>1}
503
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON ((tags.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
504
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON ((artists.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
505
- end
506
-
507
- it "should respect the association's :graph_conditions option" do
508
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_conditions=>{:a=>1}
509
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_conditions=>{:a=>1}
510
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON ((tags.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
511
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON ((artists.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
512
- end
513
-
514
- it "should respect the association's :graph_block option" do
515
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :a)=>1}}
516
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(ja, :a)=>1}}
517
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON ((tags.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
518
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON ((artists.a = 1) AND (artists.tag_ids @> ARRAY[tags.id]))"
519
- end
520
-
521
- it "should respect the association's :graph_only_conditions option" do
522
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_only_conditions=>{:a=>1}
523
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_only_conditions=>{:a=>1}
524
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON (tags.a = 1)"
525
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON (artists.a = 1)"
526
- end
527
-
528
- it "should respect the association's :graph_only_conditions with :graph_block option" do
529
- @c1.pg_array_to_many :tags, :clone=>:tags, :graph_only_conditions=>{:a=>1}, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(lja, :b)=>1}}
530
- @c2.many_to_pg_array :artists, :clone=>:artists, :graph_only_conditions=>{:a=>1}, :graph_block=>proc{|ja,lja,js| {Sequel.qualify(lja, :b)=>1}}
531
- @c1.eager_graph(:tags).sql.must_equal "SELECT artists.id, artists.tag_ids, tags.id AS tags_id FROM artists LEFT OUTER JOIN tags ON ((tags.a = 1) AND (artists.b = 1))"
532
- @c2.eager_graph(:artists).sql.must_equal "SELECT tags.id, artists.id AS artists_id, artists.tag_ids FROM tags LEFT OUTER JOIN artists ON ((artists.a = 1) AND (tags.b = 1))"
533
- end
534
-
535
- it "should define an add_ method for adding associated objects" do
536
- @o1.add_tag(@c2.load(:id=>4))
537
- @o1.tag_ids.must_equal [1,2,3,4]
538
- @db.sqls.must_equal []
539
- @o1.save_changes
540
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1,2,3,4] WHERE (id = 1)"]
541
-
542
- @o2.add_artist(@c1.load(:id=>1, :tag_ids=>Sequel.pg_array([4])))
543
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[4,2] WHERE (id = 1)"]
544
- end
545
-
546
- it "should define a remove_ method for removing associated objects" do
547
- @o1.remove_tag(@o2)
548
- @o1.tag_ids.must_equal [1,3]
549
- @db.sqls.must_equal []
550
- @o1.save_changes
551
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1,3] WHERE (id = 1)"]
552
-
553
- @o2.remove_artist(@c1.load(:id=>1, :tag_ids=>Sequel.pg_array([1,2,3,4])))
554
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1,3,4] WHERE (id = 1)"]
555
- end
556
-
557
- it "should define a remove_all_ method for removing all associated objects" do
558
- @o1.remove_all_tags
559
- @o1.tag_ids.must_equal []
560
- @db.sqls.must_equal []
561
- @o1.save_changes
562
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[] WHERE (id = 1)"]
563
-
564
- @o2.remove_all_artists
565
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = array_remove(tag_ids, 2) WHERE (tag_ids @> ARRAY[2])"]
566
- end
567
-
568
- it "should allow calling add_ and remove_ methods on new objects for pg_array_to_many associations" do
569
- a = Artist.new
570
- a.add_tag(@c2.load(:id=>4))
571
- a.tag_ids.must_equal [4]
572
- a.remove_tag(@c2.load(:id=>4))
573
- a.tag_ids.must_equal []
574
- a.add_tag(@c2.load(:id=>4))
575
- a.tag_ids.must_equal [4]
576
- a.remove_all_tags
577
- a.tag_ids.must_equal []
578
- end
579
-
580
- it "should have pg_array_to_many association modification methods save if :save_after_modify option is used" do
581
- @c1.pg_array_to_many :tags, :clone=>:tags, :save_after_modify=>true
582
-
583
- @o1.add_tag(@c2.load(:id=>4))
584
- @o1.tag_ids.must_equal [1,2,3,4]
585
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1,2,3,4] WHERE (id = 1)"]
586
-
587
- @o1.remove_tag(@o2)
588
- @o1.tag_ids.must_equal [1,3,4]
589
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1,3,4] WHERE (id = 1)"]
590
-
591
- @o1.remove_all_tags
592
- @o1.tag_ids.must_equal []
593
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[] WHERE (id = 1)"]
594
- end
595
-
596
- it "should have association modification methods deal with nil values" do
597
- v = @c1.load(:id=>1)
598
- v.add_tag(@c2.load(:id=>4))
599
- v.tag_ids.must_equal [4]
600
- @db.sqls.must_equal []
601
- v.save_changes
602
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[4]::integer[] WHERE (id = 1)"]
603
-
604
- @o2.add_artist(@c1.load(:id=>1))
605
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[2]::integer[] WHERE (id = 1)"]
606
-
607
- v = @c1.load(:id=>1)
608
- v.remove_tag(@c2.load(:id=>4))
609
- v.tag_ids.must_equal nil
610
- @db.sqls.must_equal []
611
- v.save_changes
612
- @db.sqls.must_equal []
613
-
614
- @o2.remove_artist(@c1.load(:id=>1))
615
- @db.sqls.must_equal []
616
-
617
- v = @c1.load(:id=>1)
618
- v.remove_all_tags
619
- v.tag_ids.must_equal nil
620
- @db.sqls.must_equal []
621
- v.save_changes
622
- @db.sqls.must_equal []
623
- end
624
-
625
- it "should have association modification methods deal with empty arrays values" do
626
- v = @c1.load(:id=>1, :tag_ids=>Sequel.pg_array([]))
627
- v.add_tag(@c2.load(:id=>4))
628
- v.tag_ids.must_equal [4]
629
- @db.sqls.must_equal []
630
- v.save_changes
631
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[4] WHERE (id = 1)"]
632
-
633
- @o2.add_artist(@c1.load(:id=>1, :tag_ids=>Sequel.pg_array([])))
634
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[2] WHERE (id = 1)"]
635
-
636
- v = @c1.load(:id=>1, :tag_ids=>Sequel.pg_array([]))
637
- v.remove_tag(@c2.load(:id=>4))
638
- v.tag_ids.must_equal []
639
- @db.sqls.must_equal []
640
- v.save_changes
641
- @db.sqls.must_equal []
642
-
643
- @o2.remove_artist(@c1.load(:id=>1, :tag_ids=>Sequel.pg_array([])))
644
- @db.sqls.must_equal []
645
-
646
- v = @c1.load(:id=>1, :tag_ids=>Sequel.pg_array([]))
647
- v.remove_all_tags
648
- v.tag_ids.must_equal []
649
- @db.sqls.must_equal []
650
- v.save_changes
651
- @db.sqls.must_equal []
652
- end
653
-
654
- it "should respect the :array_type option when manually creating arrays" do
655
- @c1.pg_array_to_many :tags, :clone=>:tags, :array_type=>:int8
656
- @c2.many_to_pg_array :artists, :clone=>:artists, :array_type=>:int8
657
- v = @c1.load(:id=>1)
658
- v.add_tag(@c2.load(:id=>4))
659
- v.tag_ids.must_equal [4]
660
- @db.sqls.must_equal []
661
- v.save_changes
662
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[4]::int8[] WHERE (id = 1)"]
663
-
664
- @o2.add_artist(@c1.load(:id=>1))
665
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[2]::int8[] WHERE (id = 1)"]
666
- end
667
-
668
- it "should respect the :array_type option in the associations dataset" do
669
- @c2.many_to_pg_array :artists, :clone=>:artists, :array_type=>:int8
670
- @c2.load(:id=>1).artists_dataset.sql.must_equal 'SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[1]::int8[])'
671
- end
672
-
673
- it "should respect the :array_type option when eager loading" do
674
- @c2.many_to_pg_array :artists, :clone=>:artists, :array_type=>:int8
675
- @c2.eager(:artists).all
676
- @db.sqls.must_equal ["SELECT * FROM tags", "SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[2]::int8[])"]
677
- end
678
-
679
- it "should respect the :array_type option when filtering by associations" do
680
- @c1.pg_array_to_many :tags, :clone=>:tags, :array_type=>:int8
681
- @c1.where(:tags=>@c2.load(:id=>1)).sql.must_equal 'SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[1]::int8[])'
682
- @c1.where(:tags=>[@c2.load(:id=>1), @c2.load(:id=>2)]).sql.must_equal 'SELECT * FROM artists WHERE (artists.tag_ids && ARRAY[1,2]::int8[])'
683
- end
684
-
685
- it "should automatically determine the array type by looking at the schema" do
686
- @c1.db_schema[:tag_ids][:db_type] = 'int8'
687
- @c2.many_to_pg_array :artists, :clone=>:artists
688
- @c1.pg_array_to_many :tags, :clone=>:tags, :save_after_modify=>true
689
- @c2.load(:id=>1).artists_dataset.sql.must_equal 'SELECT * FROM artists WHERE (artists.tag_ids @> ARRAY[1]::int8[])'
690
- @c1.load(:id=>1).add_tag(@c2.load(:id=>1))
691
- @db.sqls.must_equal ["UPDATE artists SET tag_ids = ARRAY[1]::int8[] WHERE (id = 1)"]
692
- end
693
-
694
- it "should automatically determine the array type by looking at the schema" do
695
- end
696
-
697
- it "should not validate the current/associated object in add_ and remove_ if the :validate=>false option is used" do
698
- @c1.pg_array_to_many :tags, :clone=>:tags, :validate=>false, :save_after_modify=>true
699
- @c2.many_to_pg_array :artists, :clone=>:artists, :validate=>false
700
- a = @c1.load(:id=>1)
701
- t = @c2.load(:id=>2)
702
- def a.validate() errors.add(:id, 'foo') end
703
- a.associations[:tags] = []
704
- a.add_tag(t).must_equal t
705
- a.tags.must_equal [t]
706
- a.remove_tag(t).must_equal t
707
- a.tags.must_equal []
708
-
709
- t.associations[:artists] = []
710
- t.add_artist(a).must_equal a
711
- t.artists.must_equal [a]
712
- t.remove_artist(a).must_equal a
713
- t.artists.must_equal []
714
- end
715
-
716
- it "should not raise exception in add_ and remove_ if the :raise_on_save_failure=>false option is used" do
717
- @c1.pg_array_to_many :tags, :clone=>:tags, :raise_on_save_failure=>false, :save_after_modify=>true
718
- @c2.many_to_pg_array :artists, :clone=>:artists, :raise_on_save_failure=>false
719
- a = @c1.load(:id=>1)
720
- t = @c2.load(:id=>2)
721
- def a.validate() errors.add(:id, 'foo') end
722
- a.associations[:tags] = []
723
- a.add_tag(t).must_equal nil
724
- a.tags.must_equal []
725
- a.associations[:tags] = [t]
726
- a.remove_tag(t).must_equal nil
727
- a.tags.must_equal [t]
728
-
729
- t.associations[:artists] = []
730
- t.add_artist(a).must_equal nil
731
- t.artists.must_equal []
732
- t.associations[:artists] = [a]
733
- t.remove_artist(a).must_equal nil
734
- t.artists.must_equal [a]
735
- end
736
- end