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
|
@@ -45,6 +45,23 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
45
45
|
@allocated[server]
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
+
# Yield all of the available connections, and the ones currently allocated to
|
|
49
|
+
# this thread. This will not yield connections currently allocated to other
|
|
50
|
+
# threads, as it is not safe to operate on them. This holds the mutex while
|
|
51
|
+
# it is yielding all of the connections, which means that until
|
|
52
|
+
# the method's block returns, the pool is locked.
|
|
53
|
+
def all_connections
|
|
54
|
+
t = Thread.current
|
|
55
|
+
sync do
|
|
56
|
+
@allocated.values.each do |threads|
|
|
57
|
+
threads.each do |thread, conn|
|
|
58
|
+
yield conn if t == thread
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
@available_connections.values.each{|v| v.each{|c| yield c}}
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
48
65
|
# An array of connections opened but not currently used, for the given
|
|
49
66
|
# server. Nonexistent servers will return nil. Treat this as read only, do
|
|
50
67
|
# not modify the resulting object.
|
|
@@ -94,7 +111,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
94
111
|
# connection can be acquired, a Sequel::PoolTimeout is
|
|
95
112
|
# raised.
|
|
96
113
|
def hold(server=:default)
|
|
97
|
-
|
|
114
|
+
server = pick_server(server)
|
|
98
115
|
t = Thread.current
|
|
99
116
|
if conn = owned_connection(t, server)
|
|
100
117
|
return yield(conn)
|
|
@@ -190,6 +207,11 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
190
207
|
def owned_connection(thread, server)
|
|
191
208
|
sync{@allocated[server][thread]}
|
|
192
209
|
end
|
|
210
|
+
|
|
211
|
+
# If the server given is in the hash, return it, otherwise, return the default server.
|
|
212
|
+
def pick_server(server)
|
|
213
|
+
sync{@servers[server]}
|
|
214
|
+
end
|
|
193
215
|
|
|
194
216
|
# Releases the connection assigned to the supplied thread and server. If the
|
|
195
217
|
# server or connection given is scheduled for disconnection, remove the
|
|
@@ -199,7 +221,16 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
|
|
|
199
221
|
if @connections_to_remove.include?(conn)
|
|
200
222
|
remove(thread, conn, server)
|
|
201
223
|
else
|
|
202
|
-
|
|
224
|
+
conn = allocated(server).delete(thread)
|
|
225
|
+
|
|
226
|
+
case @connection_handling
|
|
227
|
+
when :queue
|
|
228
|
+
available_connections(server).unshift(conn)
|
|
229
|
+
when :disconnect
|
|
230
|
+
@disconnection_proc.call(conn) if @disconnection_proc
|
|
231
|
+
else
|
|
232
|
+
available_connections(server) << conn
|
|
233
|
+
end
|
|
203
234
|
end
|
|
204
235
|
end
|
|
205
236
|
|
|
@@ -8,6 +8,11 @@ class Sequel::SingleConnectionPool < Sequel::ConnectionPool
|
|
|
8
8
|
@conn ? 1 : 0
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# Yield the connection if one has been made.
|
|
12
|
+
def all_connections
|
|
13
|
+
yield @conn if @conn
|
|
14
|
+
end
|
|
15
|
+
|
|
11
16
|
# Disconnect the connection from the database.
|
|
12
17
|
def disconnect(opts=nil, &block)
|
|
13
18
|
return unless @conn
|
|
@@ -13,6 +13,9 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
13
13
|
attr_reader :allocated
|
|
14
14
|
|
|
15
15
|
# The following additional options are respected:
|
|
16
|
+
# * :connection_handling - Set how to handle available connections. By default,
|
|
17
|
+
# uses a a stack for performance. Can be set to :queue to use a queue, which reduces
|
|
18
|
+
# the chances of connections becoming stale.
|
|
16
19
|
# * :max_connections - The maximum number of connections the connection pool
|
|
17
20
|
# will open (default 4)
|
|
18
21
|
# * :pool_sleep_time - The amount of time to sleep before attempting to acquire
|
|
@@ -24,22 +27,40 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
24
27
|
@max_size = Integer(opts[:max_connections] || 4)
|
|
25
28
|
raise(Sequel::Error, ':max_connections must be positive') if @max_size < 1
|
|
26
29
|
@mutex = Mutex.new
|
|
30
|
+
@connection_handling = opts[:connection_handling]
|
|
27
31
|
@available_connections = []
|
|
28
32
|
@allocated = {}
|
|
29
33
|
@timeout = Integer(opts[:pool_timeout] || 5)
|
|
30
34
|
@sleep_time = Float(opts[:pool_sleep_time] || 0.001)
|
|
31
35
|
end
|
|
32
36
|
|
|
33
|
-
# The total number of connections opened
|
|
34
|
-
# be
|
|
37
|
+
# The total number of connections opened, either available or allocated.
|
|
38
|
+
# This may not be completely accurate as it isn't protected by the mutex.
|
|
35
39
|
def size
|
|
36
40
|
@allocated.length + @available_connections.length
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
#
|
|
43
|
+
# Yield all of the available connections, and the one currently allocated to
|
|
44
|
+
# this thread. This will not yield connections currently allocated to other
|
|
45
|
+
# threads, as it is not safe to operate on them. This holds the mutex while
|
|
46
|
+
# it is yielding all of the available connections, which means that until
|
|
47
|
+
# the method's block returns, the pool is locked.
|
|
48
|
+
def all_connections
|
|
49
|
+
hold do |c|
|
|
50
|
+
sync do
|
|
51
|
+
yield c
|
|
52
|
+
@available_connections.each{|c| yield c}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Removes all connections currently available, optionally
|
|
40
58
|
# yielding each connection to the given block. This method has the effect of
|
|
41
59
|
# disconnecting from the database, assuming that no connections are currently
|
|
42
|
-
# being used.
|
|
60
|
+
# being used. If you want to be able to disconnect connections that are
|
|
61
|
+
# currently in use, use the ShardedThreadedConnectionPool, which can do that.
|
|
62
|
+
# This connection pool does not, for performance reasons. To use the sharded pool,
|
|
63
|
+
# pass the <tt>:servers=>{}</tt> option when connecting to the database.
|
|
43
64
|
#
|
|
44
65
|
# Once a connection is requested using #hold, the connection pool
|
|
45
66
|
# creates new connections to the database.
|
|
@@ -51,7 +72,7 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
51
72
|
end
|
|
52
73
|
end
|
|
53
74
|
|
|
54
|
-
# Chooses the first available connection
|
|
75
|
+
# Chooses the first available connection, or if none are
|
|
55
76
|
# available, creates a new connection. Passes the connection to the supplied
|
|
56
77
|
# block:
|
|
57
78
|
#
|
|
@@ -83,9 +104,10 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
83
104
|
end
|
|
84
105
|
yield conn
|
|
85
106
|
rescue Sequel::DatabaseDisconnectError
|
|
86
|
-
|
|
87
|
-
@allocated.delete(t)
|
|
107
|
+
oconn = conn
|
|
88
108
|
conn = nil
|
|
109
|
+
@disconnection_proc.call(oconn) if @disconnection_proc && oconn
|
|
110
|
+
@allocated.delete(t)
|
|
89
111
|
raise
|
|
90
112
|
ensure
|
|
91
113
|
sync{release(t)} if conn
|
|
@@ -94,7 +116,7 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
94
116
|
|
|
95
117
|
private
|
|
96
118
|
|
|
97
|
-
# Assigns a connection to the supplied thread
|
|
119
|
+
# Assigns a connection to the supplied thread, if one
|
|
98
120
|
# is available. The calling code should NOT already have the mutex when
|
|
99
121
|
# calling this.
|
|
100
122
|
def acquire(thread)
|
|
@@ -105,7 +127,7 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
105
127
|
end
|
|
106
128
|
end
|
|
107
129
|
|
|
108
|
-
# Returns an available connection
|
|
130
|
+
# Returns an available connection. If no connection is
|
|
109
131
|
# available, tries to create a new connection. The calling code should already
|
|
110
132
|
# have the mutex before calling this.
|
|
111
133
|
def available
|
|
@@ -126,18 +148,25 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
|
126
148
|
super if (n || size) < @max_size
|
|
127
149
|
end
|
|
128
150
|
|
|
129
|
-
# Returns the connection owned by the supplied thread
|
|
151
|
+
# Returns the connection owned by the supplied thread,
|
|
130
152
|
# if any. The calling code should NOT already have the mutex before calling this.
|
|
131
153
|
def owned_connection(thread)
|
|
132
154
|
sync{@allocated[thread]}
|
|
133
155
|
end
|
|
134
156
|
|
|
135
|
-
# Releases the connection assigned to the supplied thread
|
|
136
|
-
# server or connection given is scheduled for disconnection, remove the
|
|
137
|
-
# connection instead of releasing it back to the pool.
|
|
157
|
+
# Releases the connection assigned to the supplied thread back to the pool.
|
|
138
158
|
# The calling code should already have the mutex before calling this.
|
|
139
159
|
def release(thread)
|
|
140
|
-
|
|
160
|
+
conn = @allocated.delete(thread)
|
|
161
|
+
|
|
162
|
+
case @connection_handling
|
|
163
|
+
when :queue
|
|
164
|
+
@available_connections.unshift(conn)
|
|
165
|
+
when :disconnect
|
|
166
|
+
@disconnection_proc.call(conn) if @disconnection_proc
|
|
167
|
+
else
|
|
168
|
+
@available_connections << conn
|
|
169
|
+
end
|
|
141
170
|
end
|
|
142
171
|
|
|
143
172
|
# Yield to the block while inside the mutex. The calling code should NOT
|
|
@@ -53,10 +53,18 @@ class Sequel::ConnectionPool
|
|
|
53
53
|
|
|
54
54
|
# Return a connection pool class based on the given options.
|
|
55
55
|
def connection_pool_class(opts)
|
|
56
|
-
opts[:pool_class] || CONNECTION_POOL_MAP[[!!opts[:single_threaded], !!opts[:servers]]]
|
|
56
|
+
CONNECTION_POOL_MAP[opts[:pool_class]] || opts[:pool_class] || CONNECTION_POOL_MAP[[!!opts[:single_threaded], !!opts[:servers]]]
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
extend ClassMethods
|
|
60
|
+
|
|
61
|
+
# The after_connect proc used for this pool. This is called with each new
|
|
62
|
+
# connection made, and is usually used to set custom per-connection settings.
|
|
63
|
+
attr_accessor :after_connect
|
|
64
|
+
|
|
65
|
+
# The disconnect_proc used for the pool. This is called with each connection
|
|
66
|
+
# that is disconnected, usually to clean up related resources.
|
|
67
|
+
attr_accessor :disconnection_proc
|
|
60
68
|
|
|
61
69
|
# Instantiates a connection pool with the given options. The block is called
|
|
62
70
|
# with a single symbol (specifying the server/shard to use) every time a new
|
|
@@ -80,7 +88,7 @@ class Sequel::ConnectionPool
|
|
|
80
88
|
|
|
81
89
|
# An array of symbols for all shards/servers, which is a single <tt>:default</tt> by default.
|
|
82
90
|
def servers
|
|
83
|
-
[
|
|
91
|
+
[DEFAULT_SERVER]
|
|
84
92
|
end
|
|
85
93
|
|
|
86
94
|
private
|
data/lib/sequel/core.rb
CHANGED
|
@@ -17,20 +17,26 @@
|
|
|
17
17
|
#
|
|
18
18
|
# Sequel.sqlite('blog.db'){|db| puts db[:users].count}
|
|
19
19
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
20
|
+
# Sequel currently adds methods to the Array, Hash, String and Symbol classes by
|
|
21
|
+
# default. You can either require 'sequel/no_core_ext' or set the
|
|
22
|
+
# +SEQUEL_NO_CORE_EXTENSIONS+ constant or environment variable before requiring
|
|
23
|
+
# sequel to have # Sequel not add methods to those classes.
|
|
22
24
|
#
|
|
23
25
|
# For a more expanded introduction, see the {README}[link:files/README_rdoc.html].
|
|
24
26
|
# For a quicker introduction, see the {cheat sheet}[link:files/doc/cheat_sheet_rdoc.html].
|
|
25
27
|
module Sequel
|
|
26
28
|
@convert_two_digit_years = true
|
|
27
29
|
@datetime_class = Time
|
|
30
|
+
@empty_array_handle_nulls = true
|
|
28
31
|
@virtual_row_instance_eval = true
|
|
29
32
|
@require_thread = nil
|
|
30
33
|
|
|
31
34
|
# Mutex used to protect file loading/requireing
|
|
32
35
|
@require_mutex = Mutex.new
|
|
33
36
|
|
|
37
|
+
# Whether Sequel is being run in single threaded mode
|
|
38
|
+
@single_threaded = false
|
|
39
|
+
|
|
34
40
|
class << self
|
|
35
41
|
# Sequel converts two digit years in <tt>Date</tt>s and <tt>DateTime</tt>s by default,
|
|
36
42
|
# so 01/02/03 is interpreted at January 2nd, 2003, and 12/13/99 is interpreted
|
|
@@ -54,6 +60,27 @@ module Sequel
|
|
|
54
60
|
# days on +DateTime+).
|
|
55
61
|
attr_accessor :datetime_class
|
|
56
62
|
|
|
63
|
+
# Sets whether or not to attempt to handle NULL values correctly when given
|
|
64
|
+
# an empty array. By default:
|
|
65
|
+
#
|
|
66
|
+
# DB[:a].filter(:b=>[])
|
|
67
|
+
# # SELECT * FROM a WHERE (b != b)
|
|
68
|
+
# DB[:a].exclude(:b=>[])
|
|
69
|
+
# # SELECT * FROM a WHERE (b = b)
|
|
70
|
+
#
|
|
71
|
+
# However, some databases (e.g. MySQL) will perform very poorly
|
|
72
|
+
# with this type of query. You can set this to false to get the
|
|
73
|
+
# following behavior:
|
|
74
|
+
#
|
|
75
|
+
# DB[:a].filter(:b=>[])
|
|
76
|
+
# # SELECT * FROM a WHERE 1 = 0
|
|
77
|
+
# DB[:a].exclude(:b=>[])
|
|
78
|
+
# # SELECT * FROM a WHERE 1 = 1
|
|
79
|
+
#
|
|
80
|
+
# This may not handle NULLs correctly, but can be much faster on
|
|
81
|
+
# some databases.
|
|
82
|
+
attr_accessor :empty_array_handle_nulls
|
|
83
|
+
|
|
57
84
|
# For backwards compatibility, has no effect.
|
|
58
85
|
attr_accessor :virtual_row_instance_eval
|
|
59
86
|
|
|
@@ -64,6 +91,7 @@ module Sequel
|
|
|
64
91
|
|
|
65
92
|
# Make thread safe requiring reentrant to prevent deadlocks.
|
|
66
93
|
def check_requiring_thread
|
|
94
|
+
return yield if @single_threaded
|
|
67
95
|
t = Thread.current
|
|
68
96
|
return(yield) if @require_thread == t
|
|
69
97
|
@require_mutex.synchronize do
|
|
@@ -118,6 +146,12 @@ module Sequel
|
|
|
118
146
|
def self.connect(*args, &block)
|
|
119
147
|
Database.connect(*args, &block)
|
|
120
148
|
end
|
|
149
|
+
|
|
150
|
+
# Assume the core extensions are not loaded by default, if the core_extensions
|
|
151
|
+
# extension is loaded, this will be overridden.
|
|
152
|
+
def self.core_extensions?
|
|
153
|
+
false
|
|
154
|
+
end
|
|
121
155
|
|
|
122
156
|
# Convert the +exception+ to the given class. The given class should be
|
|
123
157
|
# <tt>Sequel::Error</tt> or a subclass. Returns an instance of +klass+ with
|
|
@@ -182,25 +216,62 @@ module Sequel
|
|
|
182
216
|
def self.quote_identifiers=(value)
|
|
183
217
|
Database.quote_identifiers = value
|
|
184
218
|
end
|
|
219
|
+
|
|
220
|
+
# Convert each item in the array to the correct type, handling multi-dimensional
|
|
221
|
+
# arrays. For each element in the array or subarrays, call the converter,
|
|
222
|
+
# unless the value is nil.
|
|
223
|
+
def self.recursive_map(array, converter)
|
|
224
|
+
array.map do |i|
|
|
225
|
+
if i.is_a?(Array)
|
|
226
|
+
recursive_map(i, converter)
|
|
227
|
+
elsif i
|
|
228
|
+
converter.call(i)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
185
232
|
|
|
186
233
|
# Require all given +files+ which should be in the same or a subdirectory of
|
|
187
234
|
# this file. If a +subdir+ is given, assume all +files+ are in that subdir.
|
|
188
235
|
# This is used to ensure that the files loaded are from the same version of
|
|
189
236
|
# Sequel as this file.
|
|
190
237
|
def self.require(files, subdir=nil)
|
|
191
|
-
Array(files).each{|f| super("#{File.dirname(__FILE__)}/#{"#{subdir}/" if subdir}#{f}")}
|
|
238
|
+
Array(files).each{|f| super("#{File.dirname(__FILE__).untaint}/#{"#{subdir}/" if subdir}#{f}")}
|
|
192
239
|
end
|
|
193
240
|
|
|
194
|
-
# Set whether
|
|
241
|
+
# Set whether Sequel is being used in single threaded mode. By default,
|
|
195
242
|
# Sequel uses a thread-safe connection pool, which isn't as fast as the
|
|
196
|
-
# single threaded connection pool
|
|
197
|
-
#
|
|
243
|
+
# single threaded connection pool, and also has some additional thread
|
|
244
|
+
# safety checks. If your program will only have one thread,
|
|
245
|
+
# and speed is a priority, you should set this to true:
|
|
198
246
|
#
|
|
199
247
|
# Sequel.single_threaded = true
|
|
200
248
|
def self.single_threaded=(value)
|
|
249
|
+
@single_threaded = value
|
|
201
250
|
Database.single_threaded = value
|
|
202
251
|
end
|
|
203
252
|
|
|
253
|
+
COLUMN_REF_RE1 = /\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/.freeze
|
|
254
|
+
COLUMN_REF_RE2 = /\A((?:(?!___).)+)___(.+)\z/.freeze
|
|
255
|
+
COLUMN_REF_RE3 = /\A((?:(?!__).)+)__(.+)\z/.freeze
|
|
256
|
+
|
|
257
|
+
# Splits the symbol into three parts. Each part will
|
|
258
|
+
# either be a string or nil.
|
|
259
|
+
#
|
|
260
|
+
# For columns, these parts are the table, column, and alias.
|
|
261
|
+
# For tables, these parts are the schema, table, and alias.
|
|
262
|
+
def self.split_symbol(sym)
|
|
263
|
+
case s = sym.to_s
|
|
264
|
+
when COLUMN_REF_RE1
|
|
265
|
+
[$1, $2, $3]
|
|
266
|
+
when COLUMN_REF_RE2
|
|
267
|
+
[nil, $1, $2]
|
|
268
|
+
when COLUMN_REF_RE3
|
|
269
|
+
[$1, $2, nil]
|
|
270
|
+
else
|
|
271
|
+
[nil, s, nil]
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
204
275
|
# Converts the given +string+ into a +Date+ object.
|
|
205
276
|
#
|
|
206
277
|
# Sequel.string_to_date('2010-09-10') # Date.civil(2010, 09, 10)
|
|
@@ -228,17 +299,76 @@ module Sequel
|
|
|
228
299
|
end
|
|
229
300
|
end
|
|
230
301
|
|
|
231
|
-
# Converts the given +string+ into a
|
|
302
|
+
# Converts the given +string+ into a <tt>Sequel::SQLTime</tt> object.
|
|
232
303
|
#
|
|
233
|
-
# Sequel.
|
|
304
|
+
# v = Sequel.string_to_time('10:20:30') # Sequel::SQLTime.parse('10:20:30')
|
|
305
|
+
# DB.literal(v) # => '10:20:30'
|
|
234
306
|
def self.string_to_time(string)
|
|
235
307
|
begin
|
|
236
|
-
|
|
308
|
+
SQLTime.parse(string)
|
|
237
309
|
rescue => e
|
|
238
310
|
raise convert_exception_class(e, InvalidValue)
|
|
239
311
|
end
|
|
240
312
|
end
|
|
241
313
|
|
|
314
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'ruby'
|
|
315
|
+
# Mutex used to protect mutable data structures
|
|
316
|
+
@data_mutex = Mutex.new
|
|
317
|
+
|
|
318
|
+
# Unless in single threaded mode, protects access to any mutable
|
|
319
|
+
# global data structure in Sequel.
|
|
320
|
+
# Uses a non-reentrant mutex, so calling code should be careful.
|
|
321
|
+
def self.synchronize(&block)
|
|
322
|
+
@single_threaded ? yield : @data_mutex.synchronize(&block)
|
|
323
|
+
end
|
|
324
|
+
else
|
|
325
|
+
# Yield directly to the block. You don't need to synchronize
|
|
326
|
+
# access on MRI because the GVL makes certain methods atomic.
|
|
327
|
+
def self.synchronize(&block)
|
|
328
|
+
yield
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Uses a transaction on all given databases with the given options. This:
|
|
333
|
+
#
|
|
334
|
+
# Sequel.transaction([DB1, DB2, DB3]){...}
|
|
335
|
+
#
|
|
336
|
+
# is equivalent to:
|
|
337
|
+
#
|
|
338
|
+
# DB1.transaction do
|
|
339
|
+
# DB2.transaction do
|
|
340
|
+
# DB3.transaction do
|
|
341
|
+
# ...
|
|
342
|
+
# end
|
|
343
|
+
# end
|
|
344
|
+
# end
|
|
345
|
+
#
|
|
346
|
+
# except that if Sequel::Rollback is raised by the block, the transaction is
|
|
347
|
+
# rolled back on all databases instead of just the last one.
|
|
348
|
+
#
|
|
349
|
+
# Note that this method cannot guarantee that all databases will commit or
|
|
350
|
+
# rollback. For example, if DB3 commits but attempting to commit on DB2
|
|
351
|
+
# fails (maybe because foreign key checks are deferred), there is no way
|
|
352
|
+
# to uncommit the changes on DB3. For that kind of support, you need to
|
|
353
|
+
# have two-phase commit/prepared transactions (which Sequel supports on
|
|
354
|
+
# some databases).
|
|
355
|
+
def self.transaction(dbs, opts={}, &block)
|
|
356
|
+
unless opts[:rollback]
|
|
357
|
+
rescue_rollback = true
|
|
358
|
+
opts = opts.merge(:rollback=>:reraise)
|
|
359
|
+
end
|
|
360
|
+
pr = dbs.reverse.inject(block){|bl, db| proc{db.transaction(opts, &bl)}}
|
|
361
|
+
if rescue_rollback
|
|
362
|
+
begin
|
|
363
|
+
pr.call
|
|
364
|
+
rescue Sequel::Rollback => e
|
|
365
|
+
nil
|
|
366
|
+
end
|
|
367
|
+
else
|
|
368
|
+
pr.call
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
242
372
|
# Same as Sequel.require, but wrapped in a mutex in order to be thread safe.
|
|
243
373
|
def self.ts_require(*args)
|
|
244
374
|
check_requiring_thread{require(*args)}
|
|
@@ -292,8 +422,10 @@ module Sequel
|
|
|
292
422
|
|
|
293
423
|
private_class_method :adapter_method, :def_adapter_method
|
|
294
424
|
|
|
295
|
-
require(%w"metaprogramming sql connection_pool exceptions dataset database timezones version")
|
|
296
|
-
|
|
425
|
+
require(%w"metaprogramming sql connection_pool exceptions dataset database timezones ast_transformer version")
|
|
426
|
+
if !defined?(::SEQUEL_NO_CORE_EXTENSIONS) && !ENV.has_key?('SEQUEL_NO_CORE_EXTENSIONS')
|
|
427
|
+
extension(:core_extensions)
|
|
428
|
+
end
|
|
297
429
|
|
|
298
430
|
# Add the database adapter class methods to Sequel via metaprogramming
|
|
299
431
|
def_adapter_method(*Database::ADAPTERS)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods relating to adapters, connecting, disconnecting, and sharding
|
|
4
|
+
# :section: 4 - Methods relating to adapters, connecting, disconnecting, and sharding
|
|
5
5
|
# This methods involve the Database's connection pool.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
8
8
|
# Array of supported database adapters
|
|
9
|
-
ADAPTERS = %w'ado amalgalite db2 dbi do firebird informix jdbc mysql mysql2 odbc openbase oracle postgres sqlite swift tinytds'.collect{|x| x.to_sym}
|
|
9
|
+
ADAPTERS = %w'ado amalgalite db2 dbi do firebird ibmdb informix jdbc mock mysql mysql2 odbc openbase oracle postgres sqlite swift tinytds'.collect{|x| x.to_sym}
|
|
10
10
|
|
|
11
11
|
# Whether to use the single threaded connection pool by default
|
|
12
12
|
@@single_threaded = false
|
|
@@ -46,6 +46,7 @@ module Sequel
|
|
|
46
46
|
when String
|
|
47
47
|
if match = /\A(jdbc|do):/o.match(conn_string)
|
|
48
48
|
c = adapter_class(match[1].to_sym)
|
|
49
|
+
opts = opts.merge(:orig_opts=>opts.dup)
|
|
49
50
|
opts = {:uri=>conn_string}.merge(opts)
|
|
50
51
|
else
|
|
51
52
|
uri = URI.parse(conn_string)
|
|
@@ -54,12 +55,15 @@ module Sequel
|
|
|
54
55
|
c = adapter_class(scheme)
|
|
55
56
|
uri_options = c.send(:uri_to_options, uri)
|
|
56
57
|
uri.query.split('&').collect{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
|
|
57
|
-
uri_options.
|
|
58
|
+
uri_options.to_a.each{|k,v| uri_options[k] = URI.unescape(v) if v.is_a?(String)}
|
|
59
|
+
opts = opts.merge(:orig_opts=>opts.dup)
|
|
60
|
+
opts[:uri] = conn_string
|
|
58
61
|
opts = uri_options.merge(opts)
|
|
59
62
|
opts[:adapter] = scheme
|
|
60
63
|
end
|
|
61
64
|
when Hash
|
|
62
65
|
opts = conn_string.merge(opts)
|
|
66
|
+
opts = opts.merge(:orig_opts=>opts.dup)
|
|
63
67
|
c = adapter_class(opts[:adapter_class] || opts[:adapter] || opts['adapter'])
|
|
64
68
|
else
|
|
65
69
|
raise Error, "Sequel::Database.connect takes either a Hash or a String, given: #{conn_string.inspect}"
|
|
@@ -77,7 +81,7 @@ module Sequel
|
|
|
77
81
|
ensure
|
|
78
82
|
if block_given?
|
|
79
83
|
db.disconnect if db
|
|
80
|
-
::Sequel::DATABASES.delete(db)
|
|
84
|
+
Sequel.synchronize{::Sequel::DATABASES.delete(db)}
|
|
81
85
|
end
|
|
82
86
|
end
|
|
83
87
|
block_given? ? result : db
|
|
@@ -131,8 +135,10 @@ module Sequel
|
|
|
131
135
|
#
|
|
132
136
|
# DB.add_servers(:f=>{:host=>"hash_host_f"})
|
|
133
137
|
def add_servers(servers)
|
|
134
|
-
|
|
135
|
-
|
|
138
|
+
if h = @opts[:servers]
|
|
139
|
+
Sequel.synchronize{h.merge!(servers)}
|
|
140
|
+
@pool.add_servers(servers.keys)
|
|
141
|
+
end
|
|
136
142
|
end
|
|
137
143
|
|
|
138
144
|
# Connects to the database. This method should be overridden by descendants.
|
|
@@ -155,8 +161,8 @@ module Sequel
|
|
|
155
161
|
|
|
156
162
|
# Disconnects all available connections from the connection pool. Any
|
|
157
163
|
# connections currently in use will not be disconnected. Options:
|
|
158
|
-
#
|
|
159
|
-
#
|
|
164
|
+
# :servers :: Should be a symbol specifing the server to disconnect from,
|
|
165
|
+
# or an array of symbols to specify multiple servers.
|
|
160
166
|
#
|
|
161
167
|
# Example:
|
|
162
168
|
#
|
|
@@ -187,11 +193,8 @@ module Sequel
|
|
|
187
193
|
#
|
|
188
194
|
# DB.remove_servers(:f1, :f2)
|
|
189
195
|
def remove_servers(*servers)
|
|
190
|
-
if
|
|
191
|
-
|
|
192
|
-
servers.flatten!
|
|
193
|
-
servers.each{|s| servs.delete(s)}
|
|
194
|
-
@opts[:servers] = servs
|
|
196
|
+
if h = @opts[:servers]
|
|
197
|
+
servers.flatten.each{|s| Sequel.synchronize{h.delete(s)}}
|
|
195
198
|
@pool.remove_servers(servers)
|
|
196
199
|
end
|
|
197
200
|
end
|
|
@@ -209,21 +212,26 @@ module Sequel
|
|
|
209
212
|
@single_threaded
|
|
210
213
|
end
|
|
211
214
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
215
|
+
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby'
|
|
216
|
+
# Acquires a database connection, yielding it to the passed block. This is
|
|
217
|
+
# useful if you want to make sure the same connection is used for all
|
|
218
|
+
# database queries in the block. It is also useful if you want to gain
|
|
219
|
+
# direct access to the underlying connection object if you need to do
|
|
220
|
+
# something Sequel does not natively support.
|
|
221
|
+
#
|
|
222
|
+
# If a server option is given, acquires a connection for that specific
|
|
223
|
+
# server, instead of the :default server.
|
|
224
|
+
#
|
|
225
|
+
# DB.synchronize do |conn|
|
|
226
|
+
# ...
|
|
227
|
+
# end
|
|
228
|
+
def synchronize(server=nil)
|
|
229
|
+
@pool.hold(server || :default){|conn| yield conn}
|
|
230
|
+
end
|
|
231
|
+
else
|
|
232
|
+
def synchronize(server=nil, &block)
|
|
233
|
+
@pool.hold(server || :default, &block)
|
|
234
|
+
end
|
|
227
235
|
end
|
|
228
236
|
|
|
229
237
|
# Attempts to acquire a database connection. Returns true if successful.
|
|
@@ -255,6 +263,8 @@ module Sequel
|
|
|
255
263
|
else
|
|
256
264
|
raise Error, 'Server opts should be a hash or proc'
|
|
257
265
|
end
|
|
266
|
+
elsif server.is_a?(Hash)
|
|
267
|
+
@opts.merge(server)
|
|
258
268
|
else
|
|
259
269
|
@opts.dup
|
|
260
270
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that create datasets
|
|
4
|
+
# :section: 3 - Methods that create datasets
|
|
5
5
|
# These methods all return instances of this database's dataset class.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -24,10 +24,10 @@ module Sequel
|
|
|
24
24
|
#
|
|
25
25
|
# DB.dataset # SELECT *
|
|
26
26
|
# DB.dataset.from(:items) # SELECT * FROM items
|
|
27
|
-
def dataset
|
|
28
|
-
|
|
27
|
+
def dataset(opts=nil)
|
|
28
|
+
@dataset_class.new(self, opts)
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
# Fetches records for an arbitrary SQL statement. If a block is given,
|
|
32
32
|
# it is used to iterate over the records:
|
|
33
33
|
#
|