sequel 3.48.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +114 -0
- data/Rakefile +10 -7
- data/doc/association_basics.rdoc +25 -23
- data/doc/code_order.rdoc +7 -0
- data/doc/core_extensions.rdoc +0 -10
- data/doc/object_model.rdoc +4 -1
- data/doc/querying.rdoc +3 -3
- data/doc/release_notes/4.0.0.txt +262 -0
- data/doc/security.rdoc +0 -28
- data/doc/testing.rdoc +8 -14
- data/lib/sequel/adapters/ado.rb +7 -11
- data/lib/sequel/adapters/ado/access.rb +8 -8
- data/lib/sequel/adapters/ado/mssql.rb +4 -4
- data/lib/sequel/adapters/amalgalite.rb +6 -6
- data/lib/sequel/adapters/cubrid.rb +7 -7
- data/lib/sequel/adapters/db2.rb +5 -9
- data/lib/sequel/adapters/dbi.rb +2 -6
- data/lib/sequel/adapters/do.rb +4 -4
- data/lib/sequel/adapters/firebird.rb +4 -4
- data/lib/sequel/adapters/ibmdb.rb +8 -8
- data/lib/sequel/adapters/informix.rb +2 -10
- data/lib/sequel/adapters/jdbc.rb +17 -17
- data/lib/sequel/adapters/jdbc/as400.rb +2 -2
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -1
- data/lib/sequel/adapters/jdbc/db2.rb +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +2 -2
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -1
- data/lib/sequel/adapters/jdbc/informix.rb +1 -1
- data/lib/sequel/adapters/jdbc/mssql.rb +2 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
- data/lib/sequel/adapters/jdbc/oracle.rb +5 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -3
- data/lib/sequel/adapters/jdbc/sqlite.rb +3 -3
- data/lib/sequel/adapters/jdbc/transactions.rb +3 -3
- data/lib/sequel/adapters/mock.rb +7 -7
- data/lib/sequel/adapters/mysql.rb +3 -3
- data/lib/sequel/adapters/mysql2.rb +4 -4
- data/lib/sequel/adapters/odbc.rb +2 -6
- data/lib/sequel/adapters/odbc/mssql.rb +1 -1
- data/lib/sequel/adapters/openbase.rb +1 -5
- data/lib/sequel/adapters/oracle.rb +13 -17
- data/lib/sequel/adapters/postgres.rb +20 -25
- data/lib/sequel/adapters/shared/cubrid.rb +3 -3
- data/lib/sequel/adapters/shared/db2.rb +2 -2
- data/lib/sequel/adapters/shared/firebird.rb +7 -7
- data/lib/sequel/adapters/shared/mssql.rb +9 -9
- data/lib/sequel/adapters/shared/mysql.rb +29 -13
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +7 -7
- data/lib/sequel/adapters/shared/oracle.rb +22 -13
- data/lib/sequel/adapters/shared/postgres.rb +61 -46
- data/lib/sequel/adapters/shared/sqlite.rb +9 -9
- data/lib/sequel/adapters/sqlite.rb +17 -11
- data/lib/sequel/adapters/swift.rb +3 -3
- data/lib/sequel/adapters/swift/mysql.rb +1 -1
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +8 -8
- data/lib/sequel/ast_transformer.rb +3 -1
- data/lib/sequel/connection_pool.rb +4 -2
- data/lib/sequel/connection_pool/sharded_single.rb +2 -2
- data/lib/sequel/connection_pool/sharded_threaded.rb +5 -5
- data/lib/sequel/connection_pool/threaded.rb +7 -7
- data/lib/sequel/core.rb +4 -67
- data/lib/sequel/database.rb +1 -0
- data/lib/sequel/database/connecting.rb +2 -8
- data/lib/sequel/database/dataset.rb +2 -7
- data/lib/sequel/database/dataset_defaults.rb +0 -18
- data/lib/sequel/database/features.rb +4 -4
- data/lib/sequel/database/misc.rb +6 -8
- data/lib/sequel/database/query.rb +5 -61
- data/lib/sequel/database/schema_generator.rb +22 -20
- data/lib/sequel/database/schema_methods.rb +48 -20
- data/lib/sequel/database/transactions.rb +7 -17
- data/lib/sequel/dataset.rb +2 -0
- data/lib/sequel/dataset/actions.rb +23 -91
- data/lib/sequel/dataset/features.rb +1 -4
- data/lib/sequel/dataset/graph.rb +3 -47
- data/lib/sequel/dataset/misc.rb +4 -33
- data/lib/sequel/dataset/prepared_statements.rb +3 -1
- data/lib/sequel/dataset/query.rb +116 -240
- data/lib/sequel/dataset/sql.rb +19 -97
- data/lib/sequel/deprecated.rb +0 -16
- data/lib/sequel/exceptions.rb +0 -3
- data/lib/sequel/extensions/_pretty_table.rb +1 -1
- data/lib/sequel/extensions/columns_introspection.rb +1 -12
- data/lib/sequel/extensions/constraint_validations.rb +3 -3
- data/lib/sequel/extensions/core_extensions.rb +0 -9
- data/lib/sequel/extensions/date_arithmetic.rb +1 -2
- data/lib/sequel/extensions/graph_each.rb +11 -0
- data/lib/sequel/extensions/migration.rb +5 -5
- data/lib/sequel/extensions/null_dataset.rb +11 -13
- data/lib/sequel/extensions/pagination.rb +3 -6
- data/lib/sequel/extensions/pg_array.rb +6 -4
- data/lib/sequel/extensions/pg_array_ops.rb +35 -1
- data/lib/sequel/extensions/pg_json.rb +12 -2
- data/lib/sequel/extensions/pg_json_ops.rb +266 -0
- data/lib/sequel/extensions/pg_range.rb +2 -2
- data/lib/sequel/extensions/pg_range_ops.rb +0 -8
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/pretty_table.rb +0 -4
- data/lib/sequel/extensions/query.rb +3 -8
- data/lib/sequel/extensions/schema_caching.rb +0 -7
- data/lib/sequel/extensions/schema_dumper.rb +10 -17
- data/lib/sequel/extensions/select_remove.rb +0 -4
- data/lib/sequel/extensions/set_overrides.rb +28 -0
- data/lib/sequel/extensions/to_dot.rb +6 -10
- data/lib/sequel/model.rb +6 -7
- data/lib/sequel/model/associations.rb +127 -182
- data/lib/sequel/model/base.rb +88 -211
- data/lib/sequel/model/errors.rb +0 -13
- data/lib/sequel/model/plugins.rb +2 -2
- data/lib/sequel/no_core_ext.rb +0 -1
- data/lib/sequel/plugins/after_initialize.rb +11 -17
- data/lib/sequel/plugins/association_autoreloading.rb +1 -47
- data/lib/sequel/plugins/association_dependencies.rb +2 -2
- data/lib/sequel/plugins/auto_validations.rb +2 -8
- data/lib/sequel/plugins/blacklist_security.rb +32 -2
- data/lib/sequel/plugins/caching.rb +1 -1
- data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
- data/lib/sequel/plugins/composition.rb +10 -8
- data/lib/sequel/plugins/constraint_validations.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +4 -0
- data/lib/sequel/plugins/defaults_setter.rb +8 -6
- data/lib/sequel/plugins/dirty.rb +6 -6
- data/lib/sequel/plugins/force_encoding.rb +13 -8
- data/lib/sequel/plugins/hook_class_methods.rb +1 -7
- data/lib/sequel/plugins/json_serializer.rb +13 -74
- data/lib/sequel/plugins/lazy_attributes.rb +2 -4
- data/lib/sequel/plugins/list.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +4 -11
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +1 -49
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/optimistic_locking.rb +3 -5
- data/lib/sequel/plugins/pg_array_associations.rb +453 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +23 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +20 -14
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -2
- data/lib/sequel/plugins/rcte_tree.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +5 -4
- data/lib/sequel/plugins/serialization_modification_detection.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +7 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/touch.rb +2 -2
- data/lib/sequel/plugins/tree.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +19 -4
- data/lib/sequel/plugins/validation_class_methods.rb +0 -30
- data/lib/sequel/plugins/validation_helpers.rb +13 -31
- data/lib/sequel/plugins/xml_serializer.rb +18 -57
- data/lib/sequel/sql.rb +20 -22
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/db2_spec.rb +14 -23
- data/spec/adapters/firebird_spec.rb +25 -29
- data/spec/adapters/informix_spec.rb +11 -14
- data/spec/adapters/mssql_spec.rb +71 -77
- data/spec/adapters/mysql_spec.rb +165 -172
- data/spec/adapters/oracle_spec.rb +36 -39
- data/spec/adapters/postgres_spec.rb +175 -100
- data/spec/adapters/spec_helper.rb +13 -11
- data/spec/adapters/sqlite_spec.rb +36 -44
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +55 -55
- data/spec/core/dataset_spec.rb +45 -249
- data/spec/core/deprecated_spec.rb +0 -8
- data/spec/core/expression_filters_spec.rb +23 -5
- data/spec/core/object_graph_spec.rb +4 -66
- data/spec/core/schema_spec.rb +35 -12
- data/spec/core/spec_helper.rb +3 -2
- data/spec/core_extensions_spec.rb +17 -19
- data/spec/extensions/arbitrary_servers_spec.rb +2 -3
- data/spec/extensions/association_dependencies_spec.rb +14 -14
- data/spec/extensions/auto_validations_spec.rb +7 -0
- data/spec/extensions/blacklist_security_spec.rb +5 -5
- data/spec/extensions/blank_spec.rb +2 -0
- data/spec/extensions/class_table_inheritance_spec.rb +2 -2
- data/spec/extensions/columns_introspection_spec.rb +2 -29
- data/spec/extensions/composition_spec.rb +10 -17
- data/spec/extensions/core_refinements_spec.rb +5 -1
- data/spec/extensions/dataset_associations_spec.rb +18 -0
- data/spec/extensions/date_arithmetic_spec.rb +2 -2
- data/spec/extensions/defaults_setter_spec.rb +9 -9
- data/spec/extensions/dirty_spec.rb +0 -5
- data/spec/extensions/eval_inspect_spec.rb +2 -0
- data/spec/extensions/force_encoding_spec.rb +2 -18
- data/spec/extensions/hash_aliases_spec.rb +8 -0
- data/spec/extensions/hook_class_methods_spec.rb +39 -58
- data/spec/extensions/inflector_spec.rb +2 -0
- data/spec/extensions/instance_filters_spec.rb +8 -8
- data/spec/extensions/json_serializer_spec.rb +1 -41
- data/spec/extensions/list_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +106 -109
- data/spec/extensions/migration_spec.rb +2 -0
- data/spec/extensions/named_timezones_spec.rb +1 -0
- data/spec/extensions/pg_array_associations_spec.rb +603 -0
- data/spec/extensions/pg_array_ops_spec.rb +25 -0
- data/spec/extensions/pg_array_spec.rb +9 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -0
- data/spec/extensions/pg_hstore_spec.rb +1 -0
- data/spec/extensions/pg_json_ops_spec.rb +131 -0
- data/spec/extensions/pg_json_spec.rb +10 -4
- data/spec/extensions/pg_range_ops_spec.rb +2 -5
- data/spec/extensions/pg_range_spec.rb +6 -2
- data/spec/extensions/pg_row_ops_spec.rb +2 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +26 -5
- data/spec/extensions/rcte_tree_spec.rb +15 -15
- data/spec/extensions/schema_dumper_spec.rb +0 -1
- data/spec/extensions/schema_spec.rb +9 -9
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +18 -29
- data/spec/extensions/set_overrides_spec.rb +4 -0
- data/spec/extensions/{many_to_one_pk_lookup_spec.rb → shared_caching_spec.rb} +1 -4
- data/spec/extensions/single_table_inheritance_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +8 -9
- data/spec/extensions/sql_expr_spec.rb +2 -0
- data/spec/extensions/string_date_time_spec.rb +2 -0
- data/spec/extensions/string_stripper_spec.rb +2 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +12 -12
- data/spec/extensions/thread_local_timezones_spec.rb +2 -0
- data/spec/extensions/timestamps_spec.rb +1 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/touch_spec.rb +24 -24
- data/spec/extensions/tree_spec.rb +7 -7
- data/spec/extensions/typecast_on_load_spec.rb +8 -1
- data/spec/extensions/update_primary_key_spec.rb +10 -10
- data/spec/extensions/validation_class_methods_spec.rb +10 -39
- data/spec/extensions/validation_helpers_spec.rb +29 -47
- data/spec/extensions/xml_serializer_spec.rb +1 -23
- data/spec/integration/associations_test.rb +231 -40
- data/spec/integration/database_test.rb +1 -1
- data/spec/integration/dataset_test.rb +64 -64
- data/spec/integration/eager_loader_test.rb +28 -28
- data/spec/integration/migrator_test.rb +1 -1
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +21 -21
- data/spec/integration/prepared_statement_test.rb +7 -7
- data/spec/integration/schema_test.rb +115 -110
- data/spec/integration/spec_helper.rb +17 -27
- data/spec/integration/timezone_test.rb +1 -1
- data/spec/integration/transaction_test.rb +10 -10
- data/spec/integration/type_test.rb +2 -2
- data/spec/model/association_reflection_spec.rb +2 -28
- data/spec/model/associations_spec.rb +239 -188
- data/spec/model/base_spec.rb +27 -68
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +160 -172
- data/spec/model/hooks_spec.rb +62 -79
- data/spec/model/model_spec.rb +36 -51
- data/spec/model/plugins_spec.rb +5 -19
- data/spec/model/record_spec.rb +125 -151
- data/spec/model/spec_helper.rb +8 -6
- data/spec/model/validations_spec.rb +4 -17
- data/spec/spec_config.rb +2 -10
- metadata +50 -56
- data/lib/sequel/deprecated_core_extensions.rb +0 -135
- data/lib/sequel/extensions/pg_auto_parameterize.rb +0 -185
- data/lib/sequel/extensions/pg_statement_cache.rb +0 -318
- data/lib/sequel/plugins/identity_map.rb +0 -260
- data/lib/sequel_core.rb +0 -2
- data/lib/sequel_model.rb +0 -2
- data/spec/extensions/association_autoreloading_spec.rb +0 -102
- data/spec/extensions/identity_map_spec.rb +0 -337
- data/spec/extensions/pg_auto_parameterize_spec.rb +0 -70
- data/spec/extensions/pg_statement_cache_spec.rb +0 -208
- data/spec/rcov.opts +0 -8
- data/spec/spec_config.rb.example +0 -10
@@ -46,7 +46,7 @@ module Sequel
|
|
46
46
|
|
47
47
|
# Return foreign key information using the system views, including
|
48
48
|
# :name, :on_delete, and :on_update entries in the hashes.
|
49
|
-
def foreign_key_list(table, opts=
|
49
|
+
def foreign_key_list(table, opts=OPTS)
|
50
50
|
m = output_identifier_meth
|
51
51
|
im = input_identifier_meth
|
52
52
|
schema, table = schema_and_table(table)
|
@@ -86,7 +86,7 @@ module Sequel
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# Use the system tables to get index information
|
89
|
-
def indexes(table, opts=
|
89
|
+
def indexes(table, opts=OPTS)
|
90
90
|
m = output_identifier_meth
|
91
91
|
im = input_identifier_meth
|
92
92
|
indexes = {}
|
@@ -136,13 +136,13 @@ module Sequel
|
|
136
136
|
|
137
137
|
# Microsoft SQL Server supports using the INFORMATION_SCHEMA to get
|
138
138
|
# information on tables.
|
139
|
-
def tables(opts=
|
139
|
+
def tables(opts=OPTS)
|
140
140
|
information_schema_tables('BASE TABLE', opts)
|
141
141
|
end
|
142
142
|
|
143
143
|
# Microsoft SQL Server supports using the INFORMATION_SCHEMA to get
|
144
144
|
# information on views.
|
145
|
-
def views(opts=
|
145
|
+
def views(opts=OPTS)
|
146
146
|
information_schema_tables('VIEW', opts)
|
147
147
|
end
|
148
148
|
|
@@ -220,7 +220,7 @@ module Sequel
|
|
220
220
|
|
221
221
|
# Commit the active transaction on the connection, does not commit/release
|
222
222
|
# savepoints.
|
223
|
-
def commit_transaction(conn, opts=
|
223
|
+
def commit_transaction(conn, opts=OPTS)
|
224
224
|
log_connection_execute(conn, commit_transaction_sql) unless _trans(conn)[:savepoint_level] > 1
|
225
225
|
end
|
226
226
|
|
@@ -288,7 +288,7 @@ module Sequel
|
|
288
288
|
m = output_identifier_meth
|
289
289
|
metadata_dataset.from(:information_schema__tables___t).
|
290
290
|
select(:table_name).
|
291
|
-
filter(:table_type=>type, :table_schema=>(opts[:schema]||
|
291
|
+
filter(:table_type=>type, :table_schema=>(opts[:schema]||'dbo').to_s).
|
292
292
|
map{|x| m.call(x[:table_name])}
|
293
293
|
end
|
294
294
|
|
@@ -350,7 +350,7 @@ module Sequel
|
|
350
350
|
:table_schema => :table_schema, :table_name => :table_name).
|
351
351
|
select(:column_name___column, :data_type___db_type, :character_maximum_length___max_chars, :column_default___default, :is_nullable___allow_null, :numeric_precision___column_size, :numeric_scale___scale).
|
352
352
|
filter(:c__table_name=>tn)
|
353
|
-
if schema = opts[:schema]
|
353
|
+
if schema = opts[:schema]
|
354
354
|
ds.filter!(:c__table_schema=>schema)
|
355
355
|
end
|
356
356
|
ds.map do |row|
|
@@ -524,7 +524,7 @@ module Sequel
|
|
524
524
|
end
|
525
525
|
|
526
526
|
# MSSQL uses the CONTAINS keyword for full text search
|
527
|
-
def full_text_search(cols, terms, opts =
|
527
|
+
def full_text_search(cols, terms, opts = OPTS)
|
528
528
|
terms = "\"#{terms.join('" OR "')}\"" if terms.is_a?(Array)
|
529
529
|
filter("CONTAINS (?, ?)", cols, terms)
|
530
530
|
end
|
@@ -660,7 +660,7 @@ module Sequel
|
|
660
660
|
# dataset. If OUTPUT is already set, use existing returning values. If OUTPUT
|
661
661
|
# is only set to return a single columns, return an array of just that column.
|
662
662
|
# Otherwise, return an array of hashes.
|
663
|
-
def _import(columns, values, opts=
|
663
|
+
def _import(columns, values, opts=OPTS)
|
664
664
|
if opts[:return] == :primary_key && !@opts[:output]
|
665
665
|
output(nil, [SQL::QualifiedIdentifier.new(:inserted, first_primary_key)])._import(columns, values, opts)
|
666
666
|
elsif @opts[:output]
|
@@ -61,7 +61,7 @@ module Sequel
|
|
61
61
|
# Use the Information Schema's KEY_COLUMN_USAGE table to get
|
62
62
|
# basic information on foreign key columns, but include the
|
63
63
|
# constraint name.
|
64
|
-
def foreign_key_list(table, opts=
|
64
|
+
def foreign_key_list(table, opts=OPTS)
|
65
65
|
m = output_identifier_meth
|
66
66
|
im = input_identifier_meth
|
67
67
|
ds = metadata_dataset.
|
@@ -93,7 +93,7 @@ module Sequel
|
|
93
93
|
#
|
94
94
|
# By default partial indexes are not included, you can use the
|
95
95
|
# option :partial to override this.
|
96
|
-
def indexes(table, opts=
|
96
|
+
def indexes(table, opts=OPTS)
|
97
97
|
indexes = {}
|
98
98
|
remove_indexes = []
|
99
99
|
m = output_identifier_meth
|
@@ -153,7 +153,7 @@ module Sequel
|
|
153
153
|
#
|
154
154
|
# Options:
|
155
155
|
# * :server - Set the server to use
|
156
|
-
def tables(opts=
|
156
|
+
def tables(opts=OPTS)
|
157
157
|
full_tables('BASE TABLE', opts)
|
158
158
|
end
|
159
159
|
|
@@ -170,7 +170,7 @@ module Sequel
|
|
170
170
|
#
|
171
171
|
# Options:
|
172
172
|
# * :server - Set the server to use
|
173
|
-
def views(opts=
|
173
|
+
def views(opts=OPTS)
|
174
174
|
full_tables('VIEW', opts)
|
175
175
|
end
|
176
176
|
|
@@ -290,7 +290,7 @@ module Sequel
|
|
290
290
|
|
291
291
|
# Use XA START to start a new prepared transaction if the :prepare
|
292
292
|
# option is given.
|
293
|
-
def begin_transaction(conn, opts=
|
293
|
+
def begin_transaction(conn, opts=OPTS)
|
294
294
|
if (s = opts[:prepare]) && (th = _trans(conn))[:savepoint_level] == 0
|
295
295
|
log_connection_execute(conn, "XA START #{literal(s)}")
|
296
296
|
th[:savepoint_level] += 1
|
@@ -313,7 +313,7 @@ module Sequel
|
|
313
313
|
|
314
314
|
# Prepare the XA transaction for a two-phase commit if the
|
315
315
|
# :prepare option is given.
|
316
|
-
def commit_transaction(conn, opts=
|
316
|
+
def commit_transaction(conn, opts=OPTS)
|
317
317
|
if (s = opts[:prepare]) && _trans(conn)[:savepoint_level] <= 1
|
318
318
|
log_connection_execute(conn, "XA END #{literal(s)}")
|
319
319
|
log_connection_execute(conn, "XA PREPARE #{literal(s)}")
|
@@ -323,7 +323,7 @@ module Sequel
|
|
323
323
|
end
|
324
324
|
|
325
325
|
# Use MySQL specific syntax for engine type and character encoding
|
326
|
-
def create_table_sql(name, generator, options =
|
326
|
+
def create_table_sql(name, generator, options = OPTS)
|
327
327
|
engine = options.fetch(:engine, Sequel::MySQL.default_engine)
|
328
328
|
charset = options.fetch(:charset, Sequel::MySQL.default_charset)
|
329
329
|
collate = options.fetch(:collate, Sequel::MySQL.default_collate)
|
@@ -418,7 +418,7 @@ module Sequel
|
|
418
418
|
end
|
419
419
|
|
420
420
|
# Rollback the currently open XA transaction
|
421
|
-
def rollback_transaction(conn, opts=
|
421
|
+
def rollback_transaction(conn, opts=OPTS)
|
422
422
|
if (s = opts[:prepare]) && _trans(conn)[:savepoint_level] <= 1
|
423
423
|
log_connection_execute(conn, "XA END #{literal(s)}")
|
424
424
|
log_connection_execute(conn, "XA PREPARE #{literal(s)}")
|
@@ -563,6 +563,8 @@ module Sequel
|
|
563
563
|
EXPLAIN_EXTENDED = 'EXPLAIN EXTENDED '.freeze
|
564
564
|
BACKSLASH_RE = /\\/.freeze
|
565
565
|
QUAD_BACKSLASH = "\\\\\\\\".freeze
|
566
|
+
BLOB_START = "0x".freeze
|
567
|
+
HSTAR = "H*".freeze
|
566
568
|
|
567
569
|
# MySQL specific syntax for LIKE/REGEXP searches, as well as
|
568
570
|
# string concatenation.
|
@@ -620,7 +622,7 @@ module Sequel
|
|
620
622
|
|
621
623
|
# Return the results of an EXPLAIN query as a string. Options:
|
622
624
|
# :extended :: Use EXPLAIN EXPTENDED instead of EXPLAIN if true.
|
623
|
-
def explain(opts=
|
625
|
+
def explain(opts=OPTS)
|
624
626
|
# Load the PrettyTable class, needed for explain output
|
625
627
|
Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)
|
626
628
|
|
@@ -635,12 +637,12 @@ module Sequel
|
|
635
637
|
end
|
636
638
|
|
637
639
|
# Adds full text filter
|
638
|
-
def full_text_search(cols, terms, opts =
|
640
|
+
def full_text_search(cols, terms, opts = OPTS)
|
639
641
|
filter(full_text_sql(cols, terms, opts))
|
640
642
|
end
|
641
643
|
|
642
644
|
# MySQL specific full text search syntax.
|
643
|
-
def full_text_sql(cols, terms, opts =
|
645
|
+
def full_text_sql(cols, terms, opts = OPTS)
|
644
646
|
terms = terms.join(' ') if terms.is_a?(Array)
|
645
647
|
SQL::PlaceholderLiteralString.new((opts[:boolean] ? MATCH_AGAINST_BOOLEAN : MATCH_AGAINST), [Array(cols), terms])
|
646
648
|
end
|
@@ -652,10 +654,10 @@ module Sequel
|
|
652
654
|
|
653
655
|
# Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
|
654
656
|
# Raises an error on use of :full_outer type, since MySQL doesn't support it.
|
655
|
-
def join_table(type, table, expr=nil,
|
657
|
+
def join_table(type, table, expr=nil, opts=OPTS, &block)
|
656
658
|
type = :inner if (type == :cross) && !expr.nil?
|
657
659
|
raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN") if type == :full_outer
|
658
|
-
super(type, table, expr,
|
660
|
+
super(type, table, expr, opts, &block)
|
659
661
|
end
|
660
662
|
|
661
663
|
# Transforms :natural_inner to NATURAL LEFT JOIN and straight to
|
@@ -893,11 +895,25 @@ module Sequel
|
|
893
895
|
alias delete_limit_sql limit_sql
|
894
896
|
alias update_limit_sql limit_sql
|
895
897
|
|
898
|
+
# MySQL uses a preceding X for hex escaping strings
|
899
|
+
def literal_blob_append(sql, v)
|
900
|
+
sql << BLOB_START << v.unpack(HSTAR).first
|
901
|
+
end
|
902
|
+
|
896
903
|
# Use 0 for false on MySQL
|
897
904
|
def literal_false
|
898
905
|
BOOL_FALSE
|
899
906
|
end
|
900
907
|
|
908
|
+
# Raise error for infinitate and NaN values
|
909
|
+
def literal_float(v)
|
910
|
+
if v.infinite? || v.nan?
|
911
|
+
raise InvalidValue, "Infinite floats and NaN values are not valid on MySQL"
|
912
|
+
else
|
913
|
+
super
|
914
|
+
end
|
915
|
+
end
|
916
|
+
|
901
917
|
# SQL fragment for String. Doubles \ and ' by default.
|
902
918
|
def literal_string_append(sql, v)
|
903
919
|
sql << APOS << v.gsub(BACKSLASH_RE, QUAD_BACKSLASH).gsub(APOS_RE, DOUBLE_APOS) << APOS
|
@@ -18,14 +18,14 @@ module Sequel
|
|
18
18
|
MYSQL_DATABASE_DISCONNECT_ERRORS = /\A#{Regexp.union(disconnect_errors)}/o
|
19
19
|
|
20
20
|
# Support stored procedures on MySQL
|
21
|
-
def call_sproc(name, opts=
|
21
|
+
def call_sproc(name, opts=OPTS, &block)
|
22
22
|
args = opts[:args] || []
|
23
23
|
execute("CALL #{name}#{args.empty? ? '()' : literal(args)}", opts.merge(:sproc=>false), &block)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Executes the given SQL using an available connection, yielding the
|
27
27
|
# connection if the block is given.
|
28
|
-
def execute(sql, opts=
|
28
|
+
def execute(sql, opts=OPTS, &block)
|
29
29
|
if opts[:sproc]
|
30
30
|
call_sproc(sql, opts, &block)
|
31
31
|
elsif sql.is_a?(Symbol)
|
@@ -114,17 +114,17 @@ module Sequel
|
|
114
114
|
|
115
115
|
# Execute the prepared statement with the bind arguments instead of
|
116
116
|
# the given SQL.
|
117
|
-
def execute(sql, opts=
|
117
|
+
def execute(sql, opts=OPTS, &block)
|
118
118
|
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
119
119
|
end
|
120
120
|
|
121
121
|
# Same as execute, explicit due to intricacies of alias and super.
|
122
|
-
def execute_dui(sql, opts=
|
122
|
+
def execute_dui(sql, opts=OPTS, &block)
|
123
123
|
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
124
124
|
end
|
125
125
|
|
126
126
|
# Same as execute, explicit due to intricacies of alias and super.
|
127
|
-
def execute_insert(sql, opts=
|
127
|
+
def execute_insert(sql, opts=OPTS, &block)
|
128
128
|
super(prepared_statement_name, {:arguments=>bind_arguments}.merge(opts), &block)
|
129
129
|
end
|
130
130
|
end
|
@@ -136,12 +136,12 @@ module Sequel
|
|
136
136
|
private
|
137
137
|
|
138
138
|
# Execute the database stored procedure with the stored arguments.
|
139
|
-
def execute(sql, opts=
|
139
|
+
def execute(sql, opts=OPTS, &block)
|
140
140
|
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
141
141
|
end
|
142
142
|
|
143
143
|
# Same as execute, explicit due to intricacies of alias and super.
|
144
|
-
def execute_dui(sql, opts=
|
144
|
+
def execute_dui(sql, opts=OPTS, &block)
|
145
145
|
super(@sproc_name, {:args=>@sproc_args, :sproc=>true}.merge(opts), &block)
|
146
146
|
end
|
147
147
|
end
|
@@ -10,7 +10,7 @@ module Sequel
|
|
10
10
|
|
11
11
|
attr_accessor :autosequence
|
12
12
|
|
13
|
-
def create_sequence(name, opts=
|
13
|
+
def create_sequence(name, opts=OPTS)
|
14
14
|
self << create_sequence_sql(name, opts)
|
15
15
|
end
|
16
16
|
|
@@ -36,12 +36,12 @@ module Sequel
|
|
36
36
|
false
|
37
37
|
end
|
38
38
|
|
39
|
-
def tables(opts=
|
39
|
+
def tables(opts=OPTS)
|
40
40
|
m = output_identifier_meth
|
41
41
|
metadata_dataset.from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'TABLE').map{|r| m.call(r[:tname])}
|
42
42
|
end
|
43
43
|
|
44
|
-
def views(opts=
|
44
|
+
def views(opts=OPTS)
|
45
45
|
m = output_identifier_meth
|
46
46
|
metadata_dataset.from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'VIEW').map{|r| m.call(r[:tname])}
|
47
47
|
end
|
@@ -96,7 +96,7 @@ module Sequel
|
|
96
96
|
AUTOINCREMENT
|
97
97
|
end
|
98
98
|
|
99
|
-
def create_sequence_sql(name, opts=
|
99
|
+
def create_sequence_sql(name, opts=OPTS)
|
100
100
|
"CREATE SEQUENCE #{quote_identifier(name)} start with #{opts [:start_with]||1} increment by #{opts[:increment_by]||1} nomaxvalue"
|
101
101
|
end
|
102
102
|
|
@@ -106,7 +106,7 @@ module Sequel
|
|
106
106
|
create_statements.each{|sql| execute_ddl(sql)}
|
107
107
|
end
|
108
108
|
|
109
|
-
def create_table_sql_list(name, generator, options=
|
109
|
+
def create_table_sql_list(name, generator, options=OPTS)
|
110
110
|
statements = [create_table_sql(name, generator, options)]
|
111
111
|
drop_seq_statement = nil
|
112
112
|
generator.columns.each do |c|
|
@@ -132,7 +132,7 @@ module Sequel
|
|
132
132
|
[drop_seq_statement, statements]
|
133
133
|
end
|
134
134
|
|
135
|
-
def create_trigger_sql(table, name, definition, opts=
|
135
|
+
def create_trigger_sql(table, name, definition, opts=OPTS)
|
136
136
|
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
137
137
|
sql = <<-end_sql
|
138
138
|
CREATE#{' OR REPLACE' if opts[:replace]} TRIGGER #{quote_identifier(name)}
|
@@ -247,17 +247,27 @@ module Sequel
|
|
247
247
|
when :&
|
248
248
|
sql << complex_expression_arg_pairs(args){|a, b| "CAST(BITAND(#{literal(a)}, #{literal(b)}) AS INTEGER)"}
|
249
249
|
when :|
|
250
|
-
sql << complex_expression_arg_pairs(args)
|
250
|
+
sql << complex_expression_arg_pairs(args) do |a, b|
|
251
|
+
s1 = ''
|
252
|
+
complex_expression_sql_append(s1, :&, [a, b])
|
253
|
+
"(#{literal(a)} - #{s1} + #{literal(b)})"
|
254
|
+
end
|
251
255
|
when :^
|
252
|
-
sql << complex_expression_arg_pairs(args)
|
256
|
+
sql << complex_expression_arg_pairs(args) do |*x|
|
257
|
+
s1 = ''
|
258
|
+
s2 = ''
|
259
|
+
complex_expression_sql_append(s1, :|, x)
|
260
|
+
complex_expression_sql_append(s2, :&, x)
|
261
|
+
"(#{s1} - #{s2})"
|
262
|
+
end
|
253
263
|
when :'B~'
|
254
264
|
sql << BITCOMP_OPEN
|
255
265
|
literal_append(sql, args.at(0))
|
256
266
|
sql << BITCOMP_CLOSE
|
257
267
|
when :<<
|
258
|
-
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * power(2, #{literal
|
268
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} * power(2, #{literal(b)}))"}
|
259
269
|
when :>>
|
260
|
-
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / power(2, #{literal
|
270
|
+
sql << complex_expression_arg_pairs(args){|a, b| "(#{literal(a)} / power(2, #{literal(b)}))"}
|
261
271
|
when :%
|
262
272
|
sql << complex_expression_arg_pairs(args){|a, b| "MOD(#{literal(a)}, #{literal(b)})"}
|
263
273
|
else
|
@@ -291,8 +301,7 @@ module Sequel
|
|
291
301
|
end
|
292
302
|
|
293
303
|
# Oracle uses MINUS instead of EXCEPT, and doesn't support EXCEPT ALL
|
294
|
-
def except(dataset, opts=
|
295
|
-
opts = {:all=>opts} unless opts.is_a?(Hash)
|
304
|
+
def except(dataset, opts=OPTS)
|
296
305
|
raise(Sequel::Error, "EXCEPT ALL not supported") if opts[:all]
|
297
306
|
compound_clone(:minus, dataset, opts)
|
298
307
|
end
|
@@ -391,7 +400,7 @@ module Sequel
|
|
391
400
|
|
392
401
|
# If this dataset is associated with a sequence, return the most recently
|
393
402
|
# inserted sequence value.
|
394
|
-
def execute_insert(sql, opts=
|
403
|
+
def execute_insert(sql, opts=OPTS)
|
395
404
|
f = @opts[:from]
|
396
405
|
super(sql, {:table=>(f.first if f), :sequence=>@opts[:sequence]}.merge(opts))
|
397
406
|
end
|
@@ -63,7 +63,7 @@ module Sequel
|
|
63
63
|
# :using :: Override the index_method for the exclusion constraint (defaults to gist).
|
64
64
|
# :where :: Create a partial exclusion constraint, which only affects
|
65
65
|
# a subset of table rows, value should be a filter expression.
|
66
|
-
def exclude(elements, opts=
|
66
|
+
def exclude(elements, opts=OPTS)
|
67
67
|
constraints << {:type => :exclude, :elements => elements}.merge(opts)
|
68
68
|
end
|
69
69
|
end
|
@@ -71,7 +71,7 @@ module Sequel
|
|
71
71
|
class AlterTableGenerator < Sequel::Schema::AlterTableGenerator
|
72
72
|
# Adds an exclusion constraint to an existing table, see
|
73
73
|
# CreateTableGenerator#exclude.
|
74
|
-
def add_exclusion_constraint(elements, opts=
|
74
|
+
def add_exclusion_constraint(elements, opts=OPTS)
|
75
75
|
@operations << {:op => :add_constraint, :type => :exclude, :elements => elements}.merge(opts)
|
76
76
|
end
|
77
77
|
|
@@ -89,10 +89,8 @@ module Sequel
|
|
89
89
|
module DatabaseMethods
|
90
90
|
extend Sequel::Database::ResetIdentifierMangling
|
91
91
|
|
92
|
-
EXCLUDE_SCHEMAS = /pg_*|information_schema/i
|
93
92
|
PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
|
94
93
|
RE_CURRVAL_ERROR = /currval of sequence "(.*)" is not yet defined in this session|relation "(.*)" does not exist/.freeze
|
95
|
-
SYSTEM_TABLE_REGEXP = /^pg|sql/.freeze
|
96
94
|
FOREIGN_KEY_LIST_ON_DELETE_MAP = {'a'.freeze=>:no_action, 'r'.freeze=>:restrict, 'c'.freeze=>:cascade, 'n'.freeze=>:set_null, 'd'.freeze=>:set_default}.freeze
|
97
95
|
POSTGRES_DEFAULT_RE = /\A(?:B?('.*')::[^']+|\((-?\d+(?:\.\d+)?)\))\z/
|
98
96
|
UNLOGGED = 'UNLOGGED '.freeze
|
@@ -179,7 +177,7 @@ module Sequel
|
|
179
177
|
# * :set : Configuration variables to set while the function is being run, can be a hash or an array of two pairs. search_path is
|
180
178
|
# often used here if :security_definer is used.
|
181
179
|
# * :strict : Makes the function return NULL when any argument is NULL.
|
182
|
-
def create_function(name, definition, opts=
|
180
|
+
def create_function(name, definition, opts=OPTS)
|
183
181
|
self << create_function_sql(name, definition, opts)
|
184
182
|
end
|
185
183
|
|
@@ -187,17 +185,20 @@ module Sequel
|
|
187
185
|
# * name : Name of the procedural language (e.g. plpgsql)
|
188
186
|
# * opts : options hash:
|
189
187
|
# * :handler : The name of a previously registered function used as a call handler for this language.
|
190
|
-
# * :replace: Replace the installed language if it already exists (on PostgreSQL 9.0+).
|
188
|
+
# * :replace : Replace the installed language if it already exists (on PostgreSQL 9.0+).
|
191
189
|
# * :trusted : Marks the language being created as trusted, allowing unprivileged users to create functions using this language.
|
192
190
|
# * :validator : The name of previously registered function used as a validator of functions defined in this language.
|
193
|
-
def create_language(name, opts=
|
191
|
+
def create_language(name, opts=OPTS)
|
194
192
|
self << create_language_sql(name, opts)
|
195
193
|
end
|
196
194
|
|
197
195
|
# Create a schema in the database. Arguments:
|
198
196
|
# * name : Name of the schema (e.g. admin)
|
199
|
-
|
200
|
-
|
197
|
+
# * opts : options hash:
|
198
|
+
# * :if_not_exists : Don't raise an error if the schema already exists (PostgreSQL 9.3+)
|
199
|
+
# * :owner : The owner to set for the schema (defaults to current user if not specified)
|
200
|
+
def create_schema(name, opts=OPTS)
|
201
|
+
self << create_schema_sql(name, opts)
|
201
202
|
end
|
202
203
|
|
203
204
|
# Create a trigger in the database. Arguments:
|
@@ -210,7 +211,7 @@ module Sequel
|
|
210
211
|
# * :each_row : Calls the trigger for each row instead of for each statement.
|
211
212
|
# * :events : Can be :insert, :update, :delete, or an array of any of those. Calls the trigger whenever that type of statement is used. By default,
|
212
213
|
# the trigger is called for insert, update, or delete.
|
213
|
-
def create_trigger(table, name, function, opts=
|
214
|
+
def create_trigger(table, name, function, opts=OPTS)
|
214
215
|
self << create_trigger_sql(table, name, function, opts)
|
215
216
|
end
|
216
217
|
|
@@ -224,7 +225,7 @@ module Sequel
|
|
224
225
|
#
|
225
226
|
# :language :: The procedural language the code is written in. The PostgreSQL
|
226
227
|
# default is plpgsql. Can be specified as a string or a symbol.
|
227
|
-
def do(code, opts=
|
228
|
+
def do(code, opts=OPTS)
|
228
229
|
language = opts[:language]
|
229
230
|
run "DO #{"LANGUAGE #{literal(language.to_s)} " if language}#{literal(code)}"
|
230
231
|
end
|
@@ -235,7 +236,7 @@ module Sequel
|
|
235
236
|
# * :args : The arguments for the function. See create_function_sql.
|
236
237
|
# * :cascade : Drop other objects depending on this function.
|
237
238
|
# * :if_exists : Don't raise an error if the function doesn't exist.
|
238
|
-
def drop_function(name, opts=
|
239
|
+
def drop_function(name, opts=OPTS)
|
239
240
|
self << drop_function_sql(name, opts)
|
240
241
|
end
|
241
242
|
|
@@ -244,7 +245,7 @@ module Sequel
|
|
244
245
|
# * opts : options hash:
|
245
246
|
# * :cascade : Drop other objects depending on this function.
|
246
247
|
# * :if_exists : Don't raise an error if the function doesn't exist.
|
247
|
-
def drop_language(name, opts=
|
248
|
+
def drop_language(name, opts=OPTS)
|
248
249
|
self << drop_language_sql(name, opts)
|
249
250
|
end
|
250
251
|
|
@@ -253,7 +254,7 @@ module Sequel
|
|
253
254
|
# * opts : options hash:
|
254
255
|
# * :cascade : Drop all objects in this schema.
|
255
256
|
# * :if_exists : Don't raise an error if the schema doesn't exist.
|
256
|
-
def drop_schema(name, opts=
|
257
|
+
def drop_schema(name, opts=OPTS)
|
257
258
|
self << drop_schema_sql(name, opts)
|
258
259
|
end
|
259
260
|
|
@@ -263,13 +264,13 @@ module Sequel
|
|
263
264
|
# * opts : options hash:
|
264
265
|
# * :cascade : Drop other objects depending on this function.
|
265
266
|
# * :if_exists : Don't raise an error if the function doesn't exist.
|
266
|
-
def drop_trigger(table, name, opts=
|
267
|
+
def drop_trigger(table, name, opts=OPTS)
|
267
268
|
self << drop_trigger_sql(table, name, opts)
|
268
269
|
end
|
269
270
|
|
270
271
|
# Return full foreign key information using the pg system tables, including
|
271
272
|
# :name, :on_delete, :on_update, and :deferrable entries in the hashes.
|
272
|
-
def foreign_key_list(table, opts=
|
273
|
+
def foreign_key_list(table, opts=OPTS)
|
273
274
|
m = output_identifier_meth
|
274
275
|
schema, _ = opts.fetch(:schema, schema_and_table(table))
|
275
276
|
range = 0...32
|
@@ -323,7 +324,7 @@ module Sequel
|
|
323
324
|
end
|
324
325
|
|
325
326
|
# Use the pg_* system tables to determine indexes on a table
|
326
|
-
def indexes(table, opts=
|
327
|
+
def indexes(table, opts=OPTS)
|
327
328
|
m = output_identifier_meth
|
328
329
|
range = 0...32
|
329
330
|
attnums = server_version >= 80100 ? SQL::Function.new(:ANY, :ind__indkey) : range.map{|x| SQL::Subscript.new(:ind__indkey, [x])}
|
@@ -358,7 +359,7 @@ module Sequel
|
|
358
359
|
# in PostgreSQL 9.0+.
|
359
360
|
# :server :: The server to which to send the NOTIFY statement, if the sharding support
|
360
361
|
# is being used.
|
361
|
-
def notify(channel, opts=
|
362
|
+
def notify(channel, opts=OPTS)
|
362
363
|
sql = "NOTIFY "
|
363
364
|
dataset.send(:identifier_append, sql, channel)
|
364
365
|
if payload = opts[:payload]
|
@@ -369,7 +370,7 @@ module Sequel
|
|
369
370
|
end
|
370
371
|
|
371
372
|
# Return primary key for the given table.
|
372
|
-
def primary_key(table, opts=
|
373
|
+
def primary_key(table, opts=OPTS)
|
373
374
|
quoted_table = quote_schema_table(table)
|
374
375
|
Sequel.synchronize{return @primary_keys[quoted_table] if @primary_keys.has_key?(quoted_table)}
|
375
376
|
sql = "#{SELECT_PK_SQL} AND pg_class.oid = #{literal(regclass_oid(table, opts))}"
|
@@ -378,7 +379,7 @@ module Sequel
|
|
378
379
|
end
|
379
380
|
|
380
381
|
# Return the sequence providing the default for the primary key for the given table.
|
381
|
-
def primary_key_sequence(table, opts=
|
382
|
+
def primary_key_sequence(table, opts=OPTS)
|
382
383
|
quoted_table = quote_schema_table(table)
|
383
384
|
Sequel.synchronize{return @primary_key_sequences[quoted_table] if @primary_key_sequences.has_key?(quoted_table)}
|
384
385
|
sql = "#{SELECT_SERIAL_SEQUENCE_SQL} AND t.oid = #{literal(regclass_oid(table, opts))}"
|
@@ -393,6 +394,14 @@ module Sequel
|
|
393
394
|
end
|
394
395
|
end
|
395
396
|
end
|
397
|
+
|
398
|
+
# Refresh the materialized view with the given name.
|
399
|
+
#
|
400
|
+
# DB.refresh_view(:items_view)
|
401
|
+
# # REFRESH MATERIALIZED VIEW items_view
|
402
|
+
def refresh_view(name, opts=OPTS)
|
403
|
+
run "REFRESH MATERIALIZED VIEW #{quote_schema_table(name)}"
|
404
|
+
end
|
396
405
|
|
397
406
|
# Reset the database's conversion procs, requires a server query if there
|
398
407
|
# any named types.
|
@@ -492,7 +501,7 @@ module Sequel
|
|
492
501
|
# using the schema the table is located in as the qualifier.
|
493
502
|
# :schema :: The schema to search
|
494
503
|
# :server :: The server to use
|
495
|
-
def tables(opts=
|
504
|
+
def tables(opts=OPTS, &block)
|
496
505
|
pg_class_relname('r', opts, &block)
|
497
506
|
end
|
498
507
|
|
@@ -510,7 +519,7 @@ module Sequel
|
|
510
519
|
# using the schema the view is located in as the qualifier.
|
511
520
|
# :schema :: The schema to search
|
512
521
|
# :server :: The server to use
|
513
|
-
def views(opts=
|
522
|
+
def views(opts=OPTS)
|
514
523
|
pg_class_relname('v', opts)
|
515
524
|
end
|
516
525
|
|
@@ -578,7 +587,7 @@ module Sequel
|
|
578
587
|
|
579
588
|
# If the :prepare option is given and we aren't in a savepoint,
|
580
589
|
# prepare the transaction for a two-phase commit.
|
581
|
-
def commit_transaction(conn, opts=
|
590
|
+
def commit_transaction(conn, opts=OPTS)
|
582
591
|
if (s = opts[:prepare]) && _trans(conn)[:savepoint_level] <= 1
|
583
592
|
log_connection_execute(conn, "PREPARE TRANSACTION #{literal(s)}")
|
584
593
|
else
|
@@ -602,7 +611,7 @@ module Sequel
|
|
602
611
|
if (cmm = @opts.fetch(:client_min_messages, Postgres.client_min_messages)) && !cmm.to_s.empty?
|
603
612
|
cmm = cmm.to_s.upcase.strip
|
604
613
|
unless VALID_CLIENT_MIN_MESSAGES.include?(cmm)
|
605
|
-
|
614
|
+
raise Error, "Unsupported client_min_messages setting: #{cmm}"
|
606
615
|
end
|
607
616
|
sqls << "SET client_min_messages = '#{cmm.to_s.upcase}'"
|
608
617
|
end
|
@@ -718,7 +727,7 @@ module Sequel
|
|
718
727
|
end
|
719
728
|
|
720
729
|
# SQL statement to create database function.
|
721
|
-
def create_function_sql(name, definition, opts=
|
730
|
+
def create_function_sql(name, definition, opts=OPTS)
|
722
731
|
args = opts[:args]
|
723
732
|
if !opts[:args].is_a?(Array) || !opts[:args].any?{|a| Array(a).length == 3 and %w'OUT INOUT'.include?(a[2].to_s)}
|
724
733
|
returns = opts[:returns] || 'void'
|
@@ -739,13 +748,13 @@ module Sequel
|
|
739
748
|
end
|
740
749
|
|
741
750
|
# SQL for creating a procedural language.
|
742
|
-
def create_language_sql(name, opts=
|
751
|
+
def create_language_sql(name, opts=OPTS)
|
743
752
|
"CREATE#{' OR REPLACE' if opts[:replace] && server_version >= 90000}#{' TRUSTED' if opts[:trusted]} LANGUAGE #{name}#{" HANDLER #{opts[:handler]}" if opts[:handler]}#{" VALIDATOR #{opts[:validator]}" if opts[:validator]}"
|
744
753
|
end
|
745
754
|
|
746
755
|
# SQL for creating a schema.
|
747
|
-
def create_schema_sql(name)
|
748
|
-
"CREATE SCHEMA #{quote_identifier(name)}"
|
756
|
+
def create_schema_sql(name, opts=OPTS)
|
757
|
+
"CREATE SCHEMA #{'IF NOT EXISTS ' if opts[:if_not_exists]}#{quote_identifier(name)}#{" AUTHORIZATION #{literal(opts[:owner])}" if opts[:owner]}"
|
749
758
|
end
|
750
759
|
|
751
760
|
# DDL statement for creating a table with the given name, columns, and options
|
@@ -765,7 +774,7 @@ module Sequel
|
|
765
774
|
end
|
766
775
|
|
767
776
|
# SQL for creating a database trigger.
|
768
|
-
def create_trigger_sql(table, name, function, opts=
|
777
|
+
def create_trigger_sql(table, name, function, opts=OPTS)
|
769
778
|
events = opts[:events] ? Array(opts[:events]) : [:insert, :update, :delete]
|
770
779
|
whence = opts[:after] ? 'AFTER' : 'BEFORE'
|
771
780
|
"CREATE TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
|
@@ -773,7 +782,7 @@ module Sequel
|
|
773
782
|
|
774
783
|
# DDL fragment for initial part of CREATE VIEW statement
|
775
784
|
def create_view_prefix_sql(name, options)
|
776
|
-
"CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}VIEW #{quote_schema_table(name)}"
|
785
|
+
create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
|
777
786
|
end
|
778
787
|
|
779
788
|
# The errors that the main adapters can raise, depends on the adapter being used
|
@@ -782,7 +791,7 @@ module Sequel
|
|
782
791
|
end
|
783
792
|
|
784
793
|
# SQL for dropping a function from the database.
|
785
|
-
def drop_function_sql(name, opts=
|
794
|
+
def drop_function_sql(name, opts=OPTS)
|
786
795
|
"DROP FUNCTION#{' IF EXISTS' if opts[:if_exists]} #{name}#{sql_function_args(opts[:args])}#{' CASCADE' if opts[:cascade]}"
|
787
796
|
end
|
788
797
|
|
@@ -792,28 +801,34 @@ module Sequel
|
|
792
801
|
end
|
793
802
|
|
794
803
|
# SQL for dropping a procedural language from the database.
|
795
|
-
def drop_language_sql(name, opts=
|
804
|
+
def drop_language_sql(name, opts=OPTS)
|
796
805
|
"DROP LANGUAGE#{' IF EXISTS' if opts[:if_exists]} #{name}#{' CASCADE' if opts[:cascade]}"
|
797
806
|
end
|
798
807
|
|
799
808
|
# SQL for dropping a schema from the database.
|
800
|
-
def drop_schema_sql(name, opts=
|
809
|
+
def drop_schema_sql(name, opts=OPTS)
|
801
810
|
"DROP SCHEMA#{' IF EXISTS' if opts[:if_exists]} #{quote_identifier(name)}#{' CASCADE' if opts[:cascade]}"
|
802
811
|
end
|
803
812
|
|
804
813
|
# SQL for dropping a trigger from the database.
|
805
|
-
def drop_trigger_sql(table, name, opts=
|
814
|
+
def drop_trigger_sql(table, name, opts=OPTS)
|
806
815
|
"DROP TRIGGER#{' IF EXISTS' if opts[:if_exists]} #{name} ON #{quote_schema_table(table)}#{' CASCADE' if opts[:cascade]}"
|
807
816
|
end
|
808
817
|
|
818
|
+
# SQL for dropping a view from the database.
|
819
|
+
def drop_view_sql(name, opts=OPTS)
|
820
|
+
"DROP #{'MATERIALIZED ' if opts[:materialized]}VIEW#{' IF EXISTS' if opts[:if_exists]} #{quote_schema_table(name)}#{' CASCADE' if opts[:cascade]}"
|
821
|
+
end
|
822
|
+
|
809
823
|
# If opts includes a :schema option, or a default schema is used, restrict the dataset to
|
810
824
|
# that schema. Otherwise, just exclude the default PostgreSQL schemas except for public.
|
811
825
|
def filter_schema(ds, opts)
|
812
|
-
if schema = opts[:schema]
|
813
|
-
|
826
|
+
expr = if schema = opts[:schema]
|
827
|
+
schema.to_s
|
814
828
|
else
|
815
|
-
|
829
|
+
Sequel.function(:any, Sequel.function(:current_schemas, false))
|
816
830
|
end
|
831
|
+
ds.where(:pg_namespace__nspname=>expr)
|
817
832
|
end
|
818
833
|
|
819
834
|
# Return a hash with oid keys and callable values, used for converting types.
|
@@ -850,7 +865,7 @@ module Sequel
|
|
850
865
|
case index_type
|
851
866
|
when :full_text
|
852
867
|
expr = "(to_tsvector(#{literal(index[:language] || 'simple')}::regconfig, #{literal(dataset.send(:full_text_string_join, cols))}))"
|
853
|
-
index_type = :gin
|
868
|
+
index_type = index[:index_type] || :gin
|
854
869
|
when :spatial
|
855
870
|
index_type = :gist
|
856
871
|
end
|
@@ -867,7 +882,7 @@ module Sequel
|
|
867
882
|
|
868
883
|
# Backbone of the tables and views support.
|
869
884
|
def pg_class_relname(type, opts)
|
870
|
-
ds = metadata_dataset.from(:pg_class).filter(:relkind=>type).select(:relname).
|
885
|
+
ds = metadata_dataset.from(:pg_class).filter(:relkind=>type).select(:relname).server(opts[:server]).join(:pg_namespace, :oid=>:relnamespace)
|
871
886
|
ds = filter_schema(ds, opts)
|
872
887
|
m = output_identifier_meth
|
873
888
|
if block_given?
|
@@ -887,7 +902,7 @@ module Sequel
|
|
887
902
|
|
888
903
|
# Return an expression the oid for the table expr. Used by the metadata parsing
|
889
904
|
# code to disambiguate unqualified tables.
|
890
|
-
def regclass_oid(expr, opts=
|
905
|
+
def regclass_oid(expr, opts=OPTS)
|
891
906
|
if expr.is_a?(String) && !expr.is_a?(LiteralString)
|
892
907
|
expr = Sequel.identifier(expr)
|
893
908
|
end
|
@@ -1133,7 +1148,7 @@ module Sequel
|
|
1133
1148
|
end
|
1134
1149
|
|
1135
1150
|
# Return the results of an EXPLAIN query as a string
|
1136
|
-
def explain(opts=
|
1151
|
+
def explain(opts=OPTS)
|
1137
1152
|
with_sql((opts[:analyze] ? EXPLAIN_ANALYZE : EXPLAIN) + select_sql).map(QUERY_PLAN).join(CRLF)
|
1138
1153
|
end
|
1139
1154
|
|
@@ -1144,7 +1159,7 @@ module Sequel
|
|
1144
1159
|
|
1145
1160
|
# PostgreSQL specific full text search syntax, using tsearch2 (included
|
1146
1161
|
# in 8.3 by default, and available for earlier versions as an add-on).
|
1147
|
-
def full_text_search(cols, terms, opts =
|
1162
|
+
def full_text_search(cols, terms, opts = OPTS)
|
1148
1163
|
lang = opts[:language] || 'simple'
|
1149
1164
|
terms = terms.join(' | ') if terms.is_a?(Array)
|
1150
1165
|
filter("to_tsvector(?::regconfig, ?) @@ to_tsquery(?::regconfig, ?)", lang, full_text_string_join(cols), lang, terms)
|
@@ -1178,7 +1193,7 @@ module Sequel
|
|
1178
1193
|
# a new transaction, locks the table, and yields. If a block is not given
|
1179
1194
|
# just locks the tables. Note that PostgreSQL will probably raise an error
|
1180
1195
|
# if you lock the table outside of an existing transaction. Returns nil.
|
1181
|
-
def lock(mode, opts=
|
1196
|
+
def lock(mode, opts=OPTS)
|
1182
1197
|
if block_given? # perform locking inside a transaction and yield to block
|
1183
1198
|
@db.transaction(opts){lock(mode, opts); yield}
|
1184
1199
|
else
|
@@ -1186,7 +1201,7 @@ module Sequel
|
|
1186
1201
|
source_list_append(sql, @opts[:from])
|
1187
1202
|
mode = mode.to_s.upcase.strip
|
1188
1203
|
unless LOCK_MODES.include?(mode)
|
1189
|
-
|
1204
|
+
raise Error, "Unsupported lock mode: #{mode}"
|
1190
1205
|
end
|
1191
1206
|
sql << " IN #{mode} MODE"
|
1192
1207
|
@db.execute(sql, opts)
|
@@ -1252,7 +1267,7 @@ module Sequel
|
|
1252
1267
|
# # => nil
|
1253
1268
|
# DB[:table].truncate(:cascade => true, :only=>true, :restart=>true) # TRUNCATE TABLE ONLY "table" RESTART IDENTITY CASCADE
|
1254
1269
|
# # => nil
|
1255
|
-
def truncate(opts =
|
1270
|
+
def truncate(opts = OPTS)
|
1256
1271
|
if opts.empty?
|
1257
1272
|
super()
|
1258
1273
|
else
|
@@ -1271,7 +1286,7 @@ module Sequel
|
|
1271
1286
|
# dataset. If RETURNING is already set, use existing returning values. If RETURNING
|
1272
1287
|
# is only set to return a single columns, return an array of just that column.
|
1273
1288
|
# Otherwise, return an array of hashes.
|
1274
|
-
def _import(columns, values, opts=
|
1289
|
+
def _import(columns, values, opts=OPTS)
|
1275
1290
|
if @opts[:returning]
|
1276
1291
|
statements = multi_insert_sql(columns, values)
|
1277
1292
|
@db.transaction(opts.merge(:server=>@opts[:server])) do
|