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
data/lib/sequel/adapters/jdbc.rb
CHANGED
|
@@ -32,47 +32,96 @@ 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.extend_datasets Sequel::DB2::DatasetMethods
|
|
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
|
|
76
125
|
end
|
|
77
126
|
}
|
|
78
127
|
|
|
@@ -101,13 +150,15 @@ module Sequel
|
|
|
101
150
|
# True by default, can be set to false to roughly double performance when
|
|
102
151
|
# fetching rows.
|
|
103
152
|
attr_accessor :convert_types
|
|
104
|
-
|
|
153
|
+
|
|
105
154
|
# Call the DATABASE_SETUP proc directly after initialization,
|
|
106
155
|
# so the object always uses sub adapter specific code. Also,
|
|
107
156
|
# raise an error immediately if the connection doesn't have a
|
|
108
157
|
# uri, since JDBC requires one.
|
|
109
158
|
def initialize(opts)
|
|
110
159
|
super
|
|
160
|
+
@connection_prepared_statements = {}
|
|
161
|
+
@connection_prepared_statements_mutex = Mutex.new
|
|
111
162
|
@convert_types = typecast_value_boolean(@opts.fetch(:convert_types, true))
|
|
112
163
|
raise(Error, "No connection string specified") unless uri
|
|
113
164
|
|
|
@@ -158,8 +209,9 @@ module Sequel
|
|
|
158
209
|
args = [uri(opts)]
|
|
159
210
|
args.concat([opts[:user], opts[:password]]) if opts[:user] && opts[:password]
|
|
160
211
|
begin
|
|
212
|
+
JavaSQL::DriverManager.setLoginTimeout(opts[:login_timeout]) if opts[:login_timeout]
|
|
161
213
|
JavaSQL::DriverManager.getConnection(*args)
|
|
162
|
-
rescue => e
|
|
214
|
+
rescue JavaSQL::SQLException, NativeException, StandardError => e
|
|
163
215
|
raise e unless driver
|
|
164
216
|
# If the DriverManager can't get the connection - use the connect
|
|
165
217
|
# method of the driver. (This happens under Tomcat for instance)
|
|
@@ -170,8 +222,10 @@ module Sequel
|
|
|
170
222
|
end
|
|
171
223
|
opts[:jdbc_properties].each{|k,v| props.setProperty(k.to_s, v)} if opts[:jdbc_properties]
|
|
172
224
|
begin
|
|
173
|
-
driver.new.connect(args[0], props)
|
|
174
|
-
|
|
225
|
+
c = driver.new.connect(args[0], props)
|
|
226
|
+
raise(Sequel::DatabaseError, 'driver.new.connect returned nil: probably bad JDBC connection string') unless c
|
|
227
|
+
c
|
|
228
|
+
rescue JavaSQL::SQLException, NativeException, StandardError => e2
|
|
175
229
|
e.message << "\n#{e2.class.name}: #{e2.message}"
|
|
176
230
|
raise e
|
|
177
231
|
end
|
|
@@ -180,11 +234,6 @@ module Sequel
|
|
|
180
234
|
setup_connection(conn)
|
|
181
235
|
end
|
|
182
236
|
|
|
183
|
-
# Return instances of JDBC::Dataset with the given opts.
|
|
184
|
-
def dataset(opts = nil)
|
|
185
|
-
JDBC::Dataset.new(self, opts)
|
|
186
|
-
end
|
|
187
|
-
|
|
188
237
|
# Execute the given SQL. If a block is given, if should be a SELECT
|
|
189
238
|
# statement or something else that returns rows.
|
|
190
239
|
def execute(sql, opts={}, &block)
|
|
@@ -246,12 +295,14 @@ module Sequel
|
|
|
246
295
|
indexes
|
|
247
296
|
end
|
|
248
297
|
|
|
298
|
+
# Whether or not JNDI is being used for this connection.
|
|
299
|
+
def jndi?
|
|
300
|
+
!!(uri =~ JNDI_URI_REGEXP)
|
|
301
|
+
end
|
|
302
|
+
|
|
249
303
|
# All tables in this database
|
|
250
304
|
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
|
|
305
|
+
get_tables('TABLE', opts)
|
|
255
306
|
end
|
|
256
307
|
|
|
257
308
|
# The uri for this connection. You can specify the uri
|
|
@@ -264,18 +315,31 @@ module Sequel
|
|
|
264
315
|
ur =~ /^\Ajdbc:/ ? ur : "jdbc:#{ur}"
|
|
265
316
|
end
|
|
266
317
|
|
|
267
|
-
#
|
|
268
|
-
def
|
|
269
|
-
|
|
318
|
+
# All views in this database
|
|
319
|
+
def views(opts={})
|
|
320
|
+
get_tables('VIEW', opts)
|
|
270
321
|
end
|
|
271
|
-
|
|
322
|
+
|
|
272
323
|
private
|
|
273
324
|
|
|
274
|
-
#
|
|
325
|
+
# Yield the native prepared statements hash for the given connection
|
|
326
|
+
# to the block in a thread-safe manner.
|
|
327
|
+
def cps_sync(conn, &block)
|
|
328
|
+
@connection_prepared_statements_mutex.synchronize{yield(@connection_prepared_statements[conn] ||= {})}
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# Close given adapter connections, and delete any related prepared statements.
|
|
275
332
|
def disconnect_connection(c)
|
|
333
|
+
@connection_prepared_statements_mutex.synchronize{@connection_prepared_statements.delete(c)}
|
|
276
334
|
c.close
|
|
277
335
|
end
|
|
278
336
|
|
|
337
|
+
# Raise a disconnect error if the SQL state of the cause of the exception indicates so.
|
|
338
|
+
def disconnect_error?(exception, opts)
|
|
339
|
+
cause = exception.respond_to?(:cause) ? exception.cause : exception
|
|
340
|
+
super || (cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/)
|
|
341
|
+
end
|
|
342
|
+
|
|
279
343
|
# Execute the prepared statement. If the provided name is a
|
|
280
344
|
# dataset, use that as the prepared statement, otherwise use
|
|
281
345
|
# it as a key to look it up in the prepared_statements hash.
|
|
@@ -289,20 +353,25 @@ module Sequel
|
|
|
289
353
|
ps = name
|
|
290
354
|
name = ps.prepared_statement_name
|
|
291
355
|
else
|
|
292
|
-
ps =
|
|
356
|
+
ps = prepared_statement(name)
|
|
293
357
|
end
|
|
294
358
|
sql = ps.prepared_sql
|
|
295
359
|
synchronize(opts[:server]) do |conn|
|
|
296
|
-
if name and cps = conn
|
|
360
|
+
if name and cps = cps_sync(conn){|cpsh| cpsh[name]} and cps[0] == sql
|
|
297
361
|
cps = cps[1]
|
|
298
362
|
else
|
|
299
|
-
log_yield("
|
|
300
|
-
cps = log_yield("
|
|
301
|
-
conn
|
|
363
|
+
log_yield("CLOSE #{name}"){cps[1].close} if cps
|
|
364
|
+
cps = log_yield("PREPARE#{" #{name}:" if name} #{sql}"){conn.prepareStatement(sql)}
|
|
365
|
+
cps_sync(conn){|cpsh| cpsh[name] = [sql, cps]} if name
|
|
302
366
|
end
|
|
303
367
|
i = 0
|
|
304
368
|
args.each{|arg| set_ps_arg(cps, arg, i+=1)}
|
|
305
|
-
msg = "
|
|
369
|
+
msg = "EXECUTE#{" #{name}" if name}"
|
|
370
|
+
if ps.log_sql
|
|
371
|
+
msg << " ("
|
|
372
|
+
msg << sql
|
|
373
|
+
msg << ")"
|
|
374
|
+
end
|
|
306
375
|
begin
|
|
307
376
|
if block_given?
|
|
308
377
|
yield log_yield(msg, args){cps.executeQuery}
|
|
@@ -325,6 +394,12 @@ module Sequel
|
|
|
325
394
|
end
|
|
326
395
|
end
|
|
327
396
|
|
|
397
|
+
# Gets the connection from JNDI.
|
|
398
|
+
def get_connection_from_jndi
|
|
399
|
+
jndi_name = JNDI_URI_REGEXP.match(uri)[1]
|
|
400
|
+
JavaxNaming::InitialContext.new.lookup(jndi_name).connection
|
|
401
|
+
end
|
|
402
|
+
|
|
328
403
|
# Gets the JDBC connection uri from the JNDI resource.
|
|
329
404
|
def get_uri_from_jndi
|
|
330
405
|
conn = get_connection_from_jndi
|
|
@@ -333,12 +408,14 @@ module Sequel
|
|
|
333
408
|
conn.close if conn
|
|
334
409
|
end
|
|
335
410
|
|
|
336
|
-
#
|
|
337
|
-
def
|
|
338
|
-
|
|
339
|
-
|
|
411
|
+
# Backbone of the tables and views support.
|
|
412
|
+
def get_tables(type, opts)
|
|
413
|
+
ts = []
|
|
414
|
+
m = output_identifier_meth
|
|
415
|
+
metadata(:getTables, nil, nil, nil, [type].to_java(:string)){|h| ts << m.call(h[:table_name])}
|
|
416
|
+
ts
|
|
340
417
|
end
|
|
341
|
-
|
|
418
|
+
|
|
342
419
|
# Support Date objects used in bound variables
|
|
343
420
|
def java_sql_date(date)
|
|
344
421
|
java.sql.Date.new(Time.local(date.year, date.month, date.day).to_i * 1000)
|
|
@@ -354,7 +431,8 @@ module Sequel
|
|
|
354
431
|
# Support fractional seconds for Time objects used in bound variables
|
|
355
432
|
def java_sql_timestamp(time)
|
|
356
433
|
ts = java.sql.Timestamp.new(time.to_i * 1000)
|
|
357
|
-
|
|
434
|
+
# Work around jruby 1.6 ruby 1.9 mode bug
|
|
435
|
+
ts.setNanos((RUBY_VERSION >= '1.9.0' && time.nsec != 0) ? time.nsec : time.usec * 1000)
|
|
358
436
|
ts
|
|
359
437
|
end
|
|
360
438
|
|
|
@@ -383,12 +461,6 @@ module Sequel
|
|
|
383
461
|
end
|
|
384
462
|
end
|
|
385
463
|
|
|
386
|
-
# Treat SQLExceptions with a "Connection Error" SQLState as disconnects
|
|
387
|
-
def raise_error(exception, opts={})
|
|
388
|
-
cause = exception.respond_to?(:cause) ? exception.cause : exception
|
|
389
|
-
super(exception, {:disconnect => cause.respond_to?(:getSQLState) && cause.getSQLState =~ /^08/}.merge(opts))
|
|
390
|
-
end
|
|
391
|
-
|
|
392
464
|
# Java being java, you need to specify the type of each argument
|
|
393
465
|
# for the prepared statement, and bind it individually. This
|
|
394
466
|
# guesses which JDBC method to use, and hopefully JRuby will convert
|
|
@@ -405,8 +477,8 @@ module Sequel
|
|
|
405
477
|
cps.setDouble(i, arg)
|
|
406
478
|
when TrueClass, FalseClass
|
|
407
479
|
cps.setBoolean(i, arg)
|
|
408
|
-
when
|
|
409
|
-
cps
|
|
480
|
+
when NilClass
|
|
481
|
+
set_ps_arg_nil(cps, i)
|
|
410
482
|
when DateTime
|
|
411
483
|
cps.setTimestamp(i, java_sql_datetime(arg))
|
|
412
484
|
when Date
|
|
@@ -421,22 +493,22 @@ module Sequel
|
|
|
421
493
|
cps.setObject(i, arg)
|
|
422
494
|
end
|
|
423
495
|
end
|
|
496
|
+
|
|
497
|
+
# Use setString with a nil value by default, but this doesn't work on all subadapters.
|
|
498
|
+
def set_ps_arg_nil(cps, i)
|
|
499
|
+
cps.setString(i, nil)
|
|
500
|
+
end
|
|
424
501
|
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
# adapter specific prepared statements.
|
|
502
|
+
# Return the connection. Used to do configuration on the
|
|
503
|
+
# connection object before adding it to the connection pool.
|
|
428
504
|
def setup_connection(conn)
|
|
429
|
-
class << conn
|
|
430
|
-
attr_accessor :prepared_statements
|
|
431
|
-
end
|
|
432
|
-
conn.prepared_statements = {}
|
|
433
505
|
conn
|
|
434
506
|
end
|
|
435
507
|
|
|
436
508
|
# Parse the table schema for the given table.
|
|
437
509
|
def schema_parse_table(table, opts={})
|
|
438
|
-
m = output_identifier_meth
|
|
439
|
-
im = input_identifier_meth
|
|
510
|
+
m = output_identifier_meth(opts[:dataset])
|
|
511
|
+
im = input_identifier_meth(opts[:dataset])
|
|
440
512
|
ds = dataset
|
|
441
513
|
schema, table = schema_and_table(table)
|
|
442
514
|
schema ||= opts[:schema]
|
|
@@ -444,9 +516,11 @@ module Sequel
|
|
|
444
516
|
table = im.call(table)
|
|
445
517
|
pks, ts = [], []
|
|
446
518
|
metadata(:getPrimaryKeys, nil, schema, table) do |h|
|
|
519
|
+
next if schema_parse_table_skip?(h, schema)
|
|
447
520
|
pks << h[:column_name]
|
|
448
521
|
end
|
|
449
522
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
|
523
|
+
next if schema_parse_table_skip?(h, schema)
|
|
450
524
|
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
525
|
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
|
452
526
|
s[:type] = :integer
|
|
@@ -456,6 +530,12 @@ module Sequel
|
|
|
456
530
|
ts
|
|
457
531
|
end
|
|
458
532
|
|
|
533
|
+
# Whether schema_parse_table should skip the given row when
|
|
534
|
+
# parsing the schema.
|
|
535
|
+
def schema_parse_table_skip?(h, schema)
|
|
536
|
+
h[:table_schem] == 'INFORMATION_SCHEMA'
|
|
537
|
+
end
|
|
538
|
+
|
|
459
539
|
# Yield a new statement object, and ensure that it is closed before returning.
|
|
460
540
|
def statement(conn)
|
|
461
541
|
stmt = conn.createStatement
|
|
@@ -476,6 +556,8 @@ module Sequel
|
|
|
476
556
|
|
|
477
557
|
class Dataset < Sequel::Dataset
|
|
478
558
|
include StoredProcedures
|
|
559
|
+
|
|
560
|
+
Database::DatasetClass = self
|
|
479
561
|
|
|
480
562
|
# Use JDBC PreparedStatements instead of emulated ones. Statements
|
|
481
563
|
# created using #prepare are cached at the connection level to allow
|
|
@@ -489,17 +571,17 @@ module Sequel
|
|
|
489
571
|
# Execute the prepared SQL using the stored type and
|
|
490
572
|
# arguments derived from the hash passed to call.
|
|
491
573
|
def execute(sql, opts={}, &block)
|
|
492
|
-
super(self, {:arguments=>bind_arguments
|
|
574
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
493
575
|
end
|
|
494
576
|
|
|
495
577
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
496
578
|
def execute_dui(sql, opts={}, &block)
|
|
497
|
-
super(self, {:arguments=>bind_arguments
|
|
579
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
498
580
|
end
|
|
499
581
|
|
|
500
582
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
501
583
|
def execute_insert(sql, opts={}, &block)
|
|
502
|
-
super(self, {:arguments=>bind_arguments, :type
|
|
584
|
+
super(self, {:arguments=>bind_arguments, :type=>:insert}.merge(opts), &block)
|
|
503
585
|
end
|
|
504
586
|
end
|
|
505
587
|
|
|
@@ -512,17 +594,17 @@ module Sequel
|
|
|
512
594
|
|
|
513
595
|
# Execute the database stored procedure with the stored arguments.
|
|
514
596
|
def execute(sql, opts={}, &block)
|
|
515
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
597
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
516
598
|
end
|
|
517
599
|
|
|
518
600
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
519
601
|
def execute_dui(sql, opts={}, &block)
|
|
520
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
602
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
521
603
|
end
|
|
522
604
|
|
|
523
605
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
524
606
|
def execute_insert(sql, opts={}, &block)
|
|
525
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type
|
|
607
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>:insert}.merge(opts), &block)
|
|
526
608
|
end
|
|
527
609
|
end
|
|
528
610
|
|
|
@@ -530,13 +612,7 @@ module Sequel
|
|
|
530
612
|
# Uses the database's setting by default, can be set to false to roughly
|
|
531
613
|
# double performance when fetching rows.
|
|
532
614
|
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
|
-
|
|
615
|
+
|
|
540
616
|
# Correctly return rows from the database and return them as hashes.
|
|
541
617
|
def fetch_rows(sql, &block)
|
|
542
618
|
execute(sql){|result| process_result_set(result, &block)}
|
|
@@ -550,32 +626,88 @@ module Sequel
|
|
|
550
626
|
ps.extend(PreparedStatementMethods)
|
|
551
627
|
if name
|
|
552
628
|
ps.prepared_statement_name = name
|
|
553
|
-
db.
|
|
629
|
+
db.set_prepared_statement(name, ps)
|
|
554
630
|
end
|
|
555
631
|
ps
|
|
556
632
|
end
|
|
557
633
|
|
|
558
634
|
private
|
|
559
|
-
|
|
560
|
-
#
|
|
561
|
-
|
|
635
|
+
|
|
636
|
+
# Cache Java class constants to speed up lookups
|
|
637
|
+
JAVA_SQL_TIMESTAMP = Java::JavaSQL::Timestamp
|
|
638
|
+
JAVA_SQL_TIME = Java::JavaSQL::Time
|
|
639
|
+
JAVA_SQL_DATE = Java::JavaSQL::Date
|
|
640
|
+
JAVA_SQL_BLOB = Java::JavaSQL::Blob
|
|
641
|
+
JAVA_SQL_CLOB = Java::JavaSQL::Clob
|
|
642
|
+
JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
|
|
643
|
+
JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
|
|
644
|
+
JAVA_BYTE_ARRAY = Java::byte[]
|
|
645
|
+
JAVA_UUID = Java::JavaUtil::UUID
|
|
646
|
+
|
|
647
|
+
# Handle type conversions for common Java types.
|
|
648
|
+
class TYPE_TRANSLATOR
|
|
649
|
+
LF = "\n".freeze
|
|
650
|
+
def time(v) Sequel.string_to_time("#{v.to_string}.#{sprintf('%03i', v.getTime.divmod(1000).last)}") end
|
|
651
|
+
def date(v) Date.civil(v.getYear + 1900, v.getMonth + 1, v.getDate) end
|
|
652
|
+
def decimal(v) BigDecimal.new(v.to_string) end
|
|
653
|
+
def byte_array(v) Sequel::SQL::Blob.new(String.from_java_bytes(v)) end
|
|
654
|
+
def blob(v) Sequel::SQL::Blob.new(String.from_java_bytes(v.getBytes(1, v.length))) end
|
|
655
|
+
def clob(v) Sequel::SQL::Blob.new(v.getSubString(1, v.length)) end
|
|
656
|
+
def buffered_reader(v)
|
|
657
|
+
lines = ""
|
|
658
|
+
c = false
|
|
659
|
+
while(line = v.read_line) do
|
|
660
|
+
lines << LF if c
|
|
661
|
+
lines << line
|
|
662
|
+
c ||= true
|
|
663
|
+
end
|
|
664
|
+
lines
|
|
665
|
+
end
|
|
666
|
+
def uuid(v) v.to_string end
|
|
667
|
+
end
|
|
668
|
+
TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
|
|
669
|
+
|
|
670
|
+
# Cache type translator methods so that duplicate Method
|
|
671
|
+
# objects are not created.
|
|
672
|
+
DECIMAL_METHOD = tt.method(:decimal)
|
|
673
|
+
TIME_METHOD = tt.method(:time)
|
|
674
|
+
DATE_METHOD = tt.method(:date)
|
|
675
|
+
BUFFERED_READER_METHOD = tt.method(:buffered_reader)
|
|
676
|
+
BYTE_ARRAY_METHOD = tt.method(:byte_array)
|
|
677
|
+
BLOB_METHOD = tt.method(:blob)
|
|
678
|
+
CLOB_METHOD = tt.method(:clob)
|
|
679
|
+
UUID_METHOD = tt.method(:uuid)
|
|
680
|
+
|
|
681
|
+
# Convert the given Java timestamp to an instance of Sequel.datetime_class.
|
|
682
|
+
def convert_type_timestamp(v)
|
|
683
|
+
db.to_application_timestamp([v.getYear + 1900, v.getMonth + 1, v.getDate, v.getHours, v.getMinutes, v.getSeconds, v.getNanos])
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
# Return a callable object that will convert any value of <tt>v</tt>'s
|
|
687
|
+
# class to a ruby object. If no callable object can handle <tt>v</tt>'s
|
|
688
|
+
# class, return false so that the negative lookup is cached.
|
|
689
|
+
def convert_type_proc(v)
|
|
562
690
|
case v
|
|
563
|
-
when
|
|
564
|
-
|
|
565
|
-
when
|
|
566
|
-
|
|
567
|
-
when
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
when
|
|
572
|
-
|
|
573
|
-
when
|
|
574
|
-
|
|
575
|
-
when
|
|
576
|
-
|
|
691
|
+
when JAVA_BIG_DECIMAL
|
|
692
|
+
DECIMAL_METHOD
|
|
693
|
+
when JAVA_SQL_TIMESTAMP
|
|
694
|
+
method(:convert_type_timestamp)
|
|
695
|
+
when JAVA_SQL_TIME
|
|
696
|
+
TIME_METHOD
|
|
697
|
+
when JAVA_SQL_DATE
|
|
698
|
+
DATE_METHOD
|
|
699
|
+
when JAVA_BUFFERED_READER
|
|
700
|
+
BUFFERED_READER_METHOD
|
|
701
|
+
when JAVA_BYTE_ARRAY
|
|
702
|
+
BYTE_ARRAY_METHOD
|
|
703
|
+
when JAVA_SQL_BLOB
|
|
704
|
+
BLOB_METHOD
|
|
705
|
+
when JAVA_SQL_CLOB
|
|
706
|
+
CLOB_METHOD
|
|
707
|
+
when JAVA_UUID
|
|
708
|
+
UUID_METHOD
|
|
577
709
|
else
|
|
578
|
-
|
|
710
|
+
false
|
|
579
711
|
end
|
|
580
712
|
end
|
|
581
713
|
|
|
@@ -586,32 +718,82 @@ module Sequel
|
|
|
586
718
|
|
|
587
719
|
# Split out from fetch rows to allow processing of JDBC result sets
|
|
588
720
|
# that don't come from issuing an SQL string.
|
|
589
|
-
def process_result_set(result)
|
|
721
|
+
def process_result_set(result, &block)
|
|
590
722
|
# get column names
|
|
591
723
|
meta = result.getMetaData
|
|
592
724
|
cols = []
|
|
593
725
|
i = 0
|
|
594
726
|
meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
727
|
+
columns = cols.map{|c| c.at(0)}
|
|
728
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
729
|
+
rn = row_number_column
|
|
730
|
+
columns.delete(rn)
|
|
731
|
+
end
|
|
732
|
+
@columns = columns
|
|
733
|
+
ct = @convert_types
|
|
734
|
+
if (ct.nil? ? db.convert_types : ct)
|
|
735
|
+
cols.each{|c| c << nil}
|
|
736
|
+
process_result_set_convert(cols, result, rn, &block)
|
|
737
|
+
else
|
|
738
|
+
process_result_set_no_convert(cols, result, rn, &block)
|
|
739
|
+
end
|
|
740
|
+
ensure
|
|
741
|
+
result.close
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
# Use conversion procs to convert data retrieved
|
|
745
|
+
# from the database. This has been optimized, the algorithm it uses
|
|
746
|
+
# is roughly, for each column value in each row:
|
|
747
|
+
# * check if the value is truthy (not false/nil)
|
|
748
|
+
# * if not truthy, return object
|
|
749
|
+
# * otherwise, see if a conversion method exists for
|
|
750
|
+
# the column. All columns start with a nil conversion proc,
|
|
751
|
+
# since unlike other adapters, Sequel doesn't get the type of
|
|
752
|
+
# the column when parsing the column metadata.
|
|
753
|
+
# * if a conversion proc is not false/nil, call it with the object
|
|
754
|
+
# and return the result.
|
|
755
|
+
# * if a conversion proc has already been looked up and doesn't
|
|
756
|
+
# exist (false value), return object.
|
|
757
|
+
# * if a conversion proc hasn't been looked up yet (nil value),
|
|
758
|
+
# call convert_type_proc to get the conversion method. Cache
|
|
759
|
+
# the result of as the column's conversion proc to speed up
|
|
760
|
+
# later processing. If the conversion proc exists, call it
|
|
761
|
+
# and return the result, otherwise, return the object.
|
|
762
|
+
def process_result_set_convert(cols, result, rn)
|
|
598
763
|
while result.next
|
|
599
764
|
row = {}
|
|
600
|
-
cols.each do |n, i|
|
|
601
|
-
|
|
765
|
+
cols.each do |n, i, p|
|
|
766
|
+
v = result.getObject(i)
|
|
767
|
+
row[n] = if v
|
|
768
|
+
if p
|
|
769
|
+
p.call(v)
|
|
770
|
+
elsif p.nil?
|
|
771
|
+
cols[i-1][2] = p = convert_type_proc(v)
|
|
772
|
+
if p
|
|
773
|
+
p.call(v)
|
|
774
|
+
else
|
|
775
|
+
v
|
|
776
|
+
end
|
|
777
|
+
else
|
|
778
|
+
v
|
|
779
|
+
end
|
|
780
|
+
else
|
|
781
|
+
v
|
|
782
|
+
end
|
|
602
783
|
end
|
|
784
|
+
row.delete(rn) if rn
|
|
603
785
|
yield row
|
|
604
786
|
end
|
|
605
787
|
end
|
|
606
788
|
|
|
607
|
-
#
|
|
608
|
-
#
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
789
|
+
# Yield rows without calling any conversion procs. This
|
|
790
|
+
# may yield Java values and not ruby values.
|
|
791
|
+
def process_result_set_no_convert(cols, result, rn)
|
|
792
|
+
while result.next
|
|
793
|
+
row = {}
|
|
794
|
+
cols.each{|n, i| row[n] = result.getObject(i)}
|
|
795
|
+
row.delete(rn) if rn
|
|
796
|
+
yield row
|
|
615
797
|
end
|
|
616
798
|
end
|
|
617
799
|
end
|