sequel 3.21.0 → 3.39.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.
- data/CHANGELOG +1061 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +103 -63
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +67 -51
- data/doc/advanced_associations.rdoc +189 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +10 -10
- data/doc/dataset_filtering.rdoc +54 -42
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +89 -557
- data/doc/model_hooks.rdoc +80 -29
- data/doc/object_model.rdoc +547 -0
- data/doc/opening_databases.rdoc +114 -53
- data/doc/prepared_statements.rdoc +41 -15
- data/doc/querying.rdoc +137 -56
- data/doc/reflection.rdoc +36 -10
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/release_notes/3.37.0.txt +338 -0
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/release_notes/3.39.0.txt +237 -0
- data/doc/schema_modification.rdoc +585 -0
- data/doc/sharding.rdoc +99 -8
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +169 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +78 -43
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +2 -61
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +56 -0
- data/lib/sequel/adapters/jdbc/derby.rb +325 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +40 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +77 -52
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +279 -97
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +125 -222
- data/lib/sequel/adapters/mysql2.rb +65 -56
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +368 -138
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +343 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +401 -116
- data/lib/sequel/adapters/shared/mysql.rb +424 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +257 -45
- data/lib/sequel/adapters/shared/postgres.rb +675 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +285 -96
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +10 -12
- data/lib/sequel/adapters/swift/postgres.rb +13 -79
- data/lib/sequel/adapters/swift/sqlite.rb +9 -6
- data/lib/sequel/adapters/swift.rb +28 -19
- data/lib/sequel/adapters/tinytds.rb +174 -22
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +77 -0
- data/lib/sequel/adapters/utils/pg_types.rb +81 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +33 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +43 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +190 -46
- data/lib/sequel/database/query.rb +272 -110
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +300 -67
- data/lib/sequel/dataset/actions.rb +344 -90
- data/lib/sequel/dataset/features.rb +101 -8
- data/lib/sequel/dataset/graph.rb +42 -15
- data/lib/sequel/dataset/misc.rb +52 -25
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +305 -54
- data/lib/sequel/dataset/sql.rb +720 -292
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +83 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +109 -0
- data/lib/sequel/extensions/blank.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +72 -0
- data/lib/sequel/extensions/constraint_validations.rb +451 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +30 -46
- data/lib/sequel/extensions/eval_inspect.rb +173 -0
- data/lib/sequel/extensions/inflector.rb +4 -0
- data/lib/sequel/extensions/looser_typecasting.rb +5 -4
- data/lib/sequel/extensions/migration.rb +100 -11
- data/lib/sequel/extensions/named_timezones.rb +9 -0
- data/lib/sequel/extensions/null_dataset.rb +94 -0
- data/lib/sequel/extensions/pagination.rb +4 -0
- data/lib/sequel/extensions/pg_array.rb +537 -0
- data/lib/sequel/extensions/pg_array_ops.rb +263 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +175 -0
- data/lib/sequel/extensions/pg_hstore.rb +313 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +293 -0
- data/lib/sequel/extensions/pg_inet.rb +113 -0
- data/lib/sequel/extensions/pg_interval.rb +191 -0
- data/lib/sequel/extensions/pg_json.rb +208 -0
- data/lib/sequel/extensions/pg_range.rb +512 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +182 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +317 -0
- data/lib/sequel/extensions/pretty_table.rb +17 -72
- data/lib/sequel/extensions/query.rb +8 -4
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +282 -76
- data/lib/sequel/extensions/select_remove.rb +39 -0
- data/lib/sequel/extensions/server_block.rb +140 -0
- data/lib/sequel/extensions/split_array_nil.rb +65 -0
- data/lib/sequel/extensions/sql_expr.rb +8 -110
- data/lib/sequel/extensions/string_date_time.rb +4 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +10 -4
- data/lib/sequel/extensions/to_dot.rb +99 -83
- data/lib/sequel/model/associations.rb +1263 -409
- data/lib/sequel/model/base.rb +624 -171
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +24 -2
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/constraint_validations.rb +198 -0
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +72 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +134 -15
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +13 -2
- data/lib/sequel/plugins/many_through_many.rb +103 -51
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +150 -66
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +31 -17
- data/lib/sequel/plugins/schema.rb +8 -3
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +29 -3
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +3 -3
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +55 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +649 -122
- data/lib/sequel/timezones.rb +67 -40
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +194 -66
- data/spec/adapters/mysql_spec.rb +475 -306
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +1982 -325
- data/spec/adapters/spec_helper.rb +9 -6
- data/spec/adapters/sqlite_spec.rb +203 -75
- data/spec/core/connection_pool_spec.rb +218 -93
- data/spec/core/database_spec.rb +956 -522
- data/spec/core/dataset_spec.rb +1631 -1242
- data/spec/core/expression_filters_spec.rb +690 -334
- data/spec/core/mock_adapter_spec.rb +453 -0
- data/spec/core/object_graph_spec.rb +88 -129
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +556 -53
- data/spec/core/spec_helper.rb +7 -48
- data/spec/core_extensions_spec.rb +626 -0
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/boolean_readers_spec.rb +25 -25
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/extensions/constraint_validations_plugin_spec.rb +196 -0
- data/spec/extensions/constraint_validations_spec.rb +316 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +88 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/eval_inspect_spec.rb +67 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +97 -128
- data/spec/extensions/identity_map_spec.rb +142 -24
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -12
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +49 -40
- data/spec/extensions/looser_typecasting_spec.rb +7 -7
- data/spec/extensions/many_through_many_spec.rb +368 -254
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +268 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +112 -0
- data/spec/extensions/pg_array_spec.rb +320 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +140 -0
- data/spec/extensions/pg_hstore_spec.rb +194 -0
- data/spec/extensions/pg_inet_spec.rb +47 -0
- data/spec/extensions/pg_interval_spec.rb +72 -0
- data/spec/extensions/pg_json_spec.rb +99 -0
- data/spec/extensions/pg_range_ops_spec.rb +56 -0
- data/spec/extensions/pg_range_spec.rb +395 -0
- data/spec/extensions/pg_row_ops_spec.rb +58 -0
- data/spec/extensions/pg_row_plugin_spec.rb +49 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_statement_cache_spec.rb +208 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +167 -0
- data/spec/extensions/query_spec.rb +9 -3
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +434 -49
- data/spec/extensions/schema_spec.rb +30 -49
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +86 -48
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +34 -67
- data/spec/extensions/split_array_nil_spec.rb +24 -0
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/subclasses_spec.rb +14 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +8 -11
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +58 -67
- data/spec/extensions/validation_helpers_spec.rb +31 -37
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +11 -5
- data/spec/integration/dataset_test.rb +717 -129
- data/spec/integration/eager_loader_test.rb +38 -54
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +604 -147
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +367 -57
- data/spec/integration/spec_helper.rb +42 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +31 -8
- data/spec/model/association_reflection_spec.rb +207 -8
- data/spec/model/associations_spec.rb +1206 -693
- data/spec/model/base_spec.rb +334 -100
- data/spec/model/dataset_methods_spec.rb +45 -27
- data/spec/model/eager_loading_spec.rb +828 -692
- data/spec/model/hooks_spec.rb +355 -67
- data/spec/model/model_spec.rb +251 -179
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +506 -232
- data/spec/model/spec_helper.rb +16 -77
- data/spec/model/validations_spec.rb +38 -2
- data/spec/rcov.opts +2 -0
- metadata +209 -80
- data/spec/core/core_sql_spec.rb +0 -451
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that set defaults for created datasets
|
|
4
|
+
# :section: 5 - Methods that set defaults for created datasets
|
|
5
5
|
# This methods change the default behavior of this database's datasets.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
8
|
+
# The default class to use for datasets
|
|
9
|
+
DatasetClass = Sequel::Dataset
|
|
10
|
+
|
|
8
11
|
# The identifier input method to use by default
|
|
9
12
|
@@identifier_input_method = nil
|
|
10
13
|
|
|
@@ -42,9 +45,62 @@ module Sequel
|
|
|
42
45
|
@@quote_identifiers = value
|
|
43
46
|
end
|
|
44
47
|
|
|
45
|
-
# The
|
|
48
|
+
# The class to use for creating datasets. Should respond to
|
|
49
|
+
# new with the Database argument as the first argument, and
|
|
50
|
+
# an optional options hash.
|
|
51
|
+
attr_reader :dataset_class
|
|
52
|
+
|
|
53
|
+
# The default schema to use, generally should be nil. This sets
|
|
54
|
+
# the default schema used for some schema modification and
|
|
55
|
+
# introspection queries, but does not effect most dataset code.
|
|
46
56
|
attr_accessor :default_schema
|
|
47
57
|
|
|
58
|
+
# If the database has any dataset modules associated with it,
|
|
59
|
+
# use a subclass of the given class that includes the modules
|
|
60
|
+
# as the dataset class.
|
|
61
|
+
def dataset_class=(c)
|
|
62
|
+
unless @dataset_modules.empty?
|
|
63
|
+
c = Class.new(c)
|
|
64
|
+
@dataset_modules.each{|m| c.send(:include, m)}
|
|
65
|
+
end
|
|
66
|
+
@dataset_class = c
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Equivalent to extending all datasets produced by the database with a
|
|
70
|
+
# module. What it actually does is use a subclass of the current dataset_class
|
|
71
|
+
# as the new dataset_class, and include the module in the subclass.
|
|
72
|
+
# Instead of a module, you can provide a block that is used to create an
|
|
73
|
+
# anonymous module.
|
|
74
|
+
#
|
|
75
|
+
# This allows you to override any of the dataset methods even if they are
|
|
76
|
+
# defined directly on the dataset class that this Database object uses.
|
|
77
|
+
#
|
|
78
|
+
# Examples:
|
|
79
|
+
#
|
|
80
|
+
# # Introspec columns for all of DB's datasets
|
|
81
|
+
# DB.extend_datasets(Sequel::ColumnsIntrospection)
|
|
82
|
+
#
|
|
83
|
+
# # Trace all SELECT queries by printing the SQL and the full backtrace
|
|
84
|
+
# DB.extend_datasets do
|
|
85
|
+
# def fetch_rows(sql)
|
|
86
|
+
# puts sql
|
|
87
|
+
# puts caller
|
|
88
|
+
# super
|
|
89
|
+
# end
|
|
90
|
+
# end
|
|
91
|
+
def extend_datasets(mod=nil, &block)
|
|
92
|
+
raise(Error, "must provide either mod or block, not both") if mod && block
|
|
93
|
+
reset_schema_utility_dataset
|
|
94
|
+
mod = Module.new(&block) if block
|
|
95
|
+
if @dataset_modules.empty?
|
|
96
|
+
@dataset_modules = [mod]
|
|
97
|
+
@dataset_class = Class.new(@dataset_class)
|
|
98
|
+
else
|
|
99
|
+
@dataset_modules << mod
|
|
100
|
+
end
|
|
101
|
+
@dataset_class.send(:include, mod)
|
|
102
|
+
end
|
|
103
|
+
|
|
48
104
|
# The method to call on identifiers going into the database
|
|
49
105
|
def identifier_input_method
|
|
50
106
|
case @identifier_input_method
|
|
@@ -109,6 +165,11 @@ module Sequel
|
|
|
109
165
|
|
|
110
166
|
private
|
|
111
167
|
|
|
168
|
+
# The default dataset class to use for the database
|
|
169
|
+
def dataset_class_default
|
|
170
|
+
self.class.const_get(:DatasetClass)
|
|
171
|
+
end
|
|
172
|
+
|
|
112
173
|
# The default value for default_schema.
|
|
113
174
|
def default_schema_default
|
|
114
175
|
nil
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods relating to logging
|
|
4
|
+
# :section: 6 - Methods relating to logging
|
|
5
5
|
# This methods affect relating to the logging of executed SQL.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -17,6 +17,11 @@ module Sequel
|
|
|
17
17
|
# is :info, it can be set to :debug to log at DEBUG level.
|
|
18
18
|
attr_accessor :sql_log_level
|
|
19
19
|
|
|
20
|
+
# Log a message at error level, with information about the exception.
|
|
21
|
+
def log_exception(exception, message)
|
|
22
|
+
log_each(:error, "#{exception.class}: #{exception.message.strip}: #{message}")
|
|
23
|
+
end
|
|
24
|
+
|
|
20
25
|
# Log a message at level info to all loggers.
|
|
21
26
|
def log_info(message, args=nil)
|
|
22
27
|
log_each(:info, args ? "#{message}; #{args.inspect}" : message)
|
|
@@ -31,7 +36,7 @@ module Sequel
|
|
|
31
36
|
begin
|
|
32
37
|
yield
|
|
33
38
|
rescue => e
|
|
34
|
-
|
|
39
|
+
log_exception(e, sql)
|
|
35
40
|
raise
|
|
36
41
|
ensure
|
|
37
42
|
log_duration(Time.now - start, sql) unless e
|
data/lib/sequel/database/misc.rb
CHANGED
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Miscellaneous methods
|
|
4
|
+
# :section: 7 - Miscellaneous methods
|
|
5
5
|
# These methods don't fit neatly into another category.
|
|
6
6
|
# ---------------------
|
|
7
|
+
|
|
8
|
+
# Hash of extension name symbols to callable objects to load the extension
|
|
9
|
+
# into the Database object (usually by extending it with a module defined
|
|
10
|
+
# in the extension).
|
|
11
|
+
EXTENSIONS = {}
|
|
12
|
+
|
|
13
|
+
# Register an extension callback for Database objects. ext should be the
|
|
14
|
+
# extension name symbol, and mod should either be a Module that the
|
|
15
|
+
# database is extended with, or a callable object called with the database
|
|
16
|
+
# object. If mod is not provided, a block can be provided and is treated
|
|
17
|
+
# as the mod object.
|
|
18
|
+
def self.register_extension(ext, mod=nil, &block)
|
|
19
|
+
if mod
|
|
20
|
+
raise(Error, "cannot provide both mod and block to Database.register_extension") if block
|
|
21
|
+
if mod.is_a?(Module)
|
|
22
|
+
block = proc{|db| db.extend(mod)}
|
|
23
|
+
else
|
|
24
|
+
block = mod
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
Sequel.synchronize{EXTENSIONS[ext] = block}
|
|
28
|
+
end
|
|
7
29
|
|
|
8
30
|
# Converts a uri to an options hash. These options are then passed
|
|
9
31
|
# to a newly created database object.
|
|
10
|
-
def self.uri_to_options(uri)
|
|
32
|
+
def self.uri_to_options(uri)
|
|
11
33
|
{ :user => uri.user,
|
|
12
34
|
:password => uri.password,
|
|
13
35
|
:host => uri.host,
|
|
@@ -19,11 +41,14 @@ module Sequel
|
|
|
19
41
|
# The options hash for this database
|
|
20
42
|
attr_reader :opts
|
|
21
43
|
|
|
44
|
+
# Set the timezone to use for this database, overridding <tt>Sequel.database_timezone</tt>.
|
|
45
|
+
attr_writer :timezone
|
|
46
|
+
|
|
22
47
|
# Constructs a new instance of a database connection with the specified
|
|
23
48
|
# options hash.
|
|
24
49
|
#
|
|
25
50
|
# Accepts the following options:
|
|
26
|
-
# :default_schema :: The default schema to use,
|
|
51
|
+
# :default_schema :: The default schema to use, see #default_schema.
|
|
27
52
|
# :disconnection_proc :: A proc used to disconnect the connection
|
|
28
53
|
# :identifier_input_method :: A string method symbol to call on identifiers going into the database
|
|
29
54
|
# :identifier_output_method :: A string method symbol to call on identifiers coming from the database
|
|
@@ -50,14 +75,50 @@ module Sequel
|
|
|
50
75
|
@schemas = {}
|
|
51
76
|
@default_schema = @opts.fetch(:default_schema, default_schema_default)
|
|
52
77
|
@prepared_statements = {}
|
|
53
|
-
@transactions =
|
|
78
|
+
@transactions = {}
|
|
54
79
|
@identifier_input_method = nil
|
|
55
80
|
@identifier_output_method = nil
|
|
56
81
|
@quote_identifiers = nil
|
|
82
|
+
@timezone = nil
|
|
83
|
+
@dataset_class = dataset_class_default
|
|
84
|
+
@cache_schema = typecast_value_boolean(@opts.fetch(:cache_schema, true))
|
|
85
|
+
@dataset_modules = []
|
|
57
86
|
self.sql_log_level = @opts[:sql_log_level] ? @opts[:sql_log_level].to_sym : :info
|
|
58
87
|
@pool = ConnectionPool.get_pool(@opts, &block)
|
|
59
88
|
|
|
60
|
-
::Sequel::DATABASES.push(self)
|
|
89
|
+
Sequel.synchronize{::Sequel::DATABASES.push(self)}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# If a transaction is not currently in process, yield to the block immediately.
|
|
93
|
+
# Otherwise, add the block to the list of blocks to call after the currently
|
|
94
|
+
# in progress transaction commits (and only if it commits).
|
|
95
|
+
# Options:
|
|
96
|
+
# :server :: The server/shard to use.
|
|
97
|
+
def after_commit(opts={}, &block)
|
|
98
|
+
raise Error, "must provide block to after_commit" unless block
|
|
99
|
+
synchronize(opts[:server]) do |conn|
|
|
100
|
+
if h = _trans(conn)
|
|
101
|
+
raise Error, "cannot call after_commit in a prepared transaction" if h[:prepare]
|
|
102
|
+
(h[:after_commit] ||= []) << block
|
|
103
|
+
else
|
|
104
|
+
yield
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# If a transaction is not currently in progress, ignore the block.
|
|
110
|
+
# Otherwise, add the block to the list of the blocks to call after the currently
|
|
111
|
+
# in progress transaction rolls back (and only if it rolls back).
|
|
112
|
+
# Options:
|
|
113
|
+
# :server :: The server/shard to use.
|
|
114
|
+
def after_rollback(opts={}, &block)
|
|
115
|
+
raise Error, "must provide block to after_rollback" unless block
|
|
116
|
+
synchronize(opts[:server]) do |conn|
|
|
117
|
+
if h = _trans(conn)
|
|
118
|
+
raise Error, "cannot call after_rollback in a prepared transaction" if h[:prepare]
|
|
119
|
+
(h[:after_rollback] ||= []) << block
|
|
120
|
+
end
|
|
121
|
+
end
|
|
61
122
|
end
|
|
62
123
|
|
|
63
124
|
# Cast the given type to a literal type
|
|
@@ -68,11 +129,52 @@ module Sequel
|
|
|
68
129
|
type_literal(:type=>type)
|
|
69
130
|
end
|
|
70
131
|
|
|
132
|
+
# Load an extension into the receiver. In addition to requiring the extension file, this
|
|
133
|
+
# also modifies the database to work with the extension (usually extending it with a
|
|
134
|
+
# module defined in the extension file). If no related extension file exists or the
|
|
135
|
+
# extension does not have specific support for Database objects, an Error will be raised.
|
|
136
|
+
# Returns self.
|
|
137
|
+
def extension(*exts)
|
|
138
|
+
Sequel.extension(*exts)
|
|
139
|
+
exts.each do |ext|
|
|
140
|
+
if pr = Sequel.synchronize{EXTENSIONS[ext]}
|
|
141
|
+
pr.call(self)
|
|
142
|
+
else
|
|
143
|
+
raise(Error, "Extension #{ext} does not have specific support handling individual databases")
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
self
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Convert the given timestamp from the application's timezone,
|
|
150
|
+
# to the databases's timezone or the default database timezone if
|
|
151
|
+
# the database does not have a timezone.
|
|
152
|
+
def from_application_timestamp(v)
|
|
153
|
+
Sequel.convert_output_timestamp(v, timezone)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Whether the database uses a global namespace for the index. If
|
|
157
|
+
# false, the indexes are going to be namespaced per table.
|
|
158
|
+
def global_index_namespace?
|
|
159
|
+
true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Return true if already in a transaction given the options,
|
|
163
|
+
# false otherwise. Respects the :server option for selecting
|
|
164
|
+
# a shard.
|
|
165
|
+
def in_transaction?(opts={})
|
|
166
|
+
synchronize(opts[:server]){|conn| !!_trans(conn)}
|
|
167
|
+
end
|
|
168
|
+
|
|
71
169
|
# Returns a string representation of the database object including the
|
|
72
|
-
# class name and
|
|
73
|
-
# cannot be constructed).
|
|
170
|
+
# class name and connection URI and options used when connecting (if any).
|
|
74
171
|
def inspect
|
|
75
|
-
|
|
172
|
+
a = []
|
|
173
|
+
a << uri.inspect if uri
|
|
174
|
+
if (oo = opts[:orig_opts]) && !oo.empty?
|
|
175
|
+
a << oo.inspect
|
|
176
|
+
end
|
|
177
|
+
"#<#{self.class}: #{a.join(' ')}>"
|
|
76
178
|
end
|
|
77
179
|
|
|
78
180
|
# Proxy the literal call to the dataset.
|
|
@@ -84,12 +186,34 @@ module Sequel
|
|
|
84
186
|
schema_utility_dataset.literal(v)
|
|
85
187
|
end
|
|
86
188
|
|
|
189
|
+
# Synchronize access to the prepared statements cache.
|
|
190
|
+
def prepared_statement(name)
|
|
191
|
+
Sequel.synchronize{prepared_statements[name]}
|
|
192
|
+
end
|
|
193
|
+
|
|
87
194
|
# Default serial primary key options, used by the table creation
|
|
88
195
|
# code.
|
|
89
196
|
def serial_primary_key_options
|
|
90
197
|
{:primary_key => true, :type => Integer, :auto_increment => true}
|
|
91
198
|
end
|
|
92
199
|
|
|
200
|
+
# Cache the prepared statement object at the given name.
|
|
201
|
+
def set_prepared_statement(name, ps)
|
|
202
|
+
Sequel.synchronize{prepared_statements[name] = ps}
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Whether the database supports CREATE TABLE IF NOT EXISTS syntax,
|
|
206
|
+
# false by default.
|
|
207
|
+
def supports_create_table_if_not_exists?
|
|
208
|
+
false
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Whether the database supports DROP TABLE IF EXISTS syntax,
|
|
212
|
+
# default is the same as #supports_create_table_if_not_exists?.
|
|
213
|
+
def supports_drop_table_if_exists?
|
|
214
|
+
supports_create_table_if_not_exists?
|
|
215
|
+
end
|
|
216
|
+
|
|
93
217
|
# Whether the database and adapter support prepared transactions
|
|
94
218
|
# (two-phase commit), false by default.
|
|
95
219
|
def supports_prepared_transactions?
|
|
@@ -101,11 +225,34 @@ module Sequel
|
|
|
101
225
|
false
|
|
102
226
|
end
|
|
103
227
|
|
|
228
|
+
# Whether the database and adapter support savepoints inside prepared transactions
|
|
229
|
+
# (two-phase commit), default is false.
|
|
230
|
+
def supports_savepoints_in_prepared_transactions?
|
|
231
|
+
supports_prepared_transactions? && supports_savepoints?
|
|
232
|
+
end
|
|
233
|
+
|
|
104
234
|
# Whether the database and adapter support transaction isolation levels, false by default.
|
|
105
235
|
def supports_transaction_isolation_levels?
|
|
106
236
|
false
|
|
107
237
|
end
|
|
108
238
|
|
|
239
|
+
# Whether DDL statements work correctly in transactions, false by default.
|
|
240
|
+
def supports_transactional_ddl?
|
|
241
|
+
false
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# The timezone to use for this database, defaulting to <tt>Sequel.database_timezone</tt>.
|
|
245
|
+
def timezone
|
|
246
|
+
@timezone || Sequel.database_timezone
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Convert the given timestamp to the application's timezone,
|
|
250
|
+
# from the databases's timezone or the default database timezone if
|
|
251
|
+
# the database does not have a timezone.
|
|
252
|
+
def to_application_timestamp(v)
|
|
253
|
+
Sequel.convert_timestamp(v, timezone)
|
|
254
|
+
end
|
|
255
|
+
|
|
109
256
|
# Typecast the value to the given column_type. Calls
|
|
110
257
|
# typecast_value_#{column_type} if the method exists,
|
|
111
258
|
# otherwise returns the value.
|
|
@@ -121,29 +268,10 @@ module Sequel
|
|
|
121
268
|
end
|
|
122
269
|
end
|
|
123
270
|
|
|
124
|
-
# Returns the URI
|
|
125
|
-
#
|
|
126
|
-
# This method can raise an error if the database used options
|
|
127
|
-
# instead of a connection string, and will not include uri
|
|
128
|
-
# parameters.
|
|
129
|
-
#
|
|
130
|
-
# Sequel.connect('postgres://localhost/db?user=billg').url
|
|
131
|
-
# # => "postgres://billg@localhost/db"
|
|
271
|
+
# Returns the URI use to connect to the database. If a URI
|
|
272
|
+
# was not used when connecting, returns nil.
|
|
132
273
|
def uri
|
|
133
|
-
uri
|
|
134
|
-
adapter_scheme.to_s,
|
|
135
|
-
nil,
|
|
136
|
-
@opts[:host],
|
|
137
|
-
@opts[:port],
|
|
138
|
-
nil,
|
|
139
|
-
"/#{@opts[:database]}",
|
|
140
|
-
nil,
|
|
141
|
-
nil,
|
|
142
|
-
nil
|
|
143
|
-
)
|
|
144
|
-
uri.user = @opts[:user]
|
|
145
|
-
uri.password = @opts[:password] if uri.user
|
|
146
|
-
uri.to_s
|
|
274
|
+
opts[:uri]
|
|
147
275
|
end
|
|
148
276
|
|
|
149
277
|
# Explicit alias of uri for easier subclassing.
|
|
@@ -175,12 +303,17 @@ module Sequel
|
|
|
175
303
|
def database_error_classes
|
|
176
304
|
[]
|
|
177
305
|
end
|
|
306
|
+
|
|
307
|
+
# Return true if exception represents a disconnect error, false otherwise.
|
|
308
|
+
def disconnect_error?(exception, opts)
|
|
309
|
+
opts[:disconnect]
|
|
310
|
+
end
|
|
178
311
|
|
|
179
312
|
# Convert the given exception to a DatabaseError, keeping message
|
|
180
313
|
# and traceback.
|
|
181
314
|
def raise_error(exception, opts={})
|
|
182
315
|
if !opts[:classes] || Array(opts[:classes]).any?{|c| exception.is_a?(c)}
|
|
183
|
-
raise Sequel.convert_exception_class(exception, opts
|
|
316
|
+
raise Sequel.convert_exception_class(exception, disconnect_error?(exception, opts) ? DatabaseDisconnectError : DatabaseError)
|
|
184
317
|
else
|
|
185
318
|
raise exception
|
|
186
319
|
end
|
|
@@ -194,7 +327,7 @@ module Sequel
|
|
|
194
327
|
# Typecast the value to true, false, or nil
|
|
195
328
|
def typecast_value_boolean(value)
|
|
196
329
|
case value
|
|
197
|
-
when false, 0, "0", /\Af(alse)?\z/i
|
|
330
|
+
when false, 0, "0", /\Af(alse)?\z/i, /\Ano?\z/i
|
|
198
331
|
false
|
|
199
332
|
else
|
|
200
333
|
blank_object?(value) ? nil : true
|
|
@@ -204,10 +337,10 @@ module Sequel
|
|
|
204
337
|
# Typecast the value to a Date
|
|
205
338
|
def typecast_value_date(value)
|
|
206
339
|
case value
|
|
207
|
-
when Date
|
|
208
|
-
value
|
|
209
340
|
when DateTime, Time
|
|
210
341
|
Date.new(value.year, value.month, value.day)
|
|
342
|
+
when Date
|
|
343
|
+
value
|
|
211
344
|
when String
|
|
212
345
|
Sequel.string_to_date(value)
|
|
213
346
|
when Hash
|
|
@@ -219,12 +352,7 @@ module Sequel
|
|
|
219
352
|
|
|
220
353
|
# Typecast the value to a DateTime or Time depending on Sequel.datetime_class
|
|
221
354
|
def typecast_value_datetime(value)
|
|
222
|
-
|
|
223
|
-
if value.is_a?(Hash)
|
|
224
|
-
klass.send(klass == Time ? :mktime : :new, *[:year, :month, :day, :hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
|
|
225
|
-
else
|
|
226
|
-
Sequel.typecast_to_application_timestamp(value)
|
|
227
|
-
end
|
|
355
|
+
Sequel.typecast_to_application_timestamp(value)
|
|
228
356
|
end
|
|
229
357
|
|
|
230
358
|
# Typecast the value to a BigDecimal
|
|
@@ -244,9 +372,21 @@ module Sequel
|
|
|
244
372
|
Float(value)
|
|
245
373
|
end
|
|
246
374
|
|
|
247
|
-
#
|
|
248
|
-
|
|
249
|
-
|
|
375
|
+
# Used for checking/removing leading zeroes from strings so they don't get
|
|
376
|
+
# interpreted as octal.
|
|
377
|
+
LEADING_ZERO_RE = /\A0+(\d)/.freeze
|
|
378
|
+
if RUBY_VERSION >= '1.9'
|
|
379
|
+
# Typecast the value to an Integer
|
|
380
|
+
def typecast_value_integer(value)
|
|
381
|
+
(value.is_a?(String) && value =~ LEADING_ZERO_RE) ? Integer(value, 10) : Integer(value)
|
|
382
|
+
end
|
|
383
|
+
else
|
|
384
|
+
# Replacement string when replacing leading zeroes.
|
|
385
|
+
LEADING_ZERO_REP = "\\1".freeze
|
|
386
|
+
# Typecast the value to an Integer
|
|
387
|
+
def typecast_value_integer(value)
|
|
388
|
+
Integer(value.is_a?(String) ? value.sub(LEADING_ZERO_RE, LEADING_ZERO_REP) : value)
|
|
389
|
+
end
|
|
250
390
|
end
|
|
251
391
|
|
|
252
392
|
# Typecast the value to a String
|
|
@@ -258,12 +398,16 @@ module Sequel
|
|
|
258
398
|
def typecast_value_time(value)
|
|
259
399
|
case value
|
|
260
400
|
when Time
|
|
261
|
-
value
|
|
401
|
+
if value.is_a?(SQLTime)
|
|
402
|
+
value
|
|
403
|
+
else
|
|
404
|
+
# specifically check for nsec == 0 value to work around JRuby 1.6 ruby 1.9 mode bug
|
|
405
|
+
SQLTime.create(value.hour, value.min, value.sec, (value.respond_to?(:nsec) && value.nsec != 0) ? value.nsec/1000.0 : value.usec)
|
|
406
|
+
end
|
|
262
407
|
when String
|
|
263
408
|
Sequel.string_to_time(value)
|
|
264
409
|
when Hash
|
|
265
|
-
|
|
266
|
-
Time.mktime(t.year, t.month, t.day, *[:hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
|
|
410
|
+
SQLTime.create(*[:hour, :minute, :second].map{|x| (value[x] || value[x.to_s]).to_i})
|
|
267
411
|
else
|
|
268
412
|
raise Sequel::InvalidValue, "invalid value for Time: #{value.inspect}"
|
|
269
413
|
end
|