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/adapters/jdbc.rb
CHANGED
|
@@ -32,47 +32,102 @@ module Sequel
|
|
|
32
32
|
DATABASE_SETUP = {:postgresql=>proc do |db|
|
|
33
33
|
Sequel.ts_require 'adapters/jdbc/postgresql'
|
|
34
34
|
db.extend(Sequel::JDBC::Postgres::DatabaseMethods)
|
|
35
|
+
db.dataset_class = Sequel::JDBC::Postgres::Dataset
|
|
35
36
|
JDBC.load_gem('postgres')
|
|
36
37
|
org.postgresql.Driver
|
|
37
38
|
end,
|
|
38
39
|
:mysql=>proc do |db|
|
|
39
40
|
Sequel.ts_require 'adapters/jdbc/mysql'
|
|
40
41
|
db.extend(Sequel::JDBC::MySQL::DatabaseMethods)
|
|
42
|
+
db.extend_datasets Sequel::MySQL::DatasetMethods
|
|
41
43
|
JDBC.load_gem('mysql')
|
|
42
44
|
com.mysql.jdbc.Driver
|
|
43
45
|
end,
|
|
44
46
|
:sqlite=>proc do |db|
|
|
45
47
|
Sequel.ts_require 'adapters/jdbc/sqlite'
|
|
46
48
|
db.extend(Sequel::JDBC::SQLite::DatabaseMethods)
|
|
49
|
+
db.extend_datasets Sequel::SQLite::DatasetMethods
|
|
50
|
+
db.set_integer_booleans
|
|
47
51
|
JDBC.load_gem('sqlite3')
|
|
48
52
|
org.sqlite.JDBC
|
|
49
53
|
end,
|
|
50
54
|
:oracle=>proc do |db|
|
|
51
55
|
Sequel.ts_require 'adapters/jdbc/oracle'
|
|
52
56
|
db.extend(Sequel::JDBC::Oracle::DatabaseMethods)
|
|
57
|
+
db.dataset_class = Sequel::JDBC::Oracle::Dataset
|
|
53
58
|
Java::oracle.jdbc.driver.OracleDriver
|
|
54
59
|
end,
|
|
55
60
|
:sqlserver=>proc do |db|
|
|
56
|
-
Sequel.ts_require 'adapters/jdbc/
|
|
57
|
-
db.extend(Sequel::JDBC::
|
|
61
|
+
Sequel.ts_require 'adapters/jdbc/sqlserver'
|
|
62
|
+
db.extend(Sequel::JDBC::SQLServer::DatabaseMethods)
|
|
63
|
+
db.extend_datasets Sequel::MSSQL::DatasetMethods
|
|
64
|
+
db.send(:set_mssql_unicode_strings)
|
|
58
65
|
com.microsoft.sqlserver.jdbc.SQLServerDriver
|
|
59
66
|
end,
|
|
60
67
|
:jtds=>proc do |db|
|
|
61
|
-
Sequel.ts_require 'adapters/jdbc/
|
|
62
|
-
db.extend(Sequel::JDBC::
|
|
68
|
+
Sequel.ts_require 'adapters/jdbc/jtds'
|
|
69
|
+
db.extend(Sequel::JDBC::JTDS::DatabaseMethods)
|
|
70
|
+
db.dataset_class = Sequel::JDBC::JTDS::Dataset
|
|
71
|
+
db.send(:set_mssql_unicode_strings)
|
|
63
72
|
JDBC.load_gem('jtds')
|
|
64
73
|
Java::net.sourceforge.jtds.jdbc.Driver
|
|
65
74
|
end,
|
|
66
75
|
:h2=>proc do |db|
|
|
67
76
|
Sequel.ts_require 'adapters/jdbc/h2'
|
|
68
77
|
db.extend(Sequel::JDBC::H2::DatabaseMethods)
|
|
78
|
+
db.dataset_class = Sequel::JDBC::H2::Dataset
|
|
69
79
|
JDBC.load_gem('h2')
|
|
70
80
|
org.h2.Driver
|
|
71
81
|
end,
|
|
82
|
+
:hsqldb=>proc do |db|
|
|
83
|
+
Sequel.ts_require 'adapters/jdbc/hsqldb'
|
|
84
|
+
db.extend(Sequel::JDBC::HSQLDB::DatabaseMethods)
|
|
85
|
+
db.dataset_class = Sequel::JDBC::HSQLDB::Dataset
|
|
86
|
+
# Current gem is 1.8.1.3, but Sequel supports 2.2.5
|
|
87
|
+
org.hsqldb.jdbcDriver
|
|
88
|
+
end,
|
|
89
|
+
:derby=>proc do |db|
|
|
90
|
+
Sequel.ts_require 'adapters/jdbc/derby'
|
|
91
|
+
db.extend(Sequel::JDBC::Derby::DatabaseMethods)
|
|
92
|
+
db.dataset_class = Sequel::JDBC::Derby::Dataset
|
|
93
|
+
JDBC.load_gem('derby')
|
|
94
|
+
org.apache.derby.jdbc.EmbeddedDriver
|
|
95
|
+
end,
|
|
72
96
|
:as400=>proc do |db|
|
|
73
97
|
Sequel.ts_require 'adapters/jdbc/as400'
|
|
74
98
|
db.extend(Sequel::JDBC::AS400::DatabaseMethods)
|
|
99
|
+
db.dataset_class = Sequel::JDBC::AS400::Dataset
|
|
75
100
|
com.ibm.as400.access.AS400JDBCDriver
|
|
101
|
+
end,
|
|
102
|
+
:"informix-sqli"=>proc do |db|
|
|
103
|
+
Sequel.ts_require 'adapters/jdbc/informix'
|
|
104
|
+
db.extend(Sequel::JDBC::Informix::DatabaseMethods)
|
|
105
|
+
db.extend_datasets Sequel::Informix::DatasetMethods
|
|
106
|
+
com.informix.jdbc.IfxDriver
|
|
107
|
+
end,
|
|
108
|
+
:db2=>proc do |db|
|
|
109
|
+
Sequel.ts_require 'adapters/jdbc/db2'
|
|
110
|
+
db.extend(Sequel::JDBC::DB2::DatabaseMethods)
|
|
111
|
+
db.dataset_class = Sequel::JDBC::DB2::Dataset
|
|
112
|
+
com.ibm.db2.jcc.DB2Driver
|
|
113
|
+
end,
|
|
114
|
+
:firebirdsql=>proc do |db|
|
|
115
|
+
Sequel.ts_require 'adapters/jdbc/firebird'
|
|
116
|
+
db.extend(Sequel::JDBC::Firebird::DatabaseMethods)
|
|
117
|
+
db.extend_datasets Sequel::Firebird::DatasetMethods
|
|
118
|
+
org.firebirdsql.jdbc.FBDriver
|
|
119
|
+
end,
|
|
120
|
+
:jdbcprogress=>proc do |db|
|
|
121
|
+
Sequel.ts_require 'adapters/jdbc/progress'
|
|
122
|
+
db.extend(Sequel::JDBC::Progress::DatabaseMethods)
|
|
123
|
+
db.extend_datasets Sequel::Progress::DatasetMethods
|
|
124
|
+
com.progress.sql.jdbc.JdbcProgressDriver
|
|
125
|
+
end,
|
|
126
|
+
:cubrid=>proc do |db|
|
|
127
|
+
Sequel.ts_require 'adapters/jdbc/cubrid'
|
|
128
|
+
db.extend(Sequel::JDBC::Cubrid::DatabaseMethods)
|
|
129
|
+
db.extend_datasets Sequel::Cubrid::DatasetMethods
|
|
130
|
+
Java::cubrid.jdbc.driver.CUBRIDDriver
|
|
76
131
|
end
|
|
77
132
|
}
|
|
78
133
|
|
|
@@ -101,13 +156,15 @@ module Sequel
|
|
|
101
156
|
# True by default, can be set to false to roughly double performance when
|
|
102
157
|
# fetching rows.
|
|
103
158
|
attr_accessor :convert_types
|
|
104
|
-
|
|
159
|
+
|
|
105
160
|
# Call the DATABASE_SETUP proc directly after initialization,
|
|
106
161
|
# so the object always uses sub adapter specific code. Also,
|
|
107
162
|
# raise an error immediately if the connection doesn't have a
|
|
108
163
|
# uri, since JDBC requires one.
|
|
109
164
|
def initialize(opts)
|
|
110
165
|
super
|
|
166
|
+
@connection_prepared_statements = {}
|
|
167
|
+
@connection_prepared_statements_mutex = Mutex.new
|
|
111
168
|
@convert_types = typecast_value_boolean(@opts.fetch(:convert_types, true))
|
|
112
169
|
raise(Error, "No connection string specified") unless uri
|
|
113
170
|
|
|
@@ -158,8 +215,9 @@ module Sequel
|
|
|
158
215
|
args = [uri(opts)]
|
|
159
216
|
args.concat([opts[:user], opts[:password]]) if opts[:user] && opts[:password]
|
|
160
217
|
begin
|
|
218
|
+
JavaSQL::DriverManager.setLoginTimeout(opts[:login_timeout]) if opts[:login_timeout]
|
|
161
219
|
JavaSQL::DriverManager.getConnection(*args)
|
|
162
|
-
rescue => e
|
|
220
|
+
rescue JavaSQL::SQLException, NativeException, StandardError => e
|
|
163
221
|
raise e unless driver
|
|
164
222
|
# If the DriverManager can't get the connection - use the connect
|
|
165
223
|
# method of the driver. (This happens under Tomcat for instance)
|
|
@@ -170,8 +228,10 @@ module Sequel
|
|
|
170
228
|
end
|
|
171
229
|
opts[:jdbc_properties].each{|k,v| props.setProperty(k.to_s, v)} if opts[:jdbc_properties]
|
|
172
230
|
begin
|
|
173
|
-
driver.new.connect(args[0], props)
|
|
174
|
-
|
|
231
|
+
c = driver.new.connect(args[0], props)
|
|
232
|
+
raise(Sequel::DatabaseError, 'driver.new.connect returned nil: probably bad JDBC connection string') unless c
|
|
233
|
+
c
|
|
234
|
+
rescue JavaSQL::SQLException, NativeException, StandardError => e2
|
|
175
235
|
e.message << "\n#{e2.class.name}: #{e2.message}"
|
|
176
236
|
raise e
|
|
177
237
|
end
|
|
@@ -179,10 +239,11 @@ module Sequel
|
|
|
179
239
|
end
|
|
180
240
|
setup_connection(conn)
|
|
181
241
|
end
|
|
182
|
-
|
|
183
|
-
#
|
|
184
|
-
def
|
|
185
|
-
|
|
242
|
+
|
|
243
|
+
# Close given adapter connections, and delete any related prepared statements.
|
|
244
|
+
def disconnect_connection(c)
|
|
245
|
+
@connection_prepared_statements_mutex.synchronize{@connection_prepared_statements.delete(c)}
|
|
246
|
+
c.close
|
|
186
247
|
end
|
|
187
248
|
|
|
188
249
|
# Execute the given SQL. If a block is given, if should be a SELECT
|
|
@@ -199,13 +260,7 @@ module Sequel
|
|
|
199
260
|
when :ddl
|
|
200
261
|
log_yield(sql){stmt.execute(sql)}
|
|
201
262
|
when :insert
|
|
202
|
-
log_yield(sql)
|
|
203
|
-
if requires_return_generated_keys?
|
|
204
|
-
stmt.executeUpdate(sql, JavaSQL::Statement.RETURN_GENERATED_KEYS)
|
|
205
|
-
else
|
|
206
|
-
stmt.executeUpdate(sql)
|
|
207
|
-
end
|
|
208
|
-
end
|
|
263
|
+
log_yield(sql){execute_statement_insert(stmt, sql)}
|
|
209
264
|
last_insert_id(conn, opts.merge(:stmt=>stmt))
|
|
210
265
|
else
|
|
211
266
|
log_yield(sql){stmt.executeUpdate(sql)}
|
|
@@ -215,7 +270,7 @@ module Sequel
|
|
|
215
270
|
end
|
|
216
271
|
end
|
|
217
272
|
alias execute_dui execute
|
|
218
|
-
|
|
273
|
+
|
|
219
274
|
# Execute the given DDL SQL, which should not return any
|
|
220
275
|
# values or rows.
|
|
221
276
|
def execute_ddl(sql, opts={})
|
|
@@ -246,12 +301,14 @@ module Sequel
|
|
|
246
301
|
indexes
|
|
247
302
|
end
|
|
248
303
|
|
|
304
|
+
# Whether or not JNDI is being used for this connection.
|
|
305
|
+
def jndi?
|
|
306
|
+
!!(uri =~ JNDI_URI_REGEXP)
|
|
307
|
+
end
|
|
308
|
+
|
|
249
309
|
# All tables in this database
|
|
250
310
|
def tables(opts={})
|
|
251
|
-
|
|
252
|
-
m = output_identifier_meth
|
|
253
|
-
metadata(:getTables, nil, nil, nil, ['TABLE'].to_java(:string)){|h| ts << m.call(h[:table_name])}
|
|
254
|
-
ts
|
|
311
|
+
get_tables('TABLE', opts)
|
|
255
312
|
end
|
|
256
313
|
|
|
257
314
|
# The uri for this connection. You can specify the uri
|
|
@@ -264,18 +321,29 @@ module Sequel
|
|
|
264
321
|
ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
|
|
265
322
|
end
|
|
266
323
|
|
|
267
|
-
#
|
|
268
|
-
def
|
|
269
|
-
|
|
324
|
+
# All views in this database
|
|
325
|
+
def views(opts={})
|
|
326
|
+
get_tables('VIEW', opts)
|
|
270
327
|
end
|
|
271
|
-
|
|
328
|
+
|
|
272
329
|
private
|
|
273
330
|
|
|
274
|
-
#
|
|
275
|
-
|
|
276
|
-
|
|
331
|
+
# Yield the native prepared statements hash for the given connection
|
|
332
|
+
# to the block in a thread-safe manner.
|
|
333
|
+
def cps_sync(conn, &block)
|
|
334
|
+
@connection_prepared_statements_mutex.synchronize{yield(@connection_prepared_statements[conn] ||= {})}
|
|
277
335
|
end
|
|
278
|
-
|
|
336
|
+
|
|
337
|
+
def database_error_classes
|
|
338
|
+
[NativeException]
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# Raise a disconnect error if the SQL state of the cause of the exception indicates so.
|
|
342
|
+
def disconnect_error?(exception, opts)
|
|
343
|
+
cause = exception.respond_to?(:cause) ? exception.cause : exception
|
|
344
|
+
super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
|
|
345
|
+
end
|
|
346
|
+
|
|
279
347
|
# Execute the prepared statement. If the provided name is a
|
|
280
348
|
# dataset, use that as the prepared statement, otherwise use
|
|
281
349
|
# it as a key to look it up in the prepared_statements hash.
|
|
@@ -289,20 +357,25 @@ module Sequel
|
|
|
289
357
|
ps = name
|
|
290
358
|
name = ps.prepared_statement_name
|
|
291
359
|
else
|
|
292
|
-
ps =
|
|
360
|
+
ps = prepared_statement(name)
|
|
293
361
|
end
|
|
294
362
|
sql = ps.prepared_sql
|
|
295
363
|
synchronize(opts[:server]) do |conn|
|
|
296
|
-
if name and cps = conn
|
|
364
|
+
if name and cps = cps_sync(conn){|cpsh| cpsh[name]} and cps[0] == sql
|
|
297
365
|
cps = cps[1]
|
|
298
366
|
else
|
|
299
|
-
log_yield("
|
|
300
|
-
cps = log_yield("
|
|
301
|
-
conn
|
|
367
|
+
log_yield("CLOSE #{name}"){cps[1].close} if cps
|
|
368
|
+
cps = log_yield("PREPARE#{" #{name}:" if name} #{sql}"){prepare_jdbc_statement(conn, sql, opts)}
|
|
369
|
+
cps_sync(conn){|cpsh| cpsh[name] = [sql, cps]} if name
|
|
302
370
|
end
|
|
303
371
|
i = 0
|
|
304
372
|
args.each{|arg| set_ps_arg(cps, arg, i+=1)}
|
|
305
|
-
msg = "
|
|
373
|
+
msg = "EXECUTE#{" #{name}" if name}"
|
|
374
|
+
if ps.log_sql
|
|
375
|
+
msg << " ("
|
|
376
|
+
msg << sql
|
|
377
|
+
msg << ")"
|
|
378
|
+
end
|
|
306
379
|
begin
|
|
307
380
|
if block_given?
|
|
308
381
|
yield log_yield(msg, args){cps.executeQuery}
|
|
@@ -311,8 +384,8 @@ module Sequel
|
|
|
311
384
|
when :ddl
|
|
312
385
|
log_yield(msg, args){cps.execute}
|
|
313
386
|
when :insert
|
|
314
|
-
log_yield(msg, args){cps
|
|
315
|
-
last_insert_id(conn, opts.merge(:prepared=>true))
|
|
387
|
+
log_yield(msg, args){execute_prepared_statement_insert(cps)}
|
|
388
|
+
last_insert_id(conn, opts.merge(:prepared=>true, :stmt=>cps))
|
|
316
389
|
else
|
|
317
390
|
log_yield(msg, args){cps.executeUpdate}
|
|
318
391
|
end
|
|
@@ -325,6 +398,22 @@ module Sequel
|
|
|
325
398
|
end
|
|
326
399
|
end
|
|
327
400
|
|
|
401
|
+
# Execute the prepared insert statement
|
|
402
|
+
def execute_prepared_statement_insert(stmt)
|
|
403
|
+
stmt.executeUpdate
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Execute the insert SQL using the statement
|
|
407
|
+
def execute_statement_insert(stmt, sql)
|
|
408
|
+
stmt.executeUpdate(sql)
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Gets the connection from JNDI.
|
|
412
|
+
def get_connection_from_jndi
|
|
413
|
+
jndi_name = JNDI_URI_REGEXP.match(uri)[1]
|
|
414
|
+
JavaxNaming::InitialContext.new.lookup(jndi_name).connection
|
|
415
|
+
end
|
|
416
|
+
|
|
328
417
|
# Gets the JDBC connection uri from the JNDI resource.
|
|
329
418
|
def get_uri_from_jndi
|
|
330
419
|
conn = get_connection_from_jndi
|
|
@@ -333,12 +422,14 @@ module Sequel
|
|
|
333
422
|
conn.close if conn
|
|
334
423
|
end
|
|
335
424
|
|
|
336
|
-
#
|
|
337
|
-
def
|
|
338
|
-
|
|
339
|
-
|
|
425
|
+
# Backbone of the tables and views support.
|
|
426
|
+
def get_tables(type, opts)
|
|
427
|
+
ts = []
|
|
428
|
+
m = output_identifier_meth
|
|
429
|
+
metadata(:getTables, nil, nil, nil, [type].to_java(:string)){|h| ts << m.call(h[:table_name])}
|
|
430
|
+
ts
|
|
340
431
|
end
|
|
341
|
-
|
|
432
|
+
|
|
342
433
|
# Support Date objects used in bound variables
|
|
343
434
|
def java_sql_date(date)
|
|
344
435
|
java.sql.Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
|
|
@@ -354,7 +445,8 @@ module Sequel
|
|
|
354
445
|
# Support fractional seconds for Time objects used in bound variables
|
|
355
446
|
def java_sql_timestamp(time)
|
|
356
447
|
ts = java.sql.Timestamp.new(time.to_i * 1000)
|
|
357
|
-
|
|
448
|
+
# Work around jruby 1.6 ruby 1.9 mode bug
|
|
449
|
+
ts.setNanos((RUBY_VERSION >= '1.9.0' && time.nsec != 0) ? time.nsec : time.usec * 1000)
|
|
358
450
|
ts
|
|
359
451
|
end
|
|
360
452
|
|
|
@@ -383,10 +475,9 @@ module Sequel
|
|
|
383
475
|
end
|
|
384
476
|
end
|
|
385
477
|
|
|
386
|
-
#
|
|
387
|
-
def
|
|
388
|
-
|
|
389
|
-
super(exception, {:disconnect => cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/}.merge(opts))
|
|
478
|
+
# Created a JDBC prepared statement on the connection with the given SQL.
|
|
479
|
+
def prepare_jdbc_statement(conn, sql, opts)
|
|
480
|
+
conn.prepareStatement(sql)
|
|
390
481
|
end
|
|
391
482
|
|
|
392
483
|
# Java being java, you need to specify the type of each argument
|
|
@@ -405,8 +496,8 @@ module Sequel
|
|
|
405
496
|
cps.setDouble(i, arg)
|
|
406
497
|
when TrueClass, FalseClass
|
|
407
498
|
cps.setBoolean(i, arg)
|
|
408
|
-
when
|
|
409
|
-
cps
|
|
499
|
+
when NilClass
|
|
500
|
+
set_ps_arg_nil(cps, i)
|
|
410
501
|
when DateTime
|
|
411
502
|
cps.setTimestamp(i, java_sql_datetime(arg))
|
|
412
503
|
when Date
|
|
@@ -421,22 +512,22 @@ module Sequel
|
|
|
421
512
|
cps.setObject(i, arg)
|
|
422
513
|
end
|
|
423
514
|
end
|
|
515
|
+
|
|
516
|
+
# Use setString with a nil value by default, but this doesn't work on all subadapters.
|
|
517
|
+
def set_ps_arg_nil(cps, i)
|
|
518
|
+
cps.setString(i, nil)
|
|
519
|
+
end
|
|
424
520
|
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
# adapter specific prepared statements.
|
|
521
|
+
# Return the connection. Used to do configuration on the
|
|
522
|
+
# connection object before adding it to the connection pool.
|
|
428
523
|
def setup_connection(conn)
|
|
429
|
-
class << conn
|
|
430
|
-
attr_accessor :prepared_statements
|
|
431
|
-
end
|
|
432
|
-
conn.prepared_statements = {}
|
|
433
524
|
conn
|
|
434
525
|
end
|
|
435
526
|
|
|
436
527
|
# Parse the table schema for the given table.
|
|
437
528
|
def schema_parse_table(table, opts={})
|
|
438
|
-
m = output_identifier_meth
|
|
439
|
-
im = input_identifier_meth
|
|
529
|
+
m = output_identifier_meth(opts[:dataset])
|
|
530
|
+
im = input_identifier_meth(opts[:dataset])
|
|
440
531
|
ds = dataset
|
|
441
532
|
schema, table = schema_and_table(table)
|
|
442
533
|
schema ||= opts[:schema]
|
|
@@ -444,9 +535,11 @@ module Sequel
|
|
|
444
535
|
table = im.call(table)
|
|
445
536
|
pks, ts = [], []
|
|
446
537
|
metadata(:getPrimaryKeys, nil, schema, table) do |h|
|
|
538
|
+
next if schema_parse_table_skip?(h, schema)
|
|
447
539
|
pks << h[:column_name]
|
|
448
540
|
end
|
|
449
541
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
|
542
|
+
next if schema_parse_table_skip?(h, schema)
|
|
450
543
|
s = {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size], :scale=>h[:decimal_digits]}
|
|
451
544
|
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
|
452
545
|
s[:type] = :integer
|
|
@@ -456,6 +549,12 @@ module Sequel
|
|
|
456
549
|
ts
|
|
457
550
|
end
|
|
458
551
|
|
|
552
|
+
# Whether schema_parse_table should skip the given row when
|
|
553
|
+
# parsing the schema.
|
|
554
|
+
def schema_parse_table_skip?(h, schema)
|
|
555
|
+
h[:table_schem] == 'INFORMATION_SCHEMA'
|
|
556
|
+
end
|
|
557
|
+
|
|
459
558
|
# Yield a new statement object, and ensure that it is closed before returning.
|
|
460
559
|
def statement(conn)
|
|
461
560
|
stmt = conn.createStatement
|
|
@@ -465,17 +564,12 @@ module Sequel
|
|
|
465
564
|
ensure
|
|
466
565
|
stmt.close if stmt
|
|
467
566
|
end
|
|
468
|
-
|
|
469
|
-
# This method determines whether or not to add
|
|
470
|
-
# Statement.RETURN_GENERATED_KEYS as an argument when inserting rows.
|
|
471
|
-
# Sub-adapters that require this should override this method.
|
|
472
|
-
def requires_return_generated_keys?
|
|
473
|
-
false
|
|
474
|
-
end
|
|
475
567
|
end
|
|
476
568
|
|
|
477
569
|
class Dataset < Sequel::Dataset
|
|
478
570
|
include StoredProcedures
|
|
571
|
+
|
|
572
|
+
Database::DatasetClass = self
|
|
479
573
|
|
|
480
574
|
# Use JDBC PreparedStatements instead of emulated ones. Statements
|
|
481
575
|
# created using #prepare are cached at the connection level to allow
|
|
@@ -489,17 +583,17 @@ module Sequel
|
|
|
489
583
|
# Execute the prepared SQL using the stored type and
|
|
490
584
|
# arguments derived from the hash passed to call.
|
|
491
585
|
def execute(sql, opts={}, &block)
|
|
492
|
-
super(self, {:arguments=>bind_arguments
|
|
586
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
493
587
|
end
|
|
494
588
|
|
|
495
589
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
496
590
|
def execute_dui(sql, opts={}, &block)
|
|
497
|
-
super(self, {:arguments=>bind_arguments
|
|
591
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
498
592
|
end
|
|
499
593
|
|
|
500
594
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
501
595
|
def execute_insert(sql, opts={}, &block)
|
|
502
|
-
super(self, {:arguments=>bind_arguments, :type
|
|
596
|
+
super(self, {:arguments=>bind_arguments, :type=>:insert}.merge(opts), &block)
|
|
503
597
|
end
|
|
504
598
|
end
|
|
505
599
|
|
|
@@ -512,17 +606,17 @@ module Sequel
|
|
|
512
606
|
|
|
513
607
|
# Execute the database stored procedure with the stored arguments.
|
|
514
608
|
def execute(sql, opts={}, &block)
|
|
515
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
609
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
516
610
|
end
|
|
517
611
|
|
|
518
612
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
519
613
|
def execute_dui(sql, opts={}, &block)
|
|
520
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
614
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
521
615
|
end
|
|
522
616
|
|
|
523
617
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
524
618
|
def execute_insert(sql, opts={}, &block)
|
|
525
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type
|
|
619
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>:insert}.merge(opts), &block)
|
|
526
620
|
end
|
|
527
621
|
end
|
|
528
622
|
|
|
@@ -530,13 +624,7 @@ module Sequel
|
|
|
530
624
|
# Uses the database's setting by default, can be set to false to roughly
|
|
531
625
|
# double performance when fetching rows.
|
|
532
626
|
attr_accessor :convert_types
|
|
533
|
-
|
|
534
|
-
# Use the convert_types default setting from the database
|
|
535
|
-
def initialize(db, opts={})
|
|
536
|
-
@convert_types = db.convert_types
|
|
537
|
-
super
|
|
538
|
-
end
|
|
539
|
-
|
|
627
|
+
|
|
540
628
|
# Correctly return rows from the database and return them as hashes.
|
|
541
629
|
def fetch_rows(sql, &block)
|
|
542
630
|
execute(sql){|result| process_result_set(result, &block)}
|
|
@@ -550,32 +638,88 @@ module Sequel
|
|
|
550
638
|
ps.extend(PreparedStatementMethods)
|
|
551
639
|
if name
|
|
552
640
|
ps.prepared_statement_name = name
|
|
553
|
-
db.
|
|
641
|
+
db.set_prepared_statement(name, ps)
|
|
554
642
|
end
|
|
555
643
|
ps
|
|
556
644
|
end
|
|
557
645
|
|
|
558
646
|
private
|
|
559
|
-
|
|
560
|
-
#
|
|
561
|
-
|
|
647
|
+
|
|
648
|
+
# Cache Java class constants to speed up lookups
|
|
649
|
+
JAVA_SQL_TIMESTAMP = Java::JavaSQL::Timestamp
|
|
650
|
+
JAVA_SQL_TIME = Java::JavaSQL::Time
|
|
651
|
+
JAVA_SQL_DATE = Java::JavaSQL::Date
|
|
652
|
+
JAVA_SQL_BLOB = Java::JavaSQL::Blob
|
|
653
|
+
JAVA_SQL_CLOB = Java::JavaSQL::Clob
|
|
654
|
+
JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
|
|
655
|
+
JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
|
|
656
|
+
JAVA_BYTE_ARRAY = Java::byte[]
|
|
657
|
+
JAVA_UUID = Java::JavaUtil::UUID
|
|
658
|
+
|
|
659
|
+
# Handle type conversions for common Java types.
|
|
660
|
+
class TYPE_TRANSLATOR
|
|
661
|
+
LF = "\n".freeze
|
|
662
|
+
def time(v) Sequel.string_to_time("#{v.to_string}.#{sprintf('%03i', v.getTime.divmod(1000).last)}") end
|
|
663
|
+
def date(v) Date.civil(v.getYear + 1900, v.getMonth + 1, v.getDate) end
|
|
664
|
+
def decimal(v) BigDecimal.new(v.to_string) end
|
|
665
|
+
def byte_array(v) Sequel::SQL::Blob.new(String.from_java_bytes(v)) end
|
|
666
|
+
def blob(v) Sequel::SQL::Blob.new(String.from_java_bytes(v.getBytes(1, v.length))) end
|
|
667
|
+
def clob(v) v.getSubString(1, v.length) end
|
|
668
|
+
def buffered_reader(v)
|
|
669
|
+
lines = ""
|
|
670
|
+
c = false
|
|
671
|
+
while(line = v.read_line) do
|
|
672
|
+
lines << LF if c
|
|
673
|
+
lines << line
|
|
674
|
+
c ||= true
|
|
675
|
+
end
|
|
676
|
+
lines
|
|
677
|
+
end
|
|
678
|
+
def uuid(v) v.to_string end
|
|
679
|
+
end
|
|
680
|
+
TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
|
|
681
|
+
|
|
682
|
+
# Cache type translator methods so that duplicate Method
|
|
683
|
+
# objects are not created.
|
|
684
|
+
DECIMAL_METHOD = tt.method(:decimal)
|
|
685
|
+
TIME_METHOD = tt.method(:time)
|
|
686
|
+
DATE_METHOD = tt.method(:date)
|
|
687
|
+
BUFFERED_READER_METHOD = tt.method(:buffered_reader)
|
|
688
|
+
BYTE_ARRAY_METHOD = tt.method(:byte_array)
|
|
689
|
+
BLOB_METHOD = tt.method(:blob)
|
|
690
|
+
CLOB_METHOD = tt.method(:clob)
|
|
691
|
+
UUID_METHOD = tt.method(:uuid)
|
|
692
|
+
|
|
693
|
+
# Convert the given Java timestamp to an instance of Sequel.datetime_class.
|
|
694
|
+
def convert_type_timestamp(v)
|
|
695
|
+
db.to_application_timestamp([v.getYear + 1900, v.getMonth + 1, v.getDate, v.getHours, v.getMinutes, v.getSeconds, v.getNanos])
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
# Return a callable object that will convert any value of <tt>v</tt>'s
|
|
699
|
+
# class to a ruby object. If no callable object can handle <tt>v</tt>'s
|
|
700
|
+
# class, return false so that the negative lookup is cached.
|
|
701
|
+
def convert_type_proc(v)
|
|
562
702
|
case v
|
|
563
|
-
when
|
|
564
|
-
|
|
565
|
-
when
|
|
566
|
-
|
|
567
|
-
when
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
when
|
|
572
|
-
|
|
573
|
-
when
|
|
574
|
-
|
|
575
|
-
when
|
|
576
|
-
|
|
703
|
+
when JAVA_BIG_DECIMAL
|
|
704
|
+
DECIMAL_METHOD
|
|
705
|
+
when JAVA_SQL_TIMESTAMP
|
|
706
|
+
method(:convert_type_timestamp)
|
|
707
|
+
when JAVA_SQL_TIME
|
|
708
|
+
TIME_METHOD
|
|
709
|
+
when JAVA_SQL_DATE
|
|
710
|
+
DATE_METHOD
|
|
711
|
+
when JAVA_BUFFERED_READER
|
|
712
|
+
BUFFERED_READER_METHOD
|
|
713
|
+
when JAVA_BYTE_ARRAY
|
|
714
|
+
BYTE_ARRAY_METHOD
|
|
715
|
+
when JAVA_SQL_BLOB
|
|
716
|
+
BLOB_METHOD
|
|
717
|
+
when JAVA_SQL_CLOB
|
|
718
|
+
CLOB_METHOD
|
|
719
|
+
when JAVA_UUID
|
|
720
|
+
UUID_METHOD
|
|
577
721
|
else
|
|
578
|
-
|
|
722
|
+
false
|
|
579
723
|
end
|
|
580
724
|
end
|
|
581
725
|
|
|
@@ -586,32 +730,82 @@ module Sequel
|
|
|
586
730
|
|
|
587
731
|
# Split out from fetch rows to allow processing of JDBC result sets
|
|
588
732
|
# that don't come from issuing an SQL string.
|
|
589
|
-
def process_result_set(result)
|
|
733
|
+
def process_result_set(result, &block)
|
|
590
734
|
# get column names
|
|
591
735
|
meta = result.getMetaData
|
|
592
736
|
cols = []
|
|
593
737
|
i = 0
|
|
594
738
|
meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
739
|
+
columns = cols.map{|c| c.at(0)}
|
|
740
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
741
|
+
rn = row_number_column
|
|
742
|
+
columns.delete(rn)
|
|
743
|
+
end
|
|
744
|
+
@columns = columns
|
|
745
|
+
ct = @convert_types
|
|
746
|
+
if (ct.nil? ? db.convert_types : ct)
|
|
747
|
+
cols.each{|c| c << nil}
|
|
748
|
+
process_result_set_convert(cols, result, rn, &block)
|
|
749
|
+
else
|
|
750
|
+
process_result_set_no_convert(cols, result, rn, &block)
|
|
751
|
+
end
|
|
752
|
+
ensure
|
|
753
|
+
result.close
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
# Use conversion procs to convert data retrieved
|
|
757
|
+
# from the database. This has been optimized, the algorithm it uses
|
|
758
|
+
# is roughly, for each column value in each row:
|
|
759
|
+
# * check if the value is truthy (not false/nil)
|
|
760
|
+
# * if not truthy, return object
|
|
761
|
+
# * otherwise, see if a conversion method exists for
|
|
762
|
+
# the column. All columns start with a nil conversion proc,
|
|
763
|
+
# since unlike other adapters, Sequel doesn't get the type of
|
|
764
|
+
# the column when parsing the column metadata.
|
|
765
|
+
# * if a conversion proc is not false/nil, call it with the object
|
|
766
|
+
# and return the result.
|
|
767
|
+
# * if a conversion proc has already been looked up and doesn't
|
|
768
|
+
# exist (false value), return object.
|
|
769
|
+
# * if a conversion proc hasn't been looked up yet (nil value),
|
|
770
|
+
# call convert_type_proc to get the conversion method. Cache
|
|
771
|
+
# the result of as the column's conversion proc to speed up
|
|
772
|
+
# later processing. If the conversion proc exists, call it
|
|
773
|
+
# and return the result, otherwise, return the object.
|
|
774
|
+
def process_result_set_convert(cols, result, rn)
|
|
598
775
|
while result.next
|
|
599
776
|
row = {}
|
|
600
|
-
cols.each do |n, i|
|
|
601
|
-
|
|
777
|
+
cols.each do |n, i, p|
|
|
778
|
+
v = result.getObject(i)
|
|
779
|
+
row[n] = if v
|
|
780
|
+
if p
|
|
781
|
+
p.call(v)
|
|
782
|
+
elsif p.nil?
|
|
783
|
+
cols[i-1][2] = p = convert_type_proc(v)
|
|
784
|
+
if p
|
|
785
|
+
p.call(v)
|
|
786
|
+
else
|
|
787
|
+
v
|
|
788
|
+
end
|
|
789
|
+
else
|
|
790
|
+
v
|
|
791
|
+
end
|
|
792
|
+
else
|
|
793
|
+
v
|
|
794
|
+
end
|
|
602
795
|
end
|
|
796
|
+
row.delete(rn) if rn
|
|
603
797
|
yield row
|
|
604
798
|
end
|
|
605
799
|
end
|
|
606
800
|
|
|
607
|
-
#
|
|
608
|
-
#
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
801
|
+
# Yield rows without calling any conversion procs. This
|
|
802
|
+
# may yield Java values and not ruby values.
|
|
803
|
+
def process_result_set_no_convert(cols, result, rn)
|
|
804
|
+
while result.next
|
|
805
|
+
row = {}
|
|
806
|
+
cols.each{|n, i| row[n] = result.getObject(i)}
|
|
807
|
+
row.delete(rn) if rn
|
|
808
|
+
yield row
|
|
615
809
|
end
|
|
616
810
|
end
|
|
617
811
|
end
|