sequel 3.21.0 → 3.29.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.
- data/CHANGELOG +413 -3
- data/README.rdoc +20 -6
- data/Rakefile +23 -16
- data/bin/sequel +1 -5
- data/doc/association_basics.rdoc +210 -43
- data/doc/dataset_basics.rdoc +4 -4
- data/doc/mass_assignment.rdoc +54 -0
- data/doc/migration.rdoc +15 -538
- data/doc/model_hooks.rdoc +72 -27
- data/doc/opening_databases.rdoc +86 -50
- data/doc/prepared_statements.rdoc +40 -13
- data/doc/reflection.rdoc +8 -2
- data/doc/release_notes/3.22.0.txt +39 -0
- data/doc/release_notes/3.23.0.txt +172 -0
- data/doc/release_notes/3.24.0.txt +420 -0
- data/doc/release_notes/3.25.0.txt +88 -0
- data/doc/release_notes/3.26.0.txt +88 -0
- data/doc/release_notes/3.27.0.txt +82 -0
- data/doc/release_notes/3.28.0.txt +304 -0
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/schema_modification.rdoc +547 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +115 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +15 -7
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/do.rb +17 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +448 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +5 -31
- data/lib/sequel/adapters/jdbc/db2.rb +44 -0
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +29 -0
- data/lib/sequel/adapters/jdbc/h2.rb +26 -17
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +26 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
- data/lib/sequel/adapters/jdbc/mysql.rb +9 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +67 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +6 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +41 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +107 -38
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +78 -182
- data/lib/sequel/adapters/mysql2.rb +24 -23
- data/lib/sequel/adapters/odbc/db2.rb +17 -0
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +349 -51
- data/lib/sequel/adapters/postgres.rb +169 -21
- data/lib/sequel/adapters/shared/access.rb +21 -6
- data/lib/sequel/adapters/shared/db2.rb +288 -0
- data/lib/sequel/adapters/shared/firebird.rb +214 -0
- data/lib/sequel/adapters/shared/informix.rb +45 -0
- data/lib/sequel/adapters/shared/mssql.rb +108 -65
- data/lib/sequel/adapters/shared/mysql.rb +56 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +149 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -34
- data/lib/sequel/adapters/shared/postgres.rb +107 -58
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +168 -41
- data/lib/sequel/adapters/sqlite.rb +27 -18
- data/lib/sequel/adapters/swift/mysql.rb +9 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/tinytds.rb +152 -17
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +63 -0
- data/lib/sequel/ast_transformer.rb +190 -0
- data/lib/sequel/connection_pool/threaded.rb +3 -2
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +46 -5
- data/lib/sequel/database/connecting.rb +5 -6
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +59 -1
- data/lib/sequel/database/logging.rb +1 -1
- data/lib/sequel/database/misc.rb +100 -19
- data/lib/sequel/database/query.rb +153 -58
- data/lib/sequel/database/schema_generator.rb +8 -5
- data/lib/sequel/database/schema_methods.rb +59 -29
- data/lib/sequel/dataset/actions.rb +194 -57
- data/lib/sequel/dataset/features.rb +81 -8
- data/lib/sequel/dataset/graph.rb +8 -7
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +5 -6
- data/lib/sequel/dataset/prepared_statements.rb +32 -15
- data/lib/sequel/dataset/query.rb +223 -42
- data/lib/sequel/dataset/sql.rb +58 -61
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/extensions/migration.rb +6 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/extensions/to_dot.rb +95 -83
- data/lib/sequel/model/associations.rb +997 -331
- data/lib/sequel/model/base.rb +386 -129
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model.rb +15 -8
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +114 -7
- data/lib/sequel/plugins/many_through_many.rb +65 -7
- data/lib/sequel/plugins/prepared_statements.rb +151 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
- data/lib/sequel/plugins/prepared_statements_safe.rb +82 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/serialization_modification_detection.rb +51 -0
- data/lib/sequel/plugins/sharding.rb +12 -25
- data/lib/sequel/plugins/single_table_inheritance.rb +3 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +2 -2
- data/lib/sequel/plugins/xml_serializer.rb +3 -3
- data/lib/sequel/sql.rb +107 -51
- data/lib/sequel/timezones.rb +44 -35
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/mssql_spec.rb +65 -29
- data/spec/adapters/mysql_spec.rb +122 -123
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +213 -61
- data/spec/adapters/spec_helper.rb +6 -5
- data/spec/adapters/sqlite_spec.rb +35 -21
- data/spec/core/connection_pool_spec.rb +71 -92
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +729 -508
- data/spec/core/dataset_spec.rb +980 -1044
- data/spec/core/expression_filters_spec.rb +159 -42
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +298 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/association_pks_spec.rb +38 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/identity_map_spec.rb +162 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/many_through_many_spec.rb +195 -20
- data/spec/extensions/migration_spec.rb +17 -17
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +4 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +79 -0
- data/spec/extensions/prepared_statements_spec.rb +72 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +13 -21
- data/spec/extensions/serialization_modification_detection_spec.rb +37 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/single_table_inheritance_spec.rb +11 -0
- data/spec/extensions/spec_helper.rb +7 -1
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/to_dot_spec.rb +3 -5
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/extensions/xml_serializer_spec.rb +16 -4
- data/spec/integration/associations_test.rb +522 -21
- data/spec/integration/database_test.rb +4 -2
- data/spec/integration/dataset_test.rb +375 -62
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +304 -116
- data/spec/integration/prepared_statement_test.rb +200 -120
- data/spec/integration/schema_test.rb +161 -30
- data/spec/integration/spec_helper.rb +39 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +172 -5
- data/spec/integration/type_test.rb +17 -3
- data/spec/model/association_reflection_spec.rb +174 -7
- data/spec/model/associations_spec.rb +849 -661
- data/spec/model/base_spec.rb +255 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +640 -676
- data/spec/model/hooks_spec.rb +309 -67
- data/spec/model/model_spec.rb +207 -167
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +321 -218
- data/spec/model/spec_helper.rb +13 -71
- data/spec/model/validations_spec.rb +11 -0
- metadata +95 -38
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that execute queries and/or return results
|
|
4
|
+
# :section: 1 - Methods that execute queries and/or return results
|
|
5
5
|
# This methods generally execute SQL code on the database server.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -37,9 +37,12 @@ module Sequel
|
|
|
37
37
|
attr_accessor :transaction_isolation_level
|
|
38
38
|
|
|
39
39
|
# Runs the supplied SQL statement string on the database server.
|
|
40
|
-
#
|
|
40
|
+
# Returns self so it can be safely chained:
|
|
41
|
+
#
|
|
42
|
+
# DB << "UPADTE albums SET artist_id = NULL" << "DROP TABLE artists"
|
|
41
43
|
def <<(sql)
|
|
42
44
|
run(sql)
|
|
45
|
+
self
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
# Call the prepared statement with the given name with the given hash
|
|
@@ -82,12 +85,12 @@ module Sequel
|
|
|
82
85
|
#
|
|
83
86
|
# DB.get(1) # SELECT 1
|
|
84
87
|
# # => 1
|
|
85
|
-
# DB.get{
|
|
88
|
+
# DB.get{server_version{}} # SELECT server_version()
|
|
86
89
|
def get(*args, &block)
|
|
87
90
|
dataset.get(*args, &block)
|
|
88
91
|
end
|
|
89
92
|
|
|
90
|
-
# Return a hash containing index information. Hash keys are index name symbols.
|
|
93
|
+
# Return a hash containing index information for the table. Hash keys are index name symbols.
|
|
91
94
|
# Values are subhashes with two keys, :columns and :unique. The value of :columns
|
|
92
95
|
# is an array of symbols of column names. The value of :unique is true or false
|
|
93
96
|
# depending on if the index is unique.
|
|
@@ -110,17 +113,17 @@ module Sequel
|
|
|
110
113
|
nil
|
|
111
114
|
end
|
|
112
115
|
|
|
113
|
-
# Parse the schema from the database.
|
|
114
116
|
# Returns the schema for the given table as an array with all members being arrays of length 2,
|
|
115
117
|
# the first member being the column name, and the second member being a hash of column information.
|
|
118
|
+
# The table argument can also be a dataset, as long as it only has one table.
|
|
116
119
|
# Available options are:
|
|
117
120
|
#
|
|
118
121
|
# :reload :: Ignore any cached results, and get fresh information from the database.
|
|
119
122
|
# :schema :: An explicit schema to use. It may also be implicitly provided
|
|
120
123
|
# via the table name.
|
|
121
124
|
#
|
|
122
|
-
# If schema parsing is supported by the database, the column information should at least contain the
|
|
123
|
-
# following
|
|
125
|
+
# If schema parsing is supported by the database, the column information should hash at least contain the
|
|
126
|
+
# following entries:
|
|
124
127
|
#
|
|
125
128
|
# :allow_null :: Whether NULL is an allowed value for the column.
|
|
126
129
|
# :db_type :: The database type for the column, as a database specific string.
|
|
@@ -129,7 +132,8 @@ module Sequel
|
|
|
129
132
|
# it means that primary key information is unavailable, not that the column
|
|
130
133
|
# is not a primary key.
|
|
131
134
|
# :ruby_default :: The database default for the column, as a ruby object. In many cases, complex
|
|
132
|
-
# database defaults cannot be parsed into ruby objects
|
|
135
|
+
# database defaults cannot be parsed into ruby objects, in which case nil will be
|
|
136
|
+
# used as the value.
|
|
133
137
|
# :type :: A symbol specifying the type, such as :integer or :string.
|
|
134
138
|
#
|
|
135
139
|
# Example:
|
|
@@ -152,9 +156,20 @@ module Sequel
|
|
|
152
156
|
def schema(table, opts={})
|
|
153
157
|
raise(Error, 'schema parsing is not implemented on this database') unless respond_to?(:schema_parse_table, true)
|
|
154
158
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
opts = opts.dup
|
|
160
|
+
if table.is_a?(Dataset)
|
|
161
|
+
o = table.opts
|
|
162
|
+
from = o[:from]
|
|
163
|
+
raise(Error, "can only parse the schema for a dataset with a single from table") unless from && from.length == 1 && !o.include?(:join) && !o.include?(:sql)
|
|
164
|
+
tab = table.first_source_table
|
|
165
|
+
sch, table_name = schema_and_table(tab)
|
|
166
|
+
quoted_name = table.literal(tab)
|
|
167
|
+
opts[:dataset] = table
|
|
168
|
+
else
|
|
169
|
+
sch, table_name = schema_and_table(table)
|
|
170
|
+
quoted_name = quote_schema_table(table)
|
|
171
|
+
end
|
|
172
|
+
opts[:schema] = sch if sch && !opts.include?(:schema)
|
|
158
173
|
|
|
159
174
|
@schemas.delete(quoted_name) if opts[:reload]
|
|
160
175
|
return @schemas[quoted_name] if @schemas[quoted_name]
|
|
@@ -169,13 +184,14 @@ module Sequel
|
|
|
169
184
|
# to the database.
|
|
170
185
|
#
|
|
171
186
|
# DB.table_exists?(:foo) # => false
|
|
187
|
+
# # SELECT * FROM foo LIMIT 1
|
|
172
188
|
def table_exists?(name)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
189
|
+
sch, table_name = schema_and_table(name)
|
|
190
|
+
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
|
|
191
|
+
from(name).first
|
|
192
|
+
true
|
|
193
|
+
rescue
|
|
194
|
+
false
|
|
179
195
|
end
|
|
180
196
|
|
|
181
197
|
# Return all tables in the database as an array of symbols.
|
|
@@ -198,6 +214,9 @@ module Sequel
|
|
|
198
214
|
# :prepare :: A string to use as the transaction identifier for a
|
|
199
215
|
# prepared transaction (two-phase commit), if the database/adapter
|
|
200
216
|
# supports prepared transactions.
|
|
217
|
+
# :rollback :: Can the set to :reraise to reraise any Sequel::Rollback exceptions
|
|
218
|
+
# raised, or :always to always rollback even if no exceptions occur
|
|
219
|
+
# (useful for testing).
|
|
201
220
|
# :server :: The server to use for the transaction.
|
|
202
221
|
# :savepoint :: Whether to create a new savepoint for this transaction,
|
|
203
222
|
# only respected if the database/adapter supports savepoints. By
|
|
@@ -210,6 +229,13 @@ module Sequel
|
|
|
210
229
|
end
|
|
211
230
|
end
|
|
212
231
|
|
|
232
|
+
# Return all views in the database as an array of symbols.
|
|
233
|
+
#
|
|
234
|
+
# DB.views # => [:gold_albums, :artists_with_many_albums]
|
|
235
|
+
def views(opts={})
|
|
236
|
+
raise NotImplemented, "#views should be overridden by adapters"
|
|
237
|
+
end
|
|
238
|
+
|
|
213
239
|
private
|
|
214
240
|
|
|
215
241
|
# Internal generic transaction method. Any exception raised by the given
|
|
@@ -217,40 +243,65 @@ module Sequel
|
|
|
217
243
|
# not a Sequel::Rollback, the error will be reraised. If no exception occurs
|
|
218
244
|
# inside the block, the transaction is commited.
|
|
219
245
|
def _transaction(conn, opts={})
|
|
246
|
+
rollback = opts[:rollback]
|
|
220
247
|
begin
|
|
221
|
-
add_transaction
|
|
222
|
-
|
|
223
|
-
|
|
248
|
+
add_transaction(conn, opts)
|
|
249
|
+
begin_transaction(conn, opts)
|
|
250
|
+
if rollback == :always
|
|
251
|
+
begin
|
|
252
|
+
yield(conn)
|
|
253
|
+
rescue Exception => e1
|
|
254
|
+
raise e1
|
|
255
|
+
ensure
|
|
256
|
+
raise ::Sequel::Rollback unless e1
|
|
257
|
+
end
|
|
258
|
+
else
|
|
259
|
+
yield(conn)
|
|
260
|
+
end
|
|
224
261
|
rescue Exception => e
|
|
225
|
-
rollback_transaction(
|
|
226
|
-
transaction_error(e)
|
|
262
|
+
rollback_transaction(conn, opts)
|
|
263
|
+
transaction_error(e, :conn=>conn, :rollback=>rollback)
|
|
227
264
|
ensure
|
|
228
265
|
begin
|
|
229
|
-
|
|
230
|
-
rescue Exception =>
|
|
231
|
-
raise_error(
|
|
266
|
+
committed = commit_or_rollback_transaction(e, conn, opts)
|
|
267
|
+
rescue Exception => e2
|
|
268
|
+
raise_error(e2, :classes=>database_error_classes, :conn=>conn)
|
|
232
269
|
ensure
|
|
233
|
-
remove_transaction(
|
|
270
|
+
remove_transaction(conn, committed)
|
|
234
271
|
end
|
|
235
272
|
end
|
|
236
273
|
end
|
|
237
|
-
|
|
274
|
+
|
|
238
275
|
# Add the current thread to the list of active transactions
|
|
239
|
-
def add_transaction
|
|
240
|
-
th = Thread.current
|
|
276
|
+
def add_transaction(conn, opts)
|
|
241
277
|
if supports_savepoints?
|
|
242
|
-
unless @transactions
|
|
243
|
-
|
|
244
|
-
@transactions
|
|
278
|
+
unless @transactions[conn]
|
|
279
|
+
@transactions[conn] = {:savepoint_level=>0}
|
|
280
|
+
@transactions[conn][:prepare] = opts[:prepare] if supports_prepared_transactions?
|
|
245
281
|
end
|
|
246
282
|
else
|
|
247
|
-
@transactions
|
|
283
|
+
@transactions[conn] = {}
|
|
284
|
+
@transactions[conn][:prepare] = opts[:prepare] if supports_prepared_transactions?
|
|
248
285
|
end
|
|
249
286
|
end
|
|
250
287
|
|
|
288
|
+
# Call all stored after_commit blocks for the given transaction
|
|
289
|
+
def after_transaction_commit(conn)
|
|
290
|
+
if ary = @transactions[conn][:after_commit]
|
|
291
|
+
ary.each{|b| b.call}
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Call all stored after_rollback blocks for the given transaction
|
|
296
|
+
def after_transaction_rollback(conn)
|
|
297
|
+
if ary = @transactions[conn][:after_rollback]
|
|
298
|
+
ary.each{|b| b.call}
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
251
302
|
# Whether the current thread/connection is already inside a transaction
|
|
252
303
|
def already_in_transaction?(conn, opts)
|
|
253
|
-
@transactions.
|
|
304
|
+
@transactions.has_key?(conn) && (!supports_savepoints? || !opts[:savepoint])
|
|
254
305
|
end
|
|
255
306
|
|
|
256
307
|
# SQL to start a new savepoint
|
|
@@ -267,17 +318,16 @@ module Sequel
|
|
|
267
318
|
# Start a new database transaction or a new savepoint on the given connection.
|
|
268
319
|
def begin_transaction(conn, opts={})
|
|
269
320
|
if supports_savepoints?
|
|
270
|
-
th =
|
|
271
|
-
if (depth = th[:
|
|
321
|
+
th = @transactions[conn]
|
|
322
|
+
if (depth = th[:savepoint_level]) > 0
|
|
272
323
|
log_connection_execute(conn, begin_savepoint_sql(depth))
|
|
273
324
|
else
|
|
274
325
|
begin_new_transaction(conn, opts)
|
|
275
326
|
end
|
|
276
|
-
th[:
|
|
327
|
+
th[:savepoint_level] += 1
|
|
277
328
|
else
|
|
278
329
|
begin_new_transaction(conn, opts)
|
|
279
330
|
end
|
|
280
|
-
conn
|
|
281
331
|
end
|
|
282
332
|
|
|
283
333
|
# SQL to BEGIN a transaction.
|
|
@@ -335,6 +385,38 @@ module Sequel
|
|
|
335
385
|
end
|
|
336
386
|
end
|
|
337
387
|
|
|
388
|
+
if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or RUBY_ENGINE == 'rbx') and RUBY_VERSION < '1.9'
|
|
389
|
+
# Whether to commit the current transaction. On ruby 1.8 and rubinius,
|
|
390
|
+
# Thread.current.status is checked because Thread#kill skips rescue
|
|
391
|
+
# blocks (so exception would be nil), but the transaction should
|
|
392
|
+
# still be rolled back.
|
|
393
|
+
def commit_or_rollback_transaction(exception, conn, opts)
|
|
394
|
+
if exception
|
|
395
|
+
false
|
|
396
|
+
else
|
|
397
|
+
if Thread.current.status == 'aborting'
|
|
398
|
+
rollback_transaction(conn, opts)
|
|
399
|
+
false
|
|
400
|
+
else
|
|
401
|
+
commit_transaction(conn, opts)
|
|
402
|
+
true
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
else
|
|
407
|
+
# Whether to commit the current transaction. On ruby 1.9 and JRuby,
|
|
408
|
+
# transactions will be committed if Thread#kill is used on an thread
|
|
409
|
+
# that has a transaction open, and there isn't a work around.
|
|
410
|
+
def commit_or_rollback_transaction(exception, conn, opts)
|
|
411
|
+
if exception
|
|
412
|
+
false
|
|
413
|
+
else
|
|
414
|
+
commit_transaction(conn, opts)
|
|
415
|
+
true
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
338
420
|
# SQL to commit a savepoint
|
|
339
421
|
def commit_savepoint_sql(depth)
|
|
340
422
|
SQL_RELEASE_SAVEPOINT % depth
|
|
@@ -343,7 +425,7 @@ module Sequel
|
|
|
343
425
|
# Commit the active transaction on the connection
|
|
344
426
|
def commit_transaction(conn, opts={})
|
|
345
427
|
if supports_savepoints?
|
|
346
|
-
depth =
|
|
428
|
+
depth = @transactions[conn][:savepoint_level]
|
|
347
429
|
log_connection_execute(conn, depth > 1 ? commit_savepoint_sql(depth-1) : commit_transaction_sql)
|
|
348
430
|
else
|
|
349
431
|
log_connection_execute(conn, commit_transaction_sql)
|
|
@@ -364,8 +446,8 @@ module Sequel
|
|
|
364
446
|
# Return a Method object for the dataset's output_identifier_method.
|
|
365
447
|
# Used in metadata parsing to make sure the returned information is in the
|
|
366
448
|
# correct format.
|
|
367
|
-
def input_identifier_meth
|
|
368
|
-
dataset.method(:input_identifier)
|
|
449
|
+
def input_identifier_meth(ds=nil)
|
|
450
|
+
(ds || dataset).method(:input_identifier)
|
|
369
451
|
end
|
|
370
452
|
|
|
371
453
|
# Return a dataset that uses the default identifier input and output methods
|
|
@@ -382,24 +464,28 @@ module Sequel
|
|
|
382
464
|
# Return a Method object for the dataset's output_identifier_method.
|
|
383
465
|
# Used in metadata parsing to make sure the returned information is in the
|
|
384
466
|
# correct format.
|
|
385
|
-
def output_identifier_meth
|
|
386
|
-
dataset.method(:output_identifier)
|
|
467
|
+
def output_identifier_meth(ds=nil)
|
|
468
|
+
(ds || dataset).method(:output_identifier)
|
|
387
469
|
end
|
|
388
470
|
|
|
389
|
-
# SQL to ROLLBACK a transaction.
|
|
390
|
-
def rollback_transaction_sql
|
|
391
|
-
SQL_ROLLBACK
|
|
392
|
-
end
|
|
393
|
-
|
|
394
471
|
# Remove the cached schema for the given schema name
|
|
395
472
|
def remove_cached_schema(table)
|
|
396
473
|
@schemas.delete(quote_schema_table(table)) if @schemas
|
|
397
474
|
end
|
|
398
475
|
|
|
399
476
|
# Remove the current thread from the list of active transactions
|
|
400
|
-
def remove_transaction(conn)
|
|
401
|
-
|
|
402
|
-
|
|
477
|
+
def remove_transaction(conn, committed)
|
|
478
|
+
if !supports_savepoints? || ((@transactions[conn][:savepoint_level] -= 1) <= 0)
|
|
479
|
+
begin
|
|
480
|
+
if committed
|
|
481
|
+
after_transaction_commit(conn)
|
|
482
|
+
else
|
|
483
|
+
after_transaction_rollback(conn)
|
|
484
|
+
end
|
|
485
|
+
ensure
|
|
486
|
+
@transactions.delete(conn)
|
|
487
|
+
end
|
|
488
|
+
end
|
|
403
489
|
end
|
|
404
490
|
|
|
405
491
|
# SQL to rollback to a savepoint
|
|
@@ -410,13 +496,18 @@ module Sequel
|
|
|
410
496
|
# Rollback the active transaction on the connection
|
|
411
497
|
def rollback_transaction(conn, opts={})
|
|
412
498
|
if supports_savepoints?
|
|
413
|
-
depth =
|
|
499
|
+
depth = @transactions[conn][:savepoint_level]
|
|
414
500
|
log_connection_execute(conn, depth > 1 ? rollback_savepoint_sql(depth-1) : rollback_transaction_sql)
|
|
415
501
|
else
|
|
416
502
|
log_connection_execute(conn, rollback_transaction_sql)
|
|
417
503
|
end
|
|
418
504
|
end
|
|
419
505
|
|
|
506
|
+
# SQL to ROLLBACK a transaction.
|
|
507
|
+
def rollback_transaction_sql
|
|
508
|
+
SQL_ROLLBACK
|
|
509
|
+
end
|
|
510
|
+
|
|
420
511
|
# Match the database's column type to a ruby type via a
|
|
421
512
|
# regular expression, and return the ruby type as a symbol
|
|
422
513
|
# such as :integer or :string.
|
|
@@ -434,13 +525,13 @@ module Sequel
|
|
|
434
525
|
:datetime
|
|
435
526
|
when /\Atime( with(out)? time zone)?\z/io
|
|
436
527
|
:time
|
|
437
|
-
when /\A(
|
|
528
|
+
when /\A(bool(ean)?)\z/io
|
|
438
529
|
:boolean
|
|
439
530
|
when /\A(real|float|double( precision)?)\z/io
|
|
440
531
|
:float
|
|
441
|
-
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(\d
|
|
442
|
-
$1 &&
|
|
443
|
-
when /bytea|
|
|
532
|
+
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(\d+|false|true)\))?)|(?:small)?money)\z/io
|
|
533
|
+
$1 && ['0', 'false'].include?($1) ? :integer : :decimal
|
|
534
|
+
when /bytea|[bc]lob|image|(var)?binary/io
|
|
444
535
|
:blob
|
|
445
536
|
when /\Aenum/io
|
|
446
537
|
:enum
|
|
@@ -460,8 +551,12 @@ module Sequel
|
|
|
460
551
|
end
|
|
461
552
|
|
|
462
553
|
# Raise a database error unless the exception is an Rollback.
|
|
463
|
-
def transaction_error(e)
|
|
464
|
-
|
|
554
|
+
def transaction_error(e, opts={})
|
|
555
|
+
if e.is_a?(Rollback)
|
|
556
|
+
raise e if opts[:rollback] == :reraise
|
|
557
|
+
else
|
|
558
|
+
raise_error(e, opts.merge(:classes=>database_error_classes))
|
|
559
|
+
end
|
|
465
560
|
end
|
|
466
561
|
end
|
|
467
562
|
end
|
|
@@ -86,7 +86,8 @@ module Sequel
|
|
|
86
86
|
# :index :: Create an index on this column.
|
|
87
87
|
# :key :: For foreign key columns, the column in the associated table
|
|
88
88
|
# that this column references. Unnecessary if this column
|
|
89
|
-
# references the primary key of the associated table
|
|
89
|
+
# references the primary key of the associated table, except if you are
|
|
90
|
+
# using MySQL.
|
|
90
91
|
# :null :: Mark the column as allowing NULL values (if true),
|
|
91
92
|
# or not allowing NULL values (if false). If unspecified, will default
|
|
92
93
|
# to whatever the database default is.
|
|
@@ -329,15 +330,17 @@ module Sequel
|
|
|
329
330
|
# Remove a column from the DDL for the table.
|
|
330
331
|
#
|
|
331
332
|
# drop_column(:artist_id) # DROP COLUMN artist_id
|
|
332
|
-
|
|
333
|
-
|
|
333
|
+
# drop_column(:artist_id, :cascade=>true) # DROP COLUMN artist_id CASCADE
|
|
334
|
+
def drop_column(name, opts={})
|
|
335
|
+
@operations << {:op => :drop_column, :name => name}.merge(opts)
|
|
334
336
|
end
|
|
335
337
|
|
|
336
338
|
# Remove a constraint from the DDL for the table.
|
|
337
339
|
#
|
|
338
340
|
# drop_constraint(:unique_name) # DROP CONSTRAINT unique_name
|
|
339
|
-
|
|
340
|
-
|
|
341
|
+
# drop_constraint(:unique_name, :cascade=>true) # DROP CONSTRAINT unique_name CASCADE
|
|
342
|
+
def drop_constraint(name, opts={})
|
|
343
|
+
@operations << {:op => :drop_constraint, :name => name}.merge(opts)
|
|
341
344
|
end
|
|
342
345
|
|
|
343
346
|
# Remove an index from the DDL for the table.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sequel
|
|
2
2
|
class Database
|
|
3
3
|
# ---------------------
|
|
4
|
-
# :section: Methods that modify the database schema
|
|
4
|
+
# :section: 2 - Methods that modify the database schema
|
|
5
5
|
# These methods execute code on the database that modifies the database's schema.
|
|
6
6
|
# ---------------------
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ module Sequel
|
|
|
21
21
|
UNSIGNED = ' UNSIGNED'.freeze
|
|
22
22
|
|
|
23
23
|
# The order of column modifiers to use when defining a column.
|
|
24
|
-
COLUMN_DEFINITION_ORDER = [:default, :null, :unique, :primary_key, :auto_increment, :references]
|
|
24
|
+
COLUMN_DEFINITION_ORDER = [:collate, :default, :null, :unique, :primary_key, :auto_increment, :references]
|
|
25
25
|
|
|
26
26
|
# Adds a column to the specified table. This method expects a column name,
|
|
27
27
|
# a datatype and optionally a hash with additional constraints and options:
|
|
@@ -29,7 +29,7 @@ module Sequel
|
|
|
29
29
|
# DB.add_column :items, :name, :text, :unique => true, :null => false
|
|
30
30
|
# DB.add_column :items, :category, :text, :default => 'ruby'
|
|
31
31
|
#
|
|
32
|
-
# See alter_table
|
|
32
|
+
# See <tt>alter_table</tt>.
|
|
33
33
|
def add_column(table, *args)
|
|
34
34
|
alter_table(table) {add_column(*args)}
|
|
35
35
|
end
|
|
@@ -40,9 +40,9 @@ module Sequel
|
|
|
40
40
|
# DB.add_index :posts, [:author, :title], :unique => true
|
|
41
41
|
#
|
|
42
42
|
# Options:
|
|
43
|
-
#
|
|
43
|
+
# :ignore_errors :: Ignore any DatabaseErrors that are raised
|
|
44
44
|
#
|
|
45
|
-
# See alter_table
|
|
45
|
+
# See <tt>alter_table</tt>.
|
|
46
46
|
def add_index(table, columns, options={})
|
|
47
47
|
e = options[:ignore_errors]
|
|
48
48
|
begin
|
|
@@ -65,17 +65,17 @@ module Sequel
|
|
|
65
65
|
# end
|
|
66
66
|
#
|
|
67
67
|
# Note that +add_column+ accepts all the options available for column
|
|
68
|
-
# definitions using create_table
|
|
68
|
+
# definitions using <tt>create_table</tt>, and +add_index+ accepts all the options
|
|
69
69
|
# available for index definition.
|
|
70
70
|
#
|
|
71
|
-
# See Schema::AlterTableGenerator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
|
|
71
|
+
# See <tt>Schema::AlterTableGenerator</tt> and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
|
|
72
72
|
def alter_table(name, generator=nil, &block)
|
|
73
73
|
generator ||= Schema::AlterTableGenerator.new(self, &block)
|
|
74
|
-
alter_table_sql_list(name, generator.operations).flatten.each {|sql| execute_ddl(sql)}
|
|
75
74
|
remove_cached_schema(name)
|
|
75
|
+
apply_alter_table(name, generator.operations)
|
|
76
76
|
nil
|
|
77
77
|
end
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
# Creates a table with the columns given in the provided block:
|
|
80
80
|
#
|
|
81
81
|
# DB.create_table :posts do
|
|
@@ -89,7 +89,7 @@ module Sequel
|
|
|
89
89
|
# :temp :: Create the table as a temporary table.
|
|
90
90
|
# :ignore_index_errors :: Ignore any errors when creating indexes.
|
|
91
91
|
#
|
|
92
|
-
# See Schema::Generator and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
|
|
92
|
+
# See <tt>Schema::Generator</tt> and the {"Migrations and Schema Modification" guide}[link:files/doc/migration_rdoc.html].
|
|
93
93
|
def create_table(name, options={}, &block)
|
|
94
94
|
remove_cached_schema(name)
|
|
95
95
|
options = {:generator=>options} if options.is_a?(Schema::Generator)
|
|
@@ -99,19 +99,28 @@ module Sequel
|
|
|
99
99
|
nil
|
|
100
100
|
end
|
|
101
101
|
|
|
102
|
-
# Forcibly
|
|
102
|
+
# Forcibly create a table, attempting to drop it if it already exists, then creating it.
|
|
103
103
|
#
|
|
104
104
|
# DB.create_table!(:a){Integer :a}
|
|
105
|
-
# #
|
|
105
|
+
# # SELECT * FROM a LIMIT a -- check existence
|
|
106
|
+
# # DROP TABLE a -- drop table if already exists
|
|
106
107
|
# # CREATE TABLE a (a integer)
|
|
107
108
|
def create_table!(name, options={}, &block)
|
|
108
|
-
drop_table(name)
|
|
109
|
+
drop_table(name) if table_exists?(name)
|
|
109
110
|
create_table(name, options, &block)
|
|
110
111
|
end
|
|
111
112
|
|
|
112
|
-
# Creates the table unless the table already exists
|
|
113
|
+
# Creates the table unless the table already exists.
|
|
114
|
+
#
|
|
115
|
+
# DB.create_table?(:a){Integer :a}
|
|
116
|
+
# # SELECT * FROM a LIMIT a -- check existence
|
|
117
|
+
# # CREATE TABLE a (a integer) -- if it doesn't already exist
|
|
113
118
|
def create_table?(name, options={}, &block)
|
|
114
|
-
|
|
119
|
+
if supports_create_table_if_not_exists?
|
|
120
|
+
create_table(name, options.merge(:if_not_exists=>true), &block)
|
|
121
|
+
elsif !table_exists?(name)
|
|
122
|
+
create_table(name, options, &block)
|
|
123
|
+
end
|
|
115
124
|
end
|
|
116
125
|
|
|
117
126
|
# Creates a view, replacing it if it already exists:
|
|
@@ -138,7 +147,7 @@ module Sequel
|
|
|
138
147
|
#
|
|
139
148
|
# DB.drop_column :items, :category
|
|
140
149
|
#
|
|
141
|
-
# See alter_table
|
|
150
|
+
# See <tt>alter_table</tt>.
|
|
142
151
|
def drop_column(table, *args)
|
|
143
152
|
alter_table(table) {drop_column(*args)}
|
|
144
153
|
end
|
|
@@ -148,17 +157,20 @@ module Sequel
|
|
|
148
157
|
# DB.drop_index :posts, :title
|
|
149
158
|
# DB.drop_index :posts, [:author, :title]
|
|
150
159
|
#
|
|
151
|
-
# See alter_table
|
|
160
|
+
# See <tt>alter_table</tt>.
|
|
152
161
|
def drop_index(table, columns, options={})
|
|
153
162
|
alter_table(table){drop_index(columns, options)}
|
|
154
163
|
end
|
|
155
164
|
|
|
156
165
|
# Drops one or more tables corresponding to the given names:
|
|
157
166
|
#
|
|
167
|
+
# DB.drop_table(:posts)
|
|
158
168
|
# DB.drop_table(:posts, :comments)
|
|
169
|
+
# DB.drop_table(:posts, :comments, :cascade=>true)
|
|
159
170
|
def drop_table(*names)
|
|
171
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
|
160
172
|
names.each do |n|
|
|
161
|
-
execute_ddl(drop_table_sql(n))
|
|
173
|
+
execute_ddl(drop_table_sql(n, options))
|
|
162
174
|
remove_cached_schema(n)
|
|
163
175
|
end
|
|
164
176
|
nil
|
|
@@ -167,9 +179,12 @@ module Sequel
|
|
|
167
179
|
# Drops one or more views corresponding to the given names:
|
|
168
180
|
#
|
|
169
181
|
# DB.drop_view(:cheap_items)
|
|
182
|
+
# DB.drop_view(:cheap_items, :pricey_items)
|
|
183
|
+
# DB.drop_view(:cheap_items, :pricey_items, :cascade=>true)
|
|
170
184
|
def drop_view(*names)
|
|
185
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
|
171
186
|
names.each do |n|
|
|
172
|
-
execute_ddl(
|
|
187
|
+
execute_ddl(drop_view_sql(n, options))
|
|
173
188
|
remove_cached_schema(n)
|
|
174
189
|
end
|
|
175
190
|
nil
|
|
@@ -191,7 +206,7 @@ module Sequel
|
|
|
191
206
|
#
|
|
192
207
|
# DB.rename_column :items, :cntr, :counter
|
|
193
208
|
#
|
|
194
|
-
# See alter_table
|
|
209
|
+
# See <tt>alter_table</tt>.
|
|
195
210
|
def rename_column(table, *args)
|
|
196
211
|
alter_table(table) {rename_column(*args)}
|
|
197
212
|
end
|
|
@@ -200,7 +215,7 @@ module Sequel
|
|
|
200
215
|
#
|
|
201
216
|
# DB.set_column_default :items, :category, 'perl!'
|
|
202
217
|
#
|
|
203
|
-
# See alter_table
|
|
218
|
+
# See <tt>alter_table</tt>.
|
|
204
219
|
def set_column_default(table, *args)
|
|
205
220
|
alter_table(table) {set_column_default(*args)}
|
|
206
221
|
end
|
|
@@ -209,13 +224,18 @@ module Sequel
|
|
|
209
224
|
#
|
|
210
225
|
# DB.set_column_type :items, :price, :float
|
|
211
226
|
#
|
|
212
|
-
# See alter_table
|
|
227
|
+
# See <tt>alter_table</tt>.
|
|
213
228
|
def set_column_type(table, *args)
|
|
214
229
|
alter_table(table) {set_column_type(*args)}
|
|
215
230
|
end
|
|
216
231
|
|
|
217
232
|
private
|
|
218
233
|
|
|
234
|
+
# Apply the changes in the given alter table ops to the table given by name.
|
|
235
|
+
def apply_alter_table(name, ops)
|
|
236
|
+
alter_table_sql_list(name, ops).flatten.each{|sql| execute_ddl(sql)}
|
|
237
|
+
end
|
|
238
|
+
|
|
219
239
|
# The SQL to execute to modify the DDL for the given table name. op
|
|
220
240
|
# should be one of the operations returned by the AlterTableGenerator.
|
|
221
241
|
def alter_table_sql(table, op)
|
|
@@ -224,7 +244,7 @@ module Sequel
|
|
|
224
244
|
when :add_column
|
|
225
245
|
"ADD COLUMN #{column_definition_sql(op)}"
|
|
226
246
|
when :drop_column
|
|
227
|
-
"DROP COLUMN #{quoted_name}"
|
|
247
|
+
"DROP COLUMN #{quoted_name}#{' CASCADE' if op[:cascade]}"
|
|
228
248
|
when :rename_column
|
|
229
249
|
"RENAME COLUMN #{quoted_name} TO #{quote_identifier(op[:new_name])}"
|
|
230
250
|
when :set_column_type
|
|
@@ -240,7 +260,7 @@ module Sequel
|
|
|
240
260
|
when :add_constraint
|
|
241
261
|
"ADD #{constraint_definition_sql(op)}"
|
|
242
262
|
when :drop_constraint
|
|
243
|
-
"DROP CONSTRAINT #{quoted_name}"
|
|
263
|
+
"DROP CONSTRAINT #{quoted_name}#{' CASCADE' if op[:cascade]}"
|
|
244
264
|
else
|
|
245
265
|
raise Error, "Unsupported ALTER TABLE operation"
|
|
246
266
|
end
|
|
@@ -275,7 +295,12 @@ module Sequel
|
|
|
275
295
|
def column_definition_auto_increment_sql(sql, column)
|
|
276
296
|
sql << " #{auto_increment_sql}" if column[:auto_increment]
|
|
277
297
|
end
|
|
278
|
-
|
|
298
|
+
|
|
299
|
+
# Add collate SQL fragment to column creation SQL.
|
|
300
|
+
def column_definition_collate_sql(sql, column)
|
|
301
|
+
sql << " COLLATE #{column[:collate]}" if column[:collate]
|
|
302
|
+
end
|
|
303
|
+
|
|
279
304
|
# Add default SQL fragment to column creation SQL.
|
|
280
305
|
def column_definition_default_sql(sql, column)
|
|
281
306
|
sql << " DEFAULT #{literal(column[:default])}" if column.include?(:default)
|
|
@@ -354,7 +379,7 @@ module Sequel
|
|
|
354
379
|
|
|
355
380
|
# Execute the create index statements using the generator.
|
|
356
381
|
def create_table_indexes_from_generator(name, generator, options)
|
|
357
|
-
e = options[:ignore_index_errors]
|
|
382
|
+
e = options[:ignore_index_errors] || options[:if_not_exists]
|
|
358
383
|
generator.indexes.each do |index|
|
|
359
384
|
begin
|
|
360
385
|
index_sql_list(name, [index]).each{|sql| execute_ddl(sql)}
|
|
@@ -366,7 +391,7 @@ module Sequel
|
|
|
366
391
|
|
|
367
392
|
# DDL statement for creating a table with the given name, columns, and options
|
|
368
393
|
def create_table_sql(name, generator, options)
|
|
369
|
-
"CREATE #{temporary_table_sql if options[:temp]}TABLE #{quote_schema_table(name)} (#{column_list_sql(generator)})"
|
|
394
|
+
"CREATE #{temporary_table_sql if options[:temp]}TABLE#{' IF NOT EXISTS' if options[:if_not_exists]} #{options[:temp] ? quote_identifier(name) : quote_schema_table(name)} (#{column_list_sql(generator)})"
|
|
370
395
|
end
|
|
371
396
|
|
|
372
397
|
# Default index name for the table and columns, may be too long
|
|
@@ -382,10 +407,15 @@ module Sequel
|
|
|
382
407
|
end
|
|
383
408
|
|
|
384
409
|
# SQL DDL statement to drop the table with the given name.
|
|
385
|
-
def drop_table_sql(name)
|
|
386
|
-
"DROP TABLE #{quote_schema_table(name)}"
|
|
410
|
+
def drop_table_sql(name, options)
|
|
411
|
+
"DROP TABLE #{quote_schema_table(name)}#{' CASCADE' if options[:cascade]}"
|
|
387
412
|
end
|
|
388
413
|
|
|
414
|
+
# SQL DDL statement to drop a view with the given name.
|
|
415
|
+
def drop_view_sql(name, options)
|
|
416
|
+
"DROP VIEW #{quote_schema_table(name)}#{' CASCADE' if options[:cascade]}"
|
|
417
|
+
end
|
|
418
|
+
|
|
389
419
|
# Proxy the filter_expr call to the dataset, used for creating constraints.
|
|
390
420
|
def filter_expr(*args, &block)
|
|
391
421
|
schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
|