sequel 4.36.0 → 5.61.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 (760) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG +548 -5749
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +265 -159
  5. data/bin/sequel +34 -12
  6. data/doc/advanced_associations.rdoc +228 -187
  7. data/doc/association_basics.rdoc +281 -291
  8. data/doc/bin_sequel.rdoc +5 -3
  9. data/doc/cheat_sheet.rdoc +86 -51
  10. data/doc/code_order.rdoc +25 -19
  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/fork_safety.rdoc +84 -0
  16. data/doc/mass_assignment.rdoc +74 -31
  17. data/doc/migration.rdoc +59 -51
  18. data/doc/model_dataset_method_design.rdoc +129 -0
  19. data/doc/model_hooks.rdoc +15 -25
  20. data/doc/model_plugins.rdoc +12 -12
  21. data/doc/mssql_stored_procedures.rdoc +3 -3
  22. data/doc/object_model.rdoc +58 -68
  23. data/doc/opening_databases.rdoc +85 -95
  24. data/doc/postgresql.rdoc +263 -38
  25. data/doc/prepared_statements.rdoc +29 -24
  26. data/doc/querying.rdoc +189 -167
  27. data/doc/reflection.rdoc +5 -6
  28. data/doc/release_notes/5.0.0.txt +159 -0
  29. data/doc/release_notes/5.1.0.txt +31 -0
  30. data/doc/release_notes/5.10.0.txt +84 -0
  31. data/doc/release_notes/5.11.0.txt +83 -0
  32. data/doc/release_notes/5.12.0.txt +141 -0
  33. data/doc/release_notes/5.13.0.txt +27 -0
  34. data/doc/release_notes/5.14.0.txt +63 -0
  35. data/doc/release_notes/5.15.0.txt +39 -0
  36. data/doc/release_notes/5.16.0.txt +110 -0
  37. data/doc/release_notes/5.17.0.txt +31 -0
  38. data/doc/release_notes/5.18.0.txt +69 -0
  39. data/doc/release_notes/5.19.0.txt +28 -0
  40. data/doc/release_notes/5.2.0.txt +33 -0
  41. data/doc/release_notes/5.20.0.txt +89 -0
  42. data/doc/release_notes/5.21.0.txt +87 -0
  43. data/doc/release_notes/5.22.0.txt +48 -0
  44. data/doc/release_notes/5.23.0.txt +56 -0
  45. data/doc/release_notes/5.24.0.txt +56 -0
  46. data/doc/release_notes/5.25.0.txt +32 -0
  47. data/doc/release_notes/5.26.0.txt +35 -0
  48. data/doc/release_notes/5.27.0.txt +21 -0
  49. data/doc/release_notes/5.28.0.txt +16 -0
  50. data/doc/release_notes/5.29.0.txt +22 -0
  51. data/doc/release_notes/5.3.0.txt +121 -0
  52. data/doc/release_notes/5.30.0.txt +20 -0
  53. data/doc/release_notes/5.31.0.txt +148 -0
  54. data/doc/release_notes/5.32.0.txt +46 -0
  55. data/doc/release_notes/5.33.0.txt +24 -0
  56. data/doc/release_notes/5.34.0.txt +40 -0
  57. data/doc/release_notes/5.35.0.txt +56 -0
  58. data/doc/release_notes/5.36.0.txt +60 -0
  59. data/doc/release_notes/5.37.0.txt +30 -0
  60. data/doc/release_notes/5.38.0.txt +28 -0
  61. data/doc/release_notes/5.39.0.txt +19 -0
  62. data/doc/release_notes/5.4.0.txt +80 -0
  63. data/doc/release_notes/5.40.0.txt +40 -0
  64. data/doc/release_notes/5.41.0.txt +25 -0
  65. data/doc/release_notes/5.42.0.txt +136 -0
  66. data/doc/release_notes/5.43.0.txt +98 -0
  67. data/doc/release_notes/5.44.0.txt +32 -0
  68. data/doc/release_notes/5.45.0.txt +34 -0
  69. data/doc/release_notes/5.46.0.txt +87 -0
  70. data/doc/release_notes/5.47.0.txt +59 -0
  71. data/doc/release_notes/5.48.0.txt +14 -0
  72. data/doc/release_notes/5.49.0.txt +59 -0
  73. data/doc/release_notes/5.5.0.txt +61 -0
  74. data/doc/release_notes/5.50.0.txt +78 -0
  75. data/doc/release_notes/5.51.0.txt +47 -0
  76. data/doc/release_notes/5.52.0.txt +87 -0
  77. data/doc/release_notes/5.53.0.txt +23 -0
  78. data/doc/release_notes/5.54.0.txt +27 -0
  79. data/doc/release_notes/5.55.0.txt +21 -0
  80. data/doc/release_notes/5.56.0.txt +51 -0
  81. data/doc/release_notes/5.57.0.txt +23 -0
  82. data/doc/release_notes/5.58.0.txt +31 -0
  83. data/doc/release_notes/5.59.0.txt +73 -0
  84. data/doc/release_notes/5.6.0.txt +31 -0
  85. data/doc/release_notes/5.60.0.txt +22 -0
  86. data/doc/release_notes/5.61.0.txt +43 -0
  87. data/doc/release_notes/5.7.0.txt +108 -0
  88. data/doc/release_notes/5.8.0.txt +170 -0
  89. data/doc/release_notes/5.9.0.txt +99 -0
  90. data/doc/schema_modification.rdoc +95 -75
  91. data/doc/security.rdoc +109 -80
  92. data/doc/sharding.rdoc +74 -47
  93. data/doc/sql.rdoc +147 -122
  94. data/doc/testing.rdoc +43 -20
  95. data/doc/thread_safety.rdoc +2 -4
  96. data/doc/transactions.rdoc +97 -18
  97. data/doc/validations.rdoc +52 -50
  98. data/doc/virtual_rows.rdoc +90 -109
  99. data/lib/sequel/adapters/ado/access.rb +15 -17
  100. data/lib/sequel/adapters/ado/mssql.rb +6 -15
  101. data/lib/sequel/adapters/ado.rb +150 -20
  102. data/lib/sequel/adapters/amalgalite.rb +11 -23
  103. data/lib/sequel/adapters/ibmdb.rb +47 -55
  104. data/lib/sequel/adapters/jdbc/db2.rb +29 -39
  105. data/lib/sequel/adapters/jdbc/derby.rb +58 -54
  106. data/lib/sequel/adapters/jdbc/h2.rb +93 -35
  107. data/lib/sequel/adapters/jdbc/hsqldb.rb +24 -31
  108. data/lib/sequel/adapters/jdbc/jtds.rb +2 -10
  109. data/lib/sequel/adapters/jdbc/mssql.rb +3 -11
  110. data/lib/sequel/adapters/jdbc/mysql.rb +17 -20
  111. data/lib/sequel/adapters/jdbc/oracle.rb +22 -18
  112. data/lib/sequel/adapters/jdbc/postgresql.rb +69 -71
  113. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +11 -23
  114. data/lib/sequel/adapters/jdbc/sqlite.rb +47 -11
  115. data/lib/sequel/adapters/jdbc/sqlserver.rb +34 -9
  116. data/lib/sequel/adapters/jdbc/transactions.rb +22 -38
  117. data/lib/sequel/adapters/jdbc.rb +145 -130
  118. data/lib/sequel/adapters/mock.rb +100 -111
  119. data/lib/sequel/adapters/mysql.rb +114 -122
  120. data/lib/sequel/adapters/mysql2.rb +147 -63
  121. data/lib/sequel/adapters/odbc/db2.rb +1 -1
  122. data/lib/sequel/adapters/odbc/mssql.rb +8 -14
  123. data/lib/sequel/adapters/odbc/oracle.rb +11 -0
  124. data/lib/sequel/adapters/odbc.rb +20 -25
  125. data/lib/sequel/adapters/oracle.rb +50 -56
  126. data/lib/sequel/adapters/postgres.rb +305 -327
  127. data/lib/sequel/adapters/postgresql.rb +1 -1
  128. data/lib/sequel/adapters/shared/access.rb +74 -78
  129. data/lib/sequel/adapters/shared/db2.rb +118 -71
  130. data/lib/sequel/adapters/shared/mssql.rb +301 -220
  131. data/lib/sequel/adapters/shared/mysql.rb +299 -217
  132. data/lib/sequel/adapters/shared/oracle.rb +226 -65
  133. data/lib/sequel/adapters/shared/postgres.rb +935 -395
  134. data/lib/sequel/adapters/shared/sqlanywhere.rb +105 -126
  135. data/lib/sequel/adapters/shared/sqlite.rb +447 -173
  136. data/lib/sequel/adapters/sqlanywhere.rb +48 -35
  137. data/lib/sequel/adapters/sqlite.rb +156 -111
  138. data/lib/sequel/adapters/tinytds.rb +30 -38
  139. data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
  140. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +3 -6
  141. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +2 -2
  142. data/lib/sequel/adapters/utils/mysql_mysql2.rb +87 -0
  143. data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +56 -0
  144. data/lib/sequel/adapters/utils/replace.rb +1 -4
  145. data/lib/sequel/adapters/utils/stored_procedures.rb +7 -22
  146. data/lib/sequel/adapters/utils/unmodified_identifiers.rb +28 -0
  147. data/lib/sequel/ast_transformer.rb +17 -89
  148. data/lib/sequel/connection_pool/sharded_single.rb +18 -15
  149. data/lib/sequel/connection_pool/sharded_threaded.rb +130 -111
  150. data/lib/sequel/connection_pool/single.rb +18 -13
  151. data/lib/sequel/connection_pool/threaded.rb +121 -120
  152. data/lib/sequel/connection_pool.rb +48 -29
  153. data/lib/sequel/core.rb +351 -301
  154. data/lib/sequel/database/connecting.rb +69 -57
  155. data/lib/sequel/database/dataset.rb +13 -5
  156. data/lib/sequel/database/dataset_defaults.rb +18 -102
  157. data/lib/sequel/database/features.rb +18 -4
  158. data/lib/sequel/database/logging.rb +12 -11
  159. data/lib/sequel/database/misc.rb +180 -122
  160. data/lib/sequel/database/query.rb +47 -27
  161. data/lib/sequel/database/schema_generator.rb +178 -84
  162. data/lib/sequel/database/schema_methods.rb +172 -97
  163. data/lib/sequel/database/transactions.rb +205 -44
  164. data/lib/sequel/database.rb +17 -2
  165. data/lib/sequel/dataset/actions.rb +339 -155
  166. data/lib/sequel/dataset/dataset_module.rb +46 -0
  167. data/lib/sequel/dataset/features.rb +90 -35
  168. data/lib/sequel/dataset/graph.rb +80 -58
  169. data/lib/sequel/dataset/misc.rb +137 -47
  170. data/lib/sequel/dataset/placeholder_literalizer.rb +63 -25
  171. data/lib/sequel/dataset/prepared_statements.rb +188 -85
  172. data/lib/sequel/dataset/query.rb +530 -222
  173. data/lib/sequel/dataset/sql.rb +590 -368
  174. data/lib/sequel/dataset.rb +26 -16
  175. data/lib/sequel/deprecated.rb +12 -2
  176. data/lib/sequel/exceptions.rb +46 -16
  177. data/lib/sequel/extensions/_model_constraint_validations.rb +16 -0
  178. data/lib/sequel/extensions/_model_pg_row.rb +43 -0
  179. data/lib/sequel/extensions/_pretty_table.rb +2 -5
  180. data/lib/sequel/extensions/any_not_empty.rb +45 -0
  181. data/lib/sequel/extensions/arbitrary_servers.rb +10 -10
  182. data/lib/sequel/extensions/async_thread_pool.rb +438 -0
  183. data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
  184. data/lib/sequel/extensions/blank.rb +8 -0
  185. data/lib/sequel/extensions/caller_logging.rb +79 -0
  186. data/lib/sequel/extensions/columns_introspection.rb +4 -3
  187. data/lib/sequel/extensions/connection_expiration.rb +20 -10
  188. data/lib/sequel/extensions/connection_validator.rb +11 -10
  189. data/lib/sequel/extensions/constant_sql_override.rb +65 -0
  190. data/lib/sequel/extensions/constraint_validations.rb +62 -39
  191. data/lib/sequel/extensions/core_extensions.rb +42 -48
  192. data/lib/sequel/extensions/core_refinements.rb +80 -59
  193. data/lib/sequel/extensions/current_datetime_timestamp.rb +1 -4
  194. data/lib/sequel/extensions/date_arithmetic.rb +98 -39
  195. data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
  196. data/lib/sequel/extensions/datetime_parse_to_time.rb +41 -0
  197. data/lib/sequel/extensions/duplicate_columns_handler.rb +21 -14
  198. data/lib/sequel/extensions/empty_array_consider_nulls.rb +2 -2
  199. data/lib/sequel/extensions/escaped_like.rb +100 -0
  200. data/lib/sequel/extensions/eval_inspect.rb +12 -15
  201. data/lib/sequel/extensions/exclude_or_null.rb +68 -0
  202. data/lib/sequel/extensions/fiber_concurrency.rb +24 -0
  203. data/lib/sequel/extensions/freeze_datasets.rb +3 -0
  204. data/lib/sequel/extensions/from_block.rb +1 -34
  205. data/lib/sequel/extensions/graph_each.rb +4 -4
  206. data/lib/sequel/extensions/identifier_mangling.rb +180 -0
  207. data/lib/sequel/extensions/implicit_subquery.rb +48 -0
  208. data/lib/sequel/extensions/index_caching.rb +109 -0
  209. data/lib/sequel/extensions/inflector.rb +13 -5
  210. data/lib/sequel/extensions/integer64.rb +32 -0
  211. data/lib/sequel/extensions/is_distinct_from.rb +141 -0
  212. data/lib/sequel/extensions/looser_typecasting.rb +17 -8
  213. data/lib/sequel/extensions/migration.rb +119 -78
  214. data/lib/sequel/extensions/named_timezones.rb +88 -23
  215. data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -82
  216. data/lib/sequel/extensions/null_dataset.rb +8 -8
  217. data/lib/sequel/extensions/pagination.rb +32 -29
  218. data/lib/sequel/extensions/pg_array.rb +221 -287
  219. data/lib/sequel/extensions/pg_array_ops.rb +17 -9
  220. data/lib/sequel/extensions/pg_enum.rb +63 -23
  221. data/lib/sequel/extensions/pg_extended_date_support.rb +241 -0
  222. data/lib/sequel/extensions/pg_hstore.rb +45 -54
  223. data/lib/sequel/extensions/pg_hstore_ops.rb +58 -6
  224. data/lib/sequel/extensions/pg_inet.rb +31 -12
  225. data/lib/sequel/extensions/pg_inet_ops.rb +2 -2
  226. data/lib/sequel/extensions/pg_interval.rb +56 -29
  227. data/lib/sequel/extensions/pg_json.rb +417 -140
  228. data/lib/sequel/extensions/pg_json_ops.rb +270 -18
  229. data/lib/sequel/extensions/pg_loose_count.rb +4 -2
  230. data/lib/sequel/extensions/pg_multirange.rb +372 -0
  231. data/lib/sequel/extensions/pg_range.rb +131 -191
  232. data/lib/sequel/extensions/pg_range_ops.rb +42 -13
  233. data/lib/sequel/extensions/pg_row.rb +48 -81
  234. data/lib/sequel/extensions/pg_row_ops.rb +33 -14
  235. data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
  236. data/lib/sequel/extensions/pg_timestamptz.rb +28 -0
  237. data/lib/sequel/extensions/query.rb +9 -7
  238. data/lib/sequel/extensions/round_timestamps.rb +0 -6
  239. data/lib/sequel/extensions/run_transaction_hooks.rb +72 -0
  240. data/lib/sequel/extensions/s.rb +60 -0
  241. data/lib/sequel/extensions/schema_caching.rb +10 -1
  242. data/lib/sequel/extensions/schema_dumper.rb +71 -48
  243. data/lib/sequel/extensions/select_remove.rb +4 -4
  244. data/lib/sequel/extensions/sequel_4_dataset_methods.rb +85 -0
  245. data/lib/sequel/extensions/server_block.rb +51 -27
  246. data/lib/sequel/extensions/split_array_nil.rb +4 -4
  247. data/lib/sequel/extensions/sql_comments.rb +119 -7
  248. data/lib/sequel/extensions/sql_expr.rb +2 -1
  249. data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
  250. data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
  251. data/lib/sequel/extensions/string_agg.rb +11 -8
  252. data/lib/sequel/extensions/string_date_time.rb +19 -23
  253. data/lib/sequel/extensions/symbol_aref.rb +55 -0
  254. data/lib/sequel/extensions/symbol_aref_refinement.rb +43 -0
  255. data/lib/sequel/extensions/symbol_as.rb +23 -0
  256. data/lib/sequel/extensions/symbol_as_refinement.rb +37 -0
  257. data/lib/sequel/extensions/synchronize_sql.rb +45 -0
  258. data/lib/sequel/extensions/to_dot.rb +10 -4
  259. data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
  260. data/lib/sequel/model/associations.rb +1006 -284
  261. data/lib/sequel/model/base.rb +560 -805
  262. data/lib/sequel/model/dataset_module.rb +11 -10
  263. data/lib/sequel/model/default_inflections.rb +1 -1
  264. data/lib/sequel/model/errors.rb +10 -3
  265. data/lib/sequel/model/exceptions.rb +8 -10
  266. data/lib/sequel/model/inflections.rb +7 -20
  267. data/lib/sequel/model/plugins.rb +114 -0
  268. data/lib/sequel/model.rb +32 -82
  269. data/lib/sequel/plugins/active_model.rb +30 -14
  270. data/lib/sequel/plugins/after_initialize.rb +1 -1
  271. data/lib/sequel/plugins/association_dependencies.rb +25 -18
  272. data/lib/sequel/plugins/association_lazy_eager_option.rb +66 -0
  273. data/lib/sequel/plugins/association_multi_add_remove.rb +85 -0
  274. data/lib/sequel/plugins/association_pks.rb +147 -70
  275. data/lib/sequel/plugins/association_proxies.rb +33 -9
  276. data/lib/sequel/plugins/async_thread_pool.rb +39 -0
  277. data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
  278. data/lib/sequel/plugins/auto_validations.rb +95 -28
  279. data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
  280. data/lib/sequel/plugins/before_after_save.rb +0 -42
  281. data/lib/sequel/plugins/blacklist_security.rb +21 -12
  282. data/lib/sequel/plugins/boolean_readers.rb +5 -5
  283. data/lib/sequel/plugins/boolean_subsets.rb +13 -8
  284. data/lib/sequel/plugins/caching.rb +25 -16
  285. data/lib/sequel/plugins/class_table_inheritance.rb +179 -100
  286. data/lib/sequel/plugins/column_conflicts.rb +16 -3
  287. data/lib/sequel/plugins/column_encryption.rb +728 -0
  288. data/lib/sequel/plugins/column_select.rb +7 -5
  289. data/lib/sequel/plugins/columns_updated.rb +42 -0
  290. data/lib/sequel/plugins/composition.rb +42 -26
  291. data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
  292. data/lib/sequel/plugins/constraint_validations.rb +20 -14
  293. data/lib/sequel/plugins/csv_serializer.rb +56 -35
  294. data/lib/sequel/plugins/dataset_associations.rb +40 -17
  295. data/lib/sequel/plugins/def_dataset_method.rb +90 -0
  296. data/lib/sequel/plugins/defaults_setter.rb +65 -10
  297. data/lib/sequel/plugins/delay_add_association.rb +1 -1
  298. data/lib/sequel/plugins/dirty.rb +62 -24
  299. data/lib/sequel/plugins/eager_each.rb +3 -3
  300. data/lib/sequel/plugins/eager_graph_eager.rb +139 -0
  301. data/lib/sequel/plugins/empty_failure_backtraces.rb +38 -0
  302. data/lib/sequel/plugins/enum.rb +124 -0
  303. data/lib/sequel/plugins/error_splitter.rb +17 -12
  304. data/lib/sequel/plugins/finder.rb +246 -0
  305. data/lib/sequel/plugins/forbid_lazy_load.rb +216 -0
  306. data/lib/sequel/plugins/force_encoding.rb +7 -12
  307. data/lib/sequel/plugins/hook_class_methods.rb +37 -54
  308. data/lib/sequel/plugins/input_transformer.rb +18 -10
  309. data/lib/sequel/plugins/insert_conflict.rb +76 -0
  310. data/lib/sequel/plugins/insert_returning_select.rb +2 -2
  311. data/lib/sequel/plugins/instance_filters.rb +10 -8
  312. data/lib/sequel/plugins/instance_hooks.rb +34 -17
  313. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  314. data/lib/sequel/plugins/inverted_subsets.rb +22 -13
  315. data/lib/sequel/plugins/json_serializer.rb +124 -64
  316. data/lib/sequel/plugins/lazy_attributes.rb +21 -14
  317. data/lib/sequel/plugins/list.rb +35 -21
  318. data/lib/sequel/plugins/many_through_many.rb +134 -21
  319. data/lib/sequel/plugins/modification_detection.rb +15 -5
  320. data/lib/sequel/plugins/mssql_optimistic_locking.rb +6 -5
  321. data/lib/sequel/plugins/nested_attributes.rb +61 -31
  322. data/lib/sequel/plugins/optimistic_locking.rb +3 -3
  323. data/lib/sequel/plugins/pg_array_associations.rb +103 -53
  324. data/lib/sequel/plugins/pg_auto_constraint_validations.rb +350 -0
  325. data/lib/sequel/plugins/pg_row.rb +5 -51
  326. data/lib/sequel/plugins/prepared_statements.rb +60 -72
  327. data/lib/sequel/plugins/prepared_statements_safe.rb +9 -4
  328. data/lib/sequel/plugins/rcte_tree.rb +68 -82
  329. data/lib/sequel/plugins/require_valid_schema.rb +67 -0
  330. data/lib/sequel/plugins/serialization.rb +43 -46
  331. data/lib/sequel/plugins/serialization_modification_detection.rb +3 -2
  332. data/lib/sequel/plugins/sharding.rb +15 -10
  333. data/lib/sequel/plugins/single_table_inheritance.rb +67 -28
  334. data/lib/sequel/plugins/skip_create_refresh.rb +3 -3
  335. data/lib/sequel/plugins/skip_saving_columns.rb +108 -0
  336. data/lib/sequel/plugins/split_values.rb +11 -6
  337. data/lib/sequel/plugins/sql_comments.rb +189 -0
  338. data/lib/sequel/plugins/static_cache.rb +77 -53
  339. data/lib/sequel/plugins/static_cache_cache.rb +53 -0
  340. data/lib/sequel/plugins/string_stripper.rb +3 -3
  341. data/lib/sequel/plugins/subclasses.rb +43 -10
  342. data/lib/sequel/plugins/subset_conditions.rb +15 -5
  343. data/lib/sequel/plugins/table_select.rb +2 -2
  344. data/lib/sequel/plugins/tactical_eager_loading.rb +96 -12
  345. data/lib/sequel/plugins/throw_failures.rb +110 -0
  346. data/lib/sequel/plugins/timestamps.rb +20 -8
  347. data/lib/sequel/plugins/touch.rb +19 -8
  348. data/lib/sequel/plugins/tree.rb +62 -32
  349. data/lib/sequel/plugins/typecast_on_load.rb +12 -4
  350. data/lib/sequel/plugins/unlimited_update.rb +1 -7
  351. data/lib/sequel/plugins/unused_associations.rb +521 -0
  352. data/lib/sequel/plugins/update_or_create.rb +4 -4
  353. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  354. data/lib/sequel/plugins/update_refresh.rb +26 -15
  355. data/lib/sequel/plugins/uuid.rb +7 -11
  356. data/lib/sequel/plugins/validate_associated.rb +18 -0
  357. data/lib/sequel/plugins/validation_class_methods.rb +38 -19
  358. data/lib/sequel/plugins/validation_contexts.rb +49 -0
  359. data/lib/sequel/plugins/validation_helpers.rb +57 -41
  360. data/lib/sequel/plugins/whitelist_security.rb +122 -0
  361. data/lib/sequel/plugins/xml_serializer.rb +30 -31
  362. data/lib/sequel/sql.rb +471 -331
  363. data/lib/sequel/timezones.rb +78 -47
  364. data/lib/sequel/version.rb +7 -2
  365. data/lib/sequel.rb +1 -1
  366. metadata +217 -521
  367. data/Rakefile +0 -164
  368. data/doc/active_record.rdoc +0 -928
  369. data/doc/release_notes/1.0.txt +0 -38
  370. data/doc/release_notes/1.1.txt +0 -143
  371. data/doc/release_notes/1.3.txt +0 -101
  372. data/doc/release_notes/1.4.0.txt +0 -53
  373. data/doc/release_notes/1.5.0.txt +0 -155
  374. data/doc/release_notes/2.0.0.txt +0 -298
  375. data/doc/release_notes/2.1.0.txt +0 -271
  376. data/doc/release_notes/2.10.0.txt +0 -328
  377. data/doc/release_notes/2.11.0.txt +0 -215
  378. data/doc/release_notes/2.12.0.txt +0 -534
  379. data/doc/release_notes/2.2.0.txt +0 -253
  380. data/doc/release_notes/2.3.0.txt +0 -88
  381. data/doc/release_notes/2.4.0.txt +0 -106
  382. data/doc/release_notes/2.5.0.txt +0 -137
  383. data/doc/release_notes/2.6.0.txt +0 -157
  384. data/doc/release_notes/2.7.0.txt +0 -166
  385. data/doc/release_notes/2.8.0.txt +0 -171
  386. data/doc/release_notes/2.9.0.txt +0 -97
  387. data/doc/release_notes/3.0.0.txt +0 -221
  388. data/doc/release_notes/3.1.0.txt +0 -406
  389. data/doc/release_notes/3.10.0.txt +0 -286
  390. data/doc/release_notes/3.11.0.txt +0 -254
  391. data/doc/release_notes/3.12.0.txt +0 -304
  392. data/doc/release_notes/3.13.0.txt +0 -210
  393. data/doc/release_notes/3.14.0.txt +0 -118
  394. data/doc/release_notes/3.15.0.txt +0 -78
  395. data/doc/release_notes/3.16.0.txt +0 -45
  396. data/doc/release_notes/3.17.0.txt +0 -58
  397. data/doc/release_notes/3.18.0.txt +0 -120
  398. data/doc/release_notes/3.19.0.txt +0 -67
  399. data/doc/release_notes/3.2.0.txt +0 -268
  400. data/doc/release_notes/3.20.0.txt +0 -41
  401. data/doc/release_notes/3.21.0.txt +0 -87
  402. data/doc/release_notes/3.22.0.txt +0 -39
  403. data/doc/release_notes/3.23.0.txt +0 -172
  404. data/doc/release_notes/3.24.0.txt +0 -420
  405. data/doc/release_notes/3.25.0.txt +0 -88
  406. data/doc/release_notes/3.26.0.txt +0 -88
  407. data/doc/release_notes/3.27.0.txt +0 -82
  408. data/doc/release_notes/3.28.0.txt +0 -304
  409. data/doc/release_notes/3.29.0.txt +0 -459
  410. data/doc/release_notes/3.3.0.txt +0 -192
  411. data/doc/release_notes/3.30.0.txt +0 -135
  412. data/doc/release_notes/3.31.0.txt +0 -146
  413. data/doc/release_notes/3.32.0.txt +0 -202
  414. data/doc/release_notes/3.33.0.txt +0 -157
  415. data/doc/release_notes/3.34.0.txt +0 -671
  416. data/doc/release_notes/3.35.0.txt +0 -144
  417. data/doc/release_notes/3.36.0.txt +0 -245
  418. data/doc/release_notes/3.37.0.txt +0 -338
  419. data/doc/release_notes/3.38.0.txt +0 -234
  420. data/doc/release_notes/3.39.0.txt +0 -237
  421. data/doc/release_notes/3.4.0.txt +0 -325
  422. data/doc/release_notes/3.40.0.txt +0 -73
  423. data/doc/release_notes/3.41.0.txt +0 -155
  424. data/doc/release_notes/3.42.0.txt +0 -74
  425. data/doc/release_notes/3.43.0.txt +0 -105
  426. data/doc/release_notes/3.44.0.txt +0 -152
  427. data/doc/release_notes/3.45.0.txt +0 -179
  428. data/doc/release_notes/3.46.0.txt +0 -122
  429. data/doc/release_notes/3.47.0.txt +0 -270
  430. data/doc/release_notes/3.48.0.txt +0 -477
  431. data/doc/release_notes/3.5.0.txt +0 -510
  432. data/doc/release_notes/3.6.0.txt +0 -366
  433. data/doc/release_notes/3.7.0.txt +0 -179
  434. data/doc/release_notes/3.8.0.txt +0 -151
  435. data/doc/release_notes/3.9.0.txt +0 -233
  436. data/doc/release_notes/4.0.0.txt +0 -262
  437. data/doc/release_notes/4.1.0.txt +0 -85
  438. data/doc/release_notes/4.10.0.txt +0 -226
  439. data/doc/release_notes/4.11.0.txt +0 -147
  440. data/doc/release_notes/4.12.0.txt +0 -105
  441. data/doc/release_notes/4.13.0.txt +0 -169
  442. data/doc/release_notes/4.14.0.txt +0 -68
  443. data/doc/release_notes/4.15.0.txt +0 -56
  444. data/doc/release_notes/4.16.0.txt +0 -36
  445. data/doc/release_notes/4.17.0.txt +0 -38
  446. data/doc/release_notes/4.18.0.txt +0 -36
  447. data/doc/release_notes/4.19.0.txt +0 -45
  448. data/doc/release_notes/4.2.0.txt +0 -129
  449. data/doc/release_notes/4.20.0.txt +0 -79
  450. data/doc/release_notes/4.21.0.txt +0 -94
  451. data/doc/release_notes/4.22.0.txt +0 -72
  452. data/doc/release_notes/4.23.0.txt +0 -65
  453. data/doc/release_notes/4.24.0.txt +0 -99
  454. data/doc/release_notes/4.25.0.txt +0 -181
  455. data/doc/release_notes/4.26.0.txt +0 -44
  456. data/doc/release_notes/4.27.0.txt +0 -78
  457. data/doc/release_notes/4.28.0.txt +0 -57
  458. data/doc/release_notes/4.29.0.txt +0 -41
  459. data/doc/release_notes/4.3.0.txt +0 -40
  460. data/doc/release_notes/4.30.0.txt +0 -37
  461. data/doc/release_notes/4.31.0.txt +0 -57
  462. data/doc/release_notes/4.32.0.txt +0 -132
  463. data/doc/release_notes/4.33.0.txt +0 -88
  464. data/doc/release_notes/4.34.0.txt +0 -86
  465. data/doc/release_notes/4.35.0.txt +0 -130
  466. data/doc/release_notes/4.36.0.txt +0 -116
  467. data/doc/release_notes/4.4.0.txt +0 -92
  468. data/doc/release_notes/4.5.0.txt +0 -34
  469. data/doc/release_notes/4.6.0.txt +0 -30
  470. data/doc/release_notes/4.7.0.txt +0 -103
  471. data/doc/release_notes/4.8.0.txt +0 -175
  472. data/doc/release_notes/4.9.0.txt +0 -190
  473. data/lib/sequel/adapters/cubrid.rb +0 -144
  474. data/lib/sequel/adapters/do/mysql.rb +0 -66
  475. data/lib/sequel/adapters/do/postgres.rb +0 -44
  476. data/lib/sequel/adapters/do/sqlite3.rb +0 -42
  477. data/lib/sequel/adapters/do.rb +0 -158
  478. data/lib/sequel/adapters/jdbc/as400.rb +0 -84
  479. data/lib/sequel/adapters/jdbc/cubrid.rb +0 -64
  480. data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -36
  481. data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -33
  482. data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -33
  483. data/lib/sequel/adapters/odbc/progress.rb +0 -10
  484. data/lib/sequel/adapters/shared/cubrid.rb +0 -245
  485. data/lib/sequel/adapters/shared/firebird.rb +0 -247
  486. data/lib/sequel/adapters/shared/informix.rb +0 -54
  487. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +0 -152
  488. data/lib/sequel/adapters/shared/progress.rb +0 -40
  489. data/lib/sequel/adapters/swift/mysql.rb +0 -49
  490. data/lib/sequel/adapters/swift/postgres.rb +0 -47
  491. data/lib/sequel/adapters/swift/sqlite.rb +0 -49
  492. data/lib/sequel/adapters/swift.rb +0 -160
  493. data/lib/sequel/adapters/utils/pg_types.rb +0 -70
  494. data/lib/sequel/dataset/mutation.rb +0 -111
  495. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +0 -5
  496. data/lib/sequel/extensions/filter_having.rb +0 -63
  497. data/lib/sequel/extensions/hash_aliases.rb +0 -49
  498. data/lib/sequel/extensions/meta_def.rb +0 -35
  499. data/lib/sequel/extensions/query_literals.rb +0 -84
  500. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +0 -24
  501. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +0 -122
  502. data/lib/sequel/extensions/set_overrides.rb +0 -76
  503. data/lib/sequel/no_core_ext.rb +0 -3
  504. data/lib/sequel/plugins/association_autoreloading.rb +0 -9
  505. data/lib/sequel/plugins/identifier_columns.rb +0 -47
  506. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +0 -9
  507. data/lib/sequel/plugins/pg_typecast_on_load.rb +0 -81
  508. data/lib/sequel/plugins/prepared_statements_associations.rb +0 -119
  509. data/lib/sequel/plugins/prepared_statements_with_pk.rb +0 -61
  510. data/lib/sequel/plugins/schema.rb +0 -82
  511. data/lib/sequel/plugins/scissors.rb +0 -35
  512. data/spec/adapter_spec.rb +0 -4
  513. data/spec/adapters/db2_spec.rb +0 -160
  514. data/spec/adapters/firebird_spec.rb +0 -411
  515. data/spec/adapters/informix_spec.rb +0 -100
  516. data/spec/adapters/mssql_spec.rb +0 -733
  517. data/spec/adapters/mysql_spec.rb +0 -1319
  518. data/spec/adapters/oracle_spec.rb +0 -313
  519. data/spec/adapters/postgres_spec.rb +0 -3790
  520. data/spec/adapters/spec_helper.rb +0 -49
  521. data/spec/adapters/sqlanywhere_spec.rb +0 -170
  522. data/spec/adapters/sqlite_spec.rb +0 -688
  523. data/spec/bin_spec.rb +0 -258
  524. data/spec/core/connection_pool_spec.rb +0 -1045
  525. data/spec/core/database_spec.rb +0 -2636
  526. data/spec/core/dataset_spec.rb +0 -5175
  527. data/spec/core/deprecated_spec.rb +0 -70
  528. data/spec/core/expression_filters_spec.rb +0 -1247
  529. data/spec/core/mock_adapter_spec.rb +0 -464
  530. data/spec/core/object_graph_spec.rb +0 -303
  531. data/spec/core/placeholder_literalizer_spec.rb +0 -163
  532. data/spec/core/schema_generator_spec.rb +0 -203
  533. data/spec/core/schema_spec.rb +0 -1676
  534. data/spec/core/spec_helper.rb +0 -34
  535. data/spec/core/version_spec.rb +0 -7
  536. data/spec/core_extensions_spec.rb +0 -699
  537. data/spec/core_model_spec.rb +0 -2
  538. data/spec/core_spec.rb +0 -1
  539. data/spec/extensions/accessed_columns_spec.rb +0 -51
  540. data/spec/extensions/active_model_spec.rb +0 -85
  541. data/spec/extensions/after_initialize_spec.rb +0 -24
  542. data/spec/extensions/arbitrary_servers_spec.rb +0 -109
  543. data/spec/extensions/association_dependencies_spec.rb +0 -117
  544. data/spec/extensions/association_pks_spec.rb +0 -405
  545. data/spec/extensions/association_proxies_spec.rb +0 -86
  546. data/spec/extensions/auto_validations_spec.rb +0 -192
  547. data/spec/extensions/before_after_save_spec.rb +0 -40
  548. data/spec/extensions/blacklist_security_spec.rb +0 -88
  549. data/spec/extensions/blank_spec.rb +0 -69
  550. data/spec/extensions/boolean_readers_spec.rb +0 -93
  551. data/spec/extensions/boolean_subsets_spec.rb +0 -47
  552. data/spec/extensions/caching_spec.rb +0 -270
  553. data/spec/extensions/class_table_inheritance_spec.rb +0 -444
  554. data/spec/extensions/column_conflicts_spec.rb +0 -60
  555. data/spec/extensions/column_select_spec.rb +0 -108
  556. data/spec/extensions/columns_introspection_spec.rb +0 -91
  557. data/spec/extensions/composition_spec.rb +0 -242
  558. data/spec/extensions/connection_expiration_spec.rb +0 -121
  559. data/spec/extensions/connection_validator_spec.rb +0 -127
  560. data/spec/extensions/constraint_validations_plugin_spec.rb +0 -288
  561. data/spec/extensions/constraint_validations_spec.rb +0 -389
  562. data/spec/extensions/core_refinements_spec.rb +0 -519
  563. data/spec/extensions/csv_serializer_spec.rb +0 -180
  564. data/spec/extensions/current_datetime_timestamp_spec.rb +0 -27
  565. data/spec/extensions/dataset_associations_spec.rb +0 -343
  566. data/spec/extensions/dataset_source_alias_spec.rb +0 -51
  567. data/spec/extensions/date_arithmetic_spec.rb +0 -167
  568. data/spec/extensions/defaults_setter_spec.rb +0 -102
  569. data/spec/extensions/delay_add_association_spec.rb +0 -74
  570. data/spec/extensions/dirty_spec.rb +0 -180
  571. data/spec/extensions/duplicate_columns_handler_spec.rb +0 -110
  572. data/spec/extensions/eager_each_spec.rb +0 -66
  573. data/spec/extensions/empty_array_consider_nulls_spec.rb +0 -24
  574. data/spec/extensions/error_splitter_spec.rb +0 -18
  575. data/spec/extensions/error_sql_spec.rb +0 -20
  576. data/spec/extensions/eval_inspect_spec.rb +0 -73
  577. data/spec/extensions/filter_having_spec.rb +0 -40
  578. data/spec/extensions/force_encoding_spec.rb +0 -114
  579. data/spec/extensions/from_block_spec.rb +0 -21
  580. data/spec/extensions/graph_each_spec.rb +0 -119
  581. data/spec/extensions/hash_aliases_spec.rb +0 -24
  582. data/spec/extensions/hook_class_methods_spec.rb +0 -429
  583. data/spec/extensions/identifier_columns_spec.rb +0 -17
  584. data/spec/extensions/inflector_spec.rb +0 -183
  585. data/spec/extensions/input_transformer_spec.rb +0 -54
  586. data/spec/extensions/insert_returning_select_spec.rb +0 -46
  587. data/spec/extensions/instance_filters_spec.rb +0 -79
  588. data/spec/extensions/instance_hooks_spec.rb +0 -276
  589. data/spec/extensions/inverted_subsets_spec.rb +0 -33
  590. data/spec/extensions/json_serializer_spec.rb +0 -304
  591. data/spec/extensions/lazy_attributes_spec.rb +0 -170
  592. data/spec/extensions/list_spec.rb +0 -278
  593. data/spec/extensions/looser_typecasting_spec.rb +0 -43
  594. data/spec/extensions/many_through_many_spec.rb +0 -2172
  595. data/spec/extensions/meta_def_spec.rb +0 -21
  596. data/spec/extensions/migration_spec.rb +0 -728
  597. data/spec/extensions/modification_detection_spec.rb +0 -80
  598. data/spec/extensions/mssql_optimistic_locking_spec.rb +0 -91
  599. data/spec/extensions/named_timezones_spec.rb +0 -108
  600. data/spec/extensions/nested_attributes_spec.rb +0 -697
  601. data/spec/extensions/no_auto_literal_strings_spec.rb +0 -65
  602. data/spec/extensions/null_dataset_spec.rb +0 -85
  603. data/spec/extensions/optimistic_locking_spec.rb +0 -128
  604. data/spec/extensions/pagination_spec.rb +0 -118
  605. data/spec/extensions/pg_array_associations_spec.rb +0 -736
  606. data/spec/extensions/pg_array_ops_spec.rb +0 -143
  607. data/spec/extensions/pg_array_spec.rb +0 -390
  608. data/spec/extensions/pg_enum_spec.rb +0 -92
  609. data/spec/extensions/pg_hstore_ops_spec.rb +0 -236
  610. data/spec/extensions/pg_hstore_spec.rb +0 -206
  611. data/spec/extensions/pg_inet_ops_spec.rb +0 -101
  612. data/spec/extensions/pg_inet_spec.rb +0 -52
  613. data/spec/extensions/pg_interval_spec.rb +0 -76
  614. data/spec/extensions/pg_json_ops_spec.rb +0 -275
  615. data/spec/extensions/pg_json_spec.rb +0 -218
  616. data/spec/extensions/pg_loose_count_spec.rb +0 -17
  617. data/spec/extensions/pg_range_ops_spec.rb +0 -58
  618. data/spec/extensions/pg_range_spec.rb +0 -473
  619. data/spec/extensions/pg_row_ops_spec.rb +0 -60
  620. data/spec/extensions/pg_row_plugin_spec.rb +0 -62
  621. data/spec/extensions/pg_row_spec.rb +0 -360
  622. data/spec/extensions/pg_static_cache_updater_spec.rb +0 -92
  623. data/spec/extensions/pg_typecast_on_load_spec.rb +0 -63
  624. data/spec/extensions/prepared_statements_associations_spec.rb +0 -159
  625. data/spec/extensions/prepared_statements_safe_spec.rb +0 -61
  626. data/spec/extensions/prepared_statements_spec.rb +0 -103
  627. data/spec/extensions/prepared_statements_with_pk_spec.rb +0 -31
  628. data/spec/extensions/pretty_table_spec.rb +0 -92
  629. data/spec/extensions/query_literals_spec.rb +0 -183
  630. data/spec/extensions/query_spec.rb +0 -102
  631. data/spec/extensions/rcte_tree_spec.rb +0 -392
  632. data/spec/extensions/round_timestamps_spec.rb +0 -43
  633. data/spec/extensions/schema_caching_spec.rb +0 -41
  634. data/spec/extensions/schema_dumper_spec.rb +0 -814
  635. data/spec/extensions/schema_spec.rb +0 -117
  636. data/spec/extensions/scissors_spec.rb +0 -26
  637. data/spec/extensions/select_remove_spec.rb +0 -38
  638. data/spec/extensions/sequel_3_dataset_methods_spec.rb +0 -101
  639. data/spec/extensions/serialization_modification_detection_spec.rb +0 -98
  640. data/spec/extensions/serialization_spec.rb +0 -362
  641. data/spec/extensions/server_block_spec.rb +0 -90
  642. data/spec/extensions/server_logging_spec.rb +0 -45
  643. data/spec/extensions/set_overrides_spec.rb +0 -61
  644. data/spec/extensions/sharding_spec.rb +0 -198
  645. data/spec/extensions/shared_caching_spec.rb +0 -175
  646. data/spec/extensions/single_table_inheritance_spec.rb +0 -297
  647. data/spec/extensions/singular_table_names_spec.rb +0 -22
  648. data/spec/extensions/skip_create_refresh_spec.rb +0 -17
  649. data/spec/extensions/spec_helper.rb +0 -71
  650. data/spec/extensions/split_array_nil_spec.rb +0 -24
  651. data/spec/extensions/split_values_spec.rb +0 -22
  652. data/spec/extensions/sql_comments_spec.rb +0 -27
  653. data/spec/extensions/sql_expr_spec.rb +0 -60
  654. data/spec/extensions/static_cache_spec.rb +0 -361
  655. data/spec/extensions/string_agg_spec.rb +0 -85
  656. data/spec/extensions/string_date_time_spec.rb +0 -95
  657. data/spec/extensions/string_stripper_spec.rb +0 -68
  658. data/spec/extensions/subclasses_spec.rb +0 -66
  659. data/spec/extensions/subset_conditions_spec.rb +0 -38
  660. data/spec/extensions/table_select_spec.rb +0 -71
  661. data/spec/extensions/tactical_eager_loading_spec.rb +0 -136
  662. data/spec/extensions/thread_local_timezones_spec.rb +0 -67
  663. data/spec/extensions/timestamps_spec.rb +0 -175
  664. data/spec/extensions/to_dot_spec.rb +0 -154
  665. data/spec/extensions/touch_spec.rb +0 -203
  666. data/spec/extensions/tree_spec.rb +0 -274
  667. data/spec/extensions/typecast_on_load_spec.rb +0 -80
  668. data/spec/extensions/unlimited_update_spec.rb +0 -20
  669. data/spec/extensions/update_or_create_spec.rb +0 -87
  670. data/spec/extensions/update_primary_key_spec.rb +0 -100
  671. data/spec/extensions/update_refresh_spec.rb +0 -53
  672. data/spec/extensions/uuid_spec.rb +0 -106
  673. data/spec/extensions/validate_associated_spec.rb +0 -52
  674. data/spec/extensions/validation_class_methods_spec.rb +0 -1027
  675. data/spec/extensions/validation_helpers_spec.rb +0 -554
  676. data/spec/extensions/xml_serializer_spec.rb +0 -207
  677. data/spec/files/bad_down_migration/001_create_alt_basic.rb +0 -4
  678. data/spec/files/bad_down_migration/002_create_alt_advanced.rb +0 -4
  679. data/spec/files/bad_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  680. data/spec/files/bad_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  681. data/spec/files/bad_timestamped_migrations/1273253853_3_create_users.rb +0 -3
  682. data/spec/files/bad_up_migration/001_create_alt_basic.rb +0 -4
  683. data/spec/files/bad_up_migration/002_create_alt_advanced.rb +0 -3
  684. data/spec/files/convert_to_timestamp_migrations/001_create_sessions.rb +0 -9
  685. data/spec/files/convert_to_timestamp_migrations/002_create_nodes.rb +0 -9
  686. data/spec/files/convert_to_timestamp_migrations/003_3_create_users.rb +0 -4
  687. data/spec/files/convert_to_timestamp_migrations/1273253850_create_artists.rb +0 -9
  688. data/spec/files/convert_to_timestamp_migrations/1273253852_create_albums.rb +0 -9
  689. data/spec/files/double_migration/001_create_sessions.rb +0 -9
  690. data/spec/files/double_migration/002_create_nodes.rb +0 -19
  691. data/spec/files/double_migration/003_3_create_users.rb +0 -4
  692. data/spec/files/duplicate_integer_migrations/001_create_alt_advanced.rb +0 -4
  693. data/spec/files/duplicate_integer_migrations/001_create_alt_basic.rb +0 -4
  694. data/spec/files/duplicate_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  695. data/spec/files/duplicate_timestamped_migrations/1273253853_create_nodes.rb +0 -9
  696. data/spec/files/duplicate_timestamped_migrations/1273253853_create_users.rb +0 -4
  697. data/spec/files/empty_migration/001_create_sessions.rb +0 -9
  698. data/spec/files/empty_migration/002_create_nodes.rb +0 -0
  699. data/spec/files/empty_migration/003_3_create_users.rb +0 -4
  700. data/spec/files/integer_migrations/001_create_sessions.rb +0 -9
  701. data/spec/files/integer_migrations/002_create_nodes.rb +0 -9
  702. data/spec/files/integer_migrations/003_3_create_users.rb +0 -4
  703. data/spec/files/interleaved_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  704. data/spec/files/interleaved_timestamped_migrations/1273253850_create_artists.rb +0 -9
  705. data/spec/files/interleaved_timestamped_migrations/1273253851_create_nodes.rb +0 -9
  706. data/spec/files/interleaved_timestamped_migrations/1273253852_create_albums.rb +0 -9
  707. data/spec/files/interleaved_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  708. data/spec/files/missing_integer_migrations/001_create_alt_basic.rb +0 -4
  709. data/spec/files/missing_integer_migrations/003_create_alt_advanced.rb +0 -4
  710. data/spec/files/missing_timestamped_migrations/1273253849_create_sessions.rb +0 -9
  711. data/spec/files/missing_timestamped_migrations/1273253853_3_create_users.rb +0 -4
  712. data/spec/files/reversible_migrations/001_reversible.rb +0 -5
  713. data/spec/files/reversible_migrations/002_reversible.rb +0 -5
  714. data/spec/files/reversible_migrations/003_reversible.rb +0 -5
  715. data/spec/files/reversible_migrations/004_reversible.rb +0 -5
  716. data/spec/files/reversible_migrations/005_reversible.rb +0 -10
  717. data/spec/files/reversible_migrations/006_reversible.rb +0 -10
  718. data/spec/files/reversible_migrations/007_reversible.rb +0 -10
  719. data/spec/files/timestamped_migrations/1273253849_create_sessions.rb +0 -9
  720. data/spec/files/timestamped_migrations/1273253851_create_nodes.rb +0 -9
  721. data/spec/files/timestamped_migrations/1273253853_3_create_users.rb +0 -4
  722. data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +0 -4
  723. data/spec/files/transaction_specified_migrations/002_create_basic.rb +0 -4
  724. data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +0 -3
  725. data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +0 -3
  726. data/spec/files/uppercase_timestamped_migrations/1273253849_CREATE_SESSIONS.RB +0 -9
  727. data/spec/files/uppercase_timestamped_migrations/1273253851_CREATE_NODES.RB +0 -9
  728. data/spec/files/uppercase_timestamped_migrations/1273253853_3_CREATE_USERS.RB +0 -4
  729. data/spec/guards_helper.rb +0 -55
  730. data/spec/integration/associations_test.rb +0 -2506
  731. data/spec/integration/database_test.rb +0 -113
  732. data/spec/integration/dataset_test.rb +0 -1858
  733. data/spec/integration/eager_loader_test.rb +0 -687
  734. data/spec/integration/migrator_test.rb +0 -262
  735. data/spec/integration/model_test.rb +0 -230
  736. data/spec/integration/plugin_test.rb +0 -2297
  737. data/spec/integration/prepared_statement_test.rb +0 -467
  738. data/spec/integration/schema_test.rb +0 -815
  739. data/spec/integration/spec_helper.rb +0 -56
  740. data/spec/integration/timezone_test.rb +0 -86
  741. data/spec/integration/transaction_test.rb +0 -406
  742. data/spec/integration/type_test.rb +0 -133
  743. data/spec/model/association_reflection_spec.rb +0 -565
  744. data/spec/model/associations_spec.rb +0 -4589
  745. data/spec/model/base_spec.rb +0 -759
  746. data/spec/model/class_dataset_methods_spec.rb +0 -150
  747. data/spec/model/dataset_methods_spec.rb +0 -149
  748. data/spec/model/eager_loading_spec.rb +0 -2197
  749. data/spec/model/hooks_spec.rb +0 -604
  750. data/spec/model/inflector_spec.rb +0 -26
  751. data/spec/model/model_spec.rb +0 -1097
  752. data/spec/model/plugins_spec.rb +0 -299
  753. data/spec/model/record_spec.rb +0 -2162
  754. data/spec/model/spec_helper.rb +0 -46
  755. data/spec/model/validations_spec.rb +0 -193
  756. data/spec/model_no_assoc_spec.rb +0 -1
  757. data/spec/model_spec.rb +0 -1
  758. data/spec/plugin_spec.rb +0 -1
  759. data/spec/sequel_coverage.rb +0 -15
  760. data/spec/spec_config.rb +0 -10
@@ -1,130 +1,74 @@
1
1
  # frozen-string-literal: true
2
2
 
3
- Sequel.require 'adapters/shared/postgres'
3
+ require_relative 'shared/postgres'
4
4
 
5
5
  begin
6
6
  require 'pg'
7
7
 
8
+ # :nocov:
9
+ Sequel::Postgres::PGError = PG::Error if defined?(PG::Error)
10
+ Sequel::Postgres::PGconn = PG::Connection if defined?(PG::Connection)
11
+ Sequel::Postgres::PGresult = PG::Result if defined?(PG::Result)
12
+
8
13
  # Work around postgres-pr 0.7.0+ which ships with a pg.rb file
9
- raise LoadError unless defined?(PGconn::CONNECTION_OK)
14
+ unless defined?(PG::Connection)
15
+ raise LoadError unless defined?(PGconn::CONNECTION_OK)
16
+ end
10
17
 
11
- SEQUEL_POSTGRES_USES_PG = true
18
+ if defined?(PG::TypeMapByClass)
19
+ # :nocov:
20
+ type_map = Sequel::Postgres::PG_QUERY_TYPE_MAP = PG::TypeMapByClass.new
21
+ type_map[Integer] = PG::TextEncoder::Integer.new
22
+ type_map[FalseClass] = type_map[TrueClass] = PG::TextEncoder::Boolean.new
23
+ type_map[Float] = PG::TextEncoder::Float.new
24
+ end
25
+
26
+ Sequel::Postgres::USES_PG = true
12
27
  rescue LoadError => e
13
- SEQUEL_POSTGRES_USES_PG = false
28
+ # :nocov:
14
29
  begin
15
- require 'postgres'
16
- # Attempt to get uniform behavior for the PGconn object no matter
17
- # if pg, postgres, or postgres-pr is used.
18
- class PGconn
19
- unless method_defined?(:escape_string)
20
- if self.respond_to?(:escape)
21
- # If there is no escape_string instance method, but there is an
22
- # escape class method, use that instead.
23
- def escape_string(str)
24
- Sequel::Postgres.force_standard_strings ? str.gsub("'", "''") : self.class.escape(str)
25
- end
26
- else
27
- # Raise an error if no valid string escaping method can be found.
28
- def escape_string(obj)
29
- if Sequel::Postgres.force_standard_strings
30
- str.gsub("'", "''")
31
- else
32
- raise Sequel::Error, "string escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
33
- end
34
- end
35
- end
36
- end
37
- unless method_defined?(:escape_bytea)
38
- if self.respond_to?(:escape_bytea)
39
- # If there is no escape_bytea instance method, but there is an
40
- # escape_bytea class method, use that instead.
41
- def escape_bytea(obj)
42
- self.class.escape_bytea(obj)
43
- end
44
- else
45
- begin
46
- require 'postgres-pr/typeconv/conv'
47
- require 'postgres-pr/typeconv/bytea'
48
- extend Postgres::Conversion
49
- # If we are using postgres-pr, use the encode_bytea method from
50
- # that.
51
- def escape_bytea(obj)
52
- self.class.encode_bytea(obj)
53
- end
54
- instance_eval{alias unescape_bytea decode_bytea}
55
- rescue
56
- # If no valid bytea escaping method can be found, create one that
57
- # raises an error
58
- def escape_bytea(obj)
59
- raise Sequel::Error, "bytea escaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
60
- end
61
- # If no valid bytea unescaping method can be found, create one that
62
- # raises an error
63
- def self.unescape_bytea(obj)
64
- raise Sequel::Error, "bytea unescaping not supported with this postgres driver. Try using ruby-pg, ruby-postgres, or postgres-pr."
65
- end
66
- end
67
- end
68
- end
69
- alias_method :finish, :close unless method_defined?(:finish)
70
- alias_method :async_exec, :exec unless method_defined?(:async_exec)
71
- unless method_defined?(:block)
72
- def block(timeout=nil)
73
- end
74
- end
75
- unless defined?(CONNECTION_OK)
76
- CONNECTION_OK = -1
77
- end
78
- unless method_defined?(:status)
79
- def status
80
- CONNECTION_OK
81
- end
82
- end
83
- end
84
- class PGresult
85
- alias_method :nfields, :num_fields unless method_defined?(:nfields)
86
- alias_method :ntuples, :num_tuples unless method_defined?(:ntuples)
87
- alias_method :ftype, :type unless method_defined?(:ftype)
88
- alias_method :fname, :fieldname unless method_defined?(:fname)
89
- alias_method :cmd_tuples, :cmdtuples unless method_defined?(:cmd_tuples)
90
- end
30
+ require 'sequel/postgres-pr'
91
31
  rescue LoadError
92
- raise e
32
+ begin
33
+ require 'postgres-pr/postgres-compat'
34
+ rescue LoadError
35
+ raise e
36
+ end
93
37
  end
38
+ Sequel::Postgres::USES_PG = false
39
+ # :nocov:
94
40
  end
95
41
 
96
42
  module Sequel
97
- Dataset::NON_SQL_OPTIONS << :cursor
98
43
  module Postgres
99
- CONVERTED_EXCEPTIONS << PGError
100
-
101
- PG_TYPES[17] = Class.new do
102
- def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
103
- end.new.method(:bytea)
104
-
105
- @use_iso_date_format = true
106
-
107
- class << self
108
- # As an optimization, Sequel sets the date style to ISO, so that PostgreSQL provides
109
- # the date in a known format that Sequel can parse faster. This can be turned off
110
- # if you require a date style other than ISO.
111
- attr_accessor :use_iso_date_format
44
+ # :nocov:
45
+ if USES_PG
46
+ # Whether the given sequel_pg version integer is supported.
47
+ def self.sequel_pg_version_supported?(version)
48
+ version >= 10617
49
+ end
112
50
  end
51
+ # :nocov:
113
52
 
114
53
  # PGconn subclass for connection specific methods used with the
115
- # pg, postgres, or postgres-pr driver.
116
- class Adapter < ::PGconn
54
+ # pg or postgres-pr driver.
55
+ class Adapter < PGconn
117
56
  # The underlying exception classes to reraise as disconnect errors
118
57
  # instead of regular database errors.
119
58
  DISCONNECT_ERROR_CLASSES = [IOError, Errno::EPIPE, Errno::ECONNRESET]
59
+ # :nocov:
120
60
  if defined?(::PG::ConnectionBad)
61
+ # :nocov:
121
62
  DISCONNECT_ERROR_CLASSES << ::PG::ConnectionBad
122
63
  end
64
+ DISCONNECT_ERROR_CLASSES.freeze
123
65
 
124
66
  disconnect_errors = [
67
+ 'ERROR: cached plan must not change result type',
125
68
  'could not receive data from server',
126
69
  'no connection to the server',
127
70
  'connection not open',
71
+ 'connection is closed',
128
72
  'terminating connection due to administrator command',
129
73
  'PQconsumeInput() '
130
74
  ]
@@ -134,36 +78,78 @@ module Sequel
134
78
  # errors.
135
79
  DISCONNECT_ERROR_RE = /\A#{Regexp.union(disconnect_errors)}/
136
80
 
137
- self.translate_results = false if respond_to?(:translate_results=)
138
-
139
- # Hash of prepared statements for this connection. Keys are
140
- # string names of the server side prepared statement, and values
141
- # are SQL strings.
142
- attr_reader(:prepared_statements) if SEQUEL_POSTGRES_USES_PG
81
+ if USES_PG
82
+ # Hash of prepared statements for this connection. Keys are
83
+ # string names of the server side prepared statement, and values
84
+ # are SQL strings.
85
+ attr_reader :prepared_statements
86
+
87
+ # :nocov:
88
+ unless public_method_defined?(:async_exec_params)
89
+ alias async_exec_params async_exec
90
+ end
91
+ elsif !const_defined?(:CONNECTION_OK)
92
+ # Handle old postgres-pr
93
+ # sequel-postgres-pr already implements this API
94
+
95
+ CONNECTION_OK = -1
96
+
97
+ # Escape bytea values. Uses historical format instead of hex
98
+ # format for maximum compatibility.
99
+ def escape_bytea(str)
100
+ str.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{sprintf('%o', b.each_byte{|x| break x}).rjust(3, '0')}"}
101
+ end
102
+
103
+ # Escape strings by doubling apostrophes. This only works if standard
104
+ # conforming strings are used.
105
+ def escape_string(str)
106
+ str.gsub("'", "''")
107
+ end
108
+
109
+ alias finish close
110
+
111
+ def async_exec(sql)
112
+ PGresult.new(@conn.query(sql))
113
+ end
114
+
115
+ def block(timeout=nil)
116
+ end
117
+
118
+ def status
119
+ CONNECTION_OK
120
+ end
121
+
122
+ class PGresult < ::PGresult
123
+ alias nfields num_fields
124
+ alias ntuples num_tuples
125
+ alias ftype type
126
+ alias fname fieldname
127
+ alias cmd_tuples cmdtuples
128
+ end
129
+ end
130
+ # :nocov:
143
131
 
144
132
  # Raise a Sequel::DatabaseDisconnectError if a one of the disconnect
145
133
  # error classes is raised, or a PGError is raised and the connection
146
134
  # status cannot be determined or it is not OK.
147
135
  def check_disconnect_errors
136
+ yield
137
+ rescue *DISCONNECT_ERROR_CLASSES => e
138
+ disconnect = true
139
+ raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError))
140
+ rescue PGError => e
141
+ disconnect = false
148
142
  begin
149
- yield
150
- rescue *DISCONNECT_ERROR_CLASSES => e
143
+ s = status
144
+ rescue PGError
151
145
  disconnect = true
152
- raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError))
153
- rescue PGError => e
154
- disconnect = false
155
- begin
156
- s = status
157
- rescue PGError
158
- disconnect = true
159
- end
160
- status_ok = (s == Adapter::CONNECTION_OK)
161
- disconnect ||= !status_ok
162
- disconnect ||= e.message =~ DISCONNECT_ERROR_RE
163
- disconnect ? raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)) : raise
164
- ensure
165
- block if status_ok && !disconnect
166
146
  end
147
+ status_ok = (s == Adapter::CONNECTION_OK)
148
+ disconnect ||= !status_ok
149
+ disconnect ||= e.message =~ DISCONNECT_ERROR_RE
150
+ disconnect ? raise(Sequel.convert_exception_class(e, Sequel::DatabaseDisconnectError)) : raise
151
+ ensure
152
+ block if status_ok && !disconnect
167
153
  end
168
154
 
169
155
  # Execute the given SQL with this connection. If a block is given,
@@ -172,7 +158,7 @@ module Sequel
172
158
  args = args.map{|v| @db.bound_variable_arg(v, self)} if args
173
159
  q = check_disconnect_errors{execute_query(sql, args)}
174
160
  begin
175
- block_given? ? yield(q) : q.cmd_tuples
161
+ defined?(yield) ? yield(q) : q.cmd_tuples
176
162
  ensure
177
163
  q.clear if q && q.respond_to?(:clear)
178
164
  end
@@ -180,40 +166,25 @@ module Sequel
180
166
 
181
167
  private
182
168
 
183
- # Return the PGResult object that is returned by executing the given
184
- # sql and args.
169
+ # Return the PGResult containing the query results.
185
170
  def execute_query(sql, args)
186
- @db.log_connection_yield(sql, self, args){args ? async_exec(sql, args) : async_exec(sql)}
171
+ @db.log_connection_yield(sql, self, args){args ? async_exec_params(sql, args) : async_exec(sql)}
187
172
  end
188
173
  end
189
174
 
190
- # Database class for PostgreSQL databases used with Sequel and the
191
- # pg, postgres, or postgres-pr driver.
192
175
  class Database < Sequel::Database
193
176
  include Sequel::Postgres::DatabaseMethods
194
177
 
195
- INFINITE_TIMESTAMP_STRINGS = ['infinity'.freeze, '-infinity'.freeze].freeze
196
- INFINITE_DATETIME_VALUES = ([PLUS_INFINITY, MINUS_INFINITY] + INFINITE_TIMESTAMP_STRINGS).freeze
197
-
198
178
  set_adapter_scheme :postgresql
199
179
  set_adapter_scheme :postgres
200
180
 
201
- # Whether infinite timestamps/dates should be converted on retrieval. By default, no
202
- # conversion is done, so an error is raised if you attempt to retrieve an infinite
203
- # timestamp/date. You can set this to :nil to convert to nil, :string to leave
204
- # as a string, or :float to convert to an infinite float.
205
- attr_reader :convert_infinite_timestamps
206
-
207
181
  # Convert given argument so that it can be used directly by pg. Currently, pg doesn't
208
- # handle fractional seconds in Time/DateTime or blobs with "\0", and it won't ever
209
- # handle Sequel::SQLTime values correctly. Only public for use by the adapter, shouldn't
210
- # be used by external code.
182
+ # handle fractional seconds in Time/DateTime or blobs with "\0". Only public for use by
183
+ # the adapter, shouldn't be used by external code.
211
184
  def bound_variable_arg(arg, conn)
212
185
  case arg
213
186
  when Sequel::SQL::Blob
214
187
  {:value=>arg, :type=>17, :format=>1}
215
- when Sequel::SQLTime
216
- literal(arg)
217
188
  when DateTime, Time
218
189
  literal(arg)
219
190
  else
@@ -221,33 +192,57 @@ module Sequel
221
192
  end
222
193
  end
223
194
 
195
+ # Call a procedure with the given name and arguments. Returns a hash if the procedure
196
+ # returns a value, and nil otherwise. Example:
197
+ #
198
+ # DB.call_procedure(:foo, 1, 2)
199
+ # # CALL foo(1, 2)
200
+ def call_procedure(name, *args)
201
+ dataset.send(:call_procedure, name, args)
202
+ end
203
+
224
204
  # Connects to the database. In addition to the standard database
225
205
  # options, using the :encoding or :charset option changes the
226
206
  # client encoding for the connection, :connect_timeout is a
227
207
  # connection timeout in seconds, :sslmode sets whether postgres's
228
208
  # sslmode, and :notice_receiver handles server notices in a proc.
229
- # :connect_timeout, :ssl_mode, and :notice_receiver are only supported
230
- # if the pg driver is used.
209
+ # :connect_timeout, :driver_options, :sslmode, and :notice_receiver
210
+ # are only supported if the pg driver is used.
231
211
  def connect(server)
232
212
  opts = server_opts(server)
233
- if SEQUEL_POSTGRES_USES_PG
213
+ if USES_PG
234
214
  connection_params = {
235
215
  :host => opts[:host],
236
- :port => opts[:port] || 5432,
216
+ :port => opts[:port],
237
217
  :dbname => opts[:database],
238
218
  :user => opts[:user],
239
219
  :password => opts[:password],
240
220
  :connect_timeout => opts[:connect_timeout] || 20,
241
- :sslmode => opts[:sslmode]
221
+ :sslmode => opts[:sslmode],
222
+ :sslrootcert => opts[:sslrootcert]
242
223
  }.delete_if { |key, value| blank_object?(value) }
243
- conn = Adapter.connect(connection_params)
224
+ # :nocov:
225
+ connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
226
+ # :nocov:
227
+ conn = Adapter.connect(opts[:conn_str] || connection_params)
244
228
 
245
229
  conn.instance_variable_set(:@prepared_statements, {})
246
230
 
247
231
  if receiver = opts[:notice_receiver]
248
232
  conn.set_notice_receiver(&receiver)
249
233
  end
234
+
235
+ # :nocov:
236
+ if conn.respond_to?(:type_map_for_queries=) && defined?(PG_QUERY_TYPE_MAP)
237
+ # :nocov:
238
+ conn.type_map_for_queries = PG_QUERY_TYPE_MAP
239
+ end
240
+ # :nocov:
250
241
  else
242
+ unless typecast_value_boolean(@opts.fetch(:force_standard_strings, true))
243
+ raise Error, "Cannot create connection using postgres-pr unless force_standard_strings is set"
244
+ end
245
+
251
246
  conn = Adapter.connect(
252
247
  (opts[:host] unless blank_object?(opts[:host])),
253
248
  opts[:port] || 5432,
@@ -257,9 +252,11 @@ module Sequel
257
252
  opts[:password]
258
253
  )
259
254
  end
255
+ # :nocov:
260
256
 
261
257
  conn.instance_variable_set(:@db, self)
262
258
 
259
+ # :nocov:
263
260
  if encoding = opts[:encoding] || opts[:charset]
264
261
  if conn.respond_to?(:set_client_encoding)
265
262
  conn.set_client_encoding(encoding)
@@ -267,81 +264,89 @@ module Sequel
267
264
  conn.async_exec("set client_encoding to '#{encoding}'")
268
265
  end
269
266
  end
267
+ # :nocov:
270
268
 
271
- connection_configuration_sqls.each{|sql| conn.execute(sql)}
269
+ connection_configuration_sqls(opts).each{|sql| conn.execute(sql)}
272
270
  conn
273
271
  end
274
272
 
275
- # Set whether to allow infinite timestamps/dates. Make sure the
276
- # conversion proc for date reflects that setting.
277
- def convert_infinite_timestamps=(v)
278
- @convert_infinite_timestamps = case v
279
- when Symbol
280
- v
281
- when 'nil'
282
- :nil
283
- when 'string'
284
- :string
285
- when 'float'
286
- :float
287
- when String
288
- typecast_value_boolean(v)
289
- else
290
- false
291
- end
273
+ # Always false, support was moved to pg_extended_date_support extension.
274
+ # Needs to stay defined here so that sequel_pg works.
275
+ def convert_infinite_timestamps
276
+ false
277
+ end
292
278
 
293
- pr = old_pr = @use_iso_date_format ? TYPE_TRANSLATOR.method(:date) : Sequel.method(:string_to_date)
294
- if v
295
- pr = lambda do |val|
296
- case val
297
- when *INFINITE_TIMESTAMP_STRINGS
298
- infinite_timestamp_value(val)
299
- else
300
- old_pr.call(val)
301
- end
302
- end
279
+ # Enable pg_extended_date_support extension if symbol or string is given.
280
+ def convert_infinite_timestamps=(v)
281
+ case v
282
+ when Symbol, String, true
283
+ extension(:pg_extended_date_support)
284
+ self.convert_infinite_timestamps = v
303
285
  end
304
- conversion_procs[1082] = pr
305
286
  end
306
287
 
307
- # Disconnect given connection
308
288
  def disconnect_connection(conn)
309
289
  conn.finish
310
290
  rescue PGError, IOError
311
291
  nil
312
292
  end
313
293
 
314
- if SEQUEL_POSTGRES_USES_PG && Object.const_defined?(:PG) && ::PG.const_defined?(:Constants) && ::PG::Constants.const_defined?(:PG_DIAG_SCHEMA_NAME)
294
+ # :nocov:
295
+ if USES_PG && Object.const_defined?(:PG) && ::PG.const_defined?(:Constants) && ::PG::Constants.const_defined?(:PG_DIAG_SCHEMA_NAME)
296
+ # :nocov:
315
297
  # Return a hash of information about the related PGError (or Sequel::DatabaseError that
316
- # wraps a PGError), with the following entries:
298
+ # wraps a PGError), with the following entries (any of which may be +nil+):
317
299
  #
318
300
  # :schema :: The schema name related to the error
319
301
  # :table :: The table name related to the error
320
302
  # :column :: the column name related to the error
321
303
  # :constraint :: The constraint name related to the error
322
304
  # :type :: The datatype name related to the error
305
+ # :severity :: The severity of the error (e.g. "ERROR")
306
+ # :sql_state :: The SQL state code related to the error
307
+ # :message_primary :: A single line message related to the error
308
+ # :message_detail :: Any detail supplementing the primary message
309
+ # :message_hint :: Possible suggestion about how to fix the problem
310
+ # :statement_position :: Character offset in statement submitted by client where error occurred (starting at 1)
311
+ # :internal_position :: Character offset in internal statement where error occurred (starting at 1)
312
+ # :internal_query :: Text of internally-generated statement where error occurred
313
+ # :source_file :: PostgreSQL source file where the error occurred
314
+ # :source_line :: Line number of PostgreSQL source file where the error occurred
315
+ # :source_function :: Function in PostgreSQL source file where the error occurred
323
316
  #
324
317
  # This requires a PostgreSQL 9.3+ server and 9.3+ client library,
325
318
  # and ruby-pg 0.16.0+ to be supported.
326
319
  def error_info(e)
327
320
  e = e.wrapped_exception if e.is_a?(DatabaseError)
328
321
  r = e.result
329
- h = {}
330
- h[:schema] = r.error_field(::PG::PG_DIAG_SCHEMA_NAME)
331
- h[:table] = r.error_field(::PG::PG_DIAG_TABLE_NAME)
332
- h[:column] = r.error_field(::PG::PG_DIAG_COLUMN_NAME)
333
- h[:constraint] = r.error_field(::PG::PG_DIAG_CONSTRAINT_NAME)
334
- h[:type] = r.error_field(::PG::PG_DIAG_DATATYPE_NAME)
335
- h
322
+ {
323
+ :schema => r.error_field(::PG::PG_DIAG_SCHEMA_NAME),
324
+ :table => r.error_field(::PG::PG_DIAG_TABLE_NAME),
325
+ :column => r.error_field(::PG::PG_DIAG_COLUMN_NAME),
326
+ :constraint => r.error_field(::PG::PG_DIAG_CONSTRAINT_NAME),
327
+ :type => r.error_field(::PG::PG_DIAG_DATATYPE_NAME),
328
+ :severity => r.error_field(::PG::PG_DIAG_SEVERITY),
329
+ :sql_state => r.error_field(::PG::PG_DIAG_SQLSTATE),
330
+ :message_primary => r.error_field(::PG::PG_DIAG_MESSAGE_PRIMARY),
331
+ :message_detail => r.error_field(::PG::PG_DIAG_MESSAGE_DETAIL),
332
+ :message_hint => r.error_field(::PG::PG_DIAG_MESSAGE_HINT),
333
+ :statement_position => r.error_field(::PG::PG_DIAG_STATEMENT_POSITION),
334
+ :internal_position => r.error_field(::PG::PG_DIAG_INTERNAL_POSITION),
335
+ :internal_query => r.error_field(::PG::PG_DIAG_INTERNAL_QUERY),
336
+ :source_file => r.error_field(::PG::PG_DIAG_SOURCE_FILE),
337
+ :source_line => r.error_field(::PG::PG_DIAG_SOURCE_LINE),
338
+ :source_function => r.error_field(::PG::PG_DIAG_SOURCE_FUNCTION)
339
+ }
336
340
  end
337
341
  end
338
342
 
339
- # Execute the given SQL with the given args on an available connection.
340
343
  def execute(sql, opts=OPTS, &block)
341
344
  synchronize(opts[:server]){|conn| check_database_errors{_execute(conn, sql, opts, &block)}}
342
345
  end
343
346
 
344
- if SEQUEL_POSTGRES_USES_PG
347
+ # :nocov:
348
+ if USES_PG
349
+ # :nocov:
345
350
  # +copy_table+ uses PostgreSQL's +COPY TO STDOUT+ SQL statement to return formatted
346
351
  # results directly to the caller. This method is only supported if pg is the
347
352
  # underlying ruby driver. This method should only be called if you want
@@ -354,6 +359,9 @@ module Sequel
354
359
  # a version of PostgreSQL before 9.0, you will probably want to
355
360
  # use a string if you are using any options at all, as the syntax
356
361
  # Sequel uses for options is only compatible with PostgreSQL 9.0+.
362
+ # This should be the full COPY statement passed to PostgreSQL, not
363
+ # just the SELECT query. If a string is given, the :format and
364
+ # :options options are ignored.
357
365
  # Dataset :: Uses a query instead of a table name when copying.
358
366
  # other :: Uses a table name (usually a symbol) when copying.
359
367
  #
@@ -370,18 +378,28 @@ module Sequel
370
378
  synchronize(opts[:server]) do |conn|
371
379
  conn.execute(copy_table_sql(table, opts))
372
380
  begin
373
- if block_given?
381
+ if defined?(yield)
374
382
  while buf = conn.get_copy_data
375
383
  yield buf
376
384
  end
377
- nil
385
+ b = nil
378
386
  else
379
387
  b = String.new
380
388
  b << buf while buf = conn.get_copy_data
381
- b
382
389
  end
390
+
391
+ res = conn.get_last_result
392
+ if !res || res.result_status != 1
393
+ raise PG::NotAllCopyDataRetrieved, "Not all COPY data retrieved"
394
+ end
395
+
396
+ b
397
+ rescue => e
398
+ raise_error(e, :disconnect=>true)
383
399
  ensure
384
- raise DatabaseDisconnectError, "disconnecting as a partial COPY may leave the connection in an unusable state" if buf
400
+ if buf && !e
401
+ raise DatabaseDisconnectError, "disconnecting as a partial COPY may leave the connection in an unusable state"
402
+ end
385
403
  end
386
404
  end
387
405
  end
@@ -410,16 +428,16 @@ module Sequel
410
428
  data = opts[:data]
411
429
  data = Array(data) if data.is_a?(String)
412
430
 
413
- if block_given? && data
431
+ if defined?(yield) && data
414
432
  raise Error, "Cannot provide both a :data option and a block to copy_into"
415
- elsif !block_given? && !data
433
+ elsif !defined?(yield) && !data
416
434
  raise Error, "Must provide either a :data option or a block to copy_into"
417
435
  end
418
436
 
419
437
  synchronize(opts[:server]) do |conn|
420
438
  conn.execute(copy_into_sql(table, opts))
421
439
  begin
422
- if block_given?
440
+ if defined?(yield)
423
441
  while buf = yield
424
442
  conn.put_copy_data(buf)
425
443
  end
@@ -481,7 +499,7 @@ module Sequel
481
499
  raise Error, 'calling #listen with :loop requires a block' unless block
482
500
  loop_call = l.respond_to?(:call)
483
501
  catch(:stop) do
484
- loop do
502
+ while true
485
503
  t = timeout_block ? [timeout_block.call] : []
486
504
  conn.wait_for_notify(*t, &block)
487
505
  l.call(conn) if loop_call
@@ -500,21 +518,6 @@ module Sequel
500
518
  end
501
519
  end
502
520
 
503
- # If convert_infinite_timestamps is true and the value is infinite, return an appropriate
504
- # value based on the convert_infinite_timestamps setting.
505
- def to_application_timestamp(value)
506
- if convert_infinite_timestamps
507
- case value
508
- when *INFINITE_TIMESTAMP_STRINGS
509
- infinite_timestamp_value(value)
510
- else
511
- super
512
- end
513
- else
514
- super
515
- end
516
- end
517
-
518
521
  private
519
522
 
520
523
  # Execute the given SQL string or prepared statement on the connection object.
@@ -534,38 +537,61 @@ module Sequel
534
537
  # Add the primary_keys and primary_key_sequences instance variables,
535
538
  # so we can get the correct return values for inserted rows.
536
539
  def adapter_initialize
537
- @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.use_iso_date_format))
540
+ @use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, true))
538
541
  initialize_postgres_adapter
539
- conversion_procs[1082] = TYPE_TRANSLATOR.method(:date) if @use_iso_date_format
542
+ # :nocov:
543
+ add_conversion_proc(17, method(:unescape_bytea)) if USES_PG
544
+ add_conversion_proc(1082, TYPE_TRANSLATOR_DATE) if @use_iso_date_format
545
+ # :nocov:
540
546
  self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
541
547
  end
542
548
 
543
549
  # Convert exceptions raised from the block into DatabaseErrors.
544
550
  def check_database_errors
545
- begin
546
- yield
547
- rescue => e
548
- raise_error(e, :classes=>CONVERTED_EXCEPTIONS)
549
- end
551
+ yield
552
+ rescue => e
553
+ raise_error(e, :classes=>database_error_classes)
550
554
  end
551
-
552
555
  # Set the DateStyle to ISO if configured, for faster date parsing.
553
- def connection_configuration_sqls
556
+ def connection_configuration_sqls(opts=@opts)
554
557
  sqls = super
558
+ # :nocov:
555
559
  sqls << "SET DateStyle = 'ISO'" if @use_iso_date_format
560
+ # :nocov:
556
561
  sqls
557
562
  end
558
563
 
564
+ # :nocov:
565
+ if USES_PG
566
+ def unescape_bytea(s)
567
+ ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s))
568
+ end
569
+ end
570
+ # :nocov:
571
+
572
+ DATABASE_ERROR_CLASSES = [PGError].freeze
559
573
  def database_error_classes
560
- [PGError]
574
+ DATABASE_ERROR_CLASSES
575
+ end
576
+
577
+ def disconnect_error?(exception, opts)
578
+ super ||
579
+ Adapter::DISCONNECT_ERROR_CLASSES.any?{|klass| exception.is_a?(klass)} ||
580
+ exception.message =~ Adapter::DISCONNECT_ERROR_RE
561
581
  end
562
582
 
563
583
  def database_exception_sqlstate(exception, opts)
584
+ # :nocov:
564
585
  if exception.respond_to?(:result) && (result = exception.result)
565
- result.error_field(::PGresult::PG_DIAG_SQLSTATE)
586
+ # :nocov:
587
+ result.error_field(PGresult::PG_DIAG_SQLSTATE)
566
588
  end
567
589
  end
568
590
 
591
+ def dataset_class_default
592
+ Dataset
593
+ end
594
+
569
595
  # Execute the prepared statement with the given name on an available
570
596
  # connection, using the given args. If the connection has not prepared
571
597
  # a statement with the given name yet, prepare it. If the connection
@@ -597,73 +623,25 @@ module Sequel
597
623
 
598
624
  q = conn.check_disconnect_errors{log_connection_yield(log_sql, conn, args){_execute_prepared_statement(conn, ps_name, args, opts)}}
599
625
  begin
600
- block_given? ? yield(q) : q.cmd_tuples
626
+ defined?(yield) ? yield(q) : q.cmd_tuples
601
627
  ensure
602
628
  q.clear if q && q.respond_to?(:clear)
603
629
  end
604
630
  end
605
631
 
606
- # Return an appropriate value for the given infinite timestamp string.
607
- def infinite_timestamp_value(value)
608
- case convert_infinite_timestamps
609
- when :nil
610
- nil
611
- when :string
612
- value
613
- else
614
- value == 'infinity' ? PLUS_INFINITY : MINUS_INFINITY
615
- end
616
- end
617
-
618
632
  # Don't log, since logging is done by the underlying connection.
619
633
  def log_connection_execute(conn, sql)
620
634
  conn.execute(sql)
621
635
  end
622
636
 
623
- # If the value is an infinite value (either an infinite float or a string returned by
624
- # by PostgreSQL for an infinite timestamp), return it without converting it if
625
- # convert_infinite_timestamps is set.
626
- def typecast_value_date(value)
627
- if convert_infinite_timestamps
628
- case value
629
- when *INFINITE_DATETIME_VALUES
630
- value
631
- else
632
- super
633
- end
634
- else
635
- super
636
- end
637
- end
638
-
639
- # If the value is an infinite value (either an infinite float or a string returned by
640
- # by PostgreSQL for an infinite timestamp), return it without converting it if
641
- # convert_infinite_timestamps is set.
642
- def typecast_value_datetime(value)
643
- if convert_infinite_timestamps
644
- case value
645
- when *INFINITE_DATETIME_VALUES
646
- value
647
- else
648
- super
649
- end
650
- else
651
- super
652
- end
637
+ def rollback_transaction(conn, opts=OPTS)
638
+ super unless conn.transaction_status == 0
653
639
  end
654
640
  end
655
641
 
656
- # Dataset class for PostgreSQL datasets that use the pg, postgres, or
657
- # postgres-pr driver.
658
642
  class Dataset < Sequel::Dataset
659
643
  include Sequel::Postgres::DatasetMethods
660
644
 
661
- Database::DatasetClass = self
662
- APOS = Sequel::Dataset::APOS
663
- DEFAULT_CURSOR_NAME = 'sequel_cursor'.freeze
664
-
665
- # Yield all rows returned by executing the given SQL and converting
666
- # the types.
667
645
  def fetch_rows(sql)
668
646
  return cursor_fetch_rows(sql){|h| yield h} if @opts[:cursor]
669
647
  execute(sql){|res| yield_hash_rows(res, fetch_rows_set_cols(res)){|h| yield h}}
@@ -671,6 +649,9 @@ module Sequel
671
649
 
672
650
  # Use a cursor for paging.
673
651
  def paged_each(opts=OPTS, &block)
652
+ unless defined?(yield)
653
+ return enum_for(:paged_each, opts)
654
+ end
674
655
  use_cursor(opts).each(&block)
675
656
  end
676
657
 
@@ -691,8 +672,8 @@ module Sequel
691
672
  # Usage:
692
673
  #
693
674
  # DB[:huge_table].use_cursor.each{|row| p row}
694
- # DB[:huge_table].use_cursor(:rows_per_fetch=>10000).each{|row| p row}
695
- # DB[:huge_table].use_cursor(:cursor_name=>'my_cursor').each{|row| p row}
675
+ # DB[:huge_table].use_cursor(rows_per_fetch: 10000).each{|row| p row}
676
+ # DB[:huge_table].use_cursor(cursor_name: 'my_cursor').each{|row| p row}
696
677
  #
697
678
  # This is untested with the prepared statement/bound variable support,
698
679
  # and unlikely to work with either.
@@ -705,15 +686,16 @@ module Sequel
705
686
  # large dataset by updating individual rows while processing the dataset
706
687
  # via a cursor:
707
688
  #
708
- # DB[:huge_table].use_cursor(:rows_per_fetch=>1).each do |row|
709
- # DB[:huge_table].where_current_of.update(:column=>ruby_method(row))
689
+ # DB[:huge_table].use_cursor(rows_per_fetch: 1).each do |row|
690
+ # DB[:huge_table].where_current_of.update(column: ruby_method(row))
710
691
  # end
711
- def where_current_of(cursor_name=DEFAULT_CURSOR_NAME)
692
+ def where_current_of(cursor_name='sequel_cursor')
712
693
  clone(:where=>Sequel.lit(['CURRENT OF '], Sequel.identifier(cursor_name)))
713
694
  end
714
695
 
715
- if SEQUEL_POSTGRES_USES_PG
716
-
696
+ # :nocov:
697
+ if USES_PG
698
+ # :nocov:
717
699
  PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
718
700
 
719
701
  # PostgreSQL specific argument mapper used for mapping the named
@@ -741,44 +723,21 @@ module Sequel
741
723
  end
742
724
  LiteralString.new("#{prepared_arg_placeholder}#{i}")
743
725
  end
744
-
745
- # Always assume a prepared argument.
746
- def prepared_arg?(k)
747
- true
748
- end
749
726
  end
750
727
 
751
- BindArgumentMethods = prepared_statements_module(:bind, [ArgumentMapper, ::Sequel::Postgres::DatasetMethods::PreparedStatementMethods], %w'execute execute_dui')
752
-
753
- PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods, %w'execute execute_dui') do
754
- # Raise a more obvious error if you attempt to call a unnamed prepared statement.
755
- def call(*)
756
- raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
757
- super
758
- end
759
- end
728
+ BindArgumentMethods = prepared_statements_module(:bind, [ArgumentMapper], %w'execute execute_dui')
729
+ PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods, %w'execute execute_dui')
760
730
 
761
- # Execute the given type of statement with the hash of values.
762
- def call(type, bind_vars=OPTS, *values, &block)
763
- ps = to_prepared_statement(type, values)
764
- ps.extend(BindArgumentMethods)
765
- ps.call(bind_vars, &block)
731
+ private
732
+
733
+ def bound_variable_modules
734
+ [BindArgumentMethods]
766
735
  end
767
736
 
768
- # Prepare the given type of statement with the given name, and store
769
- # it in the database to be called later.
770
- def prepare(type, name=nil, *values)
771
- ps = to_prepared_statement(type, values)
772
- ps.extend(PreparedStatementMethods)
773
- if name
774
- ps.prepared_statement_name = name
775
- db.set_prepared_statement(name, ps)
776
- end
777
- ps
737
+ def prepared_statement_modules
738
+ [PreparedStatementMethods]
778
739
  end
779
-
780
- private
781
-
740
+
782
741
  # PostgreSQL uses $N for placeholders instead of ?, so use a $
783
742
  # as the placeholder.
784
743
  def prepared_arg_placeholder
@@ -788,15 +747,26 @@ module Sequel
788
747
 
789
748
  private
790
749
 
750
+ # Generate and execute a procedure call.
751
+ def call_procedure(name, args)
752
+ sql = String.new
753
+ sql << "CALL "
754
+ identifier_append(sql, name)
755
+ sql << "("
756
+ expression_list_append(sql, args)
757
+ sql << ")"
758
+ with_sql_first(sql)
759
+ end
760
+
791
761
  # Use a cursor to fetch groups of records at a time, yielding them to the block.
792
762
  def cursor_fetch_rows(sql)
793
763
  server_opts = {:server=>@opts[:server] || :read_only}
794
764
  cursor = @opts[:cursor]
795
765
  hold = cursor[:hold]
796
- cursor_name = quote_identifier(cursor[:cursor_name] || DEFAULT_CURSOR_NAME)
766
+ cursor_name = quote_identifier(cursor[:cursor_name] || 'sequel_cursor')
797
767
  rows_per_fetch = cursor[:rows_per_fetch].to_i
798
768
 
799
- db.send(*(hold ? [:synchronize, server_opts[:server]] : [:transaction, server_opts])) do
769
+ db.public_send(*(hold ? [:synchronize, server_opts[:server]] : [:transaction, server_opts])) do
800
770
  begin
801
771
  execute_ddl("DECLARE #{cursor_name} NO SCROLL CURSOR WITH#{'OUT' unless hold} HOLD FOR #{sql}", server_opts)
802
772
  rows_per_fetch = 1000 if rows_per_fetch <= 0
@@ -808,7 +778,7 @@ module Sequel
808
778
  yield_hash_rows(res, cols){|h| yield h}
809
779
  return if res.ntuples < rows_per_fetch
810
780
  end
811
- loop do
781
+ while true
812
782
  execute(fetch_sql) do |res|
813
783
  yield_hash_rows(res, cols){|h| yield h}
814
784
  return if res.ntuples < rows_per_fetch
@@ -827,53 +797,61 @@ module Sequel
827
797
  end
828
798
  end
829
799
 
830
- # Set the @columns based on the result set, and return the array of
800
+ # Set the columns based on the result set, and return the array of
831
801
  # field numers, type conversion procs, and name symbol arrays.
832
802
  def fetch_rows_set_cols(res)
833
803
  cols = []
834
804
  procs = db.conversion_procs
835
805
  res.nfields.times do |fieldnum|
836
- cols << [fieldnum, procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
806
+ cols << [procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
837
807
  end
838
- self.columns = cols.map{|c| c.at(2)}
808
+ self.columns = cols.map{|c| c[1]}
839
809
  cols
840
810
  end
841
811
 
842
812
  # Use the driver's escape_bytea
843
813
  def literal_blob_append(sql, v)
844
- sql << APOS << db.synchronize(@opts[:server]){|c| c.check_disconnect_errors{c.escape_bytea(v)}} << APOS
814
+ sql << "'" << db.synchronize(@opts[:server]){|c| c.escape_bytea(v)} << "'"
845
815
  end
846
816
 
847
817
  # Use the driver's escape_string
848
818
  def literal_string_append(sql, v)
849
- sql << APOS << db.synchronize(@opts[:server]){|c| c.check_disconnect_errors{c.escape_string(v)}} << APOS
819
+ sql << "'" << db.synchronize(@opts[:server]){|c| c.escape_string(v)} << "'"
850
820
  end
851
821
 
852
822
  # For each row in the result set, yield a hash with column name symbol
853
823
  # keys and typecasted values.
854
824
  def yield_hash_rows(res, cols)
855
- res.ntuples.times do |recnum|
825
+ ntuples = res.ntuples
826
+ recnum = 0
827
+ while recnum < ntuples
828
+ fieldnum = 0
829
+ nfields = cols.length
856
830
  converted_rec = {}
857
- cols.each do |fieldnum, type_proc, fieldsym|
831
+ while fieldnum < nfields
832
+ type_proc, fieldsym = cols[fieldnum]
858
833
  value = res.getvalue(recnum, fieldnum)
859
834
  converted_rec[fieldsym] = (value && type_proc) ? type_proc.call(value) : value
835
+ fieldnum += 1
860
836
  end
861
837
  yield converted_rec
838
+ recnum += 1
862
839
  end
863
840
  end
864
841
  end
865
842
  end
866
843
  end
867
844
 
868
- if SEQUEL_POSTGRES_USES_PG && !ENV['NO_SEQUEL_PG']
845
+ # :nocov:
846
+ if Sequel::Postgres::USES_PG && !ENV['NO_SEQUEL_PG']
869
847
  begin
870
848
  require 'sequel_pg'
871
- rescue LoadError
872
- if RUBY_PLATFORM =~ /mingw|mswin/
873
- begin
874
- require "#{RUBY_VERSION[0...3]}/sequel_pg"
875
- rescue LoadError
876
- end
849
+ if defined?(Gem) &&
850
+ (sequel_pg_spec = Gem.loaded_specs['sequel_pg'] rescue nil) &&
851
+ (sequel_pg_spec.version < Gem::Version.new('1.6.17'))
852
+ raise Sequel::Error, "the installed sequel_pg is too old, please update to at least sequel_pg-1.6.17"
877
853
  end
854
+ rescue LoadError
878
855
  end
879
856
  end
857
+ # :nocov: