sequel 4.41.0 → 4.42.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.
- 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
|