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
@@ -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
|