sequel 4.45.0 → 4.46.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 +108 -0
- data/doc/release_notes/4.46.0.txt +404 -0
- data/doc/security.rdoc +9 -0
- data/doc/sql.rdoc +2 -2
- data/doc/testing.rdoc +1 -1
- data/doc/validations.rdoc +1 -2
- data/lib/sequel/adapters/ado.rb +8 -3
- data/lib/sequel/adapters/ado/access.rb +8 -4
- data/lib/sequel/adapters/ado/mssql.rb +3 -1
- data/lib/sequel/adapters/amalgalite.rb +5 -0
- data/lib/sequel/adapters/cubrid.rb +16 -7
- data/lib/sequel/adapters/do.rb +7 -1
- data/lib/sequel/adapters/do/mysql.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +10 -5
- data/lib/sequel/adapters/jdbc.rb +8 -2
- data/lib/sequel/adapters/jdbc/as400.rb +10 -3
- data/lib/sequel/adapters/jdbc/db2.rb +27 -16
- data/lib/sequel/adapters/jdbc/derby.rb +47 -20
- data/lib/sequel/adapters/jdbc/h2.rb +13 -7
- data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +6 -1
- data/lib/sequel/adapters/odbc.rb +20 -8
- data/lib/sequel/adapters/odbc/mssql.rb +6 -3
- data/lib/sequel/adapters/oracle.rb +12 -6
- data/lib/sequel/adapters/postgres.rb +20 -8
- data/lib/sequel/adapters/shared/access.rb +76 -47
- data/lib/sequel/adapters/shared/cubrid.rb +16 -11
- data/lib/sequel/adapters/shared/db2.rb +46 -19
- data/lib/sequel/adapters/shared/firebird.rb +20 -8
- data/lib/sequel/adapters/shared/informix.rb +6 -3
- data/lib/sequel/adapters/shared/mssql.rb +132 -72
- data/lib/sequel/adapters/shared/mysql.rb +112 -65
- data/lib/sequel/adapters/shared/oracle.rb +36 -21
- data/lib/sequel/adapters/shared/postgres.rb +91 -56
- data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
- data/lib/sequel/adapters/shared/sqlite.rb +67 -32
- data/lib/sequel/adapters/sqlanywhere.rb +9 -1
- data/lib/sequel/adapters/sqlite.rb +8 -1
- data/lib/sequel/adapters/swift.rb +5 -0
- data/lib/sequel/adapters/swift/mysql.rb +4 -2
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +10 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/adapters/utils/pg_types.rb +14 -6
- data/lib/sequel/adapters/utils/replace.rb +4 -2
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/core.rb +24 -11
- data/lib/sequel/database/connecting.rb +9 -3
- data/lib/sequel/database/dataset_defaults.rb +7 -1
- data/lib/sequel/database/logging.rb +1 -0
- data/lib/sequel/database/misc.rb +5 -2
- data/lib/sequel/database/query.rb +7 -5
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +50 -27
- data/lib/sequel/database/transactions.rb +19 -9
- data/lib/sequel/dataset/actions.rb +15 -6
- data/lib/sequel/dataset/graph.rb +15 -5
- data/lib/sequel/dataset/misc.rb +12 -4
- data/lib/sequel/dataset/mutation.rb +17 -8
- data/lib/sequel/dataset/prepared_statements.rb +3 -2
- data/lib/sequel/dataset/query.rb +84 -38
- data/lib/sequel/dataset/sql.rb +302 -191
- data/lib/sequel/deprecated.rb +26 -17
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/migration.rb +28 -4
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +4 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
- data/lib/sequel/extensions/set_overrides.rb +2 -0
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +11 -7
- data/lib/sequel/model/associations.rb +5 -7
- data/lib/sequel/model/base.rb +47 -45
- data/lib/sequel/model/dataset_module.rb +9 -14
- data/lib/sequel/model/plugins.rb +3 -0
- data/lib/sequel/no_core_ext.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -1
- data/lib/sequel/plugins/boolean_subsets.rb +7 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/finder.rb +240 -0
- data/lib/sequel/plugins/inverted_subsets.rb +19 -12
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
- data/lib/sequel/plugins/subset_conditions.rb +11 -3
- data/lib/sequel/plugins/whitelist_security.rb +118 -0
- data/lib/sequel/sql.rb +80 -36
- data/lib/sequel/timezones.rb +2 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +20 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +12 -8
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +36 -34
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +87 -9
- data/spec/core/dataset_spec.rb +501 -129
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +146 -60
- data/spec/core/mock_adapter_spec.rb +1 -1
- data/spec/core/object_graph_spec.rb +61 -9
- data/spec/core/placeholder_literalizer_spec.rb +20 -2
- data/spec/core/schema_generator_spec.rb +6 -6
- data/spec/core/schema_spec.rb +54 -5
- data/spec/core_extensions_spec.rb +122 -18
- data/spec/deprecation_helper.rb +27 -2
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
- data/spec/extensions/association_proxies_spec.rb +2 -2
- data/spec/extensions/auto_literal_strings_spec.rb +212 -0
- data/spec/extensions/blacklist_security_spec.rb +1 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
- data/spec/extensions/column_select_spec.rb +20 -8
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/core_refinements_spec.rb +29 -12
- data/spec/extensions/dataset_associations_spec.rb +12 -12
- data/spec/extensions/def_dataset_method_spec.rb +100 -0
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +260 -0
- data/spec/extensions/graph_each_spec.rb +2 -2
- data/spec/extensions/identifier_mangling_spec.rb +14 -8
- data/spec/extensions/inverted_subsets_spec.rb +4 -4
- data/spec/extensions/lazy_attributes_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +38 -14
- data/spec/extensions/nested_attributes_spec.rb +18 -6
- data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
- data/spec/extensions/pg_enum_spec.rb +16 -1
- data/spec/extensions/pg_interval_spec.rb +11 -2
- data/spec/extensions/pg_loose_count_spec.rb +5 -0
- data/spec/extensions/pg_row_spec.rb +25 -0
- data/spec/extensions/prepared_statements_spec.rb +10 -1
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/set_overrides_spec.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +0 -1
- data/spec/extensions/subset_conditions_spec.rb +6 -6
- data/spec/extensions/table_select_spec.rb +24 -12
- data/spec/extensions/to_dot_spec.rb +4 -4
- data/spec/extensions/whitelist_security_spec.rb +131 -0
- data/spec/integration/dataset_test.rb +9 -5
- data/spec/integration/model_test.rb +2 -0
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/model/associations_spec.rb +39 -11
- data/spec/model/base_spec.rb +44 -24
- data/spec/model/class_dataset_methods_spec.rb +18 -16
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +84 -24
- data/spec/model/model_spec.rb +97 -63
- data/spec/model/record_spec.rb +21 -13
- metadata +13 -2
|
@@ -18,8 +18,10 @@ module Sequel
|
|
|
18
18
|
module DatabaseMethods
|
|
19
19
|
include UnmodifiedIdentifiers::DatabaseMethods
|
|
20
20
|
|
|
21
|
-
AUTO_VACUUM = [:none, :full, :incremental].freeze
|
|
22
21
|
PRIMARY_KEY_INDEX_RE = /\Asqlite_autoindex_/.freeze
|
|
22
|
+
Sequel::Deprecation.deprecate_constant(self, :PRIMARY_KEY_INDEX_RE)
|
|
23
|
+
|
|
24
|
+
AUTO_VACUUM = [:none, :full, :incremental].freeze
|
|
23
25
|
SYNCHRONOUS = [:off, :normal, :full].freeze
|
|
24
26
|
TABLES_FILTER = Sequel.~(:name=>'sqlite_sequence'.freeze) & {:type => 'table'.freeze}
|
|
25
27
|
TEMP_STORE = [:default, :file, :memory].freeze
|
|
@@ -28,7 +30,7 @@ module Sequel
|
|
|
28
30
|
:deferred => "BEGIN DEFERRED TRANSACTION".freeze,
|
|
29
31
|
:immediate => "BEGIN IMMEDIATE TRANSACTION".freeze,
|
|
30
32
|
:exclusive => "BEGIN EXCLUSIVE TRANSACTION".freeze,
|
|
31
|
-
nil =>
|
|
33
|
+
nil => "BEGIN".freeze
|
|
32
34
|
}.freeze
|
|
33
35
|
|
|
34
36
|
# Whether to use integers for booleans in the database. SQLite recommends
|
|
@@ -114,7 +116,7 @@ module Sequel
|
|
|
114
116
|
indexes = {}
|
|
115
117
|
metadata_dataset.with_sql("PRAGMA index_list(?)", im.call(table)).each do |r|
|
|
116
118
|
# :only_autocreated internal option can be used to get only autocreated indexes
|
|
117
|
-
next if (!!(r[:name] =~
|
|
119
|
+
next if (!!(r[:name] =~ /\Asqlite_autoindex_/) ^ !!opts[:only_autocreated])
|
|
118
120
|
indexes[m.call(r[:name])] = {:unique=>r[:unique].to_i==1}
|
|
119
121
|
end
|
|
120
122
|
indexes.each do |k, v|
|
|
@@ -125,6 +127,7 @@ module Sequel
|
|
|
125
127
|
|
|
126
128
|
# Get the value of the given PRAGMA.
|
|
127
129
|
def pragma_get(name)
|
|
130
|
+
Sequel::Deprecation.deprecate('Database#{pragma_get,auto_vacuum,case_sensitive_like,foreign_keys,synchronous,temp_store} on SQLite', "These methods may not be safe when using multiple connections, call fetch(#{"PRAGMA #{name}".inspect}).single_value if you really want to get the pragma value")
|
|
128
131
|
self["PRAGMA #{name}"].single_value
|
|
129
132
|
end
|
|
130
133
|
|
|
@@ -135,6 +138,7 @@ module Sequel
|
|
|
135
138
|
# modifications should be done when the connection is created, using
|
|
136
139
|
# an option provided when creating the Database object.
|
|
137
140
|
def pragma_set(name, value)
|
|
141
|
+
Sequel::Deprecation.deprecate('Database#{pragma_set,auto_vacuum=,case_sensitive_like=,foreign_keys=,synchronous=,temp_store=} on SQLite', "These methods are not thread safe or safe when using multiple connections, pass the appropriate option when connecting to set the pragma correctly for all connections")
|
|
138
142
|
execute_ddl("PRAGMA #{name} = #{value}")
|
|
139
143
|
end
|
|
140
144
|
|
|
@@ -239,8 +243,8 @@ module Sequel
|
|
|
239
243
|
# Run all alter_table commands in a transaction. This is technically only
|
|
240
244
|
# needed for drop column.
|
|
241
245
|
def apply_alter_table(table, ops)
|
|
242
|
-
fks = foreign_keys
|
|
243
|
-
|
|
246
|
+
fks = fetch("PRAGMA foreign_keys")
|
|
247
|
+
run "PRAGMA foreign_keys = 0" if fks
|
|
244
248
|
transaction do
|
|
245
249
|
if ops.length > 1 && ops.all?{|op| op[:op] == :add_constraint}
|
|
246
250
|
# If you are just doing constraints, apply all of them at the same time,
|
|
@@ -253,7 +257,7 @@ module Sequel
|
|
|
253
257
|
end
|
|
254
258
|
end
|
|
255
259
|
ensure
|
|
256
|
-
|
|
260
|
+
run "PRAGMA foreign_keys = 1" if fks
|
|
257
261
|
end
|
|
258
262
|
|
|
259
263
|
# SQLite supports limited table modification. You can add a column
|
|
@@ -545,28 +549,50 @@ module Sequel
|
|
|
545
549
|
include Dataset::Replace
|
|
546
550
|
include UnmodifiedIdentifiers::DatasetMethods
|
|
547
551
|
|
|
548
|
-
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}
|
|
549
|
-
|
|
550
|
-
EXTRACT_MAP
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
552
|
+
CONSTANT_MAP = {:CURRENT_DATE=>"date(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIMESTAMP=>"datetime(CURRENT_TIMESTAMP, 'localtime')".freeze, :CURRENT_TIME=>"time(CURRENT_TIMESTAMP, 'localtime')".freeze}#.freeze # SEQUEL5
|
|
553
|
+
EXTRACT_MAP = {:year=>"'%Y'", :month=>"'%m'", :day=>"'%d'", :hour=>"'%H'", :minute=>"'%M'", :second=>"'%f'"}#.freeze # SEQUEL5
|
|
554
|
+
#EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
|
|
555
|
+
|
|
556
|
+
NOT_SPACE = 'NOT '.freeze
|
|
557
|
+
Sequel::Deprecation.deprecate_constant(self, :NOT_SPACE)
|
|
558
|
+
COMMA = ', '.freeze
|
|
559
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
560
|
+
PAREN_CLOSE = ')'.freeze
|
|
561
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
|
|
562
|
+
AS = ' AS '.freeze
|
|
563
|
+
Sequel::Deprecation.deprecate_constant(self, :AS)
|
|
564
|
+
APOS = "'".freeze
|
|
565
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
556
566
|
EXTRACT_OPEN = "CAST(strftime(".freeze
|
|
567
|
+
Sequel::Deprecation.deprecate_constant(self, :EXTRACT_OPEN)
|
|
557
568
|
EXTRACT_CLOSE = ') AS '.freeze
|
|
569
|
+
Sequel::Deprecation.deprecate_constant(self, :EXTRACT_CLOSE)
|
|
558
570
|
NUMERIC = 'NUMERIC'.freeze
|
|
571
|
+
Sequel::Deprecation.deprecate_constant(self, :NUMERIC)
|
|
559
572
|
INTEGER = 'INTEGER'.freeze
|
|
573
|
+
Sequel::Deprecation.deprecate_constant(self, :INTEGER)
|
|
560
574
|
BACKTICK = '`'.freeze
|
|
575
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKTICK)
|
|
561
576
|
BACKTICK_RE = /`/.freeze
|
|
577
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKTICK_RE)
|
|
562
578
|
DOUBLE_BACKTICK = '``'.freeze
|
|
579
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_BACKTICK)
|
|
563
580
|
BLOB_START = "X'".freeze
|
|
581
|
+
Sequel::Deprecation.deprecate_constant(self, :BLOB_START)
|
|
564
582
|
HSTAR = "H*".freeze
|
|
583
|
+
Sequel::Deprecation.deprecate_constant(self, :HSTAR)
|
|
565
584
|
DATE_OPEN = "date(".freeze
|
|
585
|
+
Sequel::Deprecation.deprecate_constant(self, :DATE_OPEN)
|
|
566
586
|
DATETIME_OPEN = "datetime(".freeze
|
|
587
|
+
Sequel::Deprecation.deprecate_constant(self, :DATETIME_OPEN)
|
|
567
588
|
ONLY_OFFSET = " LIMIT -1 OFFSET ".freeze
|
|
589
|
+
Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
|
|
568
590
|
OR = " OR ".freeze
|
|
591
|
+
Sequel::Deprecation.deprecate_constant(self, :OR)
|
|
569
592
|
SELECT_VALUES = "VALUES ".freeze
|
|
593
|
+
Sequel::Deprecation.deprecate_constant(self, :SELECT_VALUES)
|
|
594
|
+
EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
|
|
595
|
+
Sequel::Deprecation.deprecate_constant(self, :EMULATED_FUNCTION_MAP)
|
|
570
596
|
|
|
571
597
|
Dataset.def_sql_method(self, :delete, [['if db.sqlite_version >= 30803', %w'with delete from where'], ["else", %w'delete from where']])
|
|
572
598
|
Dataset.def_sql_method(self, :insert, [['if db.sqlite_version >= 30803', %w'with insert conflict into columns values'], ["else", %w'insert conflict into columns values']])
|
|
@@ -575,13 +601,13 @@ module Sequel
|
|
|
575
601
|
|
|
576
602
|
def cast_sql_append(sql, expr, type)
|
|
577
603
|
if type == Time or type == DateTime
|
|
578
|
-
sql <<
|
|
604
|
+
sql << "datetime("
|
|
579
605
|
literal_append(sql, expr)
|
|
580
|
-
sql <<
|
|
606
|
+
sql << ')'
|
|
581
607
|
elsif type == Date
|
|
582
|
-
sql <<
|
|
608
|
+
sql << "date("
|
|
583
609
|
literal_append(sql, expr)
|
|
584
|
-
sql <<
|
|
610
|
+
sql << ')'
|
|
585
611
|
else
|
|
586
612
|
super
|
|
587
613
|
end
|
|
@@ -592,7 +618,7 @@ module Sequel
|
|
|
592
618
|
def complex_expression_sql_append(sql, op, args)
|
|
593
619
|
case op
|
|
594
620
|
when :"NOT LIKE", :"NOT ILIKE"
|
|
595
|
-
sql <<
|
|
621
|
+
sql << 'NOT '
|
|
596
622
|
complex_expression_sql_append(sql, (op == :"NOT ILIKE" ? :ILIKE : :LIKE), args)
|
|
597
623
|
when :^
|
|
598
624
|
complex_expression_arg_pairs_append(sql, args){|a, b| Sequel.lit(["((~(", " & ", ")) & (", " | ", "))"], a, b, a, b)}
|
|
@@ -605,7 +631,7 @@ module Sequel
|
|
|
605
631
|
sql << '1'
|
|
606
632
|
else
|
|
607
633
|
sql << '('
|
|
608
|
-
arg = args
|
|
634
|
+
arg = args[0]
|
|
609
635
|
if exp < 0
|
|
610
636
|
invert = true
|
|
611
637
|
exp = exp.abs
|
|
@@ -616,17 +642,17 @@ module Sequel
|
|
|
616
642
|
sql << " * "
|
|
617
643
|
end
|
|
618
644
|
literal_append(sql, arg)
|
|
619
|
-
sql <<
|
|
645
|
+
sql << ')'
|
|
620
646
|
if invert
|
|
621
647
|
sql << "))"
|
|
622
648
|
end
|
|
623
649
|
end
|
|
624
650
|
when :extract
|
|
625
|
-
part = args
|
|
651
|
+
part = args[0]
|
|
626
652
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
|
627
|
-
sql <<
|
|
628
|
-
literal_append(sql, args
|
|
629
|
-
sql <<
|
|
653
|
+
sql << "CAST(strftime(" << format << ', '
|
|
654
|
+
literal_append(sql, args[1])
|
|
655
|
+
sql << ') AS ' << (part == :second ? 'NUMERIC' : 'INTEGER') << ')'
|
|
630
656
|
else
|
|
631
657
|
super
|
|
632
658
|
end
|
|
@@ -669,7 +695,7 @@ module Sequel
|
|
|
669
695
|
|
|
670
696
|
# SQLite uses the nonstandard ` (backtick) for quoting identifiers.
|
|
671
697
|
def quoted_identifier_append(sql, c)
|
|
672
|
-
sql <<
|
|
698
|
+
sql << '`' << c.to_s.gsub('`', '``') << '`'
|
|
673
699
|
end
|
|
674
700
|
|
|
675
701
|
# When a qualified column is selected on SQLite and the qualifier
|
|
@@ -752,7 +778,7 @@ module Sequel
|
|
|
752
778
|
def as_sql_append(sql, aliaz, column_aliases=nil)
|
|
753
779
|
raise Error, "sqlite does not support derived column lists" if column_aliases
|
|
754
780
|
aliaz = aliaz.value if aliaz.is_a?(SQL::Identifier)
|
|
755
|
-
sql << AS
|
|
781
|
+
sql << ' AS '
|
|
756
782
|
literal_append(sql, aliaz.to_s)
|
|
757
783
|
end
|
|
758
784
|
|
|
@@ -780,19 +806,19 @@ module Sequel
|
|
|
780
806
|
|
|
781
807
|
# SQL fragment specifying a list of identifiers
|
|
782
808
|
def identifier_list(columns)
|
|
783
|
-
columns.map{|i| quote_identifier(i)}.join(
|
|
809
|
+
columns.map{|i| quote_identifier(i)}.join(', ')
|
|
784
810
|
end
|
|
785
811
|
|
|
786
812
|
# Add OR clauses to SQLite INSERT statements
|
|
787
813
|
def insert_conflict_sql(sql)
|
|
788
814
|
if resolution = @opts[:insert_conflict]
|
|
789
|
-
sql << OR << resolution.to_s.upcase
|
|
815
|
+
sql << " OR " << resolution.to_s.upcase
|
|
790
816
|
end
|
|
791
817
|
end
|
|
792
818
|
|
|
793
819
|
# SQLite uses a preceding X for hex escaping strings
|
|
794
820
|
def literal_blob_append(sql, v)
|
|
795
|
-
sql <<
|
|
821
|
+
sql << "X'" << v.unpack("H*").first << "'"
|
|
796
822
|
end
|
|
797
823
|
|
|
798
824
|
# Respect the database integer_booleans setting, using 0 or 'f'.
|
|
@@ -811,6 +837,15 @@ module Sequel
|
|
|
811
837
|
db.sqlite_version >= 30711 ? :values : :union
|
|
812
838
|
end
|
|
813
839
|
|
|
840
|
+
# Emulate the char_length function with length
|
|
841
|
+
def native_function_name(emulated_function)
|
|
842
|
+
if emulated_function == :char_length
|
|
843
|
+
'length'
|
|
844
|
+
else
|
|
845
|
+
super
|
|
846
|
+
end
|
|
847
|
+
end
|
|
848
|
+
|
|
814
849
|
# SQLite does not support FOR UPDATE, but silently ignore it
|
|
815
850
|
# instead of raising an error for compatibility with other
|
|
816
851
|
# databases.
|
|
@@ -819,13 +854,13 @@ module Sequel
|
|
|
819
854
|
end
|
|
820
855
|
|
|
821
856
|
def select_only_offset_sql(sql)
|
|
822
|
-
sql <<
|
|
857
|
+
sql << " LIMIT -1 OFFSET "
|
|
823
858
|
literal_append(sql, @opts[:offset])
|
|
824
859
|
end
|
|
825
860
|
|
|
826
861
|
# Support VALUES clause instead of the SELECT clause to return rows.
|
|
827
862
|
def select_values_sql(sql)
|
|
828
|
-
sql <<
|
|
863
|
+
sql << "VALUES "
|
|
829
864
|
expression_list_append(sql, opts[:values])
|
|
830
865
|
end
|
|
831
866
|
|
|
@@ -37,12 +37,14 @@ module Sequel
|
|
|
37
37
|
}.each do |k,v|
|
|
38
38
|
k.each{|n| SQLANYWHERE_TYPES[n] = v}
|
|
39
39
|
end
|
|
40
|
+
# SQLANYWHERE_TYPES.freeze # SEQUEL5
|
|
40
41
|
|
|
41
42
|
# Database class for SQLAnywhere databases used with Sequel.
|
|
42
43
|
class Database < Sequel::Database
|
|
43
44
|
include Sequel::SqlAnywhere::DatabaseMethods
|
|
44
45
|
|
|
45
46
|
DEFAULT_CONFIG = { :user => 'dba', :password => 'sql' }
|
|
47
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_CONFIG)
|
|
46
48
|
|
|
47
49
|
attr_accessor :api
|
|
48
50
|
|
|
@@ -106,6 +108,7 @@ module Sequel
|
|
|
106
108
|
private
|
|
107
109
|
|
|
108
110
|
LAST_INSERT_ID = 'SELECT @@IDENTITY'.freeze
|
|
111
|
+
Sequel::Deprecation.deprecate_constant(self, :LAST_INSERT_ID)
|
|
109
112
|
def _execute(conn, type, sql, opts)
|
|
110
113
|
unless rs = log_connection_yield(sql, conn){@api.sqlany_execute_direct(conn, sql)}
|
|
111
114
|
result, errstr = @api.sqlany_error(conn)
|
|
@@ -118,7 +121,7 @@ module Sequel
|
|
|
118
121
|
when :rows
|
|
119
122
|
return @api.sqlany_affected_rows(rs)
|
|
120
123
|
when :insert
|
|
121
|
-
_execute(conn, :select,
|
|
124
|
+
_execute(conn, :select, 'SELECT @@IDENTITY', opts){|r| return @api.sqlany_get_column(r, 0)[1] if r && @api.sqlany_fetch_next(r) == 1}
|
|
122
125
|
end
|
|
123
126
|
ensure
|
|
124
127
|
@api.sqlany_commit(conn) unless in_transaction?
|
|
@@ -133,6 +136,10 @@ module Sequel
|
|
|
133
136
|
raise LoadError, "Could not initialize SQLAnywhere DBCAPI library" if @api.sqlany_init == 0
|
|
134
137
|
end
|
|
135
138
|
|
|
139
|
+
def dataset_class_default
|
|
140
|
+
Dataset
|
|
141
|
+
end
|
|
142
|
+
|
|
136
143
|
def log_connection_execute(conn, sql)
|
|
137
144
|
_execute(conn, nil, sql, OPTS)
|
|
138
145
|
end
|
|
@@ -143,6 +150,7 @@ module Sequel
|
|
|
143
150
|
include Sequel::SqlAnywhere::DatasetMethods
|
|
144
151
|
|
|
145
152
|
Database::DatasetClass = self
|
|
153
|
+
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
|
146
154
|
|
|
147
155
|
# Yield all rows matching this dataset. If the dataset is set to
|
|
148
156
|
# split multiple statements, yield arrays of hashes one per statement
|
|
@@ -74,6 +74,7 @@ module Sequel
|
|
|
74
74
|
}.each do |k,v|
|
|
75
75
|
k.each{|n| SQLITE_TYPES[n] = v}
|
|
76
76
|
end
|
|
77
|
+
# SQLITE_TYPES.freeze # SEQUEL5
|
|
77
78
|
|
|
78
79
|
# Database class for SQLite databases used with Sequel and the
|
|
79
80
|
# ruby-sqlite3 driver.
|
|
@@ -275,6 +276,10 @@ module Sequel
|
|
|
275
276
|
[SQLite3::Exception, ArgumentError]
|
|
276
277
|
end
|
|
277
278
|
|
|
279
|
+
def dataset_class_default
|
|
280
|
+
Dataset
|
|
281
|
+
end
|
|
282
|
+
|
|
278
283
|
# Support SQLite exception codes if ruby-sqlite3 supports them.
|
|
279
284
|
# This is disabled by default because ruby-sqlite3 doesn't currently
|
|
280
285
|
# support them (returning nil), and even if it did, it doesn't support
|
|
@@ -289,8 +294,10 @@ module Sequel
|
|
|
289
294
|
include ::Sequel::SQLite::DatasetMethods
|
|
290
295
|
|
|
291
296
|
Database::DatasetClass = self
|
|
297
|
+
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
|
292
298
|
|
|
293
299
|
PREPARED_ARG_PLACEHOLDER = ':'.freeze
|
|
300
|
+
Sequel::Deprecation.deprecate_constant(self, :PREPARED_ARG_PLACEHOLDER)
|
|
294
301
|
|
|
295
302
|
# SQLite already supports named bind arguments, so use directly.
|
|
296
303
|
module ArgumentMapper
|
|
@@ -367,7 +374,7 @@ module Sequel
|
|
|
367
374
|
|
|
368
375
|
# SQLite uses a : before the name of the argument as a placeholder.
|
|
369
376
|
def prepared_arg_placeholder
|
|
370
|
-
|
|
377
|
+
':'
|
|
371
378
|
end
|
|
372
379
|
end
|
|
373
380
|
end
|
|
@@ -116,6 +116,10 @@ module Sequel
|
|
|
116
116
|
[::Swift::Error]
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
+
def dataset_class_default
|
|
120
|
+
Dataset
|
|
121
|
+
end
|
|
122
|
+
|
|
119
123
|
# Set the :db entry to the same as the :database entry, since
|
|
120
124
|
# Swift uses :db.
|
|
121
125
|
def server_opts(o)
|
|
@@ -133,6 +137,7 @@ module Sequel
|
|
|
133
137
|
|
|
134
138
|
class Dataset < Sequel::Dataset
|
|
135
139
|
Database::DatasetClass = self
|
|
140
|
+
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
|
136
141
|
|
|
137
142
|
# Set the columns and yield the hashes to the block.
|
|
138
143
|
def fetch_rows(sql)
|
|
@@ -34,13 +34,15 @@ module Sequel
|
|
|
34
34
|
# Dataset class for MySQL datasets accessed via Swift.
|
|
35
35
|
class Dataset < Swift::Dataset
|
|
36
36
|
include Sequel::MySQL::DatasetMethods
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
APOS = "'".freeze
|
|
39
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
38
40
|
|
|
39
41
|
private
|
|
40
42
|
|
|
41
43
|
# Use Swift's escape method for quoting.
|
|
42
44
|
def literal_string_append(sql, s)
|
|
43
|
-
sql <<
|
|
45
|
+
sql << "'" << db.synchronize(@opts[:server]){|c| c.escape(s)} << "'"
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
end
|
|
@@ -40,7 +40,7 @@ module Sequel
|
|
|
40
40
|
|
|
41
41
|
# Use Swift's escape method for quoting.
|
|
42
42
|
def literal_string_append(sql, s)
|
|
43
|
-
sql <<
|
|
43
|
+
sql << "'" << db.synchronize(@opts[:server]){|c| c.escape(s)} << "'"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
end
|
|
@@ -131,10 +131,16 @@ module Sequel
|
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
+
def dataset_class_default
|
|
135
|
+
Dataset
|
|
136
|
+
end
|
|
137
|
+
|
|
134
138
|
TINYTDS_DISCONNECT_ERRORS = /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/
|
|
139
|
+
Sequel::Deprecation.deprecate_constant(self, :TINYTDS_DISCONNECT_ERRORS)
|
|
140
|
+
|
|
135
141
|
# Return true if the :conn argument is present and not active.
|
|
136
142
|
def disconnect_error?(e, opts)
|
|
137
|
-
super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) &&
|
|
143
|
+
super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out)/.match(e.message)))
|
|
138
144
|
end
|
|
139
145
|
|
|
140
146
|
# Dispose of any possible results of execution.
|
|
@@ -180,6 +186,7 @@ module Sequel
|
|
|
180
186
|
include Sequel::MSSQL::DatasetMethods
|
|
181
187
|
|
|
182
188
|
Database::DatasetClass = self
|
|
189
|
+
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
|
183
190
|
|
|
184
191
|
# SQLite already supports named bind arguments, so use directly.
|
|
185
192
|
module ArgumentMapper
|
|
@@ -247,8 +254,8 @@ module Sequel
|
|
|
247
254
|
|
|
248
255
|
# Properly escape the given string +v+.
|
|
249
256
|
def literal_string_append(sql, v)
|
|
250
|
-
sql << (mssql_unicode_strings ?
|
|
251
|
-
sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(
|
|
257
|
+
sql << (mssql_unicode_strings ? "N'" : "'")
|
|
258
|
+
sql << db.synchronize(@opts[:server]){|c| c.escape(v)}.gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
|
|
252
259
|
end
|
|
253
260
|
|
|
254
261
|
def prepared_statement_modules
|
|
@@ -32,7 +32,7 @@ module Sequel
|
|
|
32
32
|
row_count = @opts[:offset_total_count] || ds.clone(:append_sql=>String.new, :placeholder_literal_null=>true).count
|
|
33
33
|
dsa1 = dataset_alias(1)
|
|
34
34
|
|
|
35
|
-
if o.is_a?(Symbol) && @opts[:bind_vars] && (match =
|
|
35
|
+
if o.is_a?(Symbol) && @opts[:bind_vars] && (match = /\A\$(.*)\z/.match(o.to_s))
|
|
36
36
|
# Handle use of bound variable offsets. Unfortunately, prepared statement
|
|
37
37
|
# bound variable offsets cannot be handled, since the bound variable value
|
|
38
38
|
# isn't available until later.
|
|
@@ -36,7 +36,7 @@ module Sequel
|
|
|
36
36
|
sql = @opts[:append_sql] || String.new
|
|
37
37
|
subselect_sql_append(sql, unlimited.
|
|
38
38
|
unordered.
|
|
39
|
-
select_append
|
|
39
|
+
select_append(Sequel.function(:ROW_NUMBER).over(:order=>order).as(rn)).
|
|
40
40
|
from_self(:alias=>dsa1).
|
|
41
41
|
select(*columns).
|
|
42
42
|
limit(@opts[:limit]).
|
|
@@ -13,6 +13,7 @@ module Sequel
|
|
|
13
13
|
Can't connect to local MySQL server through socket
|
|
14
14
|
MySQL server has gone away
|
|
15
15
|
Lost connection to MySQL server during query
|
|
16
|
+
MySQL client is not connected
|
|
16
17
|
This connection is still waiting for a result, try again once you have the result
|
|
17
18
|
closed MySQL connection
|
|
18
19
|
END
|