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,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+ #
1
3
  # The mssql_emulate_lateral_with_apply extension converts
2
4
  # queries that use LATERAL into queries that use CROSS/OUTER
3
5
  # APPLY, allowing code that works on databases that support
@@ -21,6 +23,8 @@
21
23
  # Or you can load it into all of a database's datasets:
22
24
  #
23
25
  # DB.extension(:mssql_emulate_lateral_with_apply)
26
+ #
27
+ # Related module: Sequel::MSSQL::EmulateLateralWithApply
24
28
 
25
29
  #
26
30
  module Sequel
@@ -1,17 +1,22 @@
1
+ # frozen-string-literal: true
2
+ #
1
3
  # Allows the use of named timezones via TZInfo (requires tzinfo).
2
4
  # Forces the use of DateTime as Sequel's datetime_class, since
3
- # ruby's Time class doesn't support timezones other than local
4
- # and UTC.
5
+ # historically, Ruby's Time class doesn't support timezones other
6
+ # than local and UTC. To continue using Ruby's Time class when using
7
+ # the named_timezones extension:
8
+ #
9
+ # # Load the extension
10
+ # Sequel.extension :named_timezones
11
+ #
12
+ # # Set Sequel.datetime_class back to Time
13
+ # Sequel.datetime_class = Time
5
14
  #
6
15
  # This allows you to either pass strings or TZInfo::Timezone
7
16
  # instance to Sequel.database_timezone=, application_timezone=, and
8
17
  # typecast_timezone=. If a string is passed, it is converted to a
9
18
  # TZInfo::Timezone using TZInfo::Timezone.get.
10
19
  #
11
- # To load the extension:
12
- #
13
- # Sequel.extension :named_timezones
14
- #
15
20
  # Let's say you have the database server in New York and the
16
21
  # application server in Los Angeles. For historical reasons, data
17
22
  # is stored in local New York time, but the application server only
@@ -35,7 +40,10 @@
35
40
  # Note that typecasting from the database timezone to the application
36
41
  # timezone when fetching rows is dependent on the database adapter,
37
42
  # and only works on adapters where Sequel itself does the conversion.
38
- # It should work on mysql, postgres, sqlite, ibmdb, and jdbc.
43
+ # It should work with the mysql, postgres, sqlite, ibmdb, and jdbc
44
+ # adapters.
45
+ #
46
+ # Related module: Sequel::NamedTimezones
39
47
 
40
48
  require 'tzinfo'
41
49
 
@@ -59,24 +67,81 @@ module Sequel
59
67
 
60
68
  private
61
69
 
62
- # Assume the given DateTime has a correct time but a wrong timezone. It is
63
- # currently in UTC timezone, but it should be converted to the input_timezone.
64
- # Keep the time the same but convert the timezone to the input_timezone.
65
- # Expects the input_timezone to be a TZInfo::Timezone instance.
66
- def convert_input_datetime_other(v, input_timezone)
67
- local_offset = input_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset_rational
68
- (v - local_offset).new_offset(local_offset)
70
+ if RUBY_VERSION >= '2.6'
71
+ # Convert the given input Time (which must be in UTC) to the given input timezone,
72
+ # which should be a TZInfo::Timezone instance.
73
+ def convert_input_time_other(v, input_timezone)
74
+ Time.new(v.year, v.mon, v.day, v.hour, v.min, (v.sec + Rational(v.nsec, 1000000000)), input_timezone)
75
+ rescue TZInfo::AmbiguousTime
76
+ raise unless disamb = tzinfo_disambiguator_for(v)
77
+ period = input_timezone.period_for_local(v, &disamb)
78
+ offset = period.utc_total_offset
79
+ Time.at(v.to_i - offset, :in => input_timezone)
80
+ end
81
+
82
+ # Convert the given input Time to the given output timezone,
83
+ # which should be a TZInfo::Timezone instance.
84
+ def convert_output_time_other(v, output_timezone)
85
+ Time.at(v.to_i, :in => output_timezone)
86
+ end
87
+ else
88
+ # :nodoc:
89
+ # :nocov:
90
+ def convert_input_time_other(v, input_timezone)
91
+ local_offset = input_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset
92
+ Time.new(1970, 1, 1, 0, 0, 0, local_offset) + v.to_i
93
+ end
94
+
95
+ if defined?(TZInfo::VERSION) && TZInfo::VERSION > '2'
96
+ def convert_output_time_other(v, output_timezone)
97
+ v = output_timezone.utc_to_local(v.getutc)
98
+ local_offset = output_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset
99
+ Time.new(1970, 1, 1, 0, 0, 0, local_offset) + v.to_i + local_offset
100
+ end
101
+ else
102
+ def convert_output_time_other(v, output_timezone)
103
+ v = output_timezone.utc_to_local(v.getutc)
104
+ local_offset = output_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset
105
+ Time.new(1970, 1, 1, 0, 0, 0, local_offset) + v.to_i
106
+ end
107
+ end
69
108
  end
70
109
 
71
- # Convert the given DateTime to use the given output_timezone.
72
- # Expects the output_timezone to be a TZInfo::Timezone instance.
73
- def convert_output_datetime_other(v, output_timezone)
74
- # TZInfo converts times, but expects the given DateTime to have an offset
75
- # of 0 and always leaves the timezone offset as 0
76
- v = output_timezone.utc_to_local(v.new_offset(0))
77
- local_offset = output_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset_rational
78
- # Convert timezone offset from UTC to the offset for the output_timezone
79
- (v - local_offset).new_offset(local_offset)
110
+ # Handle both TZInfo 1 and TZInfo 2
111
+ if defined?(TZInfo::VERSION) && TZInfo::VERSION > '2'
112
+ def convert_input_datetime_other(v, input_timezone)
113
+ local_offset = Rational(input_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset, 86400)
114
+ (v - local_offset).new_offset(local_offset)
115
+ end
116
+
117
+ def convert_output_datetime_other(v, output_timezone)
118
+ v = output_timezone.utc_to_local(v.new_offset(0))
119
+
120
+ # Force DateTime output instead of TZInfo::DateTimeWithOffset
121
+ DateTime.jd(v.jd, v.hour, v.minute, v.second + v.sec_fraction, v.offset, v.start)
122
+ end
123
+ # :nodoc:
124
+ # :nocov:
125
+ else
126
+ # Assume the given DateTime has a correct time but a wrong timezone. It is
127
+ # currently in UTC timezone, but it should be converted to the input_timezone.
128
+ # Keep the time the same but convert the timezone to the input_timezone.
129
+ # Expects the input_timezone to be a TZInfo::Timezone instance.
130
+ def convert_input_datetime_other(v, input_timezone)
131
+ local_offset = input_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset_rational
132
+ (v - local_offset).new_offset(local_offset)
133
+ end
134
+
135
+ # Convert the given DateTime to use the given output_timezone.
136
+ # Expects the output_timezone to be a TZInfo::Timezone instance.
137
+ def convert_output_datetime_other(v, output_timezone)
138
+ # TZInfo 1 converts times, but expects the given DateTime to have an offset
139
+ # of 0 and always leaves the timezone offset as 0
140
+ v = output_timezone.utc_to_local(v.new_offset(0))
141
+ local_offset = output_timezone.period_for_local(v, &tzinfo_disambiguator_for(v)).utc_total_offset_rational
142
+ # Convert timezone offset from UTC to the offset for the output_timezone
143
+ (v - local_offset).new_offset(local_offset)
144
+ end
80
145
  end
81
146
 
82
147
  # Returns TZInfo::Timezone instance if given a String.
@@ -0,0 +1,4 @@
1
+ # frozen-string-literal: true
2
+
3
+ Sequel::Database.register_extension(:no_auto_literal_strings){}
4
+ Sequel::Dataset.register_extension(:no_auto_literal_strings){}
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+ #
1
3
  # The null_dataset extension adds the Dataset#nullify method, which
2
4
  # returns a cloned dataset that will never issue a query to the
3
5
  # database. It implements the null object pattern for datasets.
@@ -11,7 +13,7 @@
11
13
  #
12
14
  # Usage:
13
15
  #
14
- # ds = DB[:items].nullify.where(:a=>:b).select(:c)
16
+ # ds = DB[:items].nullify.where(a: :b).select(:c)
15
17
  # ds.sql # => "SELECT c FROM items WHERE (a = b)"
16
18
  # ds.all # => [] # no query sent to the database
17
19
  #
@@ -30,6 +32,8 @@
30
32
  # To add the nullify method to all datasets on a single database:
31
33
  #
32
34
  # DB.extension(:null_dataset)
35
+ #
36
+ # Related modules: Sequel::Dataset::Nullifiable, Sequel::Dataset::NullDataset
33
37
 
34
38
  #
35
39
  module Sequel
@@ -37,12 +41,9 @@ module Sequel
37
41
  module Nullifiable
38
42
  # Return a cloned nullified dataset.
39
43
  def nullify
40
- clone.nullify!
41
- end
42
-
43
- # Nullify the current dataset
44
- def nullify!
45
- extend NullDataset
44
+ cached_dataset(:_nullify_ds) do
45
+ with_extend(NullDataset)
46
+ end
46
47
  end
47
48
  end
48
49
 
@@ -50,7 +51,10 @@ module Sequel
50
51
  # Create a new dataset from the dataset (which won't
51
52
  # be nulled) to get the columns if they aren't already cached.
52
53
  def columns
53
- @columns ||= db.dataset.clone(@opts).columns
54
+ if cols = _columns
55
+ return cols
56
+ end
57
+ self.columns = db.dataset.clone(@opts).columns
54
58
  end
55
59
 
56
60
  # Return 0 without sending a database query.
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+ #
1
3
  # The pagination extension adds the Sequel::Dataset#paginate and #each_page methods,
2
4
  # which return paginated (limited and offset) datasets with the following methods
3
5
  # added that make creating a paginated display easier:
@@ -25,6 +27,8 @@
25
27
  # is probably the desired behavior if you are using this extension:
26
28
  #
27
29
  # DB.extension(:pagination)
30
+ #
31
+ # Related modules: Sequel::DatasetPagination, Sequel::Dataset::Pagination
28
32
 
29
33
  #
30
34
  module Sequel
@@ -35,9 +39,14 @@ module Sequel
35
39
  # number of records for this dataset.
36
40
  def paginate(page_no, page_size, record_count=nil)
37
41
  raise(Error, "You cannot paginate a dataset that already has a limit") if @opts[:limit]
38
- paginated = limit(page_size, (page_no - 1) * page_size)
39
- paginated.extend(Dataset::Pagination)
40
- paginated.set_pagination_info(page_no, page_size, record_count || count)
42
+
43
+ record_count ||= count
44
+ page_count = (record_count / page_size.to_f).ceil
45
+ page_count = 1 if page_count == 0
46
+
47
+ limit(page_size, (page_no - 1) * page_size).
48
+ with_extend(Dataset::Pagination).
49
+ clone(:page_size=>page_size, :current_page=>page_no, :pagination_record_count=>record_count, :page_count=>page_count)
41
50
  end
42
51
 
43
52
  # Yields a paginated dataset for each page and returns the receiver. Does
@@ -55,51 +64,59 @@ module Sequel
55
64
 
56
65
  class Dataset
57
66
  # Holds methods that only relate to paginated datasets. Paginated dataset
58
- # have pages starting at 1 (page 1 is offset 0, page 1 is offset page_size).
67
+ # have pages starting at 1 (page 1 is offset 0, page 2 is offset 1 * page_size).
59
68
  module Pagination
60
69
  # The number of records per page (the final page may have fewer than
61
70
  # this number of records).
62
- attr_accessor :page_size
71
+ def page_size
72
+ @opts[:page_size]
73
+ end
63
74
 
64
75
  # The number of pages in the dataset before pagination, of which
65
76
  # this paginated dataset is one. Empty datasets are considered
66
77
  # to have a single page.
67
- attr_accessor :page_count
78
+ def page_count
79
+ @opts[:page_count]
80
+ end
68
81
 
69
82
  # The current page of the dataset, starting at 1 and not 0.
70
- attr_accessor :current_page
83
+ def current_page
84
+ @opts[:current_page]
85
+ end
71
86
 
72
87
  # The total number of records in the dataset before pagination.
73
- attr_accessor :pagination_record_count
88
+ def pagination_record_count
89
+ @opts[:pagination_record_count]
90
+ end
74
91
 
75
92
  # Returns the record range for the current page
76
93
  def current_page_record_range
77
- return (0..0) if @current_page > @page_count
94
+ return (0..0) if current_page > page_count
78
95
 
79
- a = 1 + (@current_page - 1) * @page_size
80
- b = a + @page_size - 1
81
- b = @pagination_record_count if b > @pagination_record_count
96
+ a = 1 + (current_page - 1) * page_size
97
+ b = a + page_size - 1
98
+ b = pagination_record_count if b > pagination_record_count
82
99
  a..b
83
100
  end
84
101
 
85
102
  # Returns the number of records in the current page
86
103
  def current_page_record_count
87
- return 0 if @current_page > @page_count
104
+ return 0 if current_page > page_count
88
105
 
89
- a = 1 + (@current_page - 1) * @page_size
90
- b = a + @page_size - 1
91
- b = @pagination_record_count if b > @pagination_record_count
106
+ a = 1 + (current_page - 1) * page_size
107
+ b = a + page_size - 1
108
+ b = pagination_record_count if b > pagination_record_count
92
109
  b - a + 1
93
110
  end
94
111
 
95
112
  # Returns true if the current page is the first page
96
113
  def first_page?
97
- @current_page == 1
114
+ current_page == 1
98
115
  end
99
116
 
100
117
  # Returns true if the current page is the last page
101
118
  def last_page?
102
- @current_page == @page_count
119
+ current_page == page_count
103
120
  end
104
121
 
105
122
  # Returns the next page number or nil if the current page is the last page
@@ -116,16 +133,6 @@ module Sequel
116
133
  def prev_page
117
134
  current_page > 1 ? (current_page - 1) : nil
118
135
  end
119
-
120
- # Sets the pagination info for this paginated dataset, and returns self.
121
- def set_pagination_info(page_no, page_size, record_count)
122
- @current_page = page_no
123
- @page_size = page_size
124
- @pagination_record_count = record_count
125
- @page_count = (record_count / page_size.to_f).ceil
126
- @page_count = 1 if @page_count == 0
127
- self
128
- end
129
136
  end
130
137
  end
131
138
 
@@ -1,3 +1,5 @@
1
+ # frozen-string-literal: true
2
+ #
1
3
  # The pg_array extension adds support for Sequel to handle
2
4
  # PostgreSQL's array types.
3
5
  #
@@ -30,7 +32,7 @@
30
32
  #
31
33
  # So if you want to insert an array into an integer[] database column:
32
34
  #
33
- # DB[:table].insert(:column=>Sequel.pg_array([1, 2, 3]))
35
+ # DB[:table].insert(column: Sequel.pg_array([1, 2, 3]))
34
36
  #
35
37
  # To use this extension, first load it into your Sequel::Database instance:
36
38
  #
@@ -39,20 +41,14 @@
39
41
  # See the {schema modification guide}[rdoc-ref:doc/schema_modification.rdoc]
40
42
  # for details on using postgres array columns in CREATE/ALTER TABLE statements.
41
43
  #
42
- # If you are not using the native postgres or jdbc/postgresql adapter and are using array
43
- # types as model column values you probably should use the the pg_typecast_on_load plugin
44
- # if the column values are returned as a string.
45
- #
46
44
  # This extension by default includes handlers for array types for
47
45
  # all scalar types that the native postgres adapter handles. It
48
46
  # also makes it easy to add support for other array types. In
49
47
  # general, you just need to make sure that the scalar type is
50
- # handled and has the appropriate converter installed in
51
- # Sequel::Postgres::PG_TYPES or the Database instance's
52
- # conversion_procs usingthe appropriate type OID. For user defined
48
+ # handled and has the appropriate converter installed. For user defined
53
49
  # types, you can do this via:
54
50
  #
55
- # DB.conversion_procs[scalar_type_oid] = lambda{|string| }
51
+ # DB.add_conversion_proc(scalar_type_oid){|string| }
56
52
  #
57
53
  # Then you can call
58
54
  # Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
@@ -62,27 +58,19 @@
62
58
  #
63
59
  # DB.register_array_type('foo')
64
60
  #
65
- # You can also register array types on a global basis using
66
- # Sequel::Postgres::PGArray.register. In this case, you'll have
67
- # to specify the type oids:
68
- #
69
- # Sequel::Postgres::PG_TYPES[1234] = lambda{|string| }
70
- # Sequel::Postgres::PGArray.register('foo', :oid=>4321, :scalar_oid=>1234)
71
- #
72
- # Both Sequel::Postgres::PGArray::DatabaseMethods#register_array_type
73
- # and Sequel::Postgres::PGArray.register support many options to
74
- # customize the array type handling. See the Sequel::Postgres::PGArray.register
75
- # method documentation.
61
+ # While this extension can parse PostgreSQL arrays with explicit bounds, it
62
+ # currently ignores explicit bounds, so such values do not round
63
+ # trip.
76
64
  #
77
65
  # If you want an easy way to call PostgreSQL array functions and
78
66
  # operators, look into the pg_array_ops extension.
79
67
  #
80
- # This extension requires the json, strscan, and delegate libraries.
68
+ # This extension requires the delegate library, and the strscan library
69
+ # sequel_pg has not been loaded.
70
+ #
71
+ # Related module: Sequel::Postgres::PGArray
81
72
 
82
73
  require 'delegate'
83
- require 'strscan'
84
- require 'json'
85
- Sequel.require 'adapters/utils/pg_types'
86
74
 
87
75
  module Sequel
88
76
  module Postgres
@@ -90,126 +78,64 @@ module Sequel
90
78
  class PGArray < DelegateClass(Array)
91
79
  include Sequel::SQL::AliasMethods
92
80
 
93
- ARRAY = "ARRAY".freeze
94
- DOUBLE_COLON = '::'.freeze
95
- EMPTY_ARRAY = "'{}'".freeze
96
- EMPTY_BRACKET = '[]'.freeze
97
- OPEN_BRACKET = '['.freeze
98
- CLOSE_BRACKET = ']'.freeze
99
- COMMA = ','.freeze
100
- BACKSLASH = '\\'.freeze
101
- EMPTY_STRING = ''.freeze
102
- OPEN_BRACE = '{'.freeze
103
- CLOSE_BRACE = '}'.freeze
104
- NULL = 'NULL'.freeze
105
- QUOTE = '"'.freeze
106
-
107
- # Global hash of database array type name strings to symbols (e.g. 'double precision' => :float),
108
- # used by the schema parsing for array types registered globally.
109
- ARRAY_TYPES = {}
110
-
111
- # Registers an array type that the extension should handle. Makes a Database instance that
112
- # has been extended with DatabaseMethods recognize the array type given and set up the
113
- # appropriate typecasting. Also sets up automatic typecasting for the native postgres
114
- # adapter, so that on retrieval, the values are automatically converted to PGArray instances.
115
- # The db_type argument should be the exact database type used (as returned by the PostgreSQL
116
- # format_type database function). Accepts the following options:
117
- #
118
- # :array_type :: The type to automatically cast the array to when literalizing the array.
119
- # Usually the same as db_type.
120
- # :converter :: A callable object (e.g. Proc), that is called with each element of the array
121
- # (usually a string), and should return the appropriate typecasted object.
122
- # :oid :: The PostgreSQL OID for the array type. This is used by the Sequel postgres adapter
123
- # to set up automatic type conversion on retrieval from the database.
124
- # :parser :: Can be set to :json to use the faster JSON-based parser. Note that the JSON-based
125
- # parser can only correctly handle integers values correctly. It doesn't handle
126
- # full precision for numeric types, and doesn't handle NaN/Infinity values for
127
- # floating point types.
128
- # :scalar_oid :: Should be the PostgreSQL OID for the scalar version of this array type. If given,
129
- # automatically sets the :converter option by looking for scalar conversion
130
- # proc.
131
- # :scalar_typecast :: Should be a symbol indicating the typecast method that should be called on
132
- # each element of the array, when a plain array is passed into a database
133
- # typecast method. For example, for an array of integers, this could be set to
134
- # :integer, so that the typecast_value_integer method is called on all of the
135
- # array elements. Defaults to :type_symbol option.
136
- # :type_procs :: A hash mapping oids to conversion procs, used for looking up the :scalar_oid and
137
- # value and setting the :oid value. Defaults to the global Sequel::Postgres::PG_TYPES.
138
- # :type_symbol :: The base of the schema type symbol for this type. For example, if you provide
139
- # :integer, Sequel will recognize this type as :integer_array during schema parsing.
140
- # Defaults to the db_type argument.
141
- # :typecast_method_map :: The map in which to place the database type string to type symbol mapping.
142
- # Defaults to ARRAY_TYPES.
143
- # :typecast_methods_module :: If given, a module object to add the typecasting method to. Defaults
144
- # to DatabaseMethods.
145
- #
146
- # If a block is given, it is treated as the :converter option.
147
- def self.register(db_type, opts=OPTS, &block)
148
- db_type = db_type.to_s
149
- type = (opts[:type_symbol] || db_type).to_sym
150
- type_procs = opts[:type_procs] || PG_TYPES
151
- mod = opts[:typecast_methods_module] || DatabaseMethods
152
- typecast_method_map = opts[:typecast_method_map] || ARRAY_TYPES
153
-
154
- if converter = opts[:converter]
155
- raise Error, "can't provide both a block and :converter option to register" if block
156
- else
157
- converter = block
158
- end
159
-
160
- if soid = opts[:scalar_oid]
161
- raise Error, "can't provide both a converter and :scalar_oid option to register" if converter
162
- converter = type_procs[soid]
163
- end
164
-
165
- array_type = (opts[:array_type] || db_type).to_s.dup.freeze
166
- creator = (opts[:parser] == :json ? JSONCreator : Creator).new(array_type, converter)
167
-
168
- typecast_method_map[db_type] = :"#{type}_array"
169
-
170
- define_array_typecast_method(mod, type, creator, opts.fetch(:scalar_typecast, type))
171
-
172
- if oid = opts[:oid]
173
- type_procs[oid] = creator
174
- end
175
-
176
- nil
177
- end
178
-
179
- # Define a private array typecasting method in the given module for the given type that uses
180
- # the creator argument to do the type conversion.
181
- def self.define_array_typecast_method(mod, type, creator, scalar_typecast)
182
- mod.class_eval do
183
- meth = :"typecast_value_#{type}_array"
184
- scalar_typecast_method = :"typecast_value_#{scalar_typecast}"
185
- define_method(meth){|v| typecast_value_pg_array(v, creator, scalar_typecast_method)}
186
- private meth
187
- end
188
- end
189
- private_class_method :define_array_typecast_method
190
-
191
81
  module DatabaseMethods
192
- APOS = "'".freeze
193
- DOUBLE_APOS = "''".freeze
194
- ESCAPE_RE = /("|\\)/.freeze
195
- ESCAPE_REPLACEMENT = '\\\\\1'.freeze
196
82
  BLOB_RANGE = 1...-1
197
83
 
198
84
  # Create the local hash of database type strings to schema type symbols,
199
85
  # used for array types local to this database.
200
86
  def self.extended(db)
201
- db.instance_eval do
87
+ db.instance_exec do
202
88
  @pg_array_schema_types ||= {}
203
- procs = conversion_procs
204
- procs[1115] = Creator.new("timestamp without time zone", procs[1114])
205
- procs[1185] = Creator.new("timestamp with time zone", procs[1184])
206
- copy_conversion_procs([143, 791, 1000, 1001, 1003, 1005, 1006, 1007, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1021, 1022, 1028, 1182, 1183, 1231, 1270, 1561, 1563, 2951])
89
+ register_array_type('timestamp without time zone', :oid=>1115, :scalar_oid=>1114, :type_symbol=>:datetime)
90
+ register_array_type('timestamp with time zone', :oid=>1185, :scalar_oid=>1184, :type_symbol=>:datetime_timezone, :scalar_typecast=>:datetime)
91
+
92
+ register_array_type('text', :oid=>1009, :scalar_oid=>25, :type_symbol=>:string)
93
+ register_array_type('integer', :oid=>1007, :scalar_oid=>23)
94
+ register_array_type('bigint', :oid=>1016, :scalar_oid=>20, :scalar_typecast=>:integer)
95
+ register_array_type('numeric', :oid=>1231, :scalar_oid=>1700, :type_symbol=>:decimal)
96
+ register_array_type('double precision', :oid=>1022, :scalar_oid=>701, :type_symbol=>:float)
97
+
98
+ register_array_type('boolean', :oid=>1000, :scalar_oid=>16)
99
+ register_array_type('bytea', :oid=>1001, :scalar_oid=>17, :type_symbol=>:blob)
100
+ register_array_type('date', :oid=>1182, :scalar_oid=>1082)
101
+ register_array_type('time without time zone', :oid=>1183, :scalar_oid=>1083, :type_symbol=>:time)
102
+ register_array_type('time with time zone', :oid=>1270, :scalar_oid=>1266, :type_symbol=>:time_timezone, :scalar_typecast=>:time)
103
+
104
+ register_array_type('smallint', :oid=>1005, :scalar_oid=>21, :scalar_typecast=>:integer)
105
+ register_array_type('oid', :oid=>1028, :scalar_oid=>26, :scalar_typecast=>:integer)
106
+ register_array_type('real', :oid=>1021, :scalar_oid=>700, :scalar_typecast=>:float)
107
+ register_array_type('character', :oid=>1014, :converter=>nil, :array_type=>:text, :scalar_typecast=>:string)
108
+ register_array_type('character varying', :oid=>1015, :converter=>nil, :scalar_typecast=>:string, :type_symbol=>:varchar)
109
+
110
+ register_array_type('xml', :oid=>143, :scalar_oid=>142)
111
+ register_array_type('money', :oid=>791, :scalar_oid=>790)
112
+ register_array_type('bit', :oid=>1561, :scalar_oid=>1560)
113
+ register_array_type('bit varying', :oid=>1563, :scalar_oid=>1562, :type_symbol=>:varbit)
114
+ register_array_type('uuid', :oid=>2951, :scalar_oid=>2950)
115
+
116
+ register_array_type('xid', :oid=>1011, :scalar_oid=>28)
117
+ register_array_type('cid', :oid=>1012, :scalar_oid=>29)
118
+
119
+ register_array_type('name', :oid=>1003, :scalar_oid=>19)
120
+ register_array_type('tid', :oid=>1010, :scalar_oid=>27)
121
+ register_array_type('int2vector', :oid=>1006, :scalar_oid=>22)
122
+ register_array_type('oidvector', :oid=>1013, :scalar_oid=>30)
123
+
207
124
  [:string_array, :integer_array, :decimal_array, :float_array, :boolean_array, :blob_array, :date_array, :time_array, :datetime_array].each do |v|
208
125
  @schema_type_classes[v] = PGArray
209
126
  end
210
127
  end
211
128
  end
212
129
 
130
+ def add_named_conversion_proc(name, &block)
131
+ ret = super
132
+ name = name.to_s if name.is_a?(Symbol)
133
+ from(:pg_type).where(:typname=>name).select_map([:oid, :typarray]).each do |scalar_oid, array_oid|
134
+ register_array_type(name, :oid=>array_oid.to_i, :scalar_oid=>scalar_oid.to_i)
135
+ end
136
+ ret
137
+ end
138
+
213
139
  # Handle arrays in bound variables
214
140
  def bound_variable_arg(arg, conn)
215
141
  case arg
@@ -222,25 +148,75 @@ module Sequel
222
148
  end
223
149
  end
224
150
 
225
- # Register a database specific array type. This can be used to support
226
- # different array types per Database. Use of this method does not
227
- # affect global state, unlike PGArray.register. See PGArray.register for
228
- # possible options.
151
+ # Freeze the pg array schema types to prevent adding new ones.
152
+ def freeze
153
+ @pg_array_schema_types.freeze
154
+ super
155
+ end
156
+
157
+ # Register a database specific array type. Options:
158
+ #
159
+ # :array_type :: The type to automatically cast the array to when literalizing the array.
160
+ # Usually the same as db_type.
161
+ # :converter :: A callable object (e.g. Proc), that is called with each element of the array
162
+ # (usually a string), and should return the appropriate typecasted object.
163
+ # :oid :: The PostgreSQL OID for the array type. This is used by the Sequel postgres adapter
164
+ # to set up automatic type conversion on retrieval from the database.
165
+ # :scalar_oid :: Should be the PostgreSQL OID for the scalar version of this array type. If given,
166
+ # automatically sets the :converter option by looking for scalar conversion
167
+ # proc.
168
+ # :scalar_typecast :: Should be a symbol indicating the typecast method that should be called on
169
+ # each element of the array, when a plain array is passed into a database
170
+ # typecast method. For example, for an array of integers, this could be set to
171
+ # :integer, so that the typecast_value_integer method is called on all of the
172
+ # array elements. Defaults to :type_symbol option.
173
+ # :type_symbol :: The base of the schema type symbol for this type. For example, if you provide
174
+ # :integer, Sequel will recognize this type as :integer_array during schema parsing.
175
+ # Defaults to the db_type argument.
176
+ #
177
+ # If a block is given, it is treated as the :converter option.
229
178
  def register_array_type(db_type, opts=OPTS, &block)
230
- opts = {:type_procs=>conversion_procs, :typecast_method_map=>@pg_array_schema_types, :typecast_methods_module=>(class << self; self; end)}.merge!(opts)
231
- unless (opts.has_key?(:scalar_oid) || block) && opts.has_key?(:oid)
179
+ oid = opts[:oid]
180
+ soid = opts[:scalar_oid]
181
+
182
+ if has_converter = opts.has_key?(:converter)
183
+ raise Error, "can't provide both a block and :converter option to register_array_type" if block
184
+ converter = opts[:converter]
185
+ else
186
+ has_converter = true if block
187
+ converter = block
188
+ end
189
+
190
+ unless (soid || has_converter) && oid
232
191
  array_oid, scalar_oid = from(:pg_type).where(:typname=>db_type.to_s).get([:typarray, :oid])
233
- opts[:scalar_oid] = scalar_oid unless opts.has_key?(:scalar_oid) || block
234
- opts[:oid] = array_oid unless opts.has_key?(:oid)
192
+ soid ||= scalar_oid unless has_converter
193
+ oid ||= array_oid
235
194
  end
236
- PGArray.register(db_type, opts, &block)
237
- @schema_type_classes[:"#{opts[:type_symbol] || db_type}_array"] = PGArray
238
- conversion_procs_updated
239
- end
240
195
 
241
- # Return PGArray if this type matches any supported array type.
242
- def schema_type_class(type)
243
- super || (ARRAY_TYPES.each_value{|v| return PGArray if type == v}; nil)
196
+ db_type = db_type.to_s
197
+ type = (opts[:type_symbol] || db_type).to_sym
198
+ typecast_method_map = @pg_array_schema_types
199
+
200
+ if soid
201
+ raise Error, "can't provide both a converter and :scalar_oid option to register" if has_converter
202
+ converter = conversion_procs[soid]
203
+ end
204
+
205
+ array_type = (opts[:array_type] || db_type).to_s.dup.freeze
206
+ creator = Creator.new(array_type, converter)
207
+ add_conversion_proc(oid, creator)
208
+
209
+ typecast_method_map[db_type] = :"#{type}_array"
210
+
211
+ singleton_class.class_eval do
212
+ meth = :"typecast_value_#{type}_array"
213
+ scalar_typecast_method = :"typecast_value_#{opts.fetch(:scalar_typecast, type)}"
214
+ define_method(meth){|v| typecast_value_pg_array(v, creator, scalar_typecast_method)}
215
+ private meth
216
+ end
217
+
218
+ @schema_type_classes[:"#{type}_array"] = PGArray
219
+ nil
244
220
  end
245
221
 
246
222
  private
@@ -249,46 +225,23 @@ module Sequel
249
225
  def bound_variable_array(a)
250
226
  case a
251
227
  when Array
252
- "{#{a.map{|i| bound_variable_array(i)}.join(COMMA)}}"
228
+ "{#{a.map{|i| bound_variable_array(i)}.join(',')}}"
253
229
  when Sequel::SQL::Blob
254
- "\"#{literal(a)[BLOB_RANGE].gsub(DOUBLE_APOS, APOS).gsub(ESCAPE_RE, ESCAPE_REPLACEMENT)}\""
230
+ "\"#{literal(a)[BLOB_RANGE].gsub("''", "'").gsub(/("|\\)/, '\\\\\1')}\""
255
231
  when Sequel::LiteralString
256
232
  a
257
233
  when String
258
- "\"#{a.gsub(ESCAPE_RE, ESCAPE_REPLACEMENT)}\""
234
+ "\"#{a.gsub(/("|\\)/, '\\\\\1')}\""
259
235
  else
260
236
  literal(a)
261
237
  end
262
238
  end
263
239
 
264
- # Automatically handle array types for the given named types.
265
- def convert_named_procs_to_procs(named_procs)
266
- h = super
267
- unless h.empty?
268
- from(:pg_type).where(:oid=>h.keys).select_map([:typname, :oid, :typarray]).each do |name, scalar_oid, array_oid|
269
- register_array_type(name, :type_procs=>h, :oid=>array_oid.to_i, :scalar_oid=>scalar_oid.to_i)
270
- end
271
- end
272
- h
273
- end
274
-
275
- # Manually override the typecasting for timestamp array types so that
276
- # they use the database's timezone instead of the global Sequel
277
- # timezone.
278
- def get_conversion_procs
279
- procs = super
280
-
281
- procs[1115] = Creator.new("timestamp without time zone", procs[1114])
282
- procs[1185] = Creator.new("timestamp with time zone", procs[1184])
283
-
284
- procs
285
- end
286
-
287
240
  # Look into both the current database's array schema types and the global
288
241
  # array schema types to get the type symbol for the given database type
289
242
  # string.
290
243
  def pg_array_schema_type(type)
291
- @pg_array_schema_types[type] || ARRAY_TYPES[type]
244
+ @pg_array_schema_types[type]
292
245
  end
293
246
 
294
247
  # Make the column type detection handle registered array types.
@@ -300,6 +253,17 @@ module Sequel
300
253
  end
301
254
  end
302
255
 
256
+ # Set the :callable_default value if the default value is recognized as an empty array.
257
+ def schema_post_process(_)
258
+ super.each do |a|
259
+ h = a[1]
260
+ if h[:default] =~ /\A(?:'\{\}'|ARRAY\[\])::([\w ]+)\[\]\z/
261
+ type = $1.freeze
262
+ h[:callable_default] = lambda{Sequel.pg_array([], type)}
263
+ end
264
+ end
265
+ end
266
+
303
267
  # Convert ruby arrays to PostgreSQL arrays when used as default values.
304
268
  def column_definition_default_sql(sql, column)
305
269
  if (d = column[:default]) && d.is_a?(Array) && !Sequel.condition_specifier?(d)
@@ -336,97 +300,101 @@ module Sequel
336
300
  end
337
301
  end
338
302
 
339
- # PostgreSQL array parser that handles PostgreSQL array output format.
340
- # Note that does not handle all forms out input that PostgreSQL will
341
- # accept, and it will not raise an error for all forms of invalid input.
342
- class Parser < StringScanner
343
- UNQUOTED_RE = /[{}",]|[^{}",]+/
344
- QUOTED_RE = /["\\]|[^"\\]+/
345
- NULL_RE = /NULL",/
346
- OPEN_RE = /\{/
347
-
348
- # Set the source for the input, and any converter callable
349
- # to call with objects to be created. For nested parsers
350
- # the source may contain text after the end current parse,
351
- # which will be ignored.
352
- def initialize(source, converter=nil)
353
- super(source)
354
- @converter = converter
355
- @stack = [[]]
356
- @recorded = ""
357
- end
303
+ unless Sequel::Postgres.respond_to?(:parse_pg_array)
304
+ require 'strscan'
305
+
306
+ # PostgreSQL array parser that handles PostgreSQL array output format.
307
+ # Note that does not handle all forms out input that PostgreSQL will
308
+ # accept, and it will not raise an error for all forms of invalid input.
309
+ class Parser < StringScanner
310
+ # Set the source for the input, and any converter callable
311
+ # to call with objects to be created. For nested parsers
312
+ # the source may contain text after the end current parse,
313
+ # which will be ignored.
314
+ def initialize(source, converter=nil)
315
+ super(source)
316
+ @converter = converter
317
+ @stack = [[]]
318
+ @encoding = string.encoding
319
+ @recorded = String.new.force_encoding(@encoding)
320
+ end
358
321
 
359
- # Take the buffer of recorded characters and add it to the array
360
- # of entries, and use a new buffer for recorded characters.
361
- def new_entry(include_empty=false)
362
- if !@recorded.empty? || include_empty
363
- entry = @recorded
364
- if entry == NULL && !include_empty
365
- entry = nil
366
- elsif @converter
367
- entry = @converter.call(entry)
322
+ # Take the buffer of recorded characters and add it to the array
323
+ # of entries, and use a new buffer for recorded characters.
324
+ def new_entry(include_empty=false)
325
+ if !@recorded.empty? || include_empty
326
+ entry = @recorded
327
+ if entry == 'NULL' && !include_empty
328
+ entry = nil
329
+ elsif @converter
330
+ entry = @converter.call(entry)
331
+ end
332
+ @stack.last.push(entry)
333
+ @recorded = String.new.force_encoding(@encoding)
368
334
  end
369
- @stack.last.push(entry)
370
- @recorded = ""
371
335
  end
372
- end
373
336
 
374
- # Parse the input character by character, returning an array
375
- # of parsed (and potentially converted) objects.
376
- def parse
377
- raise Sequel::Error, "invalid array, empty string" if eos?
378
- raise Sequel::Error, "invalid array, doesn't start with {" unless scan(OPEN_RE)
379
-
380
- while !eos?
381
- char = scan(UNQUOTED_RE)
382
- if char == COMMA
383
- # Comma outside quoted string indicates end of current entry
384
- new_entry
385
- elsif char == QUOTE
386
- raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty?
387
- while true
388
- char = scan(QUOTED_RE)
389
- if char == BACKSLASH
390
- @recorded << getch
391
- elsif char == QUOTE
392
- n = peek(1)
393
- raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == COMMA || n == CLOSE_BRACE
394
- break
337
+ # Parse the input character by character, returning an array
338
+ # of parsed (and potentially converted) objects.
339
+ def parse
340
+ raise Sequel::Error, "invalid array, empty string" if eos?
341
+ raise Sequel::Error, "invalid array, doesn't start with {" unless scan(/((\[\d+:\d+\])+=)?\{/)
342
+
343
+ # :nocov:
344
+ while !eos?
345
+ # :nocov:
346
+ char = scan(/[{}",]|[^{}",]+/)
347
+ if char == ','
348
+ # Comma outside quoted string indicates end of current entry
349
+ new_entry
350
+ elsif char == '"'
351
+ raise Sequel::Error, "invalid array, opening quote with existing recorded data" unless @recorded.empty?
352
+ # :nocov:
353
+ while true
354
+ # :nocov:
355
+ char = scan(/["\\]|[^"\\]+/)
356
+ if char == '\\'
357
+ @recorded << getch
358
+ elsif char == '"'
359
+ n = peek(1)
360
+ raise Sequel::Error, "invalid array, closing quote not followed by comma or closing brace" unless n == ',' || n == '}'
361
+ break
362
+ else
363
+ @recorded << char
364
+ end
365
+ end
366
+ new_entry(true)
367
+ elsif char == '{'
368
+ raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty?
369
+
370
+ # Start of new array, add it to the stack
371
+ new = []
372
+ @stack.last << new
373
+ @stack << new
374
+ elsif char == '}'
375
+ # End of current array, add current entry to the current array
376
+ new_entry
377
+
378
+ if @stack.length == 1
379
+ raise Sequel::Error, "array parsing finished without parsing entire string" unless eos?
380
+
381
+ # Top level of array, parsing should be over.
382
+ # Pop current array off stack and return it as result
383
+ return @stack.pop
395
384
  else
396
- @recorded << char
385
+ # Nested array, pop current array off stack
386
+ @stack.pop
397
387
  end
398
- end
399
- new_entry(true)
400
- elsif char == OPEN_BRACE
401
- raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty?
402
-
403
- # Start of new array, add it to the stack
404
- new = []
405
- @stack.last << new
406
- @stack << new
407
- elsif char == CLOSE_BRACE
408
- # End of current array, add current entry to the current array
409
- new_entry
410
-
411
- if @stack.length == 1
412
- raise Sequel::Error, "array parsing finished without parsing entire string" unless eos?
413
-
414
- # Top level of array, parsing should be over.
415
- # Pop current array off stack and return it as result
416
- return @stack.pop
417
388
  else
418
- # Nested array, pop current array off stack
419
- @stack.pop
389
+ # Add the character to the recorded character buffer.
390
+ @recorded << char
420
391
  end
421
- else
422
- # Add the character to the recorded character buffer.
423
- @recorded << char
424
392
  end
425
- end
426
393
 
427
- raise Sequel::Error, "array parsing finished with array unclosed"
394
+ raise Sequel::Error, "array parsing finished with array unclosed"
395
+ end
428
396
  end
429
- end unless Sequel::Postgres.respond_to?(:parse_pg_array)
397
+ end
430
398
 
431
399
  # Callable object that takes the input string and parses it using Parser.
432
400
  class Creator
@@ -460,27 +428,6 @@ module Sequel
460
428
  end
461
429
  end
462
430
 
463
- # Callable object that takes the input string and parses it using.
464
- # a JSON parser. This should be faster than the standard Creator,
465
- # but only handles integer types correctly.
466
- class JSONCreator < Creator
467
- # Character conversion map mapping input strings to JSON replacements
468
- SUBST = {'{'.freeze=>'['.freeze, '}'.freeze=>']'.freeze, 'NULL'.freeze=>'null'.freeze}
469
-
470
- # Regular expression matching input strings to convert
471
- SUBST_RE = %r[\{|\}|NULL].freeze
472
-
473
- # Parse the input string by using a gsub to convert non-JSON characters to
474
- # JSON, running it through a regular JSON parser. If a converter is used, a
475
- # recursive map of the output is done to make sure that the entires in the
476
- # correct type.
477
- def call(string)
478
- array = Sequel.parse_json(string.gsub(SUBST_RE){|m| SUBST[m]})
479
- array = Sequel.recursive_map(array, @converter) if @converter
480
- PGArray.new(array, @type)
481
- end
482
- end
483
-
484
431
  # The type of this array. May be nil if no type was given. If a type
485
432
  # is provided, the array is automatically casted to this type when
486
433
  # literalizing. This type is the underlying type, not the array type
@@ -499,13 +446,13 @@ module Sequel
499
446
  def sql_literal_append(ds, sql)
500
447
  at = array_type
501
448
  if empty? && at
502
- sql << EMPTY_ARRAY
449
+ sql << "'{}'"
503
450
  else
504
- sql << ARRAY
451
+ sql << "ARRAY"
505
452
  _literal_append(sql, ds, to_a)
506
453
  end
507
454
  if at
508
- sql << DOUBLE_COLON << at.to_s << EMPTY_BRACKET
455
+ sql << '::' << at.to_s << '[]'
509
456
  end
510
457
  end
511
458
 
@@ -515,9 +462,9 @@ module Sequel
515
462
  # arrays, surrounding each with [] and interspersing
516
463
  # entries with ,.
517
464
  def _literal_append(sql, ds, array)
518
- sql << OPEN_BRACKET
465
+ sql << '['
519
466
  comma = false
520
- commas = COMMA
467
+ commas = ','
521
468
  array.each do |i|
522
469
  sql << commas if comma
523
470
  if i.is_a?(Array)
@@ -527,44 +474,8 @@ module Sequel
527
474
  end
528
475
  comma = true
529
476
  end
530
- sql << CLOSE_BRACKET
477
+ sql << ']'
531
478
  end
532
-
533
- # Register all array types that this extension handles by default.
534
-
535
- register('text', :oid=>1009, :type_symbol=>:string)
536
- register('integer', :oid=>1007, :parser=>:json)
537
- register('bigint', :oid=>1016, :parser=>:json, :scalar_typecast=>:integer)
538
- register('numeric', :oid=>1231, :scalar_oid=>1700, :type_symbol=>:decimal)
539
- register('double precision', :oid=>1022, :scalar_oid=>701, :type_symbol=>:float)
540
-
541
- register('boolean', :oid=>1000, :scalar_oid=>16)
542
- register('bytea', :oid=>1001, :scalar_oid=>17, :type_symbol=>:blob)
543
- register('date', :oid=>1182, :scalar_oid=>1082)
544
- register('time without time zone', :oid=>1183, :scalar_oid=>1083, :type_symbol=>:time)
545
- register('timestamp without time zone', :oid=>1115, :scalar_oid=>1114, :type_symbol=>:datetime)
546
- register('time with time zone', :oid=>1270, :scalar_oid=>1083, :type_symbol=>:time_timezone, :scalar_typecast=>:time)
547
- register('timestamp with time zone', :oid=>1185, :scalar_oid=>1184, :type_symbol=>:datetime_timezone, :scalar_typecast=>:datetime)
548
-
549
- register('smallint', :oid=>1005, :parser=>:json, :scalar_typecast=>:integer)
550
- register('oid', :oid=>1028, :parser=>:json, :scalar_typecast=>:integer)
551
- register('real', :oid=>1021, :scalar_oid=>700, :scalar_typecast=>:float)
552
- register('character', :oid=>1014, :array_type=>:text, :scalar_typecast=>:string)
553
- register('character varying', :oid=>1015, :scalar_typecast=>:string, :type_symbol=>:varchar)
554
-
555
- register('xml', :oid=>143, :scalar_oid=>142)
556
- register('money', :oid=>791, :scalar_oid=>790)
557
- register('bit', :oid=>1561, :scalar_oid=>1560)
558
- register('bit varying', :oid=>1563, :scalar_oid=>1562, :type_symbol=>:varbit)
559
- register('uuid', :oid=>2951, :scalar_oid=>2950)
560
-
561
- register('xid', :oid=>1011, :scalar_oid=>28)
562
- register('cid', :oid=>1012, :scalar_oid=>29)
563
-
564
- register('name', :oid=>1003, :scalar_oid=>19)
565
- register('tid', :oid=>1010, :scalar_oid=>27)
566
- register('int2vector', :oid=>1006, :scalar_oid=>22)
567
- register('oidvector', :oid=>1013, :scalar_oid=>30)
568
479
  end
569
480
  end
570
481