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