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,166 @@
|
|
|
1
|
+
Sequel.require %w'shared/mysql utils/stored_procedures', 'adapters'
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
module MySQL
|
|
5
|
+
# This module is used by the mysql and mysql2 adapters to support
|
|
6
|
+
# prepared statements and stored procedures.
|
|
7
|
+
module PreparedStatements
|
|
8
|
+
module DatabaseMethods
|
|
9
|
+
disconnect_errors = <<-END.split("\n").map{|l| l.strip}
|
|
10
|
+
Commands out of sync; you can't run this command now
|
|
11
|
+
Can't connect to local MySQL server through socket
|
|
12
|
+
MySQL server has gone away
|
|
13
|
+
Lost connection to MySQL server during query
|
|
14
|
+
This connection is still waiting for a result, try again once you have the result
|
|
15
|
+
closed MySQL connection
|
|
16
|
+
END
|
|
17
|
+
# Error messages for mysql and mysql2 that indicate the current connection should be disconnected
|
|
18
|
+
MYSQL_DATABASE_DISCONNECT_ERRORS = /\A#{Regexp.union(disconnect_errors)}/o
|
|
19
|
+
|
|
20
|
+
# Support stored procedures on MySQL
|
|
21
|
+
def call_sproc(name, opts={}, &block)
|
|
22
|
+
args = opts[:args] || []
|
|
23
|
+
execute("CALL #{name}#{args.empty? ? '()' : literal(args)}", opts.merge(:sproc=>false), &block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Executes the given SQL using an available connection, yielding the
|
|
27
|
+
# connection if the block is given.
|
|
28
|
+
def execute(sql, opts={}, &block)
|
|
29
|
+
if opts[:sproc]
|
|
30
|
+
call_sproc(sql, opts, &block)
|
|
31
|
+
elsif sql.is_a?(Symbol)
|
|
32
|
+
execute_prepared_statement(sql, opts, &block)
|
|
33
|
+
else
|
|
34
|
+
synchronize(opts[:server]){|conn| _execute(conn, sql, opts, &block)}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def add_prepared_statements_cache(conn)
|
|
41
|
+
class << conn
|
|
42
|
+
attr_accessor :prepared_statements
|
|
43
|
+
end
|
|
44
|
+
conn.prepared_statements = {}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Executes a prepared statement on an available connection. If the
|
|
48
|
+
# prepared statement already exists for the connection and has the same
|
|
49
|
+
# SQL, reuse it, otherwise, prepare the new statement. Because of the
|
|
50
|
+
# usual MySQL stupidity, we are forced to name arguments via separate
|
|
51
|
+
# SET queries. Use @sequel_arg_N (for N starting at 1) for these
|
|
52
|
+
# arguments.
|
|
53
|
+
def execute_prepared_statement(ps_name, opts, &block)
|
|
54
|
+
args = opts[:arguments]
|
|
55
|
+
ps = prepared_statement(ps_name)
|
|
56
|
+
sql = ps.prepared_sql
|
|
57
|
+
synchronize(opts[:server]) do |conn|
|
|
58
|
+
unless conn.prepared_statements[ps_name] == sql
|
|
59
|
+
_execute(conn, "PREPARE #{ps_name} FROM #{literal(sql)}", opts)
|
|
60
|
+
conn.prepared_statements[ps_name] = sql
|
|
61
|
+
end
|
|
62
|
+
i = 0
|
|
63
|
+
_execute(conn, "SET " + args.map {|arg| "@sequel_arg_#{i+=1} = #{literal(arg)}"}.join(", "), opts) unless args.empty?
|
|
64
|
+
opts = opts.merge(:log_sql=>" (#{sql})") if ps.log_sql
|
|
65
|
+
_execute(conn, "EXECUTE #{ps_name}#{" USING #{(1..i).map{|j| "@sequel_arg_#{j}"}.join(', ')}" unless i == 0}", opts, &block)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
module DatasetMethods
|
|
71
|
+
include Sequel::Dataset::StoredProcedures
|
|
72
|
+
|
|
73
|
+
# Methods to add to MySQL prepared statement calls without using a
|
|
74
|
+
# real database prepared statement and bound variables.
|
|
75
|
+
module CallableStatementMethods
|
|
76
|
+
# Extend given dataset with this module so subselects inside subselects in
|
|
77
|
+
# prepared statements work.
|
|
78
|
+
def subselect_sql_append(sql, ds)
|
|
79
|
+
ps = ds.to_prepared_statement(:select).clone(:append_sql => sql)
|
|
80
|
+
ps.extend(CallableStatementMethods)
|
|
81
|
+
ps = ps.bind(@opts[:bind_vars]) if @opts[:bind_vars]
|
|
82
|
+
ps.prepared_args = prepared_args
|
|
83
|
+
ps.prepared_sql
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Methods for MySQL prepared statements using the native driver.
|
|
88
|
+
module PreparedStatementMethods
|
|
89
|
+
include Sequel::Dataset::UnnumberedArgumentMapper
|
|
90
|
+
|
|
91
|
+
# Raise a more obvious error if you attempt to call a unnamed prepared statement.
|
|
92
|
+
def call(*)
|
|
93
|
+
raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
|
|
94
|
+
super
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# Execute the prepared statement with the bind arguments instead of
|
|
100
|
+
# the given SQL.
|
|
101
|
+
def execute(sql, opts={}, &block)
|
|
102
|
+
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Same as execute, explicit due to intricacies of alias and super.
|
|
106
|
+
def execute_dui(sql, opts={}, &block)
|
|
107
|
+
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Same as execute, explicit due to intricacies of alias and super.
|
|
111
|
+
def execute_insert(sql, opts={}, &block)
|
|
112
|
+
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Methods for MySQL stored procedures using the native driver.
|
|
117
|
+
module StoredProcedureMethods
|
|
118
|
+
include Sequel::Dataset::StoredProcedureMethods
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
# Execute the database stored procedure with the stored arguments.
|
|
123
|
+
def execute(sql, opts={}, &block)
|
|
124
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Same as execute, explicit due to intricacies of alias and super.
|
|
128
|
+
def execute_dui(sql, opts={}, &block)
|
|
129
|
+
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# MySQL is different in that it supports prepared statements but not bound
|
|
134
|
+
# variables outside of prepared statements. The default implementation
|
|
135
|
+
# breaks the use of subselects in prepared statements, so extend the
|
|
136
|
+
# temporary prepared statement that this creates with a module that
|
|
137
|
+
# fixes it.
|
|
138
|
+
def call(type, bind_arguments={}, *values, &block)
|
|
139
|
+
ps = to_prepared_statement(type, values)
|
|
140
|
+
ps.extend(CallableStatementMethods)
|
|
141
|
+
ps.call(bind_arguments, &block)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Store the given type of prepared statement in the associated database
|
|
145
|
+
# with the given name.
|
|
146
|
+
def prepare(type, name=nil, *values)
|
|
147
|
+
ps = to_prepared_statement(type, values)
|
|
148
|
+
ps.extend(PreparedStatementMethods)
|
|
149
|
+
if name
|
|
150
|
+
ps.prepared_statement_name = name
|
|
151
|
+
db.set_prepared_statement(name, ps)
|
|
152
|
+
end
|
|
153
|
+
ps
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
private
|
|
157
|
+
|
|
158
|
+
# Extend the dataset with the MySQL stored procedure methods.
|
|
159
|
+
def prepare_extend_sproc(ds)
|
|
160
|
+
ds.extend(StoredProcedureMethods)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
Sequel.require 'adapters/utils/emulate_offset_with_row_number'
|
|
2
|
+
|
|
1
3
|
module Sequel
|
|
2
4
|
module Oracle
|
|
3
5
|
module DatabaseMethods
|
|
4
6
|
TEMPORARY = 'GLOBAL TEMPORARY '.freeze
|
|
5
7
|
AUTOINCREMENT = ''.freeze
|
|
6
8
|
|
|
9
|
+
attr_accessor :autosequence
|
|
10
|
+
|
|
7
11
|
def create_sequence(name, opts={})
|
|
8
12
|
self << create_sequence_sql(name, opts)
|
|
9
13
|
end
|
|
@@ -12,6 +16,10 @@ module Sequel
|
|
|
12
16
|
self << create_trigger_sql(*args)
|
|
13
17
|
end
|
|
14
18
|
|
|
19
|
+
def current_user
|
|
20
|
+
@current_user ||= metadata_dataset.get{sys_context('USERENV', 'CURRENT_USER')}
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
def drop_sequence(name)
|
|
16
24
|
self << drop_sequence_sql(name)
|
|
17
25
|
end
|
|
@@ -21,33 +29,59 @@ module Sequel
|
|
|
21
29
|
:oracle
|
|
22
30
|
end
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
# Oracle namespaces indexes per table.
|
|
33
|
+
def global_index_namespace?
|
|
34
|
+
false
|
|
27
35
|
end
|
|
28
36
|
|
|
29
|
-
def
|
|
30
|
-
|
|
37
|
+
def tables(opts={})
|
|
38
|
+
m = output_identifier_meth
|
|
39
|
+
metadata_dataset.from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'TABLE').map{|r| m.call(r[:tname])}
|
|
31
40
|
end
|
|
32
41
|
|
|
33
42
|
def views(opts={})
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
m = output_identifier_meth
|
|
44
|
+
metadata_dataset.from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'VIEW').map{|r| m.call(r[:tname])}
|
|
36
45
|
end
|
|
37
46
|
|
|
38
47
|
def view_exists?(name)
|
|
39
|
-
|
|
48
|
+
m = input_identifier_meth
|
|
49
|
+
metadata_dataset.from(:tab).filter(:tname =>m.call(name), :tabtype => 'VIEW').count > 0
|
|
40
50
|
end
|
|
41
51
|
|
|
42
52
|
private
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
# Handle Oracle specific ALTER TABLE SQL
|
|
55
|
+
def alter_table_sql(table, op)
|
|
56
|
+
case op[:op]
|
|
57
|
+
when :add_column
|
|
58
|
+
if op[:primary_key]
|
|
59
|
+
sqls = []
|
|
60
|
+
sqls << alter_table_sql(table, op.merge(:primary_key=>nil))
|
|
61
|
+
if op[:auto_increment]
|
|
62
|
+
seq_name = default_sequence_name(table, op[:name])
|
|
63
|
+
sqls << drop_sequence_sql(seq_name)
|
|
64
|
+
sqls << create_sequence_sql(seq_name, op)
|
|
65
|
+
sqls << "UPDATE #{quote_schema_table(table)} SET #{quote_identifier(op[:name])} = #{seq_name}.nextval"
|
|
66
|
+
end
|
|
67
|
+
sqls << "ALTER TABLE #{quote_schema_table(table)} ADD PRIMARY KEY (#{quote_identifier(op[:name])})"
|
|
68
|
+
sqls
|
|
69
|
+
else
|
|
70
|
+
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
|
71
|
+
end
|
|
72
|
+
when :set_column_null
|
|
73
|
+
"ALTER TABLE #{quote_schema_table(table)} MODIFY #{quote_identifier(op[:name])} #{op[:null] ? 'NULL' : 'NOT NULL'}"
|
|
74
|
+
when :set_column_type
|
|
75
|
+
"ALTER TABLE #{quote_schema_table(table)} MODIFY #{quote_identifier(op[:name])} #{type_literal(op)}"
|
|
76
|
+
when :set_column_default
|
|
77
|
+
"ALTER TABLE #{quote_schema_table(table)} MODIFY #{quote_identifier(op[:name])} DEFAULT #{literal(op[:default])}"
|
|
78
|
+
else
|
|
79
|
+
super(table, op)
|
|
80
|
+
end
|
|
46
81
|
end
|
|
47
82
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
TEMPORARY
|
|
83
|
+
def auto_increment_sql
|
|
84
|
+
AUTOINCREMENT
|
|
51
85
|
end
|
|
52
86
|
|
|
53
87
|
def create_sequence_sql(name, opts={})
|
|
@@ -65,7 +99,7 @@ module Sequel
|
|
|
65
99
|
drop_seq_statement = nil
|
|
66
100
|
generator.columns.each do |c|
|
|
67
101
|
if c[:auto_increment]
|
|
68
|
-
c[:sequence_name] ||=
|
|
102
|
+
c[:sequence_name] ||= default_sequence_name(name, c[:name])
|
|
69
103
|
unless c[:create_sequence] == false
|
|
70
104
|
drop_seq_statement = drop_sequence_sql(c[:sequence_name])
|
|
71
105
|
statements << create_sequence_sql(c[:sequence_name], c)
|
|
@@ -97,14 +131,142 @@ module Sequel
|
|
|
97
131
|
sql
|
|
98
132
|
end
|
|
99
133
|
|
|
134
|
+
def default_sequence_name(table, column)
|
|
135
|
+
"seq_#{table}_#{column}"
|
|
136
|
+
end
|
|
137
|
+
|
|
100
138
|
def drop_sequence_sql(name)
|
|
101
139
|
"DROP SEQUENCE #{quote_identifier(name)}"
|
|
102
140
|
end
|
|
141
|
+
|
|
142
|
+
def remove_cached_schema(table)
|
|
143
|
+
@primary_key_sequences.delete(table)
|
|
144
|
+
super
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def sequence_for_table(table)
|
|
148
|
+
return nil unless autosequence
|
|
149
|
+
@primary_key_sequences.fetch(table) do |key|
|
|
150
|
+
pk = schema(table).select{|k, v| v[:primary_key]}
|
|
151
|
+
@primary_key_sequences[table] = if pk.length == 1
|
|
152
|
+
seq = "seq_#{table}_#{pk.first.first}"
|
|
153
|
+
seq.to_sym unless from(:user_sequences).filter(:sequence_name=>input_identifier_meth.call(seq)).empty?
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Oracle's integer/:number type handles larger values than
|
|
159
|
+
# most other databases's bigint types, so it should be
|
|
160
|
+
# safe to use for Bignum.
|
|
161
|
+
def type_literal_generic_bignum(column)
|
|
162
|
+
:integer
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Oracle doesn't have a time type, so use timestamp for all
|
|
166
|
+
# time columns.
|
|
167
|
+
def type_literal_generic_time(column)
|
|
168
|
+
:timestamp
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Oracle doesn't have a boolean type or even a reasonable
|
|
172
|
+
# facsimile. Using a char(1) seems to be the recommended way.
|
|
173
|
+
def type_literal_generic_trueclass(column)
|
|
174
|
+
:'char(1)'
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# SQL fragment for showing a table is temporary
|
|
178
|
+
def temporary_table_sql
|
|
179
|
+
TEMPORARY
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Oracle uses clob for text types.
|
|
183
|
+
def uses_clob_for_text?
|
|
184
|
+
true
|
|
185
|
+
end
|
|
103
186
|
end
|
|
104
187
|
|
|
105
188
|
module DatasetMethods
|
|
106
|
-
|
|
189
|
+
include EmulateOffsetWithRowNumber
|
|
190
|
+
|
|
191
|
+
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'with select distinct columns from join where group having compounds order lock')
|
|
192
|
+
ROW_NUMBER_EXPRESSION = LiteralString.new('ROWNUM').freeze
|
|
193
|
+
SPACE = Dataset::SPACE
|
|
194
|
+
APOS = Dataset::APOS
|
|
195
|
+
APOS_RE = Dataset::APOS_RE
|
|
196
|
+
DOUBLE_APOS = Dataset::DOUBLE_APOS
|
|
197
|
+
FROM = Dataset::FROM
|
|
198
|
+
BITCOMP_OPEN = "((0 - ".freeze
|
|
199
|
+
BITCOMP_CLOSE = ") - 1)".freeze
|
|
200
|
+
ILIKE_0 = "(UPPER(".freeze
|
|
201
|
+
ILIKE_1 = ") ".freeze
|
|
202
|
+
ILIKE_2 = ' UPPER('.freeze
|
|
203
|
+
ILIKE_3 = "))".freeze
|
|
204
|
+
LIKE = 'LIKE'.freeze
|
|
205
|
+
NOT_LIKE = 'NOT LIKE'.freeze
|
|
206
|
+
TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S%N %z'".freeze
|
|
207
|
+
TIMESTAMP_OFFSET_FORMAT = "%+03i:%02i".freeze
|
|
208
|
+
BOOL_FALSE = "'N'".freeze
|
|
209
|
+
BOOL_TRUE = "'Y'".freeze
|
|
210
|
+
HSTAR = "H*".freeze
|
|
211
|
+
DUAL = ['DUAL'.freeze].freeze
|
|
212
|
+
|
|
213
|
+
# Oracle needs to emulate bitwise operators and ILIKE/NOT ILIKE operators.
|
|
214
|
+
def complex_expression_sql_append(sql, op, args)
|
|
215
|
+
case op
|
|
216
|
+
when :&
|
|
217
|
+
sql << complex_expression_arg_pairs(args){|a, b| "CAST(BITAND(#{literal(a)}, #{literal(b)}) AS INTEGER)"}
|
|
218
|
+
when :|
|
|
219
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} - #{complex_expression_sql(:&, [a, b])} + #{literal(b)})"}
|
|
220
|
+
when :^
|
|
221
|
+
sql << complex_expression_arg_pairs(args){|*x| "(#{complex_expression_sql(:|, x)} - #{complex_expression_sql(:&, x)})"}
|
|
222
|
+
when :'B~'
|
|
223
|
+
sql << BITCOMP_OPEN
|
|
224
|
+
literal_append(sql, args.at(0))
|
|
225
|
+
sql << BITCOMP_CLOSE
|
|
226
|
+
when :<<
|
|
227
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * power(2, #{literal b}))"}
|
|
228
|
+
when :>>
|
|
229
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / power(2, #{literal b}))"}
|
|
230
|
+
when :%
|
|
231
|
+
sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
|
|
232
|
+
when :ILIKE, :'NOT ILIKE'
|
|
233
|
+
sql << ILIKE_0
|
|
234
|
+
literal_append(sql, args.at(0))
|
|
235
|
+
sql << ILIKE_1
|
|
236
|
+
sql << (op == :ILIKE ? LIKE : NOT_LIKE)
|
|
237
|
+
sql<< ILIKE_2
|
|
238
|
+
literal_append(sql, args.at(1))
|
|
239
|
+
sql << ILIKE_3
|
|
240
|
+
else
|
|
241
|
+
super
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Oracle doesn't support CURRENT_TIME, as it doesn't have
|
|
246
|
+
# a type for storing just time values without a date, so
|
|
247
|
+
# use CURRENT_TIMESTAMP in its place.
|
|
248
|
+
def constant_sql_append(sql, c)
|
|
249
|
+
if c == :CURRENT_TIME
|
|
250
|
+
super(sql, :CURRENT_TIMESTAMP)
|
|
251
|
+
else
|
|
252
|
+
super
|
|
253
|
+
end
|
|
254
|
+
end
|
|
107
255
|
|
|
256
|
+
# Oracle treats empty strings like NULL values, and doesn't support
|
|
257
|
+
# char_length, so make char_length use length with a nonempty string.
|
|
258
|
+
# Unfortunately, as Oracle treats the empty string as NULL, there is
|
|
259
|
+
# no way to get trim to return an empty string instead of nil if
|
|
260
|
+
# the string only contains spaces.
|
|
261
|
+
def emulated_function_sql_append(sql, f)
|
|
262
|
+
case f.f
|
|
263
|
+
when :char_length
|
|
264
|
+
literal_append(sql, Sequel::SQL::Function.new(:length, Sequel.join([f.args.first, 'x'])) - 1)
|
|
265
|
+
else
|
|
266
|
+
super
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
108
270
|
# Oracle uses MINUS instead of EXCEPT, and doesn't support EXCEPT ALL
|
|
109
271
|
def except(dataset, opts={})
|
|
110
272
|
opts = {:all=>opts} unless opts.is_a?(Hash)
|
|
@@ -112,19 +274,10 @@ module Sequel
|
|
|
112
274
|
compound_clone(:minus, dataset, opts)
|
|
113
275
|
end
|
|
114
276
|
|
|
277
|
+
# Use a custom expression with EXISTS to determine whether a dataset
|
|
278
|
+
# is empty.
|
|
115
279
|
def empty?
|
|
116
|
-
db[:dual].where(exists).get(1) == nil
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# If this dataset is associated with a sequence, return the most recently
|
|
120
|
-
# inserted sequence value.
|
|
121
|
-
def insert(*args)
|
|
122
|
-
r = super
|
|
123
|
-
if s = opts[:sequence]
|
|
124
|
-
with_sql("SELECT #{literal(s)}.currval FROM dual").single_value.to_i
|
|
125
|
-
else
|
|
126
|
-
r
|
|
127
|
-
end
|
|
280
|
+
db[:dual].where(@opts[:offset] ? exists : unordered.exists).get(1) == nil
|
|
128
281
|
end
|
|
129
282
|
|
|
130
283
|
# Oracle requires SQL standard datetimes
|
|
@@ -139,16 +292,61 @@ module Sequel
|
|
|
139
292
|
clone(:sequence=>s)
|
|
140
293
|
end
|
|
141
294
|
|
|
295
|
+
# Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
|
|
296
|
+
def select_sql
|
|
297
|
+
if (limit = @opts[:limit]) && !@opts[:sql]
|
|
298
|
+
ds = clone(:limit=>nil)
|
|
299
|
+
# Lock doesn't work in subselects, so don't use a subselect when locking.
|
|
300
|
+
# Don't use a subselect if custom SQL is used, as it breaks somethings.
|
|
301
|
+
ds = ds.from_self unless @opts[:lock]
|
|
302
|
+
sql = @opts[:append_sql] || ''
|
|
303
|
+
subselect_sql_append(sql, ds.where(SQL::ComplexExpression.new(:<=, ROW_NUMBER_EXPRESSION, limit)))
|
|
304
|
+
sql
|
|
305
|
+
else
|
|
306
|
+
super
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# Oracle requires recursive CTEs to have column aliases.
|
|
311
|
+
def recursive_cte_requires_column_aliases?
|
|
312
|
+
true
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
# Oracle supports GROUP BY CUBE
|
|
316
|
+
def supports_group_cube?
|
|
317
|
+
true
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# Oracle supports GROUP BY ROLLUP
|
|
321
|
+
def supports_group_rollup?
|
|
322
|
+
true
|
|
323
|
+
end
|
|
324
|
+
|
|
142
325
|
# Oracle does not support INTERSECT ALL or EXCEPT ALL
|
|
143
326
|
def supports_intersect_except_all?
|
|
144
327
|
false
|
|
145
328
|
end
|
|
329
|
+
|
|
330
|
+
# Oracle does not support IS TRUE.
|
|
331
|
+
def supports_is_true?
|
|
332
|
+
false
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Oracle does not support SELECT *, column
|
|
336
|
+
def supports_select_all_and_column?
|
|
337
|
+
false
|
|
338
|
+
end
|
|
146
339
|
|
|
147
340
|
# Oracle supports timezones in literal timestamps.
|
|
148
341
|
def supports_timestamp_timezones?
|
|
149
342
|
true
|
|
150
343
|
end
|
|
151
344
|
|
|
345
|
+
# Oracle does not support WHERE 'Y' for WHERE TRUE.
|
|
346
|
+
def supports_where_true?
|
|
347
|
+
false
|
|
348
|
+
end
|
|
349
|
+
|
|
152
350
|
# Oracle supports window functions
|
|
153
351
|
def supports_window_functions?
|
|
154
352
|
true
|
|
@@ -158,25 +356,54 @@ module Sequel
|
|
|
158
356
|
|
|
159
357
|
# Oracle doesn't support the use of AS when aliasing a dataset. It doesn't require
|
|
160
358
|
# the use of AS anywhere, so this disables it in all cases.
|
|
161
|
-
def
|
|
162
|
-
|
|
359
|
+
def as_sql_append(sql, aliaz)
|
|
360
|
+
sql << SPACE
|
|
361
|
+
quote_identifier_append(sql, aliaz)
|
|
163
362
|
end
|
|
164
363
|
|
|
165
364
|
# The strftime format to use when literalizing the time.
|
|
166
365
|
def default_timestamp_format
|
|
167
|
-
|
|
366
|
+
TIMESTAMP_FORMAT
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# If this dataset is associated with a sequence, return the most recently
|
|
370
|
+
# inserted sequence value.
|
|
371
|
+
def execute_insert(sql, opts={})
|
|
372
|
+
f = @opts[:from]
|
|
373
|
+
super(sql, {:table=>(f.first if f), :sequence=>@opts[:sequence]}.merge(opts))
|
|
168
374
|
end
|
|
169
375
|
|
|
170
376
|
# Use a colon for the timestamp offset, since Oracle appears to require it.
|
|
171
377
|
def format_timestamp_offset(hour, minute)
|
|
172
|
-
sprintf(
|
|
378
|
+
sprintf(TIMESTAMP_OFFSET_FORMAT, hour, minute)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# Oracle doesn't support empty values when inserting.
|
|
382
|
+
def insert_supports_empty_values?
|
|
383
|
+
false
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Use string in hex format for blob data.
|
|
387
|
+
def literal_blob_append(sql, v)
|
|
388
|
+
sql << APOS << v.unpack(HSTAR).first << APOS
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# Oracle uses 'N' for false values.
|
|
392
|
+
def literal_false
|
|
393
|
+
BOOL_FALSE
|
|
173
394
|
end
|
|
174
395
|
|
|
175
396
|
# Oracle uses the SQL standard of only doubling ' inside strings.
|
|
176
|
-
def
|
|
177
|
-
|
|
397
|
+
def literal_string_append(sql, v)
|
|
398
|
+
sql << APOS << v.gsub(APOS_RE, DOUBLE_APOS) << APOS
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# Oracle uses 'Y' for true values.
|
|
402
|
+
def literal_true
|
|
403
|
+
BOOL_TRUE
|
|
178
404
|
end
|
|
179
405
|
|
|
406
|
+
# Use the Oracle-specific SQL clauses (no limit, since it is emulated).
|
|
180
407
|
def select_clause_methods
|
|
181
408
|
SELECT_CLAUSE_METHODS
|
|
182
409
|
end
|
|
@@ -186,18 +413,8 @@ module Sequel
|
|
|
186
413
|
# so add the dummy DUAL table if the dataset doesn't select
|
|
187
414
|
# from a table.
|
|
188
415
|
def select_from_sql(sql)
|
|
189
|
-
sql <<
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
# Oracle requires a subselect to do limit and offset
|
|
193
|
-
def select_limit_sql(sql)
|
|
194
|
-
if limit = @opts[:limit]
|
|
195
|
-
if (offset = @opts[:offset]) && (offset > 0)
|
|
196
|
-
sql.replace("SELECT * FROM (SELECT raw_sql_.*, ROWNUM raw_rnum_ FROM(#{sql}) raw_sql_ WHERE ROWNUM <= #{limit + offset}) WHERE raw_rnum_ > #{offset}")
|
|
197
|
-
else
|
|
198
|
-
sql.replace("SELECT * FROM (#{sql}) WHERE ROWNUM <= #{limit}")
|
|
199
|
-
end
|
|
200
|
-
end
|
|
416
|
+
sql << FROM
|
|
417
|
+
source_list_append(sql, @opts[:from] || DUAL)
|
|
201
418
|
end
|
|
202
419
|
end
|
|
203
420
|
end
|