sequel 4.41.0 → 4.42.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +98 -0
- data/README.rdoc +23 -10
- data/doc/active_record.rdoc +4 -4
- data/doc/advanced_associations.rdoc +2 -2
- data/doc/association_basics.rdoc +5 -2
- data/doc/cheat_sheet.rdoc +3 -3
- data/doc/core_extensions.rdoc +2 -2
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/dataset_filtering.rdoc +1 -1
- data/doc/migration.rdoc +19 -1
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/release_notes/4.42.0.txt +221 -0
- data/doc/testing.rdoc +3 -1
- data/lib/sequel/adapters/ado/access.rb +0 -1
- data/lib/sequel/adapters/ado/mssql.rb +0 -1
- data/lib/sequel/adapters/do/mysql.rb +0 -1
- data/lib/sequel/adapters/do/postgres.rb +0 -1
- data/lib/sequel/adapters/do/sqlite3.rb +0 -1
- data/lib/sequel/adapters/ibmdb.rb +21 -25
- data/lib/sequel/adapters/jdbc.rb +8 -16
- data/lib/sequel/adapters/jdbc/as400.rb +0 -1
- data/lib/sequel/adapters/jdbc/cubrid.rb +0 -1
- data/lib/sequel/adapters/jdbc/db2.rb +0 -1
- data/lib/sequel/adapters/jdbc/derby.rb +0 -1
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +0 -1
- data/lib/sequel/adapters/jdbc/h2.rb +0 -1
- data/lib/sequel/adapters/jdbc/hsqldb.rb +0 -1
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +0 -1
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +0 -1
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -1
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +0 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -13
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -1
- data/lib/sequel/adapters/jdbc/sqlserver.rb +3 -4
- data/lib/sequel/adapters/mock.rb +54 -12
- data/lib/sequel/adapters/mysql.rb +1 -1
- data/lib/sequel/adapters/mysql2.rb +11 -17
- data/lib/sequel/adapters/odbc/mssql.rb +0 -1
- data/lib/sequel/adapters/oracle.rb +8 -20
- data/lib/sequel/adapters/postgres.rb +11 -29
- data/lib/sequel/adapters/shared/access.rb +5 -12
- data/lib/sequel/adapters/shared/cubrid.rb +4 -13
- data/lib/sequel/adapters/shared/db2.rb +4 -2
- data/lib/sequel/adapters/shared/firebird.rb +2 -4
- data/lib/sequel/adapters/shared/informix.rb +4 -2
- data/lib/sequel/adapters/shared/mssql.rb +3 -5
- data/lib/sequel/adapters/shared/mysql.rb +4 -14
- data/lib/sequel/adapters/shared/oracle.rb +1 -3
- data/lib/sequel/adapters/shared/postgres.rb +16 -38
- data/lib/sequel/adapters/shared/progress.rb +0 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -2
- data/lib/sequel/adapters/shared/sqlite.rb +20 -16
- data/lib/sequel/adapters/sqlite.rb +8 -20
- data/lib/sequel/adapters/swift/mysql.rb +0 -1
- data/lib/sequel/adapters/swift/postgres.rb +0 -1
- data/lib/sequel/adapters/swift/sqlite.rb +0 -1
- data/lib/sequel/adapters/tinytds.rb +4 -12
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -2
- data/lib/sequel/adapters/utils/mysql_prepared_statements.rb +11 -34
- data/lib/sequel/adapters/utils/stored_procedures.rb +9 -22
- data/lib/sequel/adapters/utils/unmodified_identifiers.rb +26 -0
- data/lib/sequel/ast_transformer.rb +2 -2
- data/lib/sequel/database/dataset.rb +1 -1
- data/lib/sequel/database/dataset_defaults.rb +0 -66
- data/lib/sequel/database/features.rb +6 -0
- data/lib/sequel/database/misc.rb +31 -17
- data/lib/sequel/database/query.rb +7 -4
- data/lib/sequel/database/schema_methods.rb +1 -1
- data/lib/sequel/dataset.rb +8 -8
- data/lib/sequel/dataset/actions.rb +140 -46
- data/lib/sequel/dataset/features.rb +1 -5
- data/lib/sequel/dataset/graph.rb +7 -8
- data/lib/sequel/dataset/misc.rb +127 -56
- data/lib/sequel/dataset/mutation.rb +9 -20
- data/lib/sequel/dataset/placeholder_literalizer.rb +10 -1
- data/lib/sequel/dataset/prepared_statements.rb +102 -46
- data/lib/sequel/dataset/query.rb +155 -72
- data/lib/sequel/dataset/sql.rb +26 -9
- data/lib/sequel/extensions/columns_introspection.rb +3 -1
- data/lib/sequel/extensions/core_extensions.rb +5 -5
- data/lib/sequel/extensions/core_refinements.rb +5 -5
- data/lib/sequel/extensions/duplicate_columns_handler.rb +4 -2
- data/lib/sequel/extensions/freeze_datasets.rb +69 -0
- data/lib/sequel/extensions/identifier_mangling.rb +196 -0
- data/lib/sequel/extensions/looser_typecasting.rb +11 -7
- data/lib/sequel/extensions/migration.rb +1 -1
- data/lib/sequel/extensions/null_dataset.rb +5 -2
- data/lib/sequel/extensions/pagination.rb +42 -23
- data/lib/sequel/extensions/pg_enum.rb +3 -3
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +15 -8
- data/lib/sequel/model/associations.rb +25 -8
- data/lib/sequel/model/base.rb +88 -29
- data/lib/sequel/model/dataset_module.rb +37 -0
- data/lib/sequel/plugins/association_pks.rb +4 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/constraint_validations.rb +1 -2
- data/lib/sequel/plugins/csv_serializer.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +8 -8
- data/lib/sequel/plugins/eager_each.rb +2 -2
- data/lib/sequel/plugins/instance_filters.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/lazy_attributes.rb +1 -1
- data/lib/sequel/plugins/list.rb +4 -4
- data/lib/sequel/plugins/prepared_statements.rb +2 -4
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -3
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +13 -13
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +9 -4
- data/lib/sequel/plugins/tactical_eager_loading.rb +4 -4
- data/lib/sequel/plugins/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +2 -2
- data/lib/sequel/sql.rb +69 -36
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +10 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -5
- data/spec/adapters/mysql_spec.rb +9 -9
- data/spec/adapters/postgres_spec.rb +67 -68
- data/spec/adapters/spec_helper.rb +6 -1
- data/spec/adapters/sqlite_spec.rb +29 -15
- data/spec/core/connection_pool_spec.rb +14 -14
- data/spec/core/database_spec.rb +38 -180
- data/spec/core/dataset_mutation_spec.rb +253 -0
- data/spec/core/dataset_spec.rb +394 -537
- data/spec/core/expression_filters_spec.rb +34 -32
- data/spec/core/mock_adapter_spec.rb +27 -35
- data/spec/core/placeholder_literalizer_spec.rb +2 -4
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +1 -2
- data/spec/core_extensions_spec.rb +22 -29
- data/spec/extensions/active_model_spec.rb +6 -6
- data/spec/extensions/association_dependencies_spec.rb +2 -2
- data/spec/extensions/blacklist_security_spec.rb +3 -3
- data/spec/extensions/boolean_readers_spec.rb +12 -12
- data/spec/extensions/caching_spec.rb +13 -10
- data/spec/extensions/class_table_inheritance_spec.rb +38 -43
- data/spec/extensions/column_conflicts_spec.rb +1 -3
- data/spec/extensions/columns_introspection_spec.rb +2 -3
- data/spec/extensions/composition_spec.rb +5 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +5 -5
- data/spec/extensions/constraint_validations_spec.rb +14 -8
- data/spec/extensions/core_refinements_spec.rb +22 -29
- data/spec/extensions/csv_serializer_spec.rb +7 -6
- data/spec/extensions/date_arithmetic_spec.rb +15 -15
- data/spec/extensions/defaults_setter_spec.rb +2 -2
- data/spec/extensions/delay_add_association_spec.rb +1 -1
- data/spec/extensions/dirty_spec.rb +19 -10
- data/spec/extensions/duplicate_columns_handler_spec.rb +12 -18
- data/spec/extensions/eager_each_spec.rb +12 -16
- data/spec/extensions/empty_array_consider_nulls_spec.rb +1 -1
- data/spec/extensions/eval_inspect_spec.rb +4 -3
- data/spec/extensions/force_encoding_spec.rb +12 -12
- data/spec/extensions/freeze_datasets_spec.rb +31 -0
- data/spec/extensions/graph_each_spec.rb +6 -18
- data/spec/extensions/hook_class_methods_spec.rb +7 -7
- data/spec/extensions/identifier_mangling_spec.rb +307 -0
- data/spec/extensions/instance_filters_spec.rb +5 -6
- data/spec/extensions/instance_hooks_spec.rb +12 -12
- data/spec/extensions/json_serializer_spec.rb +12 -15
- data/spec/extensions/lazy_attributes_spec.rb +4 -4
- data/spec/extensions/list_spec.rb +19 -21
- data/spec/extensions/many_through_many_spec.rb +108 -163
- data/spec/extensions/meta_def_spec.rb +7 -2
- data/spec/extensions/migration_spec.rb +10 -12
- data/spec/extensions/mssql_optimistic_locking_spec.rb +4 -3
- data/spec/extensions/named_timezones_spec.rb +4 -3
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +17 -12
- data/spec/extensions/optimistic_locking_spec.rb +4 -5
- data/spec/extensions/pagination_spec.rb +8 -10
- data/spec/extensions/pg_array_associations_spec.rb +28 -27
- data/spec/extensions/pg_array_ops_spec.rb +2 -1
- data/spec/extensions/pg_array_spec.rb +6 -2
- data/spec/extensions/pg_enum_spec.rb +5 -3
- data/spec/extensions/pg_hstore_ops_spec.rb +3 -1
- data/spec/extensions/pg_hstore_spec.rb +7 -6
- data/spec/extensions/pg_inet_ops_spec.rb +2 -1
- data/spec/extensions/pg_inet_spec.rb +2 -1
- data/spec/extensions/pg_interval_spec.rb +2 -1
- data/spec/extensions/pg_json_ops_spec.rb +2 -1
- data/spec/extensions/pg_json_spec.rb +6 -3
- data/spec/extensions/pg_loose_count_spec.rb +1 -0
- data/spec/extensions/pg_range_ops_spec.rb +3 -1
- data/spec/extensions/pg_range_spec.rb +9 -5
- data/spec/extensions/pg_row_ops_spec.rb +2 -1
- data/spec/extensions/pg_row_plugin_spec.rb +4 -6
- data/spec/extensions/pg_row_spec.rb +5 -3
- data/spec/extensions/pg_static_cache_updater_spec.rb +2 -1
- data/spec/extensions/pg_typecast_on_load_spec.rb +1 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/prepared_statements_spec.rb +12 -11
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +8 -5
- data/spec/extensions/rcte_tree_spec.rb +39 -39
- data/spec/extensions/round_timestamps_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +3 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +1 -2
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +30 -17
- data/spec/extensions/serialization_modification_detection_spec.rb +2 -2
- data/spec/extensions/serialization_spec.rb +15 -13
- data/spec/extensions/set_overrides_spec.rb +14 -8
- data/spec/extensions/sharding_spec.rb +9 -18
- data/spec/extensions/shared_caching_spec.rb +3 -4
- data/spec/extensions/single_table_inheritance_spec.rb +11 -11
- data/spec/extensions/skip_create_refresh_spec.rb +2 -1
- data/spec/extensions/spec_helper.rb +1 -1
- data/spec/extensions/split_values_spec.rb +2 -2
- data/spec/extensions/sql_comments_spec.rb +6 -0
- data/spec/extensions/static_cache_spec.rb +7 -9
- data/spec/extensions/string_agg_spec.rb +30 -29
- data/spec/extensions/tactical_eager_loading_spec.rb +4 -5
- data/spec/extensions/thread_local_timezones_spec.rb +2 -2
- data/spec/extensions/timestamps_spec.rb +28 -3
- data/spec/extensions/to_dot_spec.rb +1 -2
- data/spec/extensions/tree_spec.rb +33 -29
- data/spec/extensions/typecast_on_load_spec.rb +1 -1
- data/spec/extensions/unlimited_update_spec.rb +1 -0
- data/spec/extensions/update_primary_key_spec.rb +11 -7
- data/spec/extensions/update_refresh_spec.rb +1 -1
- data/spec/extensions/uuid_spec.rb +0 -1
- data/spec/extensions/validate_associated_spec.rb +1 -1
- data/spec/extensions/validation_class_methods_spec.rb +10 -10
- data/spec/extensions/validation_helpers_spec.rb +10 -10
- data/spec/extensions/xml_serializer_spec.rb +7 -3
- data/spec/integration/associations_test.rb +31 -31
- data/spec/integration/dataset_test.rb +17 -19
- data/spec/integration/eager_loader_test.rb +24 -24
- data/spec/integration/model_test.rb +6 -6
- data/spec/integration/plugin_test.rb +43 -43
- data/spec/integration/prepared_statement_test.rb +6 -6
- data/spec/integration/schema_test.rb +63 -52
- data/spec/integration/spec_helper.rb +6 -1
- data/spec/integration/transaction_test.rb +13 -13
- data/spec/model/association_reflection_spec.rb +17 -17
- data/spec/model/associations_spec.rb +101 -96
- data/spec/model/base_spec.rb +175 -49
- data/spec/model/class_dataset_methods_spec.rb +5 -9
- data/spec/model/dataset_methods_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +209 -235
- data/spec/model/hooks_spec.rb +15 -15
- data/spec/model/model_spec.rb +28 -21
- data/spec/model/plugins_spec.rb +4 -5
- data/spec/model/record_spec.rb +59 -57
- data/spec/model/spec_helper.rb +1 -1
- data/spec/model/validations_spec.rb +6 -6
- data/spec/spec_config.rb +1 -1
- metadata +10 -2
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
Sequel.require 'adapters/utils
|
3
|
+
Sequel.require %w'replace unmodified_identifiers', 'adapters/utils'
|
4
4
|
|
5
5
|
module Sequel
|
6
6
|
module SQLite
|
@@ -16,7 +16,7 @@ module Sequel
|
|
16
16
|
# can be used to set PRAGMAs on connections in a thread-safe manner:
|
17
17
|
# :auto_vacuum, :foreign_keys, :synchronous, and :temp_store.
|
18
18
|
module DatabaseMethods
|
19
|
-
|
19
|
+
include UnmodifiedIdentifiers::DatabaseMethods
|
20
20
|
|
21
21
|
AUTO_VACUUM = [:none, :full, :incremental].freeze
|
22
22
|
PRIMARY_KEY_INDEX_RE = /\Asqlite_autoindex_/.freeze
|
@@ -279,7 +279,7 @@ module Sequel
|
|
279
279
|
when :drop_constraint
|
280
280
|
case op[:type]
|
281
281
|
when :primary_key
|
282
|
-
duplicate_table(table){|columns| columns.each{|s| s[:primary_key] = nil}}
|
282
|
+
duplicate_table(table){|columns| columns.each{|s| s[:primary_key] = s[:auto_increment] = nil}}
|
283
283
|
when :foreign_key
|
284
284
|
if op[:columns]
|
285
285
|
duplicate_table(table, :skip_foreign_key_columns=>op[:columns])
|
@@ -365,7 +365,6 @@ module Sequel
|
|
365
365
|
cols.each do |c|
|
366
366
|
c[:default] = LiteralString.new(c[:default]) if c[:default]
|
367
367
|
c[:type] = c[:db_type]
|
368
|
-
c.delete(:auto_increment)
|
369
368
|
end
|
370
369
|
cols
|
371
370
|
end
|
@@ -442,16 +441,6 @@ module Sequel
|
|
442
441
|
a
|
443
442
|
end
|
444
443
|
|
445
|
-
# SQLite folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on input.
|
446
|
-
def identifier_input_method_default
|
447
|
-
nil
|
448
|
-
end
|
449
|
-
|
450
|
-
# SQLite folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on output.
|
451
|
-
def identifier_output_method_default
|
452
|
-
nil
|
453
|
-
end
|
454
|
-
|
455
444
|
# Does the reverse of on_delete_clause, eg. converts strings like +'SET NULL'+
|
456
445
|
# to symbols +:set_null+.
|
457
446
|
def on_delete_sql_to_sym str
|
@@ -471,18 +460,32 @@ module Sequel
|
|
471
460
|
|
472
461
|
# Parse the output of the table_info pragma
|
473
462
|
def parse_pragma(table_name, opts)
|
474
|
-
|
463
|
+
pks = 0
|
464
|
+
sch = metadata_dataset.with_sql("PRAGMA table_info(?)", input_identifier_meth(opts[:dataset]).call(table_name)).map do |row|
|
475
465
|
row.delete(:cid)
|
476
466
|
row[:allow_null] = row.delete(:notnull).to_i == 0
|
477
467
|
row[:default] = row.delete(:dflt_value)
|
478
468
|
row[:default] = nil if blank_object?(row[:default]) || row[:default] == 'NULL'
|
479
469
|
row[:db_type] = row.delete(:type)
|
480
470
|
if row[:primary_key] = row.delete(:pk).to_i > 0
|
471
|
+
pks += 1
|
472
|
+
# Guess that an integer primary key uses auto increment,
|
473
|
+
# since that is Sequel's default and SQLite does not provide
|
474
|
+
# a way to introspect whether it is actually autoincrementing.
|
481
475
|
row[:auto_increment] = row[:db_type].downcase == 'integer'
|
482
476
|
end
|
483
477
|
row[:type] = schema_column_type(row[:db_type])
|
484
478
|
row
|
485
479
|
end
|
480
|
+
|
481
|
+
if pks > 1
|
482
|
+
# SQLite does not allow use of auto increment for tables
|
483
|
+
# with composite primary keys, so remove auto_increment
|
484
|
+
# if composite primary keys are detected.
|
485
|
+
sch.each{|r| r.delete(:auto_increment)}
|
486
|
+
end
|
487
|
+
|
488
|
+
sch
|
486
489
|
end
|
487
490
|
|
488
491
|
# SQLite supports schema parsing using the table_info PRAGMA, so
|
@@ -497,7 +500,7 @@ module Sequel
|
|
497
500
|
# Backbone of the tables and views support.
|
498
501
|
def tables_and_views(filter, opts)
|
499
502
|
m = output_identifier_meth
|
500
|
-
metadata_dataset.from(:sqlite_master).server(opts[:server]).
|
503
|
+
metadata_dataset.from(:sqlite_master).server(opts[:server]).where(filter).map{|r| m.call(r[:name])}
|
501
504
|
end
|
502
505
|
|
503
506
|
# SQLite only supports AUTOINCREMENT on integer columns, not
|
@@ -511,6 +514,7 @@ module Sequel
|
|
511
514
|
# Instance methods for datasets that connect to an SQLite database
|
512
515
|
module DatasetMethods
|
513
516
|
include Dataset::Replace
|
517
|
+
include UnmodifiedIdentifiers::DatasetMethods
|
514
518
|
|
515
519
|
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
|
516
520
|
EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
|
@@ -310,13 +310,6 @@ module Sequel
|
|
310
310
|
BindArgumentMethods = prepared_statements_module(:bind, ArgumentMapper)
|
311
311
|
PreparedStatementMethods = prepared_statements_module(:prepare, BindArgumentMethods)
|
312
312
|
|
313
|
-
# Execute the given type of statement with the hash of values.
|
314
|
-
def call(type, bind_vars={}, *values, &block)
|
315
|
-
ps = to_prepared_statement(type, values)
|
316
|
-
ps.extend(BindArgumentMethods)
|
317
|
-
ps.call(bind_vars, &block)
|
318
|
-
end
|
319
|
-
|
320
313
|
# Yield a hash for each row in the dataset.
|
321
314
|
def fetch_rows(sql)
|
322
315
|
execute(sql) do |result|
|
@@ -339,19 +332,6 @@ module Sequel
|
|
339
332
|
end
|
340
333
|
end
|
341
334
|
|
342
|
-
# Prepare the given type of query with the given name and store
|
343
|
-
# it in the database. Note that a new native prepared statement is
|
344
|
-
# created on each call to this prepared statement.
|
345
|
-
def prepare(type, name=nil, *values)
|
346
|
-
ps = to_prepared_statement(type, values)
|
347
|
-
ps.extend(PreparedStatementMethods)
|
348
|
-
if name
|
349
|
-
ps.prepared_statement_name = name
|
350
|
-
db.set_prepared_statement(name, ps)
|
351
|
-
end
|
352
|
-
ps
|
353
|
-
end
|
354
|
-
|
355
335
|
private
|
356
336
|
|
357
337
|
# The base type name for a given type, without any parenthetical part.
|
@@ -364,6 +344,14 @@ module Sequel
|
|
364
344
|
sql << "'" << ::SQLite3::Database.quote(v) << "'"
|
365
345
|
end
|
366
346
|
|
347
|
+
def bound_variable_modules
|
348
|
+
[BindArgumentMethods]
|
349
|
+
end
|
350
|
+
|
351
|
+
def prepared_statement_modules
|
352
|
+
[PreparedStatementMethods]
|
353
|
+
end
|
354
|
+
|
367
355
|
# SQLite uses a : before the name of the argument as a placeholder.
|
368
356
|
def prepared_arg_placeholder
|
369
357
|
PREPARED_ARG_PLACEHOLDER
|
@@ -12,7 +12,6 @@ module Sequel
|
|
12
12
|
module Postgres
|
13
13
|
# Methods to add to Database instances that access PostgreSQL via Swift.
|
14
14
|
module DatabaseMethods
|
15
|
-
extend Sequel::Database::ResetIdentifierMangling
|
16
15
|
include Sequel::Postgres::DatabaseMethods
|
17
16
|
|
18
17
|
# Add the primary_keys and primary_key_sequences instance variables,
|
@@ -243,18 +243,6 @@ module Sequel
|
|
243
243
|
self
|
244
244
|
end
|
245
245
|
|
246
|
-
# Create a named prepared statement that is stored in the
|
247
|
-
# database (and connection) for reuse.
|
248
|
-
def prepare(type, name=nil, *values)
|
249
|
-
ps = to_prepared_statement(type, values)
|
250
|
-
ps.extend(PreparedStatementMethods)
|
251
|
-
if name
|
252
|
-
ps.prepared_statement_name = name
|
253
|
-
db.set_prepared_statement(name, ps)
|
254
|
-
end
|
255
|
-
ps
|
256
|
-
end
|
257
|
-
|
258
246
|
private
|
259
247
|
|
260
248
|
# Properly escape the given string +v+.
|
@@ -262,6 +250,10 @@ module Sequel
|
|
262
250
|
sql << (mssql_unicode_strings ? UNICODE_STRING_START : APOS)
|
263
251
|
sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(BACKSLASH_CRLF_RE, BACKSLASH_CRLF_REPLACE) << APOS
|
264
252
|
end
|
253
|
+
|
254
|
+
def prepared_statement_modules
|
255
|
+
[PreparedStatementMethods]
|
256
|
+
end
|
265
257
|
end
|
266
258
|
end
|
267
259
|
end
|
@@ -67,14 +67,14 @@ module Sequel
|
|
67
67
|
include Sequel::Dataset::StoredProcedures
|
68
68
|
|
69
69
|
StoredProcedureMethods = Sequel::Dataset.send(:prepared_statements_module,
|
70
|
-
"sql = @sproc_name; opts = Hash[opts]; opts[:args] = @sproc_args; opts[:sproc] = true",
|
70
|
+
"sql = @opts[:sproc_name]; opts = Hash[opts]; opts[:args] = @opts[:sproc_args]; opts[:sproc] = true",
|
71
71
|
Sequel::Dataset::StoredProcedureMethods, %w'execute execute_dui')
|
72
72
|
|
73
73
|
private
|
74
74
|
|
75
75
|
# Extend the dataset with the MySQL stored procedure methods.
|
76
76
|
def prepare_extend_sproc(ds)
|
77
|
-
ds.
|
77
|
+
ds.with_extend(StoredProcedureMethods)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -36,45 +36,22 @@ module Sequel
|
|
36
36
|
# Extend given dataset with this module so subselects inside subselects in
|
37
37
|
# prepared statements work.
|
38
38
|
def subselect_sql_append(sql, ds)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
ps.prepared_args = prepared_args
|
43
|
-
ps.prepared_sql
|
39
|
+
ds.clone(:append_sql=>sql, :prepared_args=>prepared_args, :bind_vars=>@opts[:bind_vars]).
|
40
|
+
send(:to_prepared_statement, :select, nil, :extend=>bound_variable_modules).
|
41
|
+
prepared_sql
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
|
-
PreparedStatementMethods = Sequel::Dataset.send(:prepared_statements_module,
|
48
|
-
:prepare_bind,
|
49
|
-
Sequel::Dataset::UnnumberedArgumentMapper) do
|
50
|
-
# Raise a more obvious error if you attempt to call a unnamed prepared statement.
|
51
|
-
def call(*)
|
52
|
-
raise Error, "Cannot call prepared statement without a name" if prepared_statement_name.nil?
|
53
|
-
super
|
54
|
-
end
|
55
|
-
end
|
45
|
+
PreparedStatementMethods = Sequel::Dataset.send(:prepared_statements_module, :prepare_bind, Sequel::Dataset::UnnumberedArgumentMapper)
|
56
46
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# fixes it.
|
62
|
-
def call(type, bind_arguments={}, *values, &block)
|
63
|
-
ps = to_prepared_statement(type, values)
|
64
|
-
ps.extend(CallableStatementMethods)
|
65
|
-
ps.call(bind_arguments, &block)
|
47
|
+
private
|
48
|
+
|
49
|
+
def bound_variable_modules
|
50
|
+
[CallableStatementMethods]
|
66
51
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
def prepare(type, name=nil, *values)
|
71
|
-
ps = to_prepared_statement(type, values)
|
72
|
-
ps.extend(PreparedStatementMethods)
|
73
|
-
if name
|
74
|
-
ps.prepared_statement_name = name
|
75
|
-
db.set_prepared_statement(name, ps)
|
76
|
-
end
|
77
|
-
ps
|
52
|
+
|
53
|
+
def prepared_statement_modules
|
54
|
+
[PreparedStatementMethods]
|
78
55
|
end
|
79
56
|
end
|
80
57
|
end
|
@@ -3,17 +3,16 @@
|
|
3
3
|
module Sequel
|
4
4
|
class Dataset
|
5
5
|
module StoredProcedureMethods
|
6
|
+
Dataset.def_deprecated_opts_setter(self, :sproc_type, :sproc_name, :sproc_args)
|
7
|
+
|
6
8
|
# The name of the stored procedure to call
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
attr_writer :sproc_args
|
9
|
+
def sproc_name
|
10
|
+
@opts[:sproc_name]
|
11
|
+
end
|
11
12
|
|
12
13
|
# Call the stored procedure with the given args
|
13
14
|
def call(*args, &block)
|
14
|
-
|
15
|
-
sp.sproc_args = args
|
16
|
-
sp.run(&block)
|
15
|
+
clone(:sproc_args=>args).run(&block)
|
17
16
|
end
|
18
17
|
|
19
18
|
# Programmer friendly string showing this is a stored procedure,
|
@@ -24,7 +23,7 @@ module Sequel
|
|
24
23
|
|
25
24
|
# Run the stored procedure with the current args on the database
|
26
25
|
def run(&block)
|
27
|
-
case @sproc_type
|
26
|
+
case @opts[:sproc_type]
|
28
27
|
when :select, :all
|
29
28
|
all(&block)
|
30
29
|
when :first
|
@@ -37,14 +36,6 @@ module Sequel
|
|
37
36
|
delete
|
38
37
|
end
|
39
38
|
end
|
40
|
-
|
41
|
-
# Set the type of the stored procedure and override the corresponding _sql
|
42
|
-
# method to return the empty string (since the result will be
|
43
|
-
# ignored anyway).
|
44
|
-
def sproc_type=(type)
|
45
|
-
@sproc_type = type
|
46
|
-
@opts[:sql] = ''
|
47
|
-
end
|
48
39
|
end
|
49
40
|
|
50
41
|
module StoredProcedures
|
@@ -58,18 +49,14 @@ module Sequel
|
|
58
49
|
# Transform this dataset into a stored procedure that you can call
|
59
50
|
# multiple times with new arguments.
|
60
51
|
def prepare_sproc(type, name)
|
61
|
-
|
62
|
-
prepare_extend_sproc(sp)
|
63
|
-
sp.sproc_type = type
|
64
|
-
sp.sproc_name = name
|
65
|
-
sp
|
52
|
+
prepare_extend_sproc(self).clone(:sproc_type=>type, :sproc_name=>name, :sql=>'')
|
66
53
|
end
|
67
54
|
|
68
55
|
private
|
69
56
|
|
70
57
|
# Extend the dataset with the stored procedure methods.
|
71
58
|
def prepare_extend_sproc(ds)
|
72
|
-
ds.
|
59
|
+
ds.with_extend(StoredProcedureMethods)
|
73
60
|
end
|
74
61
|
end
|
75
62
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sequel
|
2
|
+
module UnmodifiedIdentifiers
|
3
|
+
module DatabaseMethods
|
4
|
+
private
|
5
|
+
|
6
|
+
# Databases that use this module for unquoted identifiers to lowercase.
|
7
|
+
def folds_unquoted_identifiers_to_uppercase?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module DatasetMethods
|
13
|
+
private
|
14
|
+
|
15
|
+
# Turn the given symbol/string into a symbol, keeping the current case.
|
16
|
+
def output_identifier(v)
|
17
|
+
v == '' ? :untitled : v.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
# Turn the given symbol/string into a string, keeping the current case.
|
21
|
+
def input_identifier(v)
|
22
|
+
v.to_s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -137,11 +137,11 @@ module Sequel
|
|
137
137
|
#
|
138
138
|
# So it can handle cases like:
|
139
139
|
#
|
140
|
-
# DB.
|
140
|
+
# DB.where(:a=>1).exclude(:b=>2).where{c > 3}
|
141
141
|
#
|
142
142
|
# But it cannot handle cases like:
|
143
143
|
#
|
144
|
-
# DB.
|
144
|
+
# DB.where(:a + 1 < 0)
|
145
145
|
class Unbinder < ASTTransformer
|
146
146
|
# The <tt>SQL::ComplexExpression<tt> operates that will be considered
|
147
147
|
# for transformation.
|
@@ -56,7 +56,7 @@ module Sequel
|
|
56
56
|
# DB.from(:items){id > 2} # SELECT * FROM items WHERE (id > 2)
|
57
57
|
def from(*args, &block)
|
58
58
|
ds = @default_dataset.from(*args)
|
59
|
-
block ? ds.
|
59
|
+
block ? ds.where(&block) : ds
|
60
60
|
end
|
61
61
|
|
62
62
|
# Returns a new dataset with the select method invoked.
|
@@ -40,12 +40,6 @@ module Sequel
|
|
40
40
|
# an optional options hash.
|
41
41
|
attr_reader :dataset_class
|
42
42
|
|
43
|
-
# The identifier input method to use by default for this database (default: adapter default)
|
44
|
-
attr_reader :identifier_input_method
|
45
|
-
|
46
|
-
# The identifier output method to use by default for this database (default: adapter default)
|
47
|
-
attr_reader :identifier_output_method
|
48
|
-
|
49
43
|
# If the database has any dataset modules associated with it,
|
50
44
|
# use a subclass of the given class that includes the modules
|
51
45
|
# as the dataset class.
|
@@ -93,41 +87,6 @@ module Sequel
|
|
93
87
|
reset_default_dataset
|
94
88
|
end
|
95
89
|
|
96
|
-
# Set the method to call on identifiers going into the database:
|
97
|
-
#
|
98
|
-
# DB[:items] # SELECT * FROM items
|
99
|
-
# DB.identifier_input_method = :upcase
|
100
|
-
# DB[:items] # SELECT * FROM ITEMS
|
101
|
-
def identifier_input_method=(v)
|
102
|
-
reset_default_dataset
|
103
|
-
@identifier_input_method = v
|
104
|
-
end
|
105
|
-
|
106
|
-
# Set the method to call on identifiers coming from the database:
|
107
|
-
#
|
108
|
-
# DB[:items].first # {:id=>1, :name=>'foo'}
|
109
|
-
# DB.identifier_output_method = :upcase
|
110
|
-
# DB[:items].first # {:ID=>1, :NAME=>'foo'}
|
111
|
-
def identifier_output_method=(v)
|
112
|
-
reset_default_dataset
|
113
|
-
@identifier_output_method = v
|
114
|
-
end
|
115
|
-
|
116
|
-
# Set whether to quote identifiers (columns and tables) for this database:
|
117
|
-
#
|
118
|
-
# DB[:items] # SELECT * FROM items
|
119
|
-
# DB.quote_identifiers = true
|
120
|
-
# DB[:items] # SELECT * FROM "items"
|
121
|
-
def quote_identifiers=(v)
|
122
|
-
reset_default_dataset
|
123
|
-
@quote_identifiers = v
|
124
|
-
end
|
125
|
-
|
126
|
-
# Returns true if the database quotes identifiers.
|
127
|
-
def quote_identifiers?
|
128
|
-
@quote_identifiers
|
129
|
-
end
|
130
|
-
|
131
90
|
private
|
132
91
|
|
133
92
|
# The default dataset class to use for the database
|
@@ -143,35 +102,10 @@ module Sequel
|
|
143
102
|
@default_dataset = dataset
|
144
103
|
end
|
145
104
|
|
146
|
-
# The method to apply to identifiers going into the database by default.
|
147
|
-
# Should be overridden in subclasses for databases that fold unquoted
|
148
|
-
# identifiers to lower case instead of uppercase, such as
|
149
|
-
# MySQL, PostgreSQL, and SQLite.
|
150
|
-
def identifier_input_method_default
|
151
|
-
:upcase
|
152
|
-
end
|
153
|
-
|
154
|
-
# The method to apply to identifiers coming the database by default.
|
155
|
-
# Should be overridden in subclasses for databases that fold unquoted
|
156
|
-
# identifiers to lower case instead of uppercase, such as
|
157
|
-
# MySQL, PostgreSQL, and SQLite.
|
158
|
-
def identifier_output_method_default
|
159
|
-
:downcase
|
160
|
-
end
|
161
|
-
|
162
105
|
# Whether to quote identifiers by default for this database, true
|
163
106
|
# by default.
|
164
107
|
def quote_identifiers_default
|
165
108
|
true
|
166
109
|
end
|
167
|
-
|
168
|
-
# Reset the identifier mangling options. Overrides any already set on
|
169
|
-
# the instance. Only for internal use by shared adapters.
|
170
|
-
def reset_identifier_mangling
|
171
|
-
@quote_identifiers = @opts.fetch(:quote_identifiers){(qi = Database.quote_identifiers).nil? ? quote_identifiers_default : qi}
|
172
|
-
@identifier_input_method = @opts.fetch(:identifier_input_method){(iim = Database.identifier_input_method).nil? ? identifier_input_method_default : (iim if iim)}
|
173
|
-
@identifier_output_method = @opts.fetch(:identifier_output_method){(iom = Database.identifier_output_method).nil? ? identifier_output_method_default : (iom if iom)}
|
174
|
-
reset_default_dataset
|
175
|
-
end
|
176
110
|
end
|
177
111
|
end
|