sequel 3.21.0 → 3.41.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 +1131 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +106 -65
- data/Rakefile +59 -27
- data/bin/sequel +50 -26
- data/doc/active_record.rdoc +68 -52
- data/doc/advanced_associations.rdoc +201 -75
- data/doc/association_basics.rdoc +327 -79
- data/doc/bin_sequel.rdoc +144 -0
- 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 +576 -0
- data/doc/opening_databases.rdoc +121 -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/release_notes/3.40.0.txt +73 -0
- data/doc/release_notes/3.41.0.txt +155 -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/access.rb +334 -0
- data/lib/sequel/adapters/ado/mssql.rb +18 -12
- data/lib/sequel/adapters/ado.rb +69 -21
- data/lib/sequel/adapters/amalgalite.rb +17 -14
- data/lib/sequel/adapters/cubrid.rb +143 -0
- data/lib/sequel/adapters/db2.rb +178 -85
- data/lib/sequel/adapters/dbi.rb +19 -21
- 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 +20 -39
- data/lib/sequel/adapters/firebird.rb +33 -210
- data/lib/sequel/adapters/ibmdb.rb +452 -0
- data/lib/sequel/adapters/informix.rb +6 -29
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/cubrid.rb +52 -0
- data/lib/sequel/adapters/jdbc/db2.rb +78 -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 +68 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +189 -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 +16 -28
- 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 +72 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +308 -114
- data/lib/sequel/adapters/mock.rb +372 -0
- data/lib/sequel/adapters/mysql.rb +130 -230
- data/lib/sequel/adapters/mysql2.rb +64 -63
- data/lib/sequel/adapters/odbc/mssql.rb +17 -9
- data/lib/sequel/adapters/odbc.rb +29 -10
- data/lib/sequel/adapters/openbase.rb +7 -11
- data/lib/sequel/adapters/oracle.rb +364 -57
- data/lib/sequel/adapters/postgres.rb +379 -145
- data/lib/sequel/adapters/shared/access.rb +236 -11
- data/lib/sequel/adapters/shared/cubrid.rb +216 -0
- data/lib/sequel/adapters/shared/db2.rb +353 -0
- data/lib/sequel/adapters/shared/firebird.rb +231 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +412 -116
- data/lib/sequel/adapters/shared/mysql.rb +396 -89
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +166 -0
- data/lib/sequel/adapters/shared/oracle.rb +262 -45
- data/lib/sequel/adapters/shared/postgres.rb +688 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +317 -96
- data/lib/sequel/adapters/sqlite.rb +109 -46
- 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 +31 -27
- data/lib/sequel/adapters/tinytds.rb +177 -25
- 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/split_alter_table.rb +36 -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 +23 -13
- data/lib/sequel/connection_pool/sharded_threaded.rb +64 -13
- data/lib/sequel/connection_pool/single.rb +11 -3
- data/lib/sequel/connection_pool/threaded.rb +69 -20
- data/lib/sequel/connection_pool.rb +20 -18
- data/lib/sequel/core.rb +143 -11
- data/lib/sequel/database/connecting.rb +66 -29
- 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 +192 -51
- data/lib/sequel/database/query.rb +299 -114
- data/lib/sequel/database/schema_generator.rb +103 -36
- data/lib/sequel/database/schema_methods.rb +310 -69
- 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 +322 -68
- data/lib/sequel/dataset/sql.rb +716 -293
- 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/connection_validator.rb +109 -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 +539 -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 +334 -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 +212 -0
- data/lib/sequel/extensions/pg_range.rb +513 -0
- data/lib/sequel/extensions/pg_range_ops.rb +150 -0
- data/lib/sequel/extensions/pg_row.rb +576 -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 +137 -16
- 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 +77 -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 +168 -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 +57 -12
- 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/touch.rb +18 -6
- 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 +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +57 -4
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +721 -141
- 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 +53 -39
- data/spec/adapters/mssql_spec.rb +261 -66
- data/spec/adapters/mysql_spec.rb +597 -352
- data/spec/adapters/oracle_spec.rb +92 -117
- data/spec/adapters/postgres_spec.rb +2103 -341
- data/spec/adapters/spec_helper.rb +16 -6
- data/spec/adapters/sqlite_spec.rb +237 -76
- data/spec/core/connection_pool_spec.rb +270 -141
- data/spec/core/database_spec.rb +980 -524
- data/spec/core/dataset_spec.rb +1658 -1243
- data/spec/core/expression_filters_spec.rb +741 -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 +227 -33
- 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/connection_validator_spec.rb +118 -0
- 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 +324 -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 +200 -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 +340 -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 +65 -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 +53 -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 +77 -68
- data/spec/extensions/validation_helpers_spec.rb +48 -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 +25 -5
- data/spec/integration/dataset_test.rb +729 -141
- 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 +871 -160
- data/spec/integration/prepared_statement_test.rb +272 -128
- data/spec/integration/schema_test.rb +377 -57
- data/spec/integration/spec_helper.rb +49 -32
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +40 -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 +223 -81
- data/spec/core/core_sql_spec.rb +0 -451
data/lib/sequel/dataset.rb
CHANGED
|
@@ -26,6 +26,14 @@ module Sequel
|
|
|
26
26
|
extend Metaprogramming
|
|
27
27
|
include Metaprogramming
|
|
28
28
|
include Enumerable
|
|
29
|
+
include SQL::AliasMethods
|
|
30
|
+
include SQL::BooleanMethods
|
|
31
|
+
include SQL::CastMethods
|
|
32
|
+
include SQL::ComplexExpressionMethods
|
|
33
|
+
include SQL::InequalityMethods
|
|
34
|
+
include SQL::NumericMethods
|
|
35
|
+
include SQL::OrderMethods
|
|
36
|
+
include SQL::StringMethods
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
require(%w"query actions features graph prepared_statements misc mutation sql", 'dataset')
|
data/lib/sequel/exceptions.rb
CHANGED
|
@@ -44,6 +44,10 @@ module Sequel
|
|
|
44
44
|
# and won't reraise it.
|
|
45
45
|
class Rollback < Error ; end
|
|
46
46
|
|
|
47
|
+
# Exception that occurs when unbinding a dataset that has multiple different values
|
|
48
|
+
# for a given variable.
|
|
49
|
+
class UnbindDuplicate < Error; end
|
|
50
|
+
|
|
47
51
|
class Error
|
|
48
52
|
AdapterNotFound = Sequel::AdapterNotFound
|
|
49
53
|
InvalidOperation = Sequel::InvalidOperation
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# This _pretty_table extension is only for internal use.
|
|
2
|
+
# It adds the Sequel::PrettyTable class without modifying
|
|
3
|
+
# Sequel::Dataset.
|
|
4
|
+
#
|
|
5
|
+
# To load the extension:
|
|
6
|
+
#
|
|
7
|
+
# Sequel.extension :_pretty_table
|
|
8
|
+
|
|
9
|
+
module Sequel
|
|
10
|
+
module PrettyTable
|
|
11
|
+
# Prints nice-looking plain-text tables via puts
|
|
12
|
+
#
|
|
13
|
+
# +--+-------+
|
|
14
|
+
# |id|name |
|
|
15
|
+
# |--+-------|
|
|
16
|
+
# |1 |fasdfas|
|
|
17
|
+
# |2 |test |
|
|
18
|
+
# +--+-------+
|
|
19
|
+
def self.print(records, columns=nil)
|
|
20
|
+
puts string(records, columns)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Return the string that #print will print via puts.
|
|
24
|
+
def self.string(records, columns = nil) # records is an array of hashes
|
|
25
|
+
columns ||= records.first.keys.sort_by{|x|x.to_s}
|
|
26
|
+
sizes = column_sizes(records, columns)
|
|
27
|
+
sep_line = separator_line(columns, sizes)
|
|
28
|
+
|
|
29
|
+
array = [sep_line, header_line(columns, sizes), sep_line]
|
|
30
|
+
records.each {|r| array << data_line(columns, sizes, r)}
|
|
31
|
+
array << sep_line
|
|
32
|
+
array.join("\n")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
### Private Module Methods ###
|
|
36
|
+
|
|
37
|
+
# Hash of the maximum size of the value for each column
|
|
38
|
+
def self.column_sizes(records, columns) # :nodoc:
|
|
39
|
+
sizes = Hash.new {0}
|
|
40
|
+
columns.each do |c|
|
|
41
|
+
s = c.to_s.size
|
|
42
|
+
sizes[c.to_sym] = s if s > sizes[c.to_sym]
|
|
43
|
+
end
|
|
44
|
+
records.each do |r|
|
|
45
|
+
columns.each do |c|
|
|
46
|
+
s = r[c].to_s.size
|
|
47
|
+
sizes[c.to_sym] = s if s > sizes[c.to_sym]
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
sizes
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# String for each data line
|
|
54
|
+
def self.data_line(columns, sizes, record) # :nodoc:
|
|
55
|
+
'|' << columns.map {|c| format_cell(sizes[c], record[c])}.join('|') << '|'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Format the value so it takes up exactly size characters
|
|
59
|
+
def self.format_cell(size, v) # :nodoc:
|
|
60
|
+
case v
|
|
61
|
+
when Bignum, Fixnum
|
|
62
|
+
"%#{size}d" % v
|
|
63
|
+
when Float
|
|
64
|
+
"%#{size}g" % v
|
|
65
|
+
else
|
|
66
|
+
"%-#{size}s" % v.to_s
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# String for header line
|
|
71
|
+
def self.header_line(columns, sizes) # :nodoc:
|
|
72
|
+
'|' << columns.map {|c| "%-#{sizes[c]}s" % c.to_s}.join('|') << '|'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# String for separtor line
|
|
76
|
+
def self.separator_line(columns, sizes) # :nodoc:
|
|
77
|
+
'+' << columns.map {|c| '-' * sizes[c]}.join('+') << '+'
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private_class_method :column_sizes, :data_line, :format_cell, :header_line, :separator_line
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The arbitrary_servers extension allows you to connect to arbitrary
|
|
2
|
+
# servers/shards that were not defined when you created the database.
|
|
3
|
+
# To use it, you first load the extension into the Database object:
|
|
4
|
+
#
|
|
5
|
+
# DB.extension :arbitrary_servers
|
|
6
|
+
#
|
|
7
|
+
# Then you can pass arbitrary connection options for the server/shard
|
|
8
|
+
# to use as a hash:
|
|
9
|
+
#
|
|
10
|
+
# DB[:table].server(:host=>'...', :database=>'...').all
|
|
11
|
+
#
|
|
12
|
+
# Because Sequel can never be sure that the connection will be reused,
|
|
13
|
+
# arbitrary connections are disconnected as soon as the outermost block
|
|
14
|
+
# that uses them exits. So this example uses the same connection:
|
|
15
|
+
#
|
|
16
|
+
# DB.transaction(:server=>{:host=>'...', :database=>'...'}) do |c|
|
|
17
|
+
# DB.transaction(:server=>{:host=>'...', :database=>'...'}) do |c2|
|
|
18
|
+
# # c == c2
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# But this example does not:
|
|
23
|
+
#
|
|
24
|
+
# DB.transaction(:server=>{:host=>'...', :database=>'...'}) do |c|
|
|
25
|
+
# end
|
|
26
|
+
# DB.transaction(:server=>{:host=>'...', :database=>'...'}) do |c2|
|
|
27
|
+
# # c != c2
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# You can use this extension in conjunction with the server_block
|
|
31
|
+
# extension:
|
|
32
|
+
#
|
|
33
|
+
# DB.with_server(:host=>'...', :database=>'...') do
|
|
34
|
+
# DB.synchronize do
|
|
35
|
+
# # All of these use the host/database given to with_server
|
|
36
|
+
# DB[:table].insert(...)
|
|
37
|
+
# DB[:table].update(...)
|
|
38
|
+
# DB.tables
|
|
39
|
+
# DB[:table].all
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# Anyone using this extension in conjunction with the server_block
|
|
44
|
+
# extension may want to do the following to so that you don't need
|
|
45
|
+
# to call synchronize separately:
|
|
46
|
+
#
|
|
47
|
+
# def DB.with_server(*)
|
|
48
|
+
# super{synchronize{yield}}
|
|
49
|
+
# end
|
|
50
|
+
#
|
|
51
|
+
# Note that this extension only works with the sharded threaded connection
|
|
52
|
+
# pool. If you are using the sharded single connection pool, you need
|
|
53
|
+
# to switch to the sharded threaded connection pool before using this
|
|
54
|
+
# extension.
|
|
55
|
+
|
|
56
|
+
module Sequel
|
|
57
|
+
module ArbitraryServers
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# If server is a hash, create a new connection for
|
|
61
|
+
# it, and cache it first by thread and then server.
|
|
62
|
+
def acquire(thread, server)
|
|
63
|
+
if server.is_a?(Hash)
|
|
64
|
+
sync{@allocated[thread] ||= {}}[server] = make_new(server)
|
|
65
|
+
else
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# If server is a hash, the entry for it probably doesn't
|
|
71
|
+
# exist in the @allocated hash, so check for existence to
|
|
72
|
+
# avoid calling nil.[]
|
|
73
|
+
def owned_connection(thread, server)
|
|
74
|
+
if server.is_a?(Hash)
|
|
75
|
+
if a = sync{@allocated[thread]}
|
|
76
|
+
a[server]
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
super
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# If server is a hash, return it directly.
|
|
84
|
+
def pick_server(server)
|
|
85
|
+
if server.is_a?(Hash)
|
|
86
|
+
server
|
|
87
|
+
else
|
|
88
|
+
super
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# If server is a hash, delete the thread from the allocated
|
|
93
|
+
# connections for that server. Additionally, if this was the last thread
|
|
94
|
+
# using that server, delete the server from the @allocated hash.
|
|
95
|
+
def release(thread, conn, server)
|
|
96
|
+
if server.is_a?(Hash)
|
|
97
|
+
a = @allocated[thread]
|
|
98
|
+
a.delete(server)
|
|
99
|
+
@allocated.delete(thread) if a.empty?
|
|
100
|
+
db.disconnect_connection(conn)
|
|
101
|
+
else
|
|
102
|
+
super
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
Database.register_extension(:arbitrary_servers){|db| db.pool.extend(ArbitraryServers)}
|
|
108
|
+
end
|
|
109
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# The columns_introspection extension attempts to introspect the
|
|
2
|
+
# selected columns for a dataset before issuing a query. If it
|
|
3
|
+
# thinks it can guess correctly at the columns the query will use,
|
|
4
|
+
# it will return the columns without issuing a database query.
|
|
5
|
+
# This method is not fool-proof, it's possible that some databases
|
|
6
|
+
# will use column names that Sequel does not expect.
|
|
7
|
+
#
|
|
8
|
+
# To attempt to introspect columns for a single dataset:
|
|
9
|
+
#
|
|
10
|
+
# ds.extension(:columns_introspection)
|
|
11
|
+
#
|
|
12
|
+
# To attempt to introspect columns for all datasets on a single database:
|
|
13
|
+
#
|
|
14
|
+
# DB.extension(:columns_introspection)
|
|
15
|
+
#
|
|
16
|
+
# To attempt to introspect columns for all datasets on all databases:
|
|
17
|
+
#
|
|
18
|
+
# Sequel.extension :columns_introspection
|
|
19
|
+
# Sequel::Dataset.introspect_all_columns
|
|
20
|
+
|
|
21
|
+
module Sequel
|
|
22
|
+
module ColumnsIntrospection
|
|
23
|
+
# Attempt to guess the columns that will be returned
|
|
24
|
+
# if there are columns selected, in order to skip a database
|
|
25
|
+
# query to retrieve the columns. This should work with
|
|
26
|
+
# Symbols, SQL::Identifiers, SQL::QualifiedIdentifiers, and
|
|
27
|
+
# SQL::AliasedExpressions.
|
|
28
|
+
def columns
|
|
29
|
+
return @columns if @columns
|
|
30
|
+
return columns_without_introspection unless cols = opts[:select] and !cols.empty?
|
|
31
|
+
probable_columns = cols.map{|c| probable_column_name(c)}
|
|
32
|
+
if probable_columns.all?
|
|
33
|
+
@columns = probable_columns
|
|
34
|
+
else
|
|
35
|
+
columns_without_introspection
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# Return the probable name of the column, or nil if one
|
|
42
|
+
# cannot be determined.
|
|
43
|
+
def probable_column_name(c)
|
|
44
|
+
case c
|
|
45
|
+
when Symbol
|
|
46
|
+
_, c, a = split_symbol(c)
|
|
47
|
+
(a || c).to_sym
|
|
48
|
+
when SQL::Identifier
|
|
49
|
+
c.value.to_sym
|
|
50
|
+
when SQL::QualifiedIdentifier
|
|
51
|
+
col = c.column
|
|
52
|
+
col.is_a?(SQL::Identifier) ? col.value.to_sym : col.to_sym
|
|
53
|
+
when SQL::AliasedExpression
|
|
54
|
+
a = c.aliaz
|
|
55
|
+
a.is_a?(SQL::Identifier) ? a.value.to_sym : a.to_sym
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Dataset
|
|
61
|
+
alias columns_without_introspection columns
|
|
62
|
+
|
|
63
|
+
# Enable column introspection for every dataset.
|
|
64
|
+
def self.introspect_all_columns
|
|
65
|
+
include ColumnsIntrospection
|
|
66
|
+
remove_method(:columns) if instance_methods(false).map{|x| x.to_s}.include?('columns')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Dataset.register_extension(:columns_introspection, Sequel::ColumnsIntrospection)
|
|
71
|
+
end
|
|
72
|
+
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The connection_validator extension modifies a database's
|
|
2
|
+
# connection pool to validate that connections checked out
|
|
3
|
+
# from the pool are still valid, before yielding them for
|
|
4
|
+
# use. If it detects an invalid connection, it removes it
|
|
5
|
+
# from the pool and tries the next available connection,
|
|
6
|
+
# creating a new connection if no available connection is
|
|
7
|
+
# valid. Example of use:
|
|
8
|
+
#
|
|
9
|
+
# DB.extension(:connection_validator)
|
|
10
|
+
#
|
|
11
|
+
# As checking connections for validity involves issuing a
|
|
12
|
+
# query, which is potentially an expensive operation,
|
|
13
|
+
# the validation checks are only run if the connection has
|
|
14
|
+
# been idle for longer than a certain threshold. By default,
|
|
15
|
+
# that threshold is 3600 seconds (1 hour), but it can be
|
|
16
|
+
# modified by the user, set to -1 to always validate
|
|
17
|
+
# connections on checkout:
|
|
18
|
+
#
|
|
19
|
+
# DB.pool.connection_validation_timeout = -1
|
|
20
|
+
#
|
|
21
|
+
# Note that if you set the timeout to validate connections
|
|
22
|
+
# on every checkout, you should probably manually control
|
|
23
|
+
# connection checkouts on a coarse basis, using
|
|
24
|
+
# Database#synchonrize. In a web application, the optimal
|
|
25
|
+
# place for that would be a rack middleware. Validating
|
|
26
|
+
# connections on every checkout without setting up coarse
|
|
27
|
+
# connection checkouts will hurt performance, in some cases
|
|
28
|
+
# significantly. Note that setting up coarse connection
|
|
29
|
+
# checkouts reduces the concurrency level acheivable. For
|
|
30
|
+
# example, in a web application, using Database#synchronize
|
|
31
|
+
# in a rack middleware will limit the number of concurrent
|
|
32
|
+
# web requests to the number to connections in the database
|
|
33
|
+
# connection pool.
|
|
34
|
+
#
|
|
35
|
+
# Note that this extension only affects the default threaded
|
|
36
|
+
# and the sharded threaded connection pool. The single
|
|
37
|
+
# threaded and sharded single threaded connection pools are
|
|
38
|
+
# not affected. As the only reason to use the single threaded
|
|
39
|
+
# pools is for speed, and this extension makes the connection
|
|
40
|
+
# pool slower, there's not much point in modifying this
|
|
41
|
+
# extension to work with the single threaded pools. The
|
|
42
|
+
# threaded pools work fine even in single threaded code, so if
|
|
43
|
+
# you are currently using a single threaded pool and want to
|
|
44
|
+
# use this extension, switch to using a threaded pool.
|
|
45
|
+
|
|
46
|
+
module Sequel
|
|
47
|
+
module ConnectionValidator
|
|
48
|
+
class Retry < Error; end
|
|
49
|
+
|
|
50
|
+
# The number of seconds that need to pass since
|
|
51
|
+
# connection checkin before attempting to validate
|
|
52
|
+
# the connection when checking it out from the pool.
|
|
53
|
+
# Defaults to 3600 seconds (1 hour).
|
|
54
|
+
attr_accessor :connection_validation_timeout
|
|
55
|
+
|
|
56
|
+
# Initialize the data structures used by this extension.
|
|
57
|
+
def self.extended(pool)
|
|
58
|
+
pool.instance_eval do
|
|
59
|
+
@connection_timestamps ||= {}
|
|
60
|
+
@connection_validation_timeout = 3600
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Make sure the valid connection SQL query is precached,
|
|
64
|
+
# otherwise it's possible it will happen at runtime. While
|
|
65
|
+
# it should work correctly at runtime, it's better to avoid
|
|
66
|
+
# the possibility of failure altogether.
|
|
67
|
+
pool.db.send(:valid_connection_sql)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Record the time the connection was checked back into the pool.
|
|
73
|
+
def checkin_connection(*)
|
|
74
|
+
conn = super
|
|
75
|
+
@connection_timestamps[conn] = Time.now
|
|
76
|
+
conn
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# When acquiring a connection, if it has been
|
|
80
|
+
# idle for longer than the connection validation timeout,
|
|
81
|
+
# test the connection for validity. If it is not valid,
|
|
82
|
+
# disconnect the connection, and retry with a new connection.
|
|
83
|
+
def acquire(*a)
|
|
84
|
+
begin
|
|
85
|
+
if (conn = super) &&
|
|
86
|
+
(t = sync{@connection_timestamps.delete(conn)}) &&
|
|
87
|
+
Time.now - t > @connection_validation_timeout &&
|
|
88
|
+
!db.valid_connection?(conn)
|
|
89
|
+
|
|
90
|
+
if pool_type == :sharded_threaded
|
|
91
|
+
sync{allocated(a.last).delete(Thread.current)}
|
|
92
|
+
else
|
|
93
|
+
sync{@allocated.delete(Thread.current)}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
db.disconnect_connection(conn)
|
|
97
|
+
raise Retry
|
|
98
|
+
end
|
|
99
|
+
rescue Retry
|
|
100
|
+
retry
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
conn
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
Database.register_extension(:connection_validator){|db| db.pool.extend(ConnectionValidator)}
|
|
108
|
+
end
|
|
109
|
+
|