sequel 4.45.0 → 4.46.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|