sequel 5.8.0 → 5.38.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 (510) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +409 -1795
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -4
  5. data/bin/sequel +4 -0
  6. data/doc/advanced_associations.rdoc +136 -18
  7. data/doc/association_basics.rdoc +10 -5
  8. data/doc/cheat_sheet.rdoc +1 -0
  9. data/doc/code_order.rdoc +12 -2
  10. data/doc/dataset_filtering.rdoc +17 -2
  11. data/doc/mass_assignment.rdoc +3 -3
  12. data/doc/model_dataset_method_design.rdoc +1 -1
  13. data/doc/model_plugins.rdoc +1 -1
  14. data/doc/opening_databases.rdoc +30 -8
  15. data/doc/postgresql.rdoc +107 -2
  16. data/doc/release_notes/5.10.0.txt +84 -0
  17. data/doc/release_notes/5.11.0.txt +83 -0
  18. data/doc/release_notes/5.12.0.txt +141 -0
  19. data/doc/release_notes/5.13.0.txt +27 -0
  20. data/doc/release_notes/5.14.0.txt +63 -0
  21. data/doc/release_notes/5.15.0.txt +39 -0
  22. data/doc/release_notes/5.16.0.txt +110 -0
  23. data/doc/release_notes/5.17.0.txt +31 -0
  24. data/doc/release_notes/5.18.0.txt +69 -0
  25. data/doc/release_notes/5.19.0.txt +28 -0
  26. data/doc/release_notes/5.20.0.txt +89 -0
  27. data/doc/release_notes/5.21.0.txt +87 -0
  28. data/doc/release_notes/5.22.0.txt +48 -0
  29. data/doc/release_notes/5.23.0.txt +56 -0
  30. data/doc/release_notes/5.24.0.txt +56 -0
  31. data/doc/release_notes/5.25.0.txt +32 -0
  32. data/doc/release_notes/5.26.0.txt +35 -0
  33. data/doc/release_notes/5.27.0.txt +21 -0
  34. data/doc/release_notes/5.28.0.txt +16 -0
  35. data/doc/release_notes/5.29.0.txt +22 -0
  36. data/doc/release_notes/5.30.0.txt +20 -0
  37. data/doc/release_notes/5.31.0.txt +148 -0
  38. data/doc/release_notes/5.32.0.txt +46 -0
  39. data/doc/release_notes/5.33.0.txt +24 -0
  40. data/doc/release_notes/5.34.0.txt +40 -0
  41. data/doc/release_notes/5.35.0.txt +56 -0
  42. data/doc/release_notes/5.36.0.txt +60 -0
  43. data/doc/release_notes/5.37.0.txt +30 -0
  44. data/doc/release_notes/5.38.0.txt +28 -0
  45. data/doc/release_notes/5.9.0.txt +99 -0
  46. data/doc/security.rdoc +10 -0
  47. data/doc/sharding.rdoc +42 -28
  48. data/doc/sql.rdoc +12 -0
  49. data/doc/testing.rdoc +24 -17
  50. data/doc/transactions.rdoc +78 -0
  51. data/doc/validations.rdoc +2 -2
  52. data/lib/sequel/adapters/ado.rb +26 -18
  53. data/lib/sequel/adapters/ado/access.rb +2 -2
  54. data/lib/sequel/adapters/ado/mssql.rb +5 -8
  55. data/lib/sequel/adapters/amalgalite.rb +1 -1
  56. data/lib/sequel/adapters/jdbc.rb +71 -27
  57. data/lib/sequel/adapters/jdbc/mysql.rb +6 -6
  58. data/lib/sequel/adapters/jdbc/oracle.rb +7 -6
  59. data/lib/sequel/adapters/jdbc/postgresql.rb +17 -28
  60. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +5 -6
  61. data/lib/sequel/adapters/jdbc/sqlite.rb +33 -2
  62. data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -3
  63. data/lib/sequel/adapters/jdbc/transactions.rb +14 -28
  64. data/lib/sequel/adapters/mysql.rb +14 -15
  65. data/lib/sequel/adapters/mysql2.rb +5 -3
  66. data/lib/sequel/adapters/odbc.rb +4 -6
  67. data/lib/sequel/adapters/oracle.rb +7 -7
  68. data/lib/sequel/adapters/postgres.rb +52 -16
  69. data/lib/sequel/adapters/shared/access.rb +16 -12
  70. data/lib/sequel/adapters/shared/db2.rb +5 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +41 -18
  72. data/lib/sequel/adapters/shared/mysql.rb +66 -19
  73. data/lib/sequel/adapters/shared/oracle.rb +29 -23
  74. data/lib/sequel/adapters/shared/postgres.rb +341 -95
  75. data/lib/sequel/adapters/shared/sqlanywhere.rb +23 -10
  76. data/lib/sequel/adapters/shared/sqlite.rb +174 -21
  77. data/lib/sequel/adapters/sqlanywhere.rb +33 -17
  78. data/lib/sequel/adapters/sqlite.rb +78 -68
  79. data/lib/sequel/adapters/tinytds.rb +14 -6
  80. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +2 -5
  81. data/lib/sequel/adapters/utils/mysql_mysql2.rb +5 -1
  82. data/lib/sequel/connection_pool.rb +2 -6
  83. data/lib/sequel/connection_pool/sharded_single.rb +7 -4
  84. data/lib/sequel/connection_pool/sharded_threaded.rb +32 -21
  85. data/lib/sequel/connection_pool/single.rb +1 -1
  86. data/lib/sequel/connection_pool/threaded.rb +26 -11
  87. data/lib/sequel/core.rb +327 -319
  88. data/lib/sequel/database/connecting.rb +7 -8
  89. data/lib/sequel/database/logging.rb +7 -1
  90. data/lib/sequel/database/misc.rb +68 -34
  91. data/lib/sequel/database/query.rb +6 -4
  92. data/lib/sequel/database/schema_generator.rb +31 -11
  93. data/lib/sequel/database/schema_methods.rb +32 -22
  94. data/lib/sequel/database/transactions.rb +129 -25
  95. data/lib/sequel/dataset.rb +4 -2
  96. data/lib/sequel/dataset/actions.rb +34 -23
  97. data/lib/sequel/dataset/features.rb +34 -0
  98. data/lib/sequel/dataset/graph.rb +27 -11
  99. data/lib/sequel/dataset/misc.rb +17 -3
  100. data/lib/sequel/dataset/placeholder_literalizer.rb +50 -21
  101. data/lib/sequel/dataset/prepared_statements.rb +96 -26
  102. data/lib/sequel/dataset/query.rb +43 -8
  103. data/lib/sequel/dataset/sql.rb +189 -41
  104. data/lib/sequel/deprecated.rb +3 -1
  105. data/lib/sequel/exceptions.rb +2 -0
  106. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  107. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  108. data/lib/sequel/extensions/caller_logging.rb +79 -0
  109. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  110. data/lib/sequel/extensions/connection_expiration.rb +6 -6
  111. data/lib/sequel/extensions/connection_validator.rb +7 -6
  112. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  113. data/lib/sequel/extensions/constraint_validations.rb +53 -28
  114. data/lib/sequel/extensions/core_refinements.rb +2 -0
  115. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  116. data/lib/sequel/extensions/escaped_like.rb +100 -0
  117. data/lib/sequel/extensions/eval_inspect.rb +3 -1
  118. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  119. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  120. data/lib/sequel/extensions/index_caching.rb +9 -7
  121. data/lib/sequel/extensions/integer64.rb +3 -1
  122. data/lib/sequel/extensions/looser_typecasting.rb +3 -3
  123. data/lib/sequel/extensions/migration.rb +13 -6
  124. data/lib/sequel/extensions/named_timezones.rb +84 -23
  125. data/lib/sequel/extensions/pg_array.rb +87 -79
  126. data/lib/sequel/extensions/pg_array_ops.rb +14 -6
  127. data/lib/sequel/extensions/pg_enum.rb +34 -18
  128. data/lib/sequel/extensions/pg_extended_date_support.rb +34 -14
  129. data/lib/sequel/extensions/pg_hstore.rb +6 -0
  130. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  131. data/lib/sequel/extensions/pg_inet.rb +15 -5
  132. data/lib/sequel/extensions/pg_interval.rb +2 -0
  133. data/lib/sequel/extensions/pg_json.rb +387 -123
  134. data/lib/sequel/extensions/pg_json_ops.rb +168 -0
  135. data/lib/sequel/extensions/pg_range.rb +20 -10
  136. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  137. data/lib/sequel/extensions/pg_row.rb +3 -2
  138. data/lib/sequel/extensions/pg_row_ops.rb +24 -0
  139. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  140. data/lib/sequel/extensions/pg_timestamptz.rb +2 -0
  141. data/lib/sequel/extensions/query.rb +1 -0
  142. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  143. data/lib/sequel/extensions/s.rb +2 -0
  144. data/lib/sequel/extensions/schema_dumper.rb +13 -7
  145. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +4 -2
  146. data/lib/sequel/extensions/server_block.rb +18 -7
  147. data/lib/sequel/extensions/sql_comments.rb +2 -2
  148. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  149. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  150. data/lib/sequel/extensions/to_dot.rb +9 -3
  151. data/lib/sequel/model.rb +3 -1
  152. data/lib/sequel/model/associations.rb +403 -69
  153. data/lib/sequel/model/base.rb +170 -90
  154. data/lib/sequel/model/plugins.rb +105 -0
  155. data/lib/sequel/plugins/after_initialize.rb +1 -1
  156. data/lib/sequel/plugins/association_dependencies.rb +3 -3
  157. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  158. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  159. data/lib/sequel/plugins/association_pks.rb +74 -22
  160. data/lib/sequel/plugins/association_proxies.rb +6 -2
  161. data/lib/sequel/plugins/auto_validations.rb +36 -17
  162. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  163. data/lib/sequel/plugins/boolean_subsets.rb +4 -1
  164. data/lib/sequel/plugins/caching.rb +3 -0
  165. data/lib/sequel/plugins/class_table_inheritance.rb +62 -34
  166. data/lib/sequel/plugins/composition.rb +13 -9
  167. data/lib/sequel/plugins/csv_serializer.rb +28 -9
  168. data/lib/sequel/plugins/defaults_setter.rb +2 -2
  169. data/lib/sequel/plugins/dirty.rb +60 -22
  170. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  171. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  172. data/lib/sequel/plugins/finder.rb +2 -2
  173. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  174. data/lib/sequel/plugins/hook_class_methods.rb +17 -5
  175. data/lib/sequel/plugins/insert_conflict.rb +72 -0
  176. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  177. data/lib/sequel/plugins/inverted_subsets.rb +2 -2
  178. data/lib/sequel/plugins/json_serializer.rb +21 -14
  179. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  180. data/lib/sequel/plugins/list.rb +22 -10
  181. data/lib/sequel/plugins/many_through_many.rb +1 -1
  182. data/lib/sequel/plugins/nested_attributes.rb +27 -5
  183. data/lib/sequel/plugins/pg_array_associations.rb +12 -9
  184. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +149 -61
  185. data/lib/sequel/plugins/prepared_statements.rb +6 -12
  186. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  187. data/lib/sequel/plugins/rcte_tree.rb +20 -22
  188. data/lib/sequel/plugins/sharding.rb +13 -7
  189. data/lib/sequel/plugins/single_table_inheritance.rb +20 -15
  190. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  191. data/lib/sequel/plugins/static_cache.rb +36 -17
  192. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  193. data/lib/sequel/plugins/string_stripper.rb +1 -1
  194. data/lib/sequel/plugins/subclasses.rb +2 -0
  195. data/lib/sequel/plugins/subset_conditions.rb +2 -2
  196. data/lib/sequel/plugins/tactical_eager_loading.rb +73 -2
  197. data/lib/sequel/plugins/throw_failures.rb +110 -0
  198. data/lib/sequel/plugins/tree.rb +49 -31
  199. data/lib/sequel/plugins/typecast_on_load.rb +3 -2
  200. data/lib/sequel/plugins/validation_class_methods.rb +11 -5
  201. data/lib/sequel/plugins/validation_helpers.rb +2 -2
  202. data/lib/sequel/sql.rb +120 -30
  203. data/lib/sequel/timezones.rb +55 -14
  204. data/lib/sequel/version.rb +6 -1
  205. metadata +101 -361
  206. data/Rakefile +0 -151
  207. data/doc/release_notes/4.0.0.txt +0 -262
  208. data/doc/release_notes/4.1.0.txt +0 -85
  209. data/doc/release_notes/4.10.0.txt +0 -226
  210. data/doc/release_notes/4.11.0.txt +0 -147
  211. data/doc/release_notes/4.12.0.txt +0 -105
  212. data/doc/release_notes/4.13.0.txt +0 -169
  213. data/doc/release_notes/4.14.0.txt +0 -68
  214. data/doc/release_notes/4.15.0.txt +0 -56
  215. data/doc/release_notes/4.16.0.txt +0 -36
  216. data/doc/release_notes/4.17.0.txt +0 -38
  217. data/doc/release_notes/4.18.0.txt +0 -36
  218. data/doc/release_notes/4.19.0.txt +0 -45
  219. data/doc/release_notes/4.2.0.txt +0 -129
  220. data/doc/release_notes/4.20.0.txt +0 -79
  221. data/doc/release_notes/4.21.0.txt +0 -94
  222. data/doc/release_notes/4.22.0.txt +0 -72
  223. data/doc/release_notes/4.23.0.txt +0 -65
  224. data/doc/release_notes/4.24.0.txt +0 -99
  225. data/doc/release_notes/4.25.0.txt +0 -181
  226. data/doc/release_notes/4.26.0.txt +0 -44
  227. data/doc/release_notes/4.27.0.txt +0 -78
  228. data/doc/release_notes/4.28.0.txt +0 -57
  229. data/doc/release_notes/4.29.0.txt +0 -41
  230. data/doc/release_notes/4.3.0.txt +0 -40
  231. data/doc/release_notes/4.30.0.txt +0 -37
  232. data/doc/release_notes/4.31.0.txt +0 -57
  233. data/doc/release_notes/4.32.0.txt +0 -132
  234. data/doc/release_notes/4.33.0.txt +0 -88
  235. data/doc/release_notes/4.34.0.txt +0 -86
  236. data/doc/release_notes/4.35.0.txt +0 -130
  237. data/doc/release_notes/4.36.0.txt +0 -116
  238. data/doc/release_notes/4.37.0.txt +0 -50
  239. data/doc/release_notes/4.38.0.txt +0 -67
  240. data/doc/release_notes/4.39.0.txt +0 -127
  241. data/doc/release_notes/4.4.0.txt +0 -92
  242. data/doc/release_notes/4.40.0.txt +0 -179
  243. data/doc/release_notes/4.41.0.txt +0 -77
  244. data/doc/release_notes/4.42.0.txt +0 -221
  245. data/doc/release_notes/4.43.0.txt +0 -87
  246. data/doc/release_notes/4.44.0.txt +0 -125
  247. data/doc/release_notes/4.45.0.txt +0 -370
  248. data/doc/release_notes/4.46.0.txt +0 -404
  249. data/doc/release_notes/4.47.0.txt +0 -56
  250. data/doc/release_notes/4.48.0.txt +0 -293
  251. data/doc/release_notes/4.49.0.txt +0 -222
  252. data/doc/release_notes/4.5.0.txt +0 -34
  253. data/doc/release_notes/4.6.0.txt +0 -30
  254. data/doc/release_notes/4.7.0.txt +0 -103
  255. data/doc/release_notes/4.8.0.txt +0 -175
  256. data/doc/release_notes/4.9.0.txt +0 -190
  257. data/spec/adapter_spec.rb +0 -4
  258. data/spec/adapters/db2_spec.rb +0 -170
  259. data/spec/adapters/mssql_spec.rb +0 -804
  260. data/spec/adapters/mysql_spec.rb +0 -1041
  261. data/spec/adapters/oracle_spec.rb +0 -327
  262. data/spec/adapters/postgres_spec.rb +0 -4000
  263. data/spec/adapters/spec_helper.rb +0 -43
  264. data/spec/adapters/sqlanywhere_spec.rb +0 -97
  265. data/spec/adapters/sqlite_spec.rb +0 -600
  266. data/spec/bin_spec.rb +0 -269
  267. data/spec/core/connection_pool_spec.rb +0 -1228
  268. data/spec/core/database_spec.rb +0 -2673
  269. data/spec/core/dataset_spec.rb +0 -5419
  270. data/spec/core/deprecated_spec.rb +0 -70
  271. data/spec/core/expression_filters_spec.rb +0 -1344
  272. data/spec/core/mock_adapter_spec.rb +0 -722
  273. data/spec/core/object_graph_spec.rb +0 -306
  274. data/spec/core/placeholder_literalizer_spec.rb +0 -166
  275. data/spec/core/schema_generator_spec.rb +0 -214
  276. data/spec/core/schema_spec.rb +0 -1820
  277. data/spec/core/spec_helper.rb +0 -23
  278. data/spec/core/version_spec.rb +0 -7
  279. data/spec/core_extensions_spec.rb +0 -762
  280. data/spec/core_model_spec.rb +0 -2
  281. data/spec/core_spec.rb +0 -1
  282. data/spec/deprecation_helper.rb +0 -30
  283. data/spec/extensions/accessed_columns_spec.rb +0 -51
  284. data/spec/extensions/active_model_spec.rb +0 -99
  285. data/spec/extensions/after_initialize_spec.rb +0 -24
  286. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  287. data/spec/extensions/association_dependencies_spec.rb +0 -125
  288. data/spec/extensions/association_pks_spec.rb +0 -423
  289. data/spec/extensions/association_proxies_spec.rb +0 -100
  290. data/spec/extensions/auto_literal_strings_spec.rb +0 -205
  291. data/spec/extensions/auto_validations_spec.rb +0 -202
  292. data/spec/extensions/blacklist_security_spec.rb +0 -95
  293. data/spec/extensions/blank_spec.rb +0 -69
  294. data/spec/extensions/boolean_readers_spec.rb +0 -93
  295. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  296. data/spec/extensions/caching_spec.rb +0 -273
  297. data/spec/extensions/class_table_inheritance_spec.rb +0 -568
  298. data/spec/extensions/column_conflicts_spec.rb +0 -75
  299. data/spec/extensions/column_select_spec.rb +0 -129
  300. data/spec/extensions/columns_introspection_spec.rb +0 -90
  301. data/spec/extensions/columns_updated_spec.rb +0 -35
  302. data/spec/extensions/composition_spec.rb +0 -248
  303. data/spec/extensions/connection_expiration_spec.rb +0 -133
  304. data/spec/extensions/connection_validator_spec.rb +0 -127
  305. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -300
  306. data/spec/extensions/constraint_validations_spec.rb +0 -395
  307. data/spec/extensions/core_refinements_spec.rb +0 -528
  308. data/spec/extensions/csv_serializer_spec.rb +0 -183
  309. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  310. data/spec/extensions/dataset_associations_spec.rb +0 -365
  311. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  312. data/spec/extensions/date_arithmetic_spec.rb +0 -181
  313. data/spec/extensions/datetime_parse_to_time_spec.rb +0 -169
  314. data/spec/extensions/def_dataset_method_spec.rb +0 -100
  315. data/spec/extensions/defaults_setter_spec.rb +0 -141
  316. data/spec/extensions/delay_add_association_spec.rb +0 -73
  317. data/spec/extensions/dirty_spec.rb +0 -189
  318. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -104
  319. data/spec/extensions/eager_each_spec.rb +0 -62
  320. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  321. data/spec/extensions/error_splitter_spec.rb +0 -18
  322. data/spec/extensions/error_sql_spec.rb +0 -20
  323. data/spec/extensions/eval_inspect_spec.rb +0 -74
  324. data/spec/extensions/finder_spec.rb +0 -260
  325. data/spec/extensions/force_encoding_spec.rb +0 -126
  326. data/spec/extensions/freeze_datasets_spec.rb +0 -31
  327. data/spec/extensions/graph_each_spec.rb +0 -113
  328. data/spec/extensions/hook_class_methods_spec.rb +0 -380
  329. data/spec/extensions/identifier_mangling_spec.rb +0 -201
  330. data/spec/extensions/implicit_subquery_spec.rb +0 -58
  331. data/spec/extensions/index_caching_spec.rb +0 -66
  332. data/spec/extensions/inflector_spec.rb +0 -183
  333. data/spec/extensions/input_transformer_spec.rb +0 -69
  334. data/spec/extensions/insert_returning_select_spec.rb +0 -72
  335. data/spec/extensions/instance_filters_spec.rb +0 -79
  336. data/spec/extensions/instance_hooks_spec.rb +0 -246
  337. data/spec/extensions/integer64_spec.rb +0 -22
  338. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  339. data/spec/extensions/json_serializer_spec.rb +0 -336
  340. data/spec/extensions/lazy_attributes_spec.rb +0 -183
  341. data/spec/extensions/list_spec.rb +0 -275
  342. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  343. data/spec/extensions/many_through_many_spec.rb +0 -2177
  344. data/spec/extensions/migration_spec.rb +0 -840
  345. data/spec/extensions/modification_detection_spec.rb +0 -93
  346. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -92
  347. data/spec/extensions/named_timezones_spec.rb +0 -109
  348. data/spec/extensions/nested_attributes_spec.rb +0 -703
  349. data/spec/extensions/null_dataset_spec.rb +0 -85
  350. data/spec/extensions/optimistic_locking_spec.rb +0 -127
  351. data/spec/extensions/pagination_spec.rb +0 -116
  352. data/spec/extensions/pg_array_associations_spec.rb +0 -802
  353. data/spec/extensions/pg_array_ops_spec.rb +0 -144
  354. data/spec/extensions/pg_array_spec.rb +0 -398
  355. data/spec/extensions/pg_auto_constraint_validations_spec.rb +0 -165
  356. data/spec/extensions/pg_enum_spec.rb +0 -113
  357. data/spec/extensions/pg_extended_date_support_spec.rb +0 -126
  358. data/spec/extensions/pg_hstore_ops_spec.rb +0 -238
  359. data/spec/extensions/pg_hstore_spec.rb +0 -219
  360. data/spec/extensions/pg_inet_ops_spec.rb +0 -102
  361. data/spec/extensions/pg_inet_spec.rb +0 -72
  362. data/spec/extensions/pg_interval_spec.rb +0 -103
  363. data/spec/extensions/pg_json_ops_spec.rb +0 -289
  364. data/spec/extensions/pg_json_spec.rb +0 -262
  365. data/spec/extensions/pg_loose_count_spec.rb +0 -23
  366. data/spec/extensions/pg_range_ops_spec.rb +0 -60
  367. data/spec/extensions/pg_range_spec.rb +0 -487
  368. data/spec/extensions/pg_row_ops_spec.rb +0 -61
  369. data/spec/extensions/pg_row_plugin_spec.rb +0 -60
  370. data/spec/extensions/pg_row_spec.rb +0 -363
  371. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -93
  372. data/spec/extensions/pg_timestamptz_spec.rb +0 -17
  373. data/spec/extensions/prepared_statements_safe_spec.rb +0 -66
  374. data/spec/extensions/prepared_statements_spec.rb +0 -182
  375. data/spec/extensions/pretty_table_spec.rb +0 -123
  376. data/spec/extensions/query_spec.rb +0 -94
  377. data/spec/extensions/rcte_tree_spec.rb +0 -381
  378. data/spec/extensions/round_timestamps_spec.rb +0 -39
  379. data/spec/extensions/s_spec.rb +0 -60
  380. data/spec/extensions/schema_caching_spec.rb +0 -64
  381. data/spec/extensions/schema_dumper_spec.rb +0 -868
  382. data/spec/extensions/select_remove_spec.rb +0 -38
  383. data/spec/extensions/sequel_4_dataset_methods_spec.rb +0 -121
  384. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  385. data/spec/extensions/serialization_spec.rb +0 -365
  386. data/spec/extensions/server_block_spec.rb +0 -97
  387. data/spec/extensions/server_logging_spec.rb +0 -45
  388. data/spec/extensions/sharding_spec.rb +0 -189
  389. data/spec/extensions/shared_caching_spec.rb +0 -151
  390. data/spec/extensions/single_table_inheritance_spec.rb +0 -347
  391. data/spec/extensions/singular_table_names_spec.rb +0 -22
  392. data/spec/extensions/skip_create_refresh_spec.rb +0 -18
  393. data/spec/extensions/spec_helper.rb +0 -61
  394. data/spec/extensions/split_array_nil_spec.rb +0 -24
  395. data/spec/extensions/split_values_spec.rb +0 -57
  396. data/spec/extensions/sql_comments_spec.rb +0 -33
  397. data/spec/extensions/sql_expr_spec.rb +0 -59
  398. data/spec/extensions/static_cache_spec.rb +0 -410
  399. data/spec/extensions/string_agg_spec.rb +0 -90
  400. data/spec/extensions/string_date_time_spec.rb +0 -95
  401. data/spec/extensions/string_stripper_spec.rb +0 -68
  402. data/spec/extensions/subclasses_spec.rb +0 -79
  403. data/spec/extensions/subset_conditions_spec.rb +0 -38
  404. data/spec/extensions/symbol_aref_refinement_spec.rb +0 -28
  405. data/spec/extensions/symbol_as_refinement_spec.rb +0 -21
  406. data/spec/extensions/synchronize_sql_spec.rb +0 -124
  407. data/spec/extensions/table_select_spec.rb +0 -83
  408. data/spec/extensions/tactical_eager_loading_spec.rb +0 -141
  409. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  410. data/spec/extensions/timestamps_spec.rb +0 -209
  411. data/spec/extensions/to_dot_spec.rb +0 -153
  412. data/spec/extensions/touch_spec.rb +0 -226
  413. data/spec/extensions/tree_spec.rb +0 -284
  414. data/spec/extensions/typecast_on_load_spec.rb +0 -86
  415. data/spec/extensions/unlimited_update_spec.rb +0 -21
  416. data/spec/extensions/update_or_create_spec.rb +0 -83
  417. data/spec/extensions/update_primary_key_spec.rb +0 -105
  418. data/spec/extensions/update_refresh_spec.rb +0 -59
  419. data/spec/extensions/uuid_spec.rb +0 -101
  420. data/spec/extensions/validate_associated_spec.rb +0 -52
  421. data/spec/extensions/validation_class_methods_spec.rb +0 -1040
  422. data/spec/extensions/validation_contexts_spec.rb +0 -31
  423. data/spec/extensions/validation_helpers_spec.rb +0 -525
  424. data/spec/extensions/whitelist_security_spec.rb +0 -157
  425. data/spec/extensions/xml_serializer_spec.rb +0 -213
  426. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  427. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  428. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  429. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  430. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  431. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  432. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  433. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  434. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  435. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  436. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  437. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  438. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  439. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  440. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  441. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  442. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  443. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  444. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  445. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  446. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  447. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  448. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  449. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  450. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  451. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  452. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  453. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  454. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  455. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  456. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  457. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  458. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  459. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  460. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  461. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  462. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  463. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  464. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  465. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  466. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  467. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  468. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  469. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  470. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  471. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  472. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  473. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  474. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  475. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  476. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  477. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  478. data/spec/guards_helper.rb +0 -58
  479. data/spec/integration/associations_test.rb +0 -2513
  480. data/spec/integration/database_test.rb +0 -113
  481. data/spec/integration/dataset_test.rb +0 -1880
  482. data/spec/integration/eager_loader_test.rb +0 -687
  483. data/spec/integration/migrator_test.rb +0 -262
  484. data/spec/integration/model_test.rb +0 -203
  485. data/spec/integration/plugin_test.rb +0 -2302
  486. data/spec/integration/prepared_statement_test.rb +0 -398
  487. data/spec/integration/schema_test.rb +0 -869
  488. data/spec/integration/spec_helper.rb +0 -64
  489. data/spec/integration/timezone_test.rb +0 -86
  490. data/spec/integration/transaction_test.rb +0 -354
  491. data/spec/integration/type_test.rb +0 -127
  492. data/spec/model/association_reflection_spec.rb +0 -803
  493. data/spec/model/associations_spec.rb +0 -4538
  494. data/spec/model/base_spec.rb +0 -817
  495. data/spec/model/class_dataset_methods_spec.rb +0 -146
  496. data/spec/model/dataset_methods_spec.rb +0 -198
  497. data/spec/model/eager_loading_spec.rb +0 -2262
  498. data/spec/model/hooks_spec.rb +0 -370
  499. data/spec/model/inflector_spec.rb +0 -26
  500. data/spec/model/model_spec.rb +0 -953
  501. data/spec/model/plugins_spec.rb +0 -318
  502. data/spec/model/record_spec.rb +0 -2107
  503. data/spec/model/spec_helper.rb +0 -45
  504. data/spec/model/validations_spec.rb +0 -193
  505. data/spec/model_no_assoc_spec.rb +0 -1
  506. data/spec/model_spec.rb +0 -1
  507. data/spec/plugin_spec.rb +0 -1
  508. data/spec/sequel_coverage.rb +0 -15
  509. data/spec/sequel_warning.rb +0 -4
  510. data/spec/spec_config.rb +0 -12
@@ -1,568 +0,0 @@
1
- require_relative "spec_helper"
2
-
3
- describe "class_table_inheritance plugin" do
4
- before do
5
- @db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
6
- def @db.supports_schema_parsing?() true end
7
- def @db.schema(table, opts={})
8
- {:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
9
- :managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}] ],
10
- :executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
11
- :staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
12
- }[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
13
- end
14
- @db.extend_datasets do
15
- def columns
16
- {[:employees]=>[:id, :name, :kind],
17
- [:managers]=>[:id, :num_staff],
18
- [:executives]=>[:id, :num_managers],
19
- [:staff]=>[:id, :manager_id],
20
- [:employees, :managers]=>[:id, :name, :kind, :num_staff],
21
- [:employees, :managers, :executives]=>[:id, :name, :kind, :num_staff, :num_managers],
22
- [:employees, :staff]=>[:id, :name, :kind, :manager_id],
23
- }[opts[:from] + (opts[:join] || []).map{|x| x.table}]
24
- end
25
- end
26
- class ::Employee < Sequel::Model(@db)
27
- def _save_refresh; @values[:id] = 1 end
28
- def self.columns
29
- dataset.columns || dataset.opts[:from].first.expression.columns
30
- end
31
- plugin :class_table_inheritance, :key=>:kind, :table_map=>{:Staff=>:staff}
32
- end
33
- class ::Manager < Employee
34
- one_to_many :staff_members, :class=>:Staff
35
- end
36
- class ::Executive < Manager
37
- end
38
- class ::Ceo < Executive
39
- end
40
- class ::Staff < Employee
41
- many_to_one :manager
42
- end
43
- class ::Intern < Employee
44
- end
45
- @ds = Employee.dataset
46
- @db.sqls
47
- end
48
- after do
49
- [:Intern, :Ceo, :Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
50
- end
51
-
52
- it "should freeze CTI information when freezing model class" do
53
- Employee.freeze
54
- Employee.cti_models.frozen?.must_equal true
55
- Employee.cti_tables.frozen?.must_equal true
56
- Employee.cti_instance_dataset.frozen?.must_equal true
57
- Employee.cti_table_columns.frozen?.must_equal true
58
- Employee.cti_table_map.frozen?.must_equal true
59
- end
60
-
61
- it "should not attempt to use prepared statements" do
62
- Manager.plugin :prepared_statements
63
- Manager.load(:id=>1, :kind=>'Manager', :num_staff=>2).save
64
- @db.sqls.must_equal ["UPDATE employees SET kind = 'Manager' WHERE (id = 1)", "UPDATE managers SET num_staff = 2 WHERE (id = 1)"]
65
-
66
- Employee.plugin :prepared_statements
67
- Employee.load(:id=>2, :kind=>'Employee').save
68
- @db.sqls.must_equal ["UPDATE employees SET kind = 'Employee' WHERE (id = 2)"]
69
- end
70
-
71
- it "#cti_models.first should be the model that loaded the plugin" do
72
- Executive.cti_models.first.must_equal Employee
73
- end
74
-
75
- it "should have simple_table = nil for all subclasses" do
76
- Manager.simple_table.must_be_nil
77
- Executive.simple_table.must_be_nil
78
- Ceo.simple_table.must_be_nil
79
- Staff.simple_table.must_be_nil
80
- Intern.simple_table.must_be_nil
81
- end
82
-
83
- it "should have working row_proc if using set_dataset in subclass to remove columns" do
84
- Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
85
- Manager.dataset = Manager.dataset.with_fetch(:id=>1, :kind=>'Ceo')
86
- Manager[1].must_equal Ceo.load(:id=>1, :kind=>'Ceo')
87
- end
88
-
89
- it "should use a subquery in subclasses" do
90
- Employee.dataset.sql.must_equal 'SELECT * FROM employees'
91
- Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
92
- Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees'
93
- Ceo.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (employees.kind IN (\'Ceo\'))) AS employees'
94
- Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees'
95
- Intern.dataset.sql.must_equal 'SELECT * FROM employees WHERE (employees.kind IN (\'Intern\'))'
96
- end
97
-
98
- it "should return rows with the correct class based on the polymorphic_key value" do
99
- @ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.collect{|x| x.class}.must_equal [Employee, Manager, Executive, Ceo, Staff, Intern]
100
- end
101
-
102
- it "should return rows with the correct class based on the polymorphic_key value for subclasses" do
103
- Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}]).all.collect{|x| x.class}.must_equal [Manager, Executive, Ceo]
104
- end
105
-
106
- it "should have refresh return all columns in subclass after loading from superclass" do
107
- Employee.dataset = Employee.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo'}])
108
- Ceo.dataset = Ceo.dataset.with_fetch([{:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2}])
109
- a = Employee.first
110
- a.class.must_equal Ceo
111
- a.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo')
112
- a.refresh.values.must_equal(:id=>1, :name=>'A', :kind=>'Ceo', :num_staff=>3, :num_managers=>2)
113
- @db.sqls.must_equal ["SELECT * FROM employees LIMIT 1",
114
- "SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id) WHERE (employees.kind IN ('Ceo'))) AS employees WHERE (id = 1) LIMIT 1"]
115
- end
116
-
117
- it "should return rows with the current class if sti_key is nil" do
118
- Employee.plugin :class_table_inheritance
119
- Employee.dataset.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Staff'}, {:kind=>'Intern'}]).all.map{|x| x.class}.must_equal [Employee, Employee, Employee, Employee, Employee, Employee]
120
- end
121
-
122
- it "should return rows with the current class if sti_key is nil in subclasses" do
123
- Employee.plugin :class_table_inheritance
124
- Object.send(:remove_const, :Executive)
125
- Object.send(:remove_const, :Manager)
126
- class ::Manager < Employee; end
127
- class ::Executive < Manager; end
128
- Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}]).all.map{|x| x.class}.must_equal [Manager, Manager]
129
- end
130
-
131
- it "should handle a model map with integer values" do
132
- Employee.plugin :class_table_inheritance, :key=>:kind, :model_map=>{0=>:Employee, 1=>:Manager, 2=>:Executive, 3=>:Ceo, 4=>:Intern}
133
- Object.send(:remove_const, :Intern)
134
- Object.send(:remove_const, :Ceo)
135
- Object.send(:remove_const, :Executive)
136
- Object.send(:remove_const, :Manager)
137
- class ::Intern < Employee; end
138
- class ::Manager < Employee; end
139
- class ::Executive < Manager; end
140
- class ::Ceo < Executive; end
141
- Employee.dataset = Employee.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}, {:kind=>4}])
142
- Employee.all.collect{|x| x.class}.must_equal [Employee, Employee, Manager, Executive, Ceo, Intern]
143
- Manager.dataset = Manager.dataset.with_fetch([{:kind=>nil},{:kind=>0},{:kind=>1}, {:kind=>2}, {:kind=>3}])
144
- Manager.all.collect{|x| x.class}.must_equal [Manager, Employee, Manager, Executive, Ceo]
145
- end
146
-
147
- it "should fallback to the main class if the given class does not exist" do
148
- @ds.with_fetch([{:kind=>'Employee'}, {:kind=>'Manager'}, {:kind=>'Blah'}, {:kind=>'Staff'}]).all.map{|x| x.class}.must_equal [Employee, Manager, Employee, Staff]
149
- end
150
-
151
- it "should fallback to the main class if the given class does not exist in subclasses" do
152
- Manager.dataset.with_fetch([{:kind=>'Manager'}, {:kind=>'Executive'}, {:kind=>'Ceo'}, {:kind=>'Blah'}]).all.map{|x| x.class}.must_equal [Manager, Executive, Ceo, Manager]
153
- end
154
-
155
- it "should sets the model class name for the key when creating new parent class records" do
156
- Employee.create
157
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
158
- end
159
-
160
- it "should sets the model class name for the key when creating new class records for subclass without separate table" do
161
- Intern.create
162
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Intern')"]
163
- end
164
-
165
- it "should sets the model class name for the key when creating new subclass records" do
166
- Ceo.create
167
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Ceo')",
168
- "INSERT INTO managers (id) VALUES (1)",
169
- "INSERT INTO executives (id) VALUES (1)"]
170
- end
171
-
172
- it "should ignore existing sti_key value when creating new records" do
173
- Employee.create(:kind=>'Manager')
174
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
175
- end
176
-
177
- it "should ignore existing sti_key value in subclasses" do
178
- Manager.create(:kind=>'Executive')
179
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Manager')",
180
- "INSERT INTO managers (id) VALUES (1)"]
181
- end
182
-
183
- it "should handle validations on the type column field" do
184
- o = Employee.new
185
- def o.validate
186
- errors.add(:kind, 'not present') unless kind
187
- end
188
- o.valid?.must_equal true
189
- end
190
-
191
- it "should set the type column field even when not validating" do
192
- Employee.new.save(:validate=>false)
193
- @db.sqls.must_equal ["INSERT INTO employees (kind) VALUES ('Employee')"]
194
- end
195
-
196
- it "should allow specifying a map of names to tables to override implicit mapping" do
197
- Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
198
- Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees'
199
- end
200
-
201
- it "should lazily load attributes for columns in subclass tables" do
202
- Manager.dataset = Manager.dataset.with_fetch(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2)
203
- m = Manager[1]
204
- @db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 1) LIMIT 1']
205
- @db.fetch = {:num_managers=>3}
206
- m.must_be_kind_of Ceo
207
- m.num_managers.must_equal 3
208
- @db.sqls.must_equal ['SELECT employees.num_managers FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees WHERE (employees.id = 1) LIMIT 1']
209
- m.values.must_equal(:id=>1, :name=>'J', :kind=>'Ceo', :num_staff=>2, :num_managers=>3)
210
- end
211
-
212
- it "should lazily load columns in middle classes correctly when loaded from parent class" do
213
- Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
214
- @db.fetch = [[:num_staff=>2]]
215
- e = Employee[1]
216
- e.must_be_kind_of(Ceo)
217
- @db.sqls.must_equal ["SELECT * FROM employees WHERE (id = 1) LIMIT 1"]
218
- e.num_staff.must_equal 2
219
- @db.sqls.must_equal ["SELECT employees.num_staff FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (employees.id = 1) LIMIT 1"]
220
- end
221
-
222
- it "should eagerly load lazily columns in subclasses when loaded from parent class" do
223
- Employee.dataset = Employee.dataset.with_fetch(:id=>1, :kind=>'Ceo')
224
- @db.fetch = [[{:id=>1, :num_staff=>2}], [{:id=>1, :num_managers=>3}]]
225
- e = Employee.all.first
226
- e.must_be_kind_of(Ceo)
227
- @db.sqls.must_equal ["SELECT * FROM employees"]
228
- e.num_staff.must_equal 2
229
- @db.sqls.must_equal ["SELECT employees.id, employees.num_staff FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (employees.id IN (1))"]
230
- e.num_managers.must_equal 3
231
- @db.sqls.must_equal ['SELECT employees.id, employees.num_managers FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees WHERE (employees.id IN (1))']
232
- end
233
-
234
- it "should include schema for columns for tables for ancestor classes" do
235
- Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
236
- Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer})
237
- Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
238
- Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :manager_id=>{:type=>:integer})
239
- Intern.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string})
240
- end
241
-
242
- it "should use the correct primary key (which should have the same name in all subclasses)" do
243
- [Employee, Manager, Executive, Ceo, Staff, Intern].each{|c| c.primary_key.must_equal :id}
244
- end
245
-
246
- it "should have table_name return the table name of the most specific table" do
247
- Employee.table_name.must_equal :employees
248
- Manager.table_name.must_equal :employees
249
- Executive.table_name.must_equal :employees
250
- Ceo.table_name.must_equal :employees
251
- Staff.table_name.must_equal :employees
252
- Intern.table_name.must_equal :employees
253
- end
254
-
255
- it "should delete the correct rows from all tables when deleting" do
256
- Employee.load(:id=>1).delete
257
- @db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
258
-
259
- Intern.load(:id=>1).delete
260
- @db.sqls.must_equal ["DELETE FROM employees WHERE (id = 1)"]
261
-
262
- Ceo.load(:id=>1).delete
263
- @db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
264
- end
265
-
266
- it "should not allow deletion of frozen object" do
267
- [Ceo, Executive, Employee, Manager, Intern].each do |c|
268
- o = c.load(:id=>1)
269
- o.freeze
270
- proc{o.delete}.must_raise(Sequel::Error)
271
- @db.sqls.must_equal []
272
- end
273
- end
274
-
275
- it "should insert the correct rows into all tables when inserting into parent class" do
276
- Employee.create(:name=>'E')
277
- @db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Employee')"]
278
- end
279
-
280
- it "should insert the correct rows into all tables when inserting into subclass without separate table" do
281
- Intern.create(:name=>'E')
282
- @db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Intern')"]
283
- end
284
-
285
- it "should insert the correct rows into all tables when inserting" do
286
- Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
287
- @db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Ceo')",
288
- "INSERT INTO managers (id, num_staff) VALUES (1, 2)",
289
- "INSERT INTO executives (id, num_managers) VALUES (1, 3)"]
290
- end
291
-
292
- it "should insert the correct rows into all tables when inserting when insert_select is supported" do
293
- [Executive, Manager, Employee].each do |klass|
294
- klass.instance_variable_set(:@cti_instance_dataset, klass.cti_instance_dataset.with_extend do
295
- def supports_insert_select?; true; end
296
- def insert_select(v)
297
- db.run(insert_sql(v) + " RETURNING *")
298
- v.merge(:id=>1)
299
- end
300
- end)
301
- end
302
- Ceo.create(:num_managers=>3, :num_staff=>2, :name=>'E')
303
- @db.sqls.must_equal ["INSERT INTO employees (name, kind) VALUES ('E', 'Ceo') RETURNING *",
304
- "INSERT INTO managers (id, num_staff) VALUES (1, 2) RETURNING *",
305
- "INSERT INTO executives (id, num_managers) VALUES (1, 3) RETURNING *"]
306
- end
307
-
308
- it "should insert the correct rows into all tables with a given primary key" do
309
- e = Ceo.new(:num_managers=>3, :num_staff=>2, :name=>'E')
310
- e.id = 2
311
- e.save
312
- @db.sqls.must_equal ["INSERT INTO employees (id, name, kind) VALUES (2, 'E', 'Ceo')",
313
- "INSERT INTO managers (id, num_staff) VALUES (2, 2)",
314
- "INSERT INTO executives (id, num_managers) VALUES (2, 3)"]
315
- end
316
-
317
- it "should update the correct rows in all tables when updating parent class" do
318
- Employee.load(:id=>2).update(:name=>'E')
319
- @db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
320
- end
321
-
322
- it "should update the correct rows in all tables when updating subclass without separate table" do
323
- Intern.load(:id=>2).update(:name=>'E')
324
- @db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)"]
325
- end
326
-
327
- it "should update the correct rows in all tables when updating" do
328
- Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
329
- @db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
330
- end
331
-
332
- it "should raise error if one of the updates does not update a single row" do
333
- @db.numrows = [1, 0]
334
- proc{Ceo.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')}.must_raise Sequel::NoExistingObject
335
- @db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)"]
336
- end
337
-
338
- it "should handle many_to_one relationships correctly" do
339
- Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
340
- Staff.load(:manager_id=>3).manager.must_equal Ceo.load(:id=>3, :name=>'E', :kind=>'Ceo', :num_managers=>3)
341
- @db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees WHERE (id = 3) LIMIT 1']
342
- end
343
-
344
- it "should handle one_to_many relationships correctly" do
345
- Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)
346
- Ceo.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :kind=>'Staff', :manager_id=>3)]
347
- @db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, employees.kind, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS employees WHERE (employees.manager_id = 3)']
348
- end
349
- end
350
-
351
- describe "class_table_inheritance plugin without sti_key with :alias option" do
352
- before do
353
- @db = Sequel.mock(:numrows=>1, :autoid=>proc{|sql| 1})
354
- def @db.supports_schema_parsing?() true end
355
- def @db.schema(table, opts={})
356
- {:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}]],
357
- :managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}]],
358
- :executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}]],
359
- :staff=>[[:id, {:type=>:integer}], [:manager_id, {:type=>:integer}]],
360
- }[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
361
- end
362
- @db.extend_datasets do
363
- def columns
364
- {[:employees]=>[:id, :name],
365
- [:managers]=>[:id, :num_staff],
366
- [:executives]=>[:id, :num_managers],
367
- [:staff]=>[:id, :manager_id],
368
- [:employees, :managers]=>[:id, :name, :num_staff],
369
- [:employees, :managers, :executives]=>[:id, :name, :num_staff, :num_managers],
370
- [:employees, :staff]=>[:id, :name, :manager_id],
371
- }[opts[:from] + (opts[:join] || []).map{|x| x.table}]
372
- end
373
- end
374
- class ::Employee < Sequel::Model(@db)
375
- def _save_refresh; @values[:id] = 1 end
376
- def self.columns
377
- dataset.columns || dataset.opts[:from].first.expression.columns
378
- end
379
- plugin :class_table_inheritance, :table_map=>{:Staff=>:staff}, :alias=>:emps
380
- end
381
- class ::Manager < Employee
382
- one_to_many :staff_members, :class=>:Staff
383
- end
384
- class ::Executive < Manager
385
- end
386
- class ::Staff < Employee
387
- many_to_one :manager
388
- end
389
- @ds = Employee.dataset
390
- @db.sqls
391
- end
392
- after do
393
- Object.send(:remove_const, :Executive)
394
- Object.send(:remove_const, :Manager)
395
- Object.send(:remove_const, :Staff)
396
- Object.send(:remove_const, :Employee)
397
- end
398
-
399
- it "should have simple_table = nil for all subclasses" do
400
- Manager.simple_table.must_be_nil
401
- Executive.simple_table.must_be_nil
402
- Staff.simple_table.must_be_nil
403
- end
404
-
405
- it "should have working row_proc if using set_dataset in subclass to remove columns" do
406
- Manager.set_dataset(Manager.dataset.select(*(Manager.columns - [:blah])))
407
- Manager.dataset = Manager.dataset.with_fetch(:id=>1)
408
- Manager[1].must_equal Manager.load(:id=>1)
409
- end
410
-
411
- it "should use a joined dataset in subclasses" do
412
- Employee.dataset.sql.must_equal 'SELECT * FROM employees'
413
- Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS emps'
414
- Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS emps'
415
- Staff.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS emps'
416
- end
417
-
418
- it "should return rows with the current class if sti_key is nil" do
419
- Employee.plugin(:class_table_inheritance)
420
- Employee.dataset = Employee.dataset.with_fetch([{}])
421
- Employee.first.class.must_equal Employee
422
- end
423
-
424
- it "should include schema for columns for tables for ancestor classes" do
425
- Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string})
426
- Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer})
427
- Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :num_staff=>{:type=>:integer}, :num_managers=>{:type=>:integer})
428
- Staff.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :manager_id=>{:type=>:integer})
429
- end
430
-
431
- it "should use the correct primary key (which should have the same name in all subclasses)" do
432
- [Employee, Manager, Executive, Staff].each{|c| c.primary_key.must_equal :id}
433
- end
434
-
435
- it "should have table_name return the table name of the most specific table" do
436
- Employee.table_name.must_equal :employees
437
- Manager.table_name.must_equal :emps
438
- Executive.table_name.must_equal :emps
439
- Staff.table_name.must_equal :emps
440
- end
441
-
442
- it "should delete the correct rows from all tables when deleting" do
443
- Executive.load(:id=>1).delete
444
- @db.sqls.must_equal ["DELETE FROM executives WHERE (id = 1)", "DELETE FROM managers WHERE (id = 1)", "DELETE FROM employees WHERE (id = 1)"]
445
- end
446
-
447
- it "should not allow deletion of frozen object" do
448
- o = Executive.load(:id=>1)
449
- o.freeze
450
- proc{o.delete}.must_raise(Sequel::Error)
451
- @db.sqls.must_equal []
452
- end
453
-
454
- it "should insert the correct rows into all tables when inserting" do
455
- Executive.create(:num_managers=>3, :num_staff=>2, :name=>'E')
456
- @db.sqls.must_equal ["INSERT INTO employees (name) VALUES ('E')",
457
- "INSERT INTO managers (id, num_staff) VALUES (1, 2)",
458
- "INSERT INTO executives (id, num_managers) VALUES (1, 3)"]
459
- end
460
-
461
- it "should insert the correct rows into all tables with a given primary key" do
462
- e = Executive.new(:num_managers=>3, :num_staff=>2, :name=>'E')
463
- e.id = 2
464
- e.save
465
- @db.sqls.must_equal ["INSERT INTO employees (id, name) VALUES (2, 'E')",
466
- "INSERT INTO managers (id, num_staff) VALUES (2, 2)",
467
- "INSERT INTO executives (id, num_managers) VALUES (2, 3)"]
468
- end
469
-
470
- it "should update the correct rows in all tables when updating" do
471
- Executive.load(:id=>2).update(:num_managers=>3, :num_staff=>2, :name=>'E')
472
- @db.sqls.must_equal ["UPDATE employees SET name = 'E' WHERE (id = 2)", "UPDATE managers SET num_staff = 2 WHERE (id = 2)", "UPDATE executives SET num_managers = 3 WHERE (id = 2)"]
473
- end
474
-
475
- it "should handle many_to_one relationships correctly" do
476
- Manager.dataset = Manager.dataset.with_fetch(:id=>3, :name=>'E', :num_staff=>3)
477
- Staff.load(:manager_id=>3).manager.must_equal Manager.load(:id=>3, :name=>'E', :num_staff=>3)
478
- @db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, managers.num_staff FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS emps WHERE (id = 3) LIMIT 1']
479
- end
480
-
481
- it "should handle one_to_many relationships correctly" do
482
- Staff.dataset = Staff.dataset.with_fetch(:id=>1, :name=>'S', :manager_id=>3)
483
- Executive.load(:id=>3).staff_members.must_equal [Staff.load(:id=>1, :name=>'S', :manager_id=>3)]
484
- @db.sqls.must_equal ['SELECT * FROM (SELECT employees.id, employees.name, staff.manager_id FROM employees INNER JOIN staff ON (staff.id = employees.id)) AS emps WHERE (emps.manager_id = 3)']
485
- end
486
- end
487
-
488
- describe "class_table_inheritance plugin with duplicate columns" do
489
- it "should raise error if no columns are explicitly ignored" do
490
- @db = Sequel.mock(:autoid=>proc{|sql| 1})
491
- def @db.supports_schema_parsing?() true end
492
- def @db.schema(table, opts={})
493
- {:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}]],
494
- :managers=>[[:id, {:type=>:integer}], [:name, {:type=>:string}]],
495
- }[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
496
- end
497
- @db.extend_datasets do
498
- def columns
499
- {[:employees]=>[:id, :name, :kind],
500
- [:managers]=>[:id, :name],
501
- }[opts[:from] + (opts[:join] || []).map{|x| x.table}]
502
- end
503
- end
504
- class ::Employee < Sequel::Model(@db)
505
- def _save_refresh; @values[:id] = 1 end
506
- def self.columns
507
- dataset.columns || dataset.opts[:from].first.expression.columns
508
- end
509
- plugin :class_table_inheritance
510
- end
511
- proc{class ::Manager < Employee; end}.must_raise Sequel::Error
512
- end
513
-
514
- describe "with certain sub-class columns ignored" do
515
- before do
516
- @db = Sequel.mock(:autoid=>proc{|sql| 1})
517
- def @db.supports_schema_parsing?() true end
518
- def @db.schema(table, opts={})
519
- {:employees=>[[:id, {:primary_key=>true, :type=>:integer}], [:name, {:type=>:string}], [:kind, {:type=>:string}], [:updated_at, {:type=>:datetime}]],
520
- :managers=>[[:id, {:type=>:integer}], [:num_staff, {:type=>:integer}], [:updated_at, {:type=>:datetime}], [:another_duplicate_column, {:type=>:integer}]],
521
- :executives=>[[:id, {:type=>:integer}], [:num_managers, {:type=>:integer}], [:updated_at, {:type=>:datetime}], [:another_duplicate_column, {:type=>:integer}]],
522
- }[table.is_a?(Sequel::Dataset) ? table.first_source_table : table]
523
- end
524
- @db.extend_datasets do
525
- def columns
526
- {[:employees]=>[:id, :name, :kind, :updated_at],
527
- [:managers]=>[:id, :num_staff, :updated_at, :another_duplicate_column],
528
- [:executives]=>[:id, :num_managers, :updated_at, :another_duplicate_column],
529
- [:employees, :managers]=>[:id, :name, :kind, :updated_at, :num_staff],
530
- }[opts[:from] + (opts[:join] || []).map{|x| x.table}]
531
- end
532
- end
533
- class ::Employee < Sequel::Model(@db)
534
- def _save_refresh; @values[:id] = 1 end
535
- def self.columns
536
- dataset.columns || dataset.opts[:from].first.expression.columns
537
- end
538
- plugin :class_table_inheritance, :ignore_subclass_columns=>[:updated_at]
539
- end
540
- class ::Manager < Employee
541
- Manager.cti_ignore_subclass_columns.push(:another_duplicate_column)
542
- end
543
- class ::Executive < Manager; end
544
- end
545
-
546
- it "should not use the ignored column in a sub-class subquery" do
547
- Employee.dataset.sql.must_equal 'SELECT * FROM employees'
548
- Manager.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, employees.updated_at, managers.num_staff, managers.another_duplicate_column FROM employees INNER JOIN managers ON (managers.id = employees.id)) AS employees'
549
- Executive.dataset.sql.must_equal 'SELECT * FROM (SELECT employees.id, employees.name, employees.kind, employees.updated_at, managers.num_staff, managers.another_duplicate_column, executives.num_managers FROM employees INNER JOIN managers ON (managers.id = employees.id) INNER JOIN executives ON (executives.id = managers.id)) AS employees'
550
- end
551
-
552
- it "should include schema for columns for tables for ancestor classes" do
553
- Employee.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime})
554
- Manager.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime}, :num_staff=>{:type=>:integer}, :another_duplicate_column=>{:type=>:integer})
555
- Executive.db_schema.must_equal(:id=>{:primary_key=>true, :type=>:integer}, :name=>{:type=>:string}, :kind=>{:type=>:string}, :updated_at=>{:type=>:datetime}, :num_staff=>{:type=>:integer}, :another_duplicate_column=>{:type=>:integer}, :num_managers=>{:type=>:integer})
556
- end
557
-
558
- after do
559
- Object.send(:remove_const, :Executive)
560
- end
561
- end
562
-
563
- after do
564
- Object.send(:remove_const, :Manager)
565
- Object.send(:remove_const, :Employee)
566
- end
567
- end
568
-