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
|
@@ -97,9 +97,12 @@ module Sequel
|
|
|
97
97
|
module Postgres
|
|
98
98
|
CONVERTED_EXCEPTIONS << PGError
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
TYPE_CONVERTOR = Class.new do
|
|
101
101
|
def bytea(s) ::Sequel::SQL::Blob.new(Adapter.unescape_bytea(s)) end
|
|
102
|
-
end.new
|
|
102
|
+
end.new
|
|
103
|
+
|
|
104
|
+
# SEQUEL5: Remove
|
|
105
|
+
PG_TYPES[17] = TYPE_CONVERTOR.method(:bytea)
|
|
103
106
|
|
|
104
107
|
if Sequel::Postgres::USES_PG
|
|
105
108
|
# Whether the given sequel_pg version integer is supported.
|
|
@@ -126,6 +129,7 @@ module Sequel
|
|
|
126
129
|
if defined?(::PG::ConnectionBad)
|
|
127
130
|
DISCONNECT_ERROR_CLASSES << ::PG::ConnectionBad
|
|
128
131
|
end
|
|
132
|
+
#DISCONNECT_ERROR_CLASSES.freeze # SEQUEL5
|
|
129
133
|
|
|
130
134
|
disconnect_errors = [
|
|
131
135
|
'could not receive data from server',
|
|
@@ -542,6 +546,7 @@ module Sequel
|
|
|
542
546
|
def adapter_initialize
|
|
543
547
|
@use_iso_date_format = typecast_value_boolean(@opts.fetch(:use_iso_date_format, Postgres.use_iso_date_format))
|
|
544
548
|
initialize_postgres_adapter
|
|
549
|
+
conversion_procs[17] = TYPE_CONVERTOR.method(:bytea)
|
|
545
550
|
conversion_procs[1082] = TYPE_TRANSLATOR.method(:date) if @use_iso_date_format
|
|
546
551
|
self.convert_infinite_timestamps = @opts[:convert_infinite_timestamps]
|
|
547
552
|
end
|
|
@@ -578,6 +583,10 @@ module Sequel
|
|
|
578
583
|
end
|
|
579
584
|
end
|
|
580
585
|
|
|
586
|
+
def dataset_class_default
|
|
587
|
+
Dataset
|
|
588
|
+
end
|
|
589
|
+
|
|
581
590
|
# Execute the prepared statement with the given name on an available
|
|
582
591
|
# connection, using the given args. If the connection has not prepared
|
|
583
592
|
# a statement with the given name yet, prepare it. If the connection
|
|
@@ -671,8 +680,11 @@ module Sequel
|
|
|
671
680
|
include Sequel::Postgres::DatasetMethods
|
|
672
681
|
|
|
673
682
|
Database::DatasetClass = self
|
|
674
|
-
|
|
683
|
+
Sequel::Deprecation.deprecate_constant(Database, :DatasetClass)
|
|
684
|
+
APOS = "'".freeze
|
|
685
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
675
686
|
DEFAULT_CURSOR_NAME = 'sequel_cursor'.freeze
|
|
687
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_CURSOR_NAME)
|
|
676
688
|
|
|
677
689
|
# Yield all rows returned by executing the given SQL and converting
|
|
678
690
|
# the types.
|
|
@@ -720,7 +732,7 @@ module Sequel
|
|
|
720
732
|
# DB[:huge_table].use_cursor(:rows_per_fetch=>1).each do |row|
|
|
721
733
|
# DB[:huge_table].where_current_of.update(:column=>ruby_method(row))
|
|
722
734
|
# end
|
|
723
|
-
def where_current_of(cursor_name=
|
|
735
|
+
def where_current_of(cursor_name='sequel_cursor')
|
|
724
736
|
clone(:where=>Sequel.lit(['CURRENT OF '], Sequel.identifier(cursor_name)))
|
|
725
737
|
end
|
|
726
738
|
|
|
@@ -787,7 +799,7 @@ module Sequel
|
|
|
787
799
|
server_opts = {:server=>@opts[:server] || :read_only}
|
|
788
800
|
cursor = @opts[:cursor]
|
|
789
801
|
hold = cursor[:hold]
|
|
790
|
-
cursor_name = quote_identifier(cursor[:cursor_name] ||
|
|
802
|
+
cursor_name = quote_identifier(cursor[:cursor_name] || 'sequel_cursor')
|
|
791
803
|
rows_per_fetch = cursor[:rows_per_fetch].to_i
|
|
792
804
|
|
|
793
805
|
db.send(*(hold ? [:synchronize, server_opts[:server]] : [:transaction, server_opts])) do
|
|
@@ -829,18 +841,18 @@ module Sequel
|
|
|
829
841
|
res.nfields.times do |fieldnum|
|
|
830
842
|
cols << [fieldnum, procs[res.ftype(fieldnum)], output_identifier(res.fname(fieldnum))]
|
|
831
843
|
end
|
|
832
|
-
self.columns = cols.map{|c| c
|
|
844
|
+
self.columns = cols.map{|c| c[2]}
|
|
833
845
|
cols
|
|
834
846
|
end
|
|
835
847
|
|
|
836
848
|
# Use the driver's escape_bytea
|
|
837
849
|
def literal_blob_append(sql, v)
|
|
838
|
-
sql <<
|
|
850
|
+
sql << "'" << db.synchronize(@opts[:server]){|c| c.escape_bytea(v)} << "'"
|
|
839
851
|
end
|
|
840
852
|
|
|
841
853
|
# Use the driver's escape_string
|
|
842
854
|
def literal_string_append(sql, v)
|
|
843
|
-
sql <<
|
|
855
|
+
sql << "'" << db.synchronize(@opts[:server]){|c| c.escape_string(v)} << "'"
|
|
844
856
|
end
|
|
845
857
|
|
|
846
858
|
# For each row in the result set, yield a hash with column name symbol
|
|
@@ -85,29 +85,49 @@ module Sequel
|
|
|
85
85
|
include EmulateOffsetWithReverseAndCount
|
|
86
86
|
include UnmodifiedIdentifiers::DatasetMethods
|
|
87
87
|
|
|
88
|
+
EXTRACT_MAP = {:year=>"'yyyy'", :month=>"'m'", :day=>"'d'", :hour=>"'h'", :minute=>"'n'", :second=>"'s'"}#.freeze # SEQUEL5
|
|
89
|
+
#EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
|
|
90
|
+
OPS = {:'%'=>' Mod '.freeze, :'||'=>' & '.freeze}#.freeze # SEQUEL5
|
|
91
|
+
CAST_TYPES = {String=>:CStr, Integer=>:CLng, Date=>:CDate, Time=>:CDate, DateTime=>:CDate, Numeric=>:CDec, BigDecimal=>:CDec, File=>:CStr, Float=>:CDbl, TrueClass=>:CBool, FalseClass=>:CBool}#.freeze # SEQUEL5
|
|
92
|
+
|
|
88
93
|
DATE_FORMAT = '#%Y-%m-%d#'.freeze
|
|
94
|
+
Sequel::Deprecation.deprecate_constant(self, :DATE_FORMAT)
|
|
89
95
|
TIMESTAMP_FORMAT = '#%Y-%m-%d %H:%M:%S#'.freeze
|
|
96
|
+
Sequel::Deprecation.deprecate_constant(self, :TIMESTAMP_FORMAT)
|
|
90
97
|
TOP = " TOP ".freeze
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
Sequel::Deprecation.deprecate_constant(self, :TOP)
|
|
99
|
+
BRACKET_CLOSE = ']'.freeze
|
|
100
|
+
Sequel::Deprecation.deprecate_constant(self, :BRACKET_CLOSE)
|
|
101
|
+
BRACKET_OPEN = '['.freeze
|
|
102
|
+
Sequel::Deprecation.deprecate_constant(self, :BRACKET_OPEN)
|
|
103
|
+
COMMA = ', '.freeze
|
|
104
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
105
|
+
PAREN_CLOSE = ')'.freeze
|
|
106
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
|
|
107
|
+
PAREN_OPEN = '('.freeze
|
|
108
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_OPEN)
|
|
109
|
+
INTO = " INTO ".freeze
|
|
110
|
+
Sequel::Deprecation.deprecate_constant(self, :INTO)
|
|
111
|
+
FROM = ' FROM '.freeze
|
|
112
|
+
Sequel::Deprecation.deprecate_constant(self, :FROM)
|
|
113
|
+
SPACE = ' '.freeze
|
|
114
|
+
Sequel::Deprecation.deprecate_constant(self, :SPACE)
|
|
98
115
|
NOT_EQUAL = ' <> '.freeze
|
|
99
|
-
|
|
116
|
+
Sequel::Deprecation.deprecate_constant(self, :NOT_EQUAL)
|
|
100
117
|
BOOL_FALSE = '0'.freeze
|
|
118
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
101
119
|
BOOL_TRUE = '-1'.freeze
|
|
120
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
102
121
|
DATE_FUNCTION = 'Date()'.freeze
|
|
122
|
+
Sequel::Deprecation.deprecate_constant(self, :DATE_FUNCTION)
|
|
103
123
|
NOW_FUNCTION = 'Now()'.freeze
|
|
124
|
+
Sequel::Deprecation.deprecate_constant(self, :NOW_FUNCTION)
|
|
104
125
|
TIME_FUNCTION = 'Time()'.freeze
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
EMULATED_FUNCTION_MAP = {:char_length=>:len}
|
|
108
|
-
EXTRACT_MAP = {:year=>"'yyyy'", :month=>"'m'", :day=>"'d'", :hour=>"'h'", :minute=>"'n'", :second=>"'s'"}
|
|
109
|
-
COMMA = Dataset::COMMA
|
|
126
|
+
Sequel::Deprecation.deprecate_constant(self, :TIME_FUNCTION)
|
|
110
127
|
DATEPART_OPEN = "datepart(".freeze
|
|
128
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART_OPEN)
|
|
129
|
+
EMULATED_FUNCTION_MAP = {:char_length=>:len}
|
|
130
|
+
Sequel::Deprecation.deprecate_constant(self, :EMULATED_FUNCTION_MAP)
|
|
111
131
|
|
|
112
132
|
# Access doesn't support CASE, but it can be emulated with nested
|
|
113
133
|
# IIF function calls.
|
|
@@ -119,9 +139,9 @@ module Sequel
|
|
|
119
139
|
# type conversion
|
|
120
140
|
def cast_sql_append(sql, expr, type)
|
|
121
141
|
sql << CAST_TYPES.fetch(type, type).to_s
|
|
122
|
-
sql <<
|
|
142
|
+
sql << '('
|
|
123
143
|
literal_append(sql, expr)
|
|
124
|
-
sql <<
|
|
144
|
+
sql << ')'
|
|
125
145
|
end
|
|
126
146
|
|
|
127
147
|
def complex_expression_sql_append(sql, op, args)
|
|
@@ -131,19 +151,19 @@ module Sequel
|
|
|
131
151
|
when :'NOT ILIKE'
|
|
132
152
|
complex_expression_sql_append(sql, :'NOT LIKE', args)
|
|
133
153
|
when :LIKE, :'NOT LIKE'
|
|
134
|
-
sql <<
|
|
135
|
-
literal_append(sql, args
|
|
136
|
-
sql <<
|
|
137
|
-
literal_append(sql, args
|
|
138
|
-
sql <<
|
|
154
|
+
sql << '('
|
|
155
|
+
literal_append(sql, args[0])
|
|
156
|
+
sql << ' ' << op.to_s << ' '
|
|
157
|
+
literal_append(sql, args[1])
|
|
158
|
+
sql << ')'
|
|
139
159
|
when :'!='
|
|
140
|
-
sql <<
|
|
141
|
-
literal_append(sql, args
|
|
142
|
-
sql <<
|
|
143
|
-
literal_append(sql, args
|
|
144
|
-
sql <<
|
|
160
|
+
sql << '('
|
|
161
|
+
literal_append(sql, args[0])
|
|
162
|
+
sql << ' <> '
|
|
163
|
+
literal_append(sql, args[1])
|
|
164
|
+
sql << ')'
|
|
145
165
|
when :'%', :'||'
|
|
146
|
-
sql <<
|
|
166
|
+
sql << '('
|
|
147
167
|
c = false
|
|
148
168
|
op_str = OPS[op]
|
|
149
169
|
args.each do |a|
|
|
@@ -151,19 +171,19 @@ module Sequel
|
|
|
151
171
|
literal_append(sql, a)
|
|
152
172
|
c ||= true
|
|
153
173
|
end
|
|
154
|
-
sql <<
|
|
174
|
+
sql << ')'
|
|
155
175
|
when :**
|
|
156
|
-
sql <<
|
|
176
|
+
sql << '('
|
|
157
177
|
literal_append(sql, args[0])
|
|
158
178
|
sql << ' ^ '
|
|
159
179
|
literal_append(sql, args[1])
|
|
160
|
-
sql <<
|
|
180
|
+
sql << ')'
|
|
161
181
|
when :extract
|
|
162
|
-
part = args
|
|
182
|
+
part = args[0]
|
|
163
183
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
|
164
|
-
sql <<
|
|
165
|
-
literal_append(sql, args
|
|
166
|
-
sql <<
|
|
184
|
+
sql << "datepart(" << format.to_s << ', '
|
|
185
|
+
literal_append(sql, args[1])
|
|
186
|
+
sql << ')'
|
|
167
187
|
else
|
|
168
188
|
super
|
|
169
189
|
end
|
|
@@ -173,11 +193,11 @@ module Sequel
|
|
|
173
193
|
def constant_sql_append(sql, constant)
|
|
174
194
|
case constant
|
|
175
195
|
when :CURRENT_DATE
|
|
176
|
-
sql <<
|
|
196
|
+
sql << 'Date()'
|
|
177
197
|
when :CURRENT_TIMESTAMP
|
|
178
|
-
sql <<
|
|
198
|
+
sql << 'Now()'
|
|
179
199
|
when :CURRENT_TIME
|
|
180
|
-
sql <<
|
|
200
|
+
sql << 'Time()'
|
|
181
201
|
else
|
|
182
202
|
super
|
|
183
203
|
end
|
|
@@ -233,31 +253,40 @@ module Sequel
|
|
|
233
253
|
|
|
234
254
|
# Access uses # to quote dates
|
|
235
255
|
def literal_date(d)
|
|
236
|
-
d.strftime(
|
|
256
|
+
d.strftime('#%Y-%m-%d#')
|
|
237
257
|
end
|
|
238
258
|
|
|
239
259
|
# Access uses # to quote datetimes
|
|
240
260
|
def literal_datetime(t)
|
|
241
|
-
t.strftime(
|
|
261
|
+
t.strftime('#%Y-%m-%d %H:%M:%S#')
|
|
242
262
|
end
|
|
243
263
|
alias literal_time literal_datetime
|
|
244
264
|
|
|
245
265
|
# Use 0 for false on MSSQL
|
|
246
266
|
def literal_false
|
|
247
|
-
|
|
267
|
+
'0'
|
|
248
268
|
end
|
|
249
269
|
|
|
250
|
-
# Use
|
|
270
|
+
# Use -1 for true on MSSQL
|
|
251
271
|
def literal_true
|
|
252
|
-
|
|
272
|
+
'-1'
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Emulate the char_length function with len
|
|
276
|
+
def native_function_name(emulated_function)
|
|
277
|
+
if emulated_function == :char_length
|
|
278
|
+
'len'
|
|
279
|
+
else
|
|
280
|
+
super
|
|
281
|
+
end
|
|
253
282
|
end
|
|
254
283
|
|
|
255
284
|
# Access requires parentheses when joining more than one table
|
|
256
285
|
def select_from_sql(sql)
|
|
257
286
|
if f = @opts[:from]
|
|
258
|
-
sql << FROM
|
|
287
|
+
sql << ' FROM '
|
|
259
288
|
if (j = @opts[:join]) && !j.empty?
|
|
260
|
-
sql << (
|
|
289
|
+
sql << ('(' * j.length)
|
|
261
290
|
end
|
|
262
291
|
source_list_append(sql, f)
|
|
263
292
|
end
|
|
@@ -265,7 +294,7 @@ module Sequel
|
|
|
265
294
|
|
|
266
295
|
def select_into_sql(sql)
|
|
267
296
|
if i = @opts[:into]
|
|
268
|
-
sql << INTO
|
|
297
|
+
sql << " INTO "
|
|
269
298
|
identifier_append(sql, i)
|
|
270
299
|
end
|
|
271
300
|
end
|
|
@@ -275,7 +304,7 @@ module Sequel
|
|
|
275
304
|
if js = @opts[:join]
|
|
276
305
|
js.each do |j|
|
|
277
306
|
literal_append(sql, j)
|
|
278
|
-
sql <<
|
|
307
|
+
sql << ')'
|
|
279
308
|
end
|
|
280
309
|
end
|
|
281
310
|
end
|
|
@@ -283,14 +312,14 @@ module Sequel
|
|
|
283
312
|
# Access uses TOP for limits
|
|
284
313
|
def select_limit_sql(sql)
|
|
285
314
|
if l = @opts[:limit]
|
|
286
|
-
sql << TOP
|
|
315
|
+
sql << " TOP "
|
|
287
316
|
literal_append(sql, l)
|
|
288
317
|
end
|
|
289
318
|
end
|
|
290
319
|
|
|
291
320
|
# Access uses [] for quoting identifiers
|
|
292
321
|
def quoted_identifier_append(sql, v)
|
|
293
|
-
sql <<
|
|
322
|
+
sql << '[' << v.to_s << ']'
|
|
294
323
|
end
|
|
295
324
|
end
|
|
296
325
|
end
|
|
@@ -13,7 +13,8 @@ module Sequel
|
|
|
13
13
|
include UnmodifiedIdentifiers::DatabaseMethods
|
|
14
14
|
|
|
15
15
|
AUTOINCREMENT = 'AUTO_INCREMENT'.freeze
|
|
16
|
-
|
|
16
|
+
Sequel::Deprecation.deprecate_constant(self, :AUTOINCREMENT)
|
|
17
|
+
COLUMN_DEFINITION_ORDER = [:auto_increment, :default, :null, :unique, :primary_key, :references]#.freeze # SEQUEL5
|
|
17
18
|
|
|
18
19
|
def database_type
|
|
19
20
|
:cubrid
|
|
@@ -115,7 +116,7 @@ module Sequel
|
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
def auto_increment_sql
|
|
118
|
-
|
|
119
|
+
'AUTO_INCREMENT'
|
|
119
120
|
end
|
|
120
121
|
|
|
121
122
|
# CUBRID requires auto increment before primary key
|
|
@@ -168,13 +169,16 @@ module Sequel
|
|
|
168
169
|
module DatasetMethods
|
|
169
170
|
include UnmodifiedIdentifiers::DatasetMethods
|
|
170
171
|
|
|
171
|
-
COMMA =
|
|
172
|
-
|
|
172
|
+
COMMA = ', '.freeze
|
|
173
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
174
|
+
LIMIT = " LIMIT ".freeze
|
|
175
|
+
Sequel::Deprecation.deprecate_constant(self, :LIMIT)
|
|
173
176
|
BOOL_FALSE = '0'.freeze
|
|
177
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
174
178
|
BOOL_TRUE = '1'.freeze
|
|
175
|
-
|
|
176
|
-
# Hope you don't have more than 2**32 + offset rows in your dataset
|
|
179
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
177
180
|
ONLY_OFFSET = ",4294967295".freeze
|
|
181
|
+
Sequel::Deprecation.deprecate_constant(self, :ONLY_OFFSET)
|
|
178
182
|
|
|
179
183
|
def supports_join_using?
|
|
180
184
|
false
|
|
@@ -198,11 +202,11 @@ module Sequel
|
|
|
198
202
|
private
|
|
199
203
|
|
|
200
204
|
def literal_false
|
|
201
|
-
|
|
205
|
+
'0'
|
|
202
206
|
end
|
|
203
207
|
|
|
204
208
|
def literal_true
|
|
205
|
-
|
|
209
|
+
'1'
|
|
206
210
|
end
|
|
207
211
|
|
|
208
212
|
# CUBRID supports multiple rows in INSERT.
|
|
@@ -217,14 +221,15 @@ module Sequel
|
|
|
217
221
|
l = @opts[:limit]
|
|
218
222
|
o = @opts[:offset]
|
|
219
223
|
if l || o
|
|
220
|
-
sql << LIMIT
|
|
224
|
+
sql << " LIMIT "
|
|
221
225
|
if o
|
|
222
226
|
literal_append(sql, o)
|
|
223
227
|
if l
|
|
224
|
-
sql <<
|
|
228
|
+
sql << ', '
|
|
225
229
|
literal_append(sql, l)
|
|
226
230
|
else
|
|
227
|
-
|
|
231
|
+
# Hope you don't have more than 2**32 + offset rows in your dataset
|
|
232
|
+
sql << ",4294967295"
|
|
228
233
|
end
|
|
229
234
|
else
|
|
230
235
|
literal_append(sql, l)
|
|
@@ -15,8 +15,11 @@ module Sequel
|
|
|
15
15
|
|
|
16
16
|
module DatabaseMethods
|
|
17
17
|
AUTOINCREMENT = 'GENERATED ALWAYS AS IDENTITY'.freeze
|
|
18
|
+
Sequel::Deprecation.deprecate_constant(self, :AUTOINCREMENT)
|
|
18
19
|
NOT_NULL = ' NOT NULL'.freeze
|
|
20
|
+
Sequel::Deprecation.deprecate_constant(self, :NOT_NULL)
|
|
19
21
|
NULL = ''.freeze
|
|
22
|
+
Sequel::Deprecation.deprecate_constant(self, :NULL)
|
|
20
23
|
|
|
21
24
|
# DB2 always uses :db2 as it's database type
|
|
22
25
|
def database_type
|
|
@@ -134,7 +137,7 @@ module Sequel
|
|
|
134
137
|
[
|
|
135
138
|
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op.merge(:auto_increment=>false, :primary_key=>false, :default=>0, :null=>false))}",
|
|
136
139
|
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} DROP DEFAULT",
|
|
137
|
-
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} SET #{
|
|
140
|
+
"ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{literal(op[:name])} SET #{auto_increment_sql}"
|
|
138
141
|
]
|
|
139
142
|
else
|
|
140
143
|
"ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
|
|
@@ -172,7 +175,7 @@ module Sequel
|
|
|
172
175
|
|
|
173
176
|
# DB2 uses an identity column for autoincrement.
|
|
174
177
|
def auto_increment_sql
|
|
175
|
-
|
|
178
|
+
'GENERATED ALWAYS AS IDENTITY'
|
|
176
179
|
end
|
|
177
180
|
|
|
178
181
|
# DB2 does not allow adding primary key constraints to NULLable columns.
|
|
@@ -283,28 +286,43 @@ module Sequel
|
|
|
283
286
|
module DatasetMethods
|
|
284
287
|
include EmulateOffsetWithRowNumber
|
|
285
288
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR, :'B~'=>:BITNOT}#.freeze # SEQUEL5
|
|
290
|
+
|
|
291
|
+
PAREN_CLOSE = ')'.freeze
|
|
292
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
|
|
293
|
+
PAREN_OPEN = '('.freeze
|
|
294
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_OPEN)
|
|
290
295
|
BOOL_TRUE = '1'.freeze
|
|
296
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
291
297
|
BOOL_FALSE = '0'.freeze
|
|
298
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
292
299
|
CAST_STRING_OPEN = "RTRIM(CHAR(".freeze
|
|
300
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST_STRING_OPEN)
|
|
293
301
|
CAST_STRING_CLOSE = "))".freeze
|
|
302
|
+
Sequel::Deprecation.deprecate_constant(self, :CAST_STRING_CLOSE)
|
|
294
303
|
FETCH_FIRST_ROW_ONLY = " FETCH FIRST ROW ONLY".freeze
|
|
304
|
+
Sequel::Deprecation.deprecate_constant(self, :FETCH_FIRST_ROW_ONLY)
|
|
295
305
|
FETCH_FIRST = " FETCH FIRST ".freeze
|
|
306
|
+
Sequel::Deprecation.deprecate_constant(self, :FETCH_FIRST)
|
|
296
307
|
ROWS_ONLY = " ROWS ONLY".freeze
|
|
308
|
+
Sequel::Deprecation.deprecate_constant(self, :ROWS_ONLY)
|
|
297
309
|
EMPTY_FROM_TABLE = ' FROM "SYSIBM"."SYSDUMMY1"'.freeze
|
|
310
|
+
Sequel::Deprecation.deprecate_constant(self, :EMPTY_FROM_TABLE)
|
|
298
311
|
HSTAR = "H*".freeze
|
|
312
|
+
Sequel::Deprecation.deprecate_constant(self, :HSTAR)
|
|
299
313
|
BLOB_OPEN = "BLOB(X'".freeze
|
|
314
|
+
Sequel::Deprecation.deprecate_constant(self, :BLOB_OPEN)
|
|
300
315
|
BLOB_CLOSE = "')".freeze
|
|
316
|
+
Sequel::Deprecation.deprecate_constant(self, :BLOB_CLOSE)
|
|
317
|
+
EMULATED_FUNCTION_MAP = {:char_length=>'length'.freeze}
|
|
318
|
+
Sequel::Deprecation.deprecate_constant(self, :EMULATED_FUNCTION_MAP)
|
|
301
319
|
|
|
302
320
|
# DB2 casts strings using RTRIM and CHAR instead of VARCHAR.
|
|
303
321
|
def cast_sql_append(sql, expr, type)
|
|
304
322
|
if(type == String)
|
|
305
|
-
sql <<
|
|
323
|
+
sql << "RTRIM(CHAR("
|
|
306
324
|
literal_append(sql, expr)
|
|
307
|
-
sql <<
|
|
325
|
+
sql << "))"
|
|
308
326
|
else
|
|
309
327
|
super
|
|
310
328
|
end
|
|
@@ -317,10 +335,10 @@ module Sequel
|
|
|
317
335
|
when :'B~'
|
|
318
336
|
literal_append(sql, SQL::Function.new(:BITNOT, *args))
|
|
319
337
|
when :extract
|
|
320
|
-
sql << args
|
|
321
|
-
sql <<
|
|
322
|
-
literal_append(sql, args
|
|
323
|
-
sql <<
|
|
338
|
+
sql << args[0].to_s
|
|
339
|
+
sql << '('
|
|
340
|
+
literal_append(sql, args[1])
|
|
341
|
+
sql << ')'
|
|
324
342
|
else
|
|
325
343
|
super
|
|
326
344
|
end
|
|
@@ -387,7 +405,7 @@ module Sequel
|
|
|
387
405
|
private
|
|
388
406
|
|
|
389
407
|
def empty_from_sql
|
|
390
|
-
|
|
408
|
+
' FROM "SYSIBM"."SYSDUMMY1"'
|
|
391
409
|
end
|
|
392
410
|
|
|
393
411
|
# Emulate offset with row number by default, and also when the limit_offset
|
|
@@ -405,12 +423,12 @@ module Sequel
|
|
|
405
423
|
|
|
406
424
|
# Use 0 for false on DB2
|
|
407
425
|
def literal_false
|
|
408
|
-
|
|
426
|
+
'0'
|
|
409
427
|
end
|
|
410
428
|
|
|
411
429
|
# Use 1 for true on DB2
|
|
412
430
|
def literal_true
|
|
413
|
-
|
|
431
|
+
'1'
|
|
414
432
|
end
|
|
415
433
|
|
|
416
434
|
# DB2 uses a literal hexidecimal number for blob strings
|
|
@@ -418,7 +436,7 @@ module Sequel
|
|
|
418
436
|
if ::Sequel::DB2.use_clob_as_blob
|
|
419
437
|
super
|
|
420
438
|
else
|
|
421
|
-
sql <<
|
|
439
|
+
sql << "BLOB(X'" << v.unpack("H*").first << "')"
|
|
422
440
|
end
|
|
423
441
|
end
|
|
424
442
|
|
|
@@ -427,6 +445,15 @@ module Sequel
|
|
|
427
445
|
:union
|
|
428
446
|
end
|
|
429
447
|
|
|
448
|
+
# Emulate the char_length function with length
|
|
449
|
+
def native_function_name(emulated_function)
|
|
450
|
+
if emulated_function == :char_length
|
|
451
|
+
'length'
|
|
452
|
+
else
|
|
453
|
+
super
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
430
457
|
# DB2 does not require that ROW_NUMBER be ordered.
|
|
431
458
|
def require_offset_order?
|
|
432
459
|
false
|
|
@@ -447,11 +474,11 @@ module Sequel
|
|
|
447
474
|
|
|
448
475
|
if l = @opts[:limit]
|
|
449
476
|
if l == 1
|
|
450
|
-
sql <<
|
|
477
|
+
sql << " FETCH FIRST ROW ONLY"
|
|
451
478
|
else
|
|
452
|
-
sql <<
|
|
479
|
+
sql << " FETCH FIRST "
|
|
453
480
|
literal_append(sql, l)
|
|
454
|
-
sql <<
|
|
481
|
+
sql << " ROWS ONLY"
|
|
455
482
|
end
|
|
456
483
|
end
|
|
457
484
|
end
|