sequel 3.21.0 → 3.36.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 +855 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -7
- data/Rakefile +42 -24
- data/bin/sequel +26 -8
- data/doc/active_record.rdoc +1 -0
- data/doc/advanced_associations.rdoc +171 -11
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +85 -552
- data/doc/model_hooks.rdoc +78 -27
- data/doc/object_model.rdoc +541 -0
- data/doc/opening_databases.rdoc +97 -50
- data/doc/prepared_statements.rdoc +40 -14
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +30 -4
- 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/schema_modification.rdoc +572 -0
- data/doc/sharding.rdoc +95 -3
- data/doc/testing.rdoc +129 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +51 -2
- 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 +1 -57
- 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 +47 -0
- data/lib/sequel/adapters/jdbc/derby.rb +287 -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 +29 -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 +58 -48
- 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 +265 -94
- data/lib/sequel/adapters/mock.rb +361 -0
- data/lib/sequel/adapters/mysql.rb +118 -222
- data/lib/sequel/adapters/mysql2.rb +58 -57
- data/lib/sequel/adapters/odbc/mssql.rb +15 -7
- 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 +356 -107
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +342 -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 +335 -118
- data/lib/sequel/adapters/shared/mysql.rb +340 -76
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +243 -45
- data/lib/sequel/adapters/shared/postgres.rb +524 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +265 -89
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +9 -12
- data/lib/sequel/adapters/swift/postgres.rb +9 -74
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +8 -7
- data/lib/sequel/adapters/tinytds.rb +161 -21
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -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 +28 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +38 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +118 -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 +150 -46
- data/lib/sequel/database/query.rb +215 -65
- data/lib/sequel/database/schema_generator.rb +64 -20
- data/lib/sequel/database/schema_methods.rb +212 -54
- data/lib/sequel/dataset/actions.rb +322 -85
- data/lib/sequel/dataset/features.rb +96 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +237 -44
- data/lib/sequel/dataset/sql.rb +698 -278
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
- data/lib/sequel/extensions/migration.rb +97 -11
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_inet.rb +89 -0
- data/lib/sequel/extensions/pg_json.rb +178 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query.rb +1 -1
- 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 +251 -37
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +1187 -393
- data/lib/sequel/model/base.rb +578 -170
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- 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/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -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 +123 -8
- 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 +12 -2
- data/lib/sequel/plugins/many_through_many.rb +79 -28
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +139 -63
- data/lib/sequel/plugins/optimistic_locking.rb +8 -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 +29 -15
- data/lib/sequel/plugins/schema.rb +7 -2
- 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 +10 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -1
- 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/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +526 -59
- data/lib/sequel/timezones.rb +57 -38
- 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 +142 -40
- data/spec/adapters/mysql_spec.rb +380 -234
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +1050 -212
- data/spec/adapters/spec_helper.rb +8 -5
- data/spec/adapters/sqlite_spec.rb +139 -27
- data/spec/core/connection_pool_spec.rb +196 -93
- data/spec/core/database_spec.rb +879 -510
- data/spec/core/dataset_spec.rb +1415 -1086
- data/spec/core/expression_filters_spec.rb +554 -109
- data/spec/core/mock_adapter_spec.rb +449 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +482 -38
- data/spec/core/spec_helper.rb +6 -48
- 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/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/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +69 -92
- data/spec/extensions/identity_map_spec.rb +131 -22
- 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 -6
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +48 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- 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 +251 -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 +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_inet_spec.rb +44 -0
- data/spec/extensions/pg_json_spec.rb +101 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -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 +168 -0
- data/spec/extensions/query_spec.rb +6 -0
- 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 +429 -22
- data/spec/extensions/schema_spec.rb +25 -21
- 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 +85 -43
- 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 +22 -61
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -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 +4 -7
- 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 +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- 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 +9 -3
- data/spec/integration/dataset_test.rb +605 -91
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +454 -143
- data/spec/integration/prepared_statement_test.rb +263 -128
- data/spec/integration/schema_test.rb +309 -43
- data/spec/integration/spec_helper.rb +40 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +18 -4
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +1067 -661
- data/spec/model/base_spec.rb +329 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +240 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +490 -232
- data/spec/model/spec_helper.rb +14 -71
- data/spec/model/validations_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- metadata +178 -80
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/
|
|
68
|
+
Sequel.ts_require 'adapters/jdbc/jtds'
|
|
62
69
|
db.extend(Sequel::JDBC::MSSQL::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)
|
|
@@ -171,7 +223,9 @@ module Sequel
|
|
|
171
223
|
opts[:jdbc_properties].each{|k,v| props.setProperty(k.to_s, v)} if opts[:jdbc_properties]
|
|
172
224
|
begin
|
|
173
225
|
driver.new.connect(args[0], props)
|
|
174
|
-
|
|
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)
|
|
@@ -383,12 +460,6 @@ module Sequel
|
|
|
383
460
|
end
|
|
384
461
|
end
|
|
385
462
|
|
|
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
463
|
# Java being java, you need to specify the type of each argument
|
|
393
464
|
# for the prepared statement, and bind it individually. This
|
|
394
465
|
# guesses which JDBC method to use, and hopefully JRuby will convert
|
|
@@ -405,8 +476,8 @@ module Sequel
|
|
|
405
476
|
cps.setDouble(i, arg)
|
|
406
477
|
when TrueClass, FalseClass
|
|
407
478
|
cps.setBoolean(i, arg)
|
|
408
|
-
when
|
|
409
|
-
cps.
|
|
479
|
+
when NilClass
|
|
480
|
+
cps.setString(i, nil)
|
|
410
481
|
when DateTime
|
|
411
482
|
cps.setTimestamp(i, java_sql_datetime(arg))
|
|
412
483
|
when Date
|
|
@@ -422,21 +493,16 @@ module Sequel
|
|
|
422
493
|
end
|
|
423
494
|
end
|
|
424
495
|
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
# adapter specific prepared statements.
|
|
496
|
+
# Return the connection. Used to do configuration on the
|
|
497
|
+
# connection object before adding it to the connection pool.
|
|
428
498
|
def setup_connection(conn)
|
|
429
|
-
class << conn
|
|
430
|
-
attr_accessor :prepared_statements
|
|
431
|
-
end
|
|
432
|
-
conn.prepared_statements = {}
|
|
433
499
|
conn
|
|
434
500
|
end
|
|
435
501
|
|
|
436
502
|
# Parse the table schema for the given table.
|
|
437
503
|
def schema_parse_table(table, opts={})
|
|
438
|
-
m = output_identifier_meth
|
|
439
|
-
im = input_identifier_meth
|
|
504
|
+
m = output_identifier_meth(opts[:dataset])
|
|
505
|
+
im = input_identifier_meth(opts[:dataset])
|
|
440
506
|
ds = dataset
|
|
441
507
|
schema, table = schema_and_table(table)
|
|
442
508
|
schema ||= opts[:schema]
|
|
@@ -444,9 +510,11 @@ module Sequel
|
|
|
444
510
|
table = im.call(table)
|
|
445
511
|
pks, ts = [], []
|
|
446
512
|
metadata(:getPrimaryKeys, nil, schema, table) do |h|
|
|
513
|
+
next if schema_parse_table_skip?(h, schema)
|
|
447
514
|
pks << h[:column_name]
|
|
448
515
|
end
|
|
449
516
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
|
517
|
+
next if schema_parse_table_skip?(h, schema)
|
|
450
518
|
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
519
|
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
|
452
520
|
s[:type] = :integer
|
|
@@ -456,6 +524,12 @@ module Sequel
|
|
|
456
524
|
ts
|
|
457
525
|
end
|
|
458
526
|
|
|
527
|
+
# Whether schema_parse_table should skip the given row when
|
|
528
|
+
# parsing the schema.
|
|
529
|
+
def schema_parse_table_skip?(h, schema)
|
|
530
|
+
h[:table_schem] == 'INFORMATION_SCHEMA'
|
|
531
|
+
end
|
|
532
|
+
|
|
459
533
|
# Yield a new statement object, and ensure that it is closed before returning.
|
|
460
534
|
def statement(conn)
|
|
461
535
|
stmt = conn.createStatement
|
|
@@ -476,6 +550,8 @@ module Sequel
|
|
|
476
550
|
|
|
477
551
|
class Dataset < Sequel::Dataset
|
|
478
552
|
include StoredProcedures
|
|
553
|
+
|
|
554
|
+
Database::DatasetClass = self
|
|
479
555
|
|
|
480
556
|
# Use JDBC PreparedStatements instead of emulated ones. Statements
|
|
481
557
|
# created using #prepare are cached at the connection level to allow
|
|
@@ -489,17 +565,17 @@ module Sequel
|
|
|
489
565
|
# Execute the prepared SQL using the stored type and
|
|
490
566
|
# arguments derived from the hash passed to call.
|
|
491
567
|
def execute(sql, opts={}, &block)
|
|
492
|
-
super(self, {:arguments=>bind_arguments
|
|
568
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
493
569
|
end
|
|
494
570
|
|
|
495
571
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
496
572
|
def execute_dui(sql, opts={}, &block)
|
|
497
|
-
super(self, {:arguments=>bind_arguments
|
|
573
|
+
super(self, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
498
574
|
end
|
|
499
575
|
|
|
500
576
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
501
577
|
def execute_insert(sql, opts={}, &block)
|
|
502
|
-
super(self, {:arguments=>bind_arguments, :type
|
|
578
|
+
super(self, {:arguments=>bind_arguments, :type=>:insert}.merge(opts), &block)
|
|
503
579
|
end
|
|
504
580
|
end
|
|
505
581
|
|
|
@@ -512,17 +588,17 @@ module Sequel
|
|
|
512
588
|
|
|
513
589
|
# Execute the database stored procedure with the stored arguments.
|
|
514
590
|
def execute(sql, opts={}, &block)
|
|
515
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
591
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
516
592
|
end
|
|
517
593
|
|
|
518
594
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
519
595
|
def execute_dui(sql, opts={}, &block)
|
|
520
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true
|
|
596
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
521
597
|
end
|
|
522
598
|
|
|
523
599
|
# Same as execute, explicit due to intricacies of alias and super.
|
|
524
600
|
def execute_insert(sql, opts={}, &block)
|
|
525
|
-
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type
|
|
601
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true, :type=>:insert}.merge(opts), &block)
|
|
526
602
|
end
|
|
527
603
|
end
|
|
528
604
|
|
|
@@ -530,13 +606,7 @@ module Sequel
|
|
|
530
606
|
# Uses the database's setting by default, can be set to false to roughly
|
|
531
607
|
# double performance when fetching rows.
|
|
532
608
|
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
|
-
|
|
609
|
+
|
|
540
610
|
# Correctly return rows from the database and return them as hashes.
|
|
541
611
|
def fetch_rows(sql, &block)
|
|
542
612
|
execute(sql){|result| process_result_set(result, &block)}
|
|
@@ -550,32 +620,83 @@ module Sequel
|
|
|
550
620
|
ps.extend(PreparedStatementMethods)
|
|
551
621
|
if name
|
|
552
622
|
ps.prepared_statement_name = name
|
|
553
|
-
db.
|
|
623
|
+
db.set_prepared_statement(name, ps)
|
|
554
624
|
end
|
|
555
625
|
ps
|
|
556
626
|
end
|
|
557
627
|
|
|
558
628
|
private
|
|
559
|
-
|
|
560
|
-
#
|
|
561
|
-
|
|
629
|
+
|
|
630
|
+
# Cache Java class constants to speed up lookups
|
|
631
|
+
JAVA_SQL_TIMESTAMP = Java::JavaSQL::Timestamp
|
|
632
|
+
JAVA_SQL_TIME = Java::JavaSQL::Time
|
|
633
|
+
JAVA_SQL_DATE = Java::JavaSQL::Date
|
|
634
|
+
JAVA_SQL_BLOB = Java::JavaSQL::Blob
|
|
635
|
+
JAVA_SQL_CLOB = Java::JavaSQL::Clob
|
|
636
|
+
JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
|
|
637
|
+
JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
|
|
638
|
+
JAVA_BYTE_ARRAY = Java::byte[]
|
|
639
|
+
|
|
640
|
+
# Handle type conversions for common Java types.
|
|
641
|
+
class TYPE_TRANSLATOR
|
|
642
|
+
LF = "\n".freeze
|
|
643
|
+
def time(v) Sequel.string_to_time("#{v.to_string}.#{sprintf('%03i', v.getTime.divmod(1000).last)}") end
|
|
644
|
+
def date(v) Date.civil(v.getYear + 1900, v.getMonth + 1, v.getDate) end
|
|
645
|
+
def decimal(v) BigDecimal.new(v.to_string) end
|
|
646
|
+
def byte_array(v) Sequel::SQL::Blob.new(String.from_java_bytes(v)) end
|
|
647
|
+
def blob(v) Sequel::SQL::Blob.new(String.from_java_bytes(v.getBytes(1, v.length))) end
|
|
648
|
+
def clob(v) Sequel::SQL::Blob.new(v.getSubString(1, v.length)) end
|
|
649
|
+
def buffered_reader(v)
|
|
650
|
+
lines = ""
|
|
651
|
+
c = false
|
|
652
|
+
while(line = v.read_line) do
|
|
653
|
+
lines << LF if c
|
|
654
|
+
lines << line
|
|
655
|
+
c ||= true
|
|
656
|
+
end
|
|
657
|
+
lines
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
|
|
661
|
+
|
|
662
|
+
# Cache type translator methods so that duplicate Method
|
|
663
|
+
# objects are not created.
|
|
664
|
+
DECIMAL_METHOD = tt.method(:decimal)
|
|
665
|
+
TIME_METHOD = tt.method(:time)
|
|
666
|
+
DATE_METHOD = tt.method(:date)
|
|
667
|
+
BUFFERED_READER_METHOD = tt.method(:buffered_reader)
|
|
668
|
+
BYTE_ARRAY_METHOD = tt.method(:byte_array)
|
|
669
|
+
BLOB_METHOD = tt.method(:blob)
|
|
670
|
+
CLOB_METHOD = tt.method(:clob)
|
|
671
|
+
|
|
672
|
+
# Convert the given Java timestamp to an instance of Sequel.datetime_class.
|
|
673
|
+
def convert_type_timestamp(v)
|
|
674
|
+
db.to_application_timestamp([v.getYear + 1900, v.getMonth + 1, v.getDate, v.getHours, v.getMinutes, v.getSeconds, v.getNanos])
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
# Return a callable object that will convert any value of <tt>v</tt>'s
|
|
678
|
+
# class to a ruby object. If no callable object can handle <tt>v</tt>'s
|
|
679
|
+
# class, return false so that the negative lookup is cached.
|
|
680
|
+
def convert_type_proc(v)
|
|
562
681
|
case v
|
|
563
|
-
when
|
|
564
|
-
|
|
565
|
-
when
|
|
566
|
-
|
|
567
|
-
when
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
when
|
|
572
|
-
|
|
573
|
-
when
|
|
574
|
-
|
|
575
|
-
when
|
|
576
|
-
|
|
682
|
+
when JAVA_BIG_DECIMAL
|
|
683
|
+
DECIMAL_METHOD
|
|
684
|
+
when JAVA_SQL_TIMESTAMP
|
|
685
|
+
method(:convert_type_timestamp)
|
|
686
|
+
when JAVA_SQL_TIME
|
|
687
|
+
TIME_METHOD
|
|
688
|
+
when JAVA_SQL_DATE
|
|
689
|
+
DATE_METHOD
|
|
690
|
+
when JAVA_BUFFERED_READER
|
|
691
|
+
BUFFERED_READER_METHOD
|
|
692
|
+
when JAVA_BYTE_ARRAY
|
|
693
|
+
BYTE_ARRAY_METHOD
|
|
694
|
+
when JAVA_SQL_BLOB
|
|
695
|
+
BLOB_METHOD
|
|
696
|
+
when JAVA_SQL_CLOB
|
|
697
|
+
CLOB_METHOD
|
|
577
698
|
else
|
|
578
|
-
|
|
699
|
+
false
|
|
579
700
|
end
|
|
580
701
|
end
|
|
581
702
|
|
|
@@ -586,32 +707,82 @@ module Sequel
|
|
|
586
707
|
|
|
587
708
|
# Split out from fetch rows to allow processing of JDBC result sets
|
|
588
709
|
# that don't come from issuing an SQL string.
|
|
589
|
-
def process_result_set(result)
|
|
710
|
+
def process_result_set(result, &block)
|
|
590
711
|
# get column names
|
|
591
712
|
meta = result.getMetaData
|
|
592
713
|
cols = []
|
|
593
714
|
i = 0
|
|
594
715
|
meta.getColumnCount.times{cols << [output_identifier(meta.getColumnLabel(i+=1)), i]}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
716
|
+
columns = cols.map{|c| c.at(0)}
|
|
717
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
718
|
+
rn = row_number_column
|
|
719
|
+
columns.delete(rn)
|
|
720
|
+
end
|
|
721
|
+
@columns = columns
|
|
722
|
+
ct = @convert_types
|
|
723
|
+
if (ct.nil? ? db.convert_types : ct)
|
|
724
|
+
cols.each{|c| c << nil}
|
|
725
|
+
process_result_set_convert(cols, result, rn, &block)
|
|
726
|
+
else
|
|
727
|
+
process_result_set_no_convert(cols, result, rn, &block)
|
|
728
|
+
end
|
|
729
|
+
ensure
|
|
730
|
+
result.close
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
# Use conversion procs to convert data retrieved
|
|
734
|
+
# from the database. This has been optimized, the algorithm it uses
|
|
735
|
+
# is roughly, for each column value in each row:
|
|
736
|
+
# * check if the value is truthy (not false/nil)
|
|
737
|
+
# * if not truthy, return object
|
|
738
|
+
# * otherwise, see if a conversion method exists for
|
|
739
|
+
# the column. All columns start with a nil conversion proc,
|
|
740
|
+
# since unlike other adapters, Sequel doesn't get the type of
|
|
741
|
+
# the column when parsing the column metadata.
|
|
742
|
+
# * if a conversion proc is not false/nil, call it with the object
|
|
743
|
+
# and return the result.
|
|
744
|
+
# * if a conversion proc has already been looked up and doesn't
|
|
745
|
+
# exist (false value), return object.
|
|
746
|
+
# * if a conversion proc hasn't been looked up yet (nil value),
|
|
747
|
+
# call convert_type_proc to get the conversion method. Cache
|
|
748
|
+
# the result of as the column's conversion proc to speed up
|
|
749
|
+
# later processing. If the conversion proc exists, call it
|
|
750
|
+
# and return the result, otherwise, return the object.
|
|
751
|
+
def process_result_set_convert(cols, result, rn)
|
|
598
752
|
while result.next
|
|
599
753
|
row = {}
|
|
600
|
-
cols.each do |n, i|
|
|
601
|
-
|
|
754
|
+
cols.each do |n, i, p|
|
|
755
|
+
v = result.getObject(i)
|
|
756
|
+
row[n] = if v
|
|
757
|
+
if p
|
|
758
|
+
p.call(v)
|
|
759
|
+
elsif p.nil?
|
|
760
|
+
cols[i-1][2] = p = convert_type_proc(v)
|
|
761
|
+
if p
|
|
762
|
+
p.call(v)
|
|
763
|
+
else
|
|
764
|
+
v
|
|
765
|
+
end
|
|
766
|
+
else
|
|
767
|
+
v
|
|
768
|
+
end
|
|
769
|
+
else
|
|
770
|
+
v
|
|
771
|
+
end
|
|
602
772
|
end
|
|
773
|
+
row.delete(rn) if rn
|
|
603
774
|
yield row
|
|
604
775
|
end
|
|
605
776
|
end
|
|
606
777
|
|
|
607
|
-
#
|
|
608
|
-
#
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
778
|
+
# Yield rows without calling any conversion procs. This
|
|
779
|
+
# may yield Java values and not ruby values.
|
|
780
|
+
def process_result_set_no_convert(cols, result, rn)
|
|
781
|
+
while result.next
|
|
782
|
+
row = {}
|
|
783
|
+
cols.each{|n, i| row[n] = result.getObject(i)}
|
|
784
|
+
row.delete(rn) if rn
|
|
785
|
+
yield row
|
|
615
786
|
end
|
|
616
787
|
end
|
|
617
788
|
end
|