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
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'cubrid'
|
|
2
|
+
Sequel.require 'adapters/shared/cubrid'
|
|
3
|
+
|
|
4
|
+
module Sequel
|
|
5
|
+
module Cubrid
|
|
6
|
+
CUBRID_TYPE_PROCS = {
|
|
7
|
+
::Cubrid::DATE => lambda{|t| Date.new(t.year, t.month, t.day)},
|
|
8
|
+
::Cubrid::TIME => lambda{|t| SQLTime.create(t.hour, t.min, t.sec)},
|
|
9
|
+
21 => lambda{|s| s.to_i}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class Database < Sequel::Database
|
|
13
|
+
include Sequel::Cubrid::DatabaseMethods
|
|
14
|
+
|
|
15
|
+
ROW_COUNT = "SELECT ROW_COUNT()".freeze
|
|
16
|
+
LAST_INSERT_ID = "SELECT LAST_INSERT_ID()".freeze
|
|
17
|
+
|
|
18
|
+
set_adapter_scheme :cubrid
|
|
19
|
+
|
|
20
|
+
def connect(server)
|
|
21
|
+
opts = server_opts(server)
|
|
22
|
+
conn = ::Cubrid.connect(
|
|
23
|
+
opts[:database],
|
|
24
|
+
opts[:host] || 'localhost',
|
|
25
|
+
opts[:port] || 30000,
|
|
26
|
+
opts[:user] || 'public',
|
|
27
|
+
opts[:password] || ''
|
|
28
|
+
)
|
|
29
|
+
conn.auto_commit = true
|
|
30
|
+
conn
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def server_version
|
|
34
|
+
@server_version ||= synchronize{|c| c.server_version}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def execute(sql, opts={})
|
|
38
|
+
synchronize(opts[:server]) do |conn|
|
|
39
|
+
r = log_yield(sql) do
|
|
40
|
+
begin
|
|
41
|
+
conn.query(sql)
|
|
42
|
+
rescue => e
|
|
43
|
+
raise_error(e)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
if block_given?
|
|
47
|
+
yield(r)
|
|
48
|
+
else
|
|
49
|
+
begin
|
|
50
|
+
case opts[:type]
|
|
51
|
+
when :dui
|
|
52
|
+
# This is cubrid's API, but it appears to be completely broken,
|
|
53
|
+
# giving StandardError: ERROR: CCI, -18, Invalid request handle
|
|
54
|
+
#r.affected_rows
|
|
55
|
+
|
|
56
|
+
# Work around bugs by using the ROW_COUNT function.
|
|
57
|
+
begin
|
|
58
|
+
r2 = conn.query(ROW_COUNT)
|
|
59
|
+
r2.each{|a| return a.first.to_i}
|
|
60
|
+
ensure
|
|
61
|
+
r2.close if r2
|
|
62
|
+
end
|
|
63
|
+
when :insert
|
|
64
|
+
begin
|
|
65
|
+
r2 = conn.query(LAST_INSERT_ID)
|
|
66
|
+
r2.each{|a| return a.first.to_i}
|
|
67
|
+
ensure
|
|
68
|
+
r2.close if r2
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
ensure
|
|
72
|
+
r.close
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def execute_ddl(sql, opts={})
|
|
79
|
+
execute(sql, opts.merge(:type=>:ddl))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def execute_dui(sql, opts={})
|
|
83
|
+
execute(sql, opts.merge(:type=>:dui))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def execute_insert(sql, opts={})
|
|
87
|
+
execute(sql, opts.merge(:type=>:insert))
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def begin_transaction(conn, opts={})
|
|
93
|
+
log_yield(TRANSACTION_BEGIN){conn.auto_commit = false}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def commit_transaction(conn, opts={})
|
|
97
|
+
log_yield(TRANSACTION_COMMIT){conn.commit}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def database_error_classes
|
|
101
|
+
[StandardError]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def remove_transaction(conn, committed)
|
|
105
|
+
conn.auto_commit = true
|
|
106
|
+
ensure
|
|
107
|
+
super
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# This doesn't actually work, as the cubrid ruby driver
|
|
111
|
+
# does not implement transactions correctly.
|
|
112
|
+
def rollback_transaction(conn, opts={})
|
|
113
|
+
log_yield(TRANSACTION_ROLLBACK){conn.rollback}
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
class Dataset < Sequel::Dataset
|
|
118
|
+
include Sequel::Cubrid::DatasetMethods
|
|
119
|
+
COLUMN_INFO_NAME = "name".freeze
|
|
120
|
+
COLUMN_INFO_TYPE = "type_name".freeze
|
|
121
|
+
|
|
122
|
+
Database::DatasetClass = self
|
|
123
|
+
|
|
124
|
+
def fetch_rows(sql)
|
|
125
|
+
execute(sql) do |stmt|
|
|
126
|
+
begin
|
|
127
|
+
procs =
|
|
128
|
+
cols = stmt.column_info.map{|c| [output_identifier(c[COLUMN_INFO_NAME]), CUBRID_TYPE_PROCS[c[COLUMN_INFO_TYPE]]]}
|
|
129
|
+
@columns = cols.map{|c| c.first}
|
|
130
|
+
stmt.each do |r|
|
|
131
|
+
row = {}
|
|
132
|
+
cols.zip(r).each{|(k, p), v| row[k] = (v && p) ? p.call(v) : v}
|
|
133
|
+
yield row
|
|
134
|
+
end
|
|
135
|
+
ensure
|
|
136
|
+
stmt.close
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
self
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
data/lib/sequel/adapters/db2.rb
CHANGED
|
@@ -1,139 +1,232 @@
|
|
|
1
1
|
require 'db2/db2cli'
|
|
2
|
+
Sequel.require %w'shared/db2', 'adapters'
|
|
2
3
|
|
|
3
4
|
module Sequel
|
|
4
5
|
module DB2
|
|
6
|
+
|
|
7
|
+
@convert_smallint_to_bool = true
|
|
8
|
+
|
|
9
|
+
# Underlying error raised by Sequel, since ruby-db2 doesn't
|
|
10
|
+
# use exceptions.
|
|
11
|
+
class DB2Error < StandardError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
# Whether to convert smallint values to bool, true by default.
|
|
16
|
+
# Can also be overridden per dataset.
|
|
17
|
+
attr_accessor :convert_smallint_to_bool
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
tt = Class.new do
|
|
21
|
+
def boolean(s) !s.to_i.zero? end
|
|
22
|
+
def date(s) Date.new(s.year, s.month, s.day) end
|
|
23
|
+
def time(s) Sequel::SQLTime.create(s.hour, s.minute, s.second) end
|
|
24
|
+
end.new
|
|
25
|
+
|
|
26
|
+
# Hash holding type translation methods, used by Dataset#fetch_rows.
|
|
27
|
+
DB2_TYPES = {
|
|
28
|
+
:boolean => tt.method(:boolean),
|
|
29
|
+
DB2CLI::SQL_BLOB => ::Sequel::SQL::Blob.method(:new),
|
|
30
|
+
DB2CLI::SQL_TYPE_DATE => tt.method(:date),
|
|
31
|
+
DB2CLI::SQL_TYPE_TIME => tt.method(:time),
|
|
32
|
+
DB2CLI::SQL_DECIMAL => ::BigDecimal.method(:new)
|
|
33
|
+
}
|
|
34
|
+
DB2_TYPES[DB2CLI::SQL_CLOB] = DB2_TYPES[DB2CLI::SQL_BLOB]
|
|
35
|
+
|
|
5
36
|
class Database < Sequel::Database
|
|
6
|
-
|
|
37
|
+
include DatabaseMethods
|
|
7
38
|
|
|
8
|
-
|
|
39
|
+
set_adapter_scheme :db2
|
|
9
40
|
|
|
10
41
|
TEMPORARY = 'GLOBAL TEMPORARY '.freeze
|
|
42
|
+
rc, NullHandle = DB2CLI.SQLAllocHandle(DB2CLI::SQL_HANDLE_ENV, DB2CLI::SQL_NULL_HANDLE)
|
|
11
43
|
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
# Hash of connection procs for converting
|
|
45
|
+
attr_reader :conversion_procs
|
|
46
|
+
|
|
47
|
+
def initialize(opts={})
|
|
48
|
+
super
|
|
49
|
+
@conversion_procs = DB2_TYPES.dup
|
|
50
|
+
@conversion_procs[DB2CLI::SQL_TYPE_TIMESTAMP] = method(:to_application_timestamp_db2)
|
|
51
|
+
end
|
|
14
52
|
|
|
15
53
|
def connect(server)
|
|
16
54
|
opts = server_opts(server)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
rc = SQLConnect(dbc, opts[:database], opts[:user], opts[:password])
|
|
21
|
-
check_error(rc, "Could not connect to database")
|
|
22
|
-
|
|
55
|
+
dbc = checked_error("Could not allocate database connection"){DB2CLI.SQLAllocHandle(DB2CLI::SQL_HANDLE_DBC, NullHandle)}
|
|
56
|
+
checked_error("Could not connect to database"){DB2CLI.SQLConnect(dbc, opts[:database], opts[:user], opts[:password])}
|
|
23
57
|
dbc
|
|
24
58
|
end
|
|
25
59
|
|
|
26
|
-
def
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
def disconnect_connection(conn)
|
|
61
|
+
DB2CLI.SQLDisconnect(conn)
|
|
62
|
+
DB2CLI.SQLFreeHandle(DB2CLI::SQL_HANDLE_DBC, conn)
|
|
29
63
|
end
|
|
30
64
|
|
|
31
|
-
def
|
|
32
|
-
|
|
65
|
+
def execute(sql, opts={}, &block)
|
|
66
|
+
synchronize(opts[:server]){|conn| log_connection_execute(conn, sql, &block)}
|
|
33
67
|
end
|
|
34
|
-
|
|
35
|
-
|
|
68
|
+
alias do execute
|
|
69
|
+
|
|
70
|
+
def execute_insert(sql, opts={})
|
|
36
71
|
synchronize(opts[:server]) do |conn|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
ensure
|
|
50
|
-
rc = SQLFreeHandle(SQL_HANDLE_STMT, sth)
|
|
51
|
-
check_error(rc, "Could not free statement")
|
|
72
|
+
log_connection_execute(conn, sql)
|
|
73
|
+
sql = "SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1"
|
|
74
|
+
log_connection_execute(conn, sql) do |sth|
|
|
75
|
+
name, buflen, datatype, size, digits, nullable = checked_error("Could not describe column"){DB2CLI.SQLDescribeCol(sth, 1, 256)}
|
|
76
|
+
if DB2CLI.SQLFetch(sth) != DB2CLI::SQL_NO_DATA_FOUND
|
|
77
|
+
v, _ = checked_error("Could not get data"){DB2CLI.SQLGetData(sth, 1, datatype, size)}
|
|
78
|
+
if v.is_a?(String)
|
|
79
|
+
return v.to_i
|
|
80
|
+
else
|
|
81
|
+
return nil
|
|
82
|
+
end
|
|
83
|
+
end
|
|
52
84
|
end
|
|
53
85
|
end
|
|
54
86
|
end
|
|
55
|
-
alias_method :do, :execute
|
|
56
|
-
|
|
57
|
-
private
|
|
58
87
|
|
|
88
|
+
ERROR_MAP = {}
|
|
89
|
+
%w'SQL_INVALID_HANDLE SQL_STILL_EXECUTING SQL_ERROR'.each do |s|
|
|
90
|
+
ERROR_MAP[DB2CLI.const_get(s)] = s
|
|
91
|
+
end
|
|
59
92
|
def check_error(rc, msg)
|
|
60
93
|
case rc
|
|
61
|
-
when SQL_SUCCESS, SQL_SUCCESS_WITH_INFO
|
|
94
|
+
when DB2CLI::SQL_SUCCESS, DB2CLI::SQL_SUCCESS_WITH_INFO, DB2CLI::SQL_NO_DATA_FOUND
|
|
62
95
|
nil
|
|
96
|
+
when DB2CLI::SQL_INVALID_HANDLE, DB2CLI::SQL_STILL_EXECUTING
|
|
97
|
+
e = DB2Error.new("#{ERROR_MAP[rc]}: #{msg}")
|
|
98
|
+
e.set_backtrace(caller)
|
|
99
|
+
raise_error(e, :disconnect=>true)
|
|
63
100
|
else
|
|
64
|
-
|
|
101
|
+
e = DB2Error.new("#{ERROR_MAP[rc] || "Error code #{rc}"}: #{msg}")
|
|
102
|
+
e.set_backtrace(caller)
|
|
103
|
+
raise_error(e, :disconnect=>true)
|
|
65
104
|
end
|
|
66
105
|
end
|
|
67
106
|
|
|
68
|
-
def
|
|
69
|
-
rc =
|
|
70
|
-
check_error(rc,
|
|
107
|
+
def checked_error(msg)
|
|
108
|
+
rc, *ary= yield
|
|
109
|
+
check_error(rc, msg)
|
|
110
|
+
ary.length <= 1 ? ary.first : ary
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def to_application_timestamp_db2(v)
|
|
114
|
+
to_application_timestamp(v.to_s)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def database_error_classes
|
|
120
|
+
[DB2Error]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def begin_transaction(conn, opts={})
|
|
124
|
+
log_yield(TRANSACTION_BEGIN){DB2CLI.SQLSetConnectAttr(conn, DB2CLI::SQL_ATTR_AUTOCOMMIT, DB2CLI::SQL_AUTOCOMMIT_OFF)}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def remove_transaction(conn, committed)
|
|
128
|
+
DB2CLI.SQLSetConnectAttr(conn, DB2CLI::SQL_ATTR_AUTOCOMMIT, DB2CLI::SQL_AUTOCOMMIT_ON)
|
|
129
|
+
ensure
|
|
130
|
+
super
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def rollback_transaction(conn, opts={})
|
|
134
|
+
log_yield(TRANSACTION_ROLLBACK){DB2CLI.SQLEndTran(DB2CLI::SQL_HANDLE_DBC, conn, DB2CLI::SQL_ROLLBACK)}
|
|
135
|
+
end
|
|
71
136
|
|
|
72
|
-
|
|
73
|
-
|
|
137
|
+
def commit_transaction(conn, opts={})
|
|
138
|
+
log_yield(TRANSACTION_COMMIT){DB2CLI.SQLEndTran(DB2CLI::SQL_HANDLE_DBC, conn, DB2CLI::SQL_COMMIT)}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def log_connection_execute(conn, sql)
|
|
142
|
+
sth = checked_error("Could not allocate statement"){DB2CLI.SQLAllocHandle(DB2CLI::SQL_HANDLE_STMT, conn)}
|
|
143
|
+
|
|
144
|
+
begin
|
|
145
|
+
checked_error("Could not execute statement: #{sql}"){log_yield(sql){DB2CLI.SQLExecDirect(sth, sql)}}
|
|
146
|
+
|
|
147
|
+
if block_given?
|
|
148
|
+
yield(sth)
|
|
149
|
+
else
|
|
150
|
+
checked_error("Could not get RPC"){DB2CLI.SQLRowCount(sth)}
|
|
151
|
+
end
|
|
152
|
+
ensure
|
|
153
|
+
checked_error("Could not free statement"){DB2CLI.SQLFreeHandle(DB2CLI::SQL_HANDLE_STMT, sth)}
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Convert smallint type to boolean if convert_smallint_to_bool is true
|
|
158
|
+
def schema_column_type(db_type)
|
|
159
|
+
if DB2.convert_smallint_to_bool && db_type =~ /smallint/i
|
|
160
|
+
:boolean
|
|
161
|
+
else
|
|
162
|
+
super
|
|
163
|
+
end
|
|
74
164
|
end
|
|
75
165
|
end
|
|
76
166
|
|
|
77
167
|
class Dataset < Sequel::Dataset
|
|
168
|
+
include DatasetMethods
|
|
169
|
+
|
|
170
|
+
Database::DatasetClass = self
|
|
78
171
|
MAX_COL_SIZE = 256
|
|
79
172
|
|
|
173
|
+
# Whether to convert smallint to boolean arguments for this dataset.
|
|
174
|
+
# Defaults to the DB2 module setting.
|
|
175
|
+
def convert_smallint_to_bool
|
|
176
|
+
defined?(@convert_smallint_to_bool) ? @convert_smallint_to_bool : (@convert_smallint_to_bool = DB2.convert_smallint_to_bool)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Override the default DB2.convert_smallint_to_bool setting for this dataset.
|
|
180
|
+
attr_writer :convert_smallint_to_bool
|
|
181
|
+
|
|
80
182
|
def fetch_rows(sql)
|
|
81
183
|
execute(sql) do |sth|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
184
|
+
offset = @opts[:offset]
|
|
185
|
+
db = @db
|
|
186
|
+
i = 1
|
|
187
|
+
column_info = get_column_info(sth)
|
|
188
|
+
cols = column_info.map{|c| c.at(1)}
|
|
189
|
+
cols.delete(row_number_column) if offset
|
|
190
|
+
@columns = cols
|
|
191
|
+
errors = [DB2CLI::SQL_NO_DATA_FOUND, DB2CLI::SQL_ERROR]
|
|
192
|
+
until errors.include?(rc = DB2CLI.SQLFetch(sth))
|
|
193
|
+
db.check_error(rc, "Could not fetch row")
|
|
194
|
+
row = {}
|
|
195
|
+
column_info.each do |i, c, t, s, pr|
|
|
196
|
+
v, _ = db.checked_error("Could not get data"){DB2CLI.SQLGetData(sth, i, t, s)}
|
|
197
|
+
row[c] = if v == DB2CLI::Null
|
|
198
|
+
nil
|
|
199
|
+
elsif pr
|
|
200
|
+
pr.call(v)
|
|
201
|
+
else
|
|
202
|
+
v
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
row.delete(row_number_column) if offset
|
|
206
|
+
yield row
|
|
87
207
|
end
|
|
88
208
|
end
|
|
89
209
|
self
|
|
90
210
|
end
|
|
91
211
|
|
|
92
|
-
# DB2 supports window functions
|
|
93
|
-
def supports_window_functions?
|
|
94
|
-
true
|
|
95
|
-
end
|
|
96
|
-
|
|
97
212
|
private
|
|
98
213
|
|
|
99
214
|
def get_column_info(sth)
|
|
100
|
-
|
|
101
|
-
|
|
215
|
+
db = @db
|
|
216
|
+
column_count = db.checked_error("Could not get number of result columns"){DB2CLI.SQLNumResultCols(sth)}
|
|
217
|
+
convert = convert_smallint_to_bool
|
|
218
|
+
cps = db.conversion_procs
|
|
102
219
|
|
|
103
220
|
(1..column_count).map do |i|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
221
|
+
name, buflen, datatype, size, digits, nullable = db.checked_error("Could not describe column"){DB2CLI.SQLDescribeCol(sth, i, MAX_COL_SIZE)}
|
|
222
|
+
pr = if datatype == DB2CLI::SQL_SMALLINT && convert && size <= 5 && digits <= 1
|
|
223
|
+
cps[:boolean]
|
|
224
|
+
else
|
|
225
|
+
cps[datatype]
|
|
226
|
+
end
|
|
227
|
+
[i, output_identifier(name), datatype, size, pr]
|
|
108
228
|
end
|
|
109
229
|
end
|
|
110
|
-
|
|
111
|
-
def hash_row(sth)
|
|
112
|
-
row = {}
|
|
113
|
-
@column_info.each_with_index do |c, i|
|
|
114
|
-
rc, v = SQLGetData(sth, i+1, c[:db2_type], c[:precision])
|
|
115
|
-
@db.check_error(rc, "Could not get data")
|
|
116
|
-
|
|
117
|
-
row[output_identifier(c[:name])] = convert_type(v)
|
|
118
|
-
end
|
|
119
|
-
row
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def convert_type(v)
|
|
123
|
-
case v
|
|
124
|
-
when DB2CLI::Date
|
|
125
|
-
DBI::Date.new(v.year, v.month, v.day)
|
|
126
|
-
when DB2CLI::Time
|
|
127
|
-
DBI::Time.new(v.hour, v.minute, v.second)
|
|
128
|
-
when DB2CLI::Timestamp
|
|
129
|
-
DBI::Timestamp.new(v.year, v.month, v.day,
|
|
130
|
-
v.hour, v.minute, v.second, v.fraction)
|
|
131
|
-
when DB2CLI::Null
|
|
132
|
-
nil
|
|
133
|
-
else
|
|
134
|
-
v
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
230
|
end
|
|
138
231
|
end
|
|
139
232
|
end
|
data/lib/sequel/adapters/dbi.rb
CHANGED
|
@@ -62,11 +62,11 @@ module Sequel
|
|
|
62
62
|
end
|
|
63
63
|
::DBI.connect(dbname, opts[:user], opts[:password])
|
|
64
64
|
end
|
|
65
|
-
|
|
66
|
-
def
|
|
67
|
-
|
|
65
|
+
|
|
66
|
+
def disconnect_connection(c)
|
|
67
|
+
c.disconnect
|
|
68
68
|
end
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
def execute(sql, opts={})
|
|
71
71
|
synchronize(opts[:server]) do |conn|
|
|
72
72
|
r = log_yield(sql){conn.execute(sql)}
|
|
@@ -79,35 +79,33 @@ module Sequel
|
|
|
79
79
|
synchronize(opts[:server]){|conn| log_yield(sql){conn.do(sql)}}
|
|
80
80
|
end
|
|
81
81
|
alias_method :execute_dui, :do
|
|
82
|
-
|
|
83
|
-
private
|
|
84
|
-
|
|
85
|
-
def disconnect_connection(c)
|
|
86
|
-
c.disconnect
|
|
87
|
-
end
|
|
88
82
|
end
|
|
89
83
|
|
|
90
84
|
class Dataset < Sequel::Dataset
|
|
85
|
+
Database::DatasetClass = self
|
|
86
|
+
|
|
91
87
|
def fetch_rows(sql)
|
|
92
88
|
execute(sql) do |s|
|
|
93
89
|
begin
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
columns = cols = s.column_names.map{|c| output_identifier(c)}
|
|
91
|
+
if opts[:offset] && offset_returns_row_number_column?
|
|
92
|
+
rn = row_number_column
|
|
93
|
+
columns = columns.dup
|
|
94
|
+
columns.delete(rn)
|
|
95
|
+
end
|
|
96
|
+
@columns = columns
|
|
97
|
+
s.fetch do |r|
|
|
98
|
+
row = {}
|
|
99
|
+
cols.each{|c| row[c] = r.shift}
|
|
100
|
+
row.delete(rn) if rn
|
|
101
|
+
yield row
|
|
102
|
+
end
|
|
96
103
|
ensure
|
|
97
104
|
s.finish rescue nil
|
|
98
105
|
end
|
|
99
106
|
end
|
|
100
107
|
self
|
|
101
108
|
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
def hash_row(stmt, row)
|
|
106
|
-
@columns.inject({}) do |m, c|
|
|
107
|
-
m[c] = row.shift
|
|
108
|
-
m
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
109
|
end
|
|
112
110
|
end
|
|
113
111
|
end
|
|
@@ -9,11 +9,6 @@ module Sequel
|
|
|
9
9
|
module DatabaseMethods
|
|
10
10
|
include Sequel::MySQL::DatabaseMethods
|
|
11
11
|
|
|
12
|
-
# Return instance of Sequel::DataObjects::MySQL::Dataset with the given opts.
|
|
13
|
-
def dataset(opts=nil)
|
|
14
|
-
Sequel::DataObjects::MySQL::Dataset.new(self, opts)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
private
|
|
18
13
|
|
|
19
14
|
# The database name for the given database. Need to parse it out
|
|
@@ -23,25 +18,36 @@ module Sequel
|
|
|
23
18
|
(m = /\/(.*)/.match(URI.parse(uri).path)) && m[1]
|
|
24
19
|
end
|
|
25
20
|
|
|
21
|
+
# Recognize the tinyint(1) column as boolean.
|
|
26
22
|
def schema_column_type(db_type)
|
|
27
23
|
db_type == 'tinyint(1)' ? :boolean : super
|
|
28
24
|
end
|
|
25
|
+
|
|
26
|
+
# Apply the connectiong setting SQLs for every new connection.
|
|
27
|
+
def setup_connection(conn)
|
|
28
|
+
mysql_connection_setting_sqls.each{|sql| log_yield(sql){conn.create_command(sql).execute_non_query}}
|
|
29
|
+
super
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Dataset class for MySQL datasets accessed via DataObjects.
|
|
32
34
|
class Dataset < DataObjects::Dataset
|
|
33
35
|
include Sequel::MySQL::DatasetMethods
|
|
36
|
+
APOS = Dataset::APOS
|
|
37
|
+
APOS_RE = Dataset::APOS_RE
|
|
38
|
+
DOUBLE_APOS = Dataset::DOUBLE_APOS
|
|
34
39
|
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
# The DataObjects MySQL driver uses the number of rows actually modified in the update,
|
|
41
|
+
# instead of the number of matched by the filter.
|
|
42
|
+
def provides_accurate_rows_matched?
|
|
43
|
+
false
|
|
38
44
|
end
|
|
39
|
-
|
|
45
|
+
|
|
40
46
|
private
|
|
41
47
|
|
|
42
48
|
# do_mysql sets NO_BACKSLASH_ESCAPES, so use standard SQL string escaping
|
|
43
|
-
def
|
|
44
|
-
|
|
49
|
+
def literal_string_append(sql, s)
|
|
50
|
+
sql << APOS << s.gsub(APOS_RE, DOUBLE_APOS) << APOS
|
|
45
51
|
end
|
|
46
52
|
end
|
|
47
53
|
end
|
|
@@ -7,40 +7,6 @@ module Sequel
|
|
|
7
7
|
# Adapter, Database, and Dataset support for accessing a PostgreSQL
|
|
8
8
|
# database via DataObjects.
|
|
9
9
|
module Postgres
|
|
10
|
-
# Methods to add to the DataObjects adapter/connection to allow it to work
|
|
11
|
-
# with the shared PostgreSQL code.
|
|
12
|
-
module AdapterMethods
|
|
13
|
-
include Sequel::Postgres::AdapterMethods
|
|
14
|
-
|
|
15
|
-
# Give the DataObjects adapter a direct execute method, which creates
|
|
16
|
-
# a statement with the given sql and executes it.
|
|
17
|
-
def execute(sql, args=nil)
|
|
18
|
-
command = create_command(sql)
|
|
19
|
-
begin
|
|
20
|
-
if block_given?
|
|
21
|
-
begin
|
|
22
|
-
yield(reader = @db.log_yield(sql){command.execute_reader})
|
|
23
|
-
ensure
|
|
24
|
-
reader.close if reader
|
|
25
|
-
end
|
|
26
|
-
else
|
|
27
|
-
@db.log_yield(sql){command.execute_non_query}
|
|
28
|
-
end
|
|
29
|
-
rescue ::DataObjects::Error => e
|
|
30
|
-
@db.send(:raise_error, e)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
# DataObjects specific method of getting specific values from a result set.
|
|
37
|
-
def single_value(reader)
|
|
38
|
-
while(reader.next!) do
|
|
39
|
-
return reader.values.at(0)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
10
|
# Methods to add to Database instances that access PostgreSQL via
|
|
45
11
|
# DataObjects.
|
|
46
12
|
module DatabaseMethods
|
|
@@ -49,25 +15,7 @@ module Sequel
|
|
|
49
15
|
# Add the primary_keys and primary_key_sequences instance variables,
|
|
50
16
|
# so we can get the correct return values for inserted rows.
|
|
51
17
|
def self.extended(db)
|
|
52
|
-
db.
|
|
53
|
-
@primary_keys = {}
|
|
54
|
-
@primary_key_sequences = {}
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Return instance of Sequel::DataObjects::Postgres::Dataset with the given opts.
|
|
59
|
-
def dataset(opts=nil)
|
|
60
|
-
Sequel::DataObjects::Postgres::Dataset.new(self, opts)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Run the INSERT sql on the database and return the primary key
|
|
64
|
-
# for the record.
|
|
65
|
-
def execute_insert(sql, opts={})
|
|
66
|
-
synchronize(opts[:server]) do |conn|
|
|
67
|
-
com = conn.create_command(sql)
|
|
68
|
-
log_yield(sql){com.execute_non_query}
|
|
69
|
-
insert_result(conn, opts[:table], opts[:values])
|
|
70
|
-
end
|
|
18
|
+
db.send(:initialize_postgres_adapter)
|
|
71
19
|
end
|
|
72
20
|
|
|
73
21
|
private
|
|
@@ -75,17 +23,10 @@ module Sequel
|
|
|
75
23
|
# Extend the adapter with the DataObjects PostgreSQL AdapterMethods
|
|
76
24
|
def setup_connection(conn)
|
|
77
25
|
conn = super(conn)
|
|
78
|
-
conn.
|
|
79
|
-
conn.db = self
|
|
80
|
-
conn.apply_connection_settings
|
|
26
|
+
connection_configuration_sqls.each{|sql| log_yield(sql){conn.create_command(sql).execute_non_query}}
|
|
81
27
|
conn
|
|
82
28
|
end
|
|
83
29
|
end
|
|
84
|
-
|
|
85
|
-
# Dataset subclass used for datasets that connect to PostgreSQL via DataObjects.
|
|
86
|
-
class Dataset < DataObjects::Dataset
|
|
87
|
-
include Sequel::Postgres::DatasetMethods
|
|
88
|
-
end
|
|
89
30
|
end
|
|
90
31
|
end
|
|
91
32
|
end
|
|
@@ -8,11 +8,6 @@ module Sequel
|
|
|
8
8
|
module DatabaseMethods
|
|
9
9
|
include Sequel::SQLite::DatabaseMethods
|
|
10
10
|
|
|
11
|
-
# Return Sequel::DataObjects::SQLite::Dataset object with the given opts.
|
|
12
|
-
def dataset(opts=nil)
|
|
13
|
-
Sequel::DataObjects::SQLite::Dataset.new(self, opts)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
11
|
private
|
|
17
12
|
|
|
18
13
|
# Default to a single connection for a memory database.
|
|
@@ -30,11 +25,6 @@ module Sequel
|
|
|
30
25
|
super
|
|
31
26
|
end
|
|
32
27
|
end
|
|
33
|
-
|
|
34
|
-
# Dataset class for SQLite datasets accessed via DataObjects.
|
|
35
|
-
class Dataset < DataObjects::Dataset
|
|
36
|
-
include Sequel::SQLite::DatasetMethods
|
|
37
|
-
end
|
|
38
28
|
end
|
|
39
29
|
end
|
|
40
30
|
end
|