sequel 3.21.0 → 3.36.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 +855 -3
- data/MIT-LICENSE +1 -1
- data/README.rdoc +23 -7
- data/Rakefile +42 -24
- data/bin/sequel +26 -8
- data/doc/active_record.rdoc +1 -0
- data/doc/advanced_associations.rdoc +171 -11
- data/doc/association_basics.rdoc +293 -43
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +8 -0
- data/doc/mass_assignment.rdoc +56 -0
- data/doc/migration.rdoc +85 -552
- data/doc/model_hooks.rdoc +78 -27
- data/doc/object_model.rdoc +541 -0
- data/doc/opening_databases.rdoc +97 -50
- data/doc/prepared_statements.rdoc +40 -14
- data/doc/querying.rdoc +28 -4
- data/doc/reflection.rdoc +30 -4
- 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/release_notes/3.30.0.txt +135 -0
- data/doc/release_notes/3.31.0.txt +146 -0
- data/doc/release_notes/3.32.0.txt +202 -0
- data/doc/release_notes/3.33.0.txt +157 -0
- data/doc/release_notes/3.34.0.txt +671 -0
- data/doc/release_notes/3.35.0.txt +144 -0
- data/doc/release_notes/3.36.0.txt +245 -0
- data/doc/schema_modification.rdoc +572 -0
- data/doc/sharding.rdoc +95 -3
- data/doc/testing.rdoc +129 -0
- data/doc/thread_safety.rdoc +17 -0
- data/doc/transactions.rdoc +137 -0
- data/doc/virtual_rows.rdoc +51 -2
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/ado.rb +40 -18
- data/lib/sequel/adapters/amalgalite.rb +17 -9
- data/lib/sequel/adapters/db2.rb +175 -86
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do/mysql.rb +17 -11
- data/lib/sequel/adapters/do/postgres.rb +1 -57
- data/lib/sequel/adapters/do/sqlite.rb +0 -10
- data/lib/sequel/adapters/do.rb +18 -36
- data/lib/sequel/adapters/firebird.rb +27 -208
- data/lib/sequel/adapters/ibmdb.rb +453 -0
- data/lib/sequel/adapters/informix.rb +6 -23
- data/lib/sequel/adapters/jdbc/as400.rb +16 -34
- data/lib/sequel/adapters/jdbc/db2.rb +47 -0
- data/lib/sequel/adapters/jdbc/derby.rb +287 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +24 -0
- data/lib/sequel/adapters/jdbc/h2.rb +73 -31
- data/lib/sequel/adapters/jdbc/hsqldb.rb +184 -0
- data/lib/sequel/adapters/jdbc/informix.rb +21 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +29 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +3 -33
- data/lib/sequel/adapters/jdbc/mysql.rb +7 -24
- data/lib/sequel/adapters/jdbc/oracle.rb +88 -25
- data/lib/sequel/adapters/jdbc/postgresql.rb +58 -48
- data/lib/sequel/adapters/jdbc/progress.rb +21 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +20 -10
- data/lib/sequel/adapters/jdbc/sqlserver.rb +66 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +83 -0
- data/lib/sequel/adapters/jdbc.rb +265 -94
- data/lib/sequel/adapters/mock.rb +361 -0
- data/lib/sequel/adapters/mysql.rb +118 -222
- data/lib/sequel/adapters/mysql2.rb +58 -57
- data/lib/sequel/adapters/odbc/mssql.rb +15 -7
- data/lib/sequel/adapters/odbc.rb +28 -9
- data/lib/sequel/adapters/openbase.rb +3 -5
- data/lib/sequel/adapters/oracle.rb +349 -53
- data/lib/sequel/adapters/postgres.rb +356 -107
- data/lib/sequel/adapters/shared/access.rb +32 -9
- data/lib/sequel/adapters/shared/db2.rb +342 -0
- data/lib/sequel/adapters/shared/firebird.rb +221 -0
- data/lib/sequel/adapters/shared/informix.rb +53 -0
- data/lib/sequel/adapters/shared/mssql.rb +335 -118
- data/lib/sequel/adapters/shared/mysql.rb +340 -76
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +155 -0
- data/lib/sequel/adapters/shared/oracle.rb +243 -45
- data/lib/sequel/adapters/shared/postgres.rb +524 -279
- data/lib/sequel/adapters/shared/progress.rb +5 -8
- data/lib/sequel/adapters/shared/sqlite.rb +265 -89
- data/lib/sequel/adapters/sqlite.rb +101 -39
- data/lib/sequel/adapters/swift/mysql.rb +9 -12
- data/lib/sequel/adapters/swift/postgres.rb +9 -74
- data/lib/sequel/adapters/swift/sqlite.rb +8 -6
- data/lib/sequel/adapters/swift.rb +8 -7
- data/lib/sequel/adapters/tinytds.rb +161 -21
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +66 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
- data/lib/sequel/ast_transformer.rb +194 -0
- data/lib/sequel/connection_pool/sharded_single.rb +11 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +28 -2
- data/lib/sequel/connection_pool/single.rb +5 -0
- data/lib/sequel/connection_pool/threaded.rb +38 -14
- data/lib/sequel/connection_pool.rb +10 -2
- data/lib/sequel/core.rb +118 -11
- data/lib/sequel/database/connecting.rb +38 -28
- data/lib/sequel/database/dataset.rb +4 -4
- data/lib/sequel/database/dataset_defaults.rb +63 -2
- data/lib/sequel/database/logging.rb +7 -2
- data/lib/sequel/database/misc.rb +150 -46
- data/lib/sequel/database/query.rb +215 -65
- data/lib/sequel/database/schema_generator.rb +64 -20
- data/lib/sequel/database/schema_methods.rb +212 -54
- data/lib/sequel/dataset/actions.rb +322 -85
- data/lib/sequel/dataset/features.rb +96 -8
- data/lib/sequel/dataset/graph.rb +38 -11
- data/lib/sequel/dataset/misc.rb +50 -23
- data/lib/sequel/dataset/mutation.rb +12 -7
- data/lib/sequel/dataset/prepared_statements.rb +68 -30
- data/lib/sequel/dataset/query.rb +237 -44
- data/lib/sequel/dataset/sql.rb +698 -278
- data/lib/sequel/dataset.rb +8 -0
- data/lib/sequel/exceptions.rb +4 -0
- data/lib/sequel/extensions/_pretty_table.rb +79 -0
- data/lib/sequel/extensions/arbitrary_servers.rb +108 -0
- data/lib/sequel/extensions/columns_introspection.rb +61 -0
- data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +16 -34
- data/lib/sequel/extensions/migration.rb +97 -11
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/null_dataset.rb +90 -0
- data/lib/sequel/extensions/pg_array.rb +460 -0
- data/lib/sequel/extensions/pg_array_ops.rb +220 -0
- data/lib/sequel/extensions/pg_auto_parameterize.rb +169 -0
- data/lib/sequel/extensions/pg_hstore.rb +296 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
- data/lib/sequel/extensions/pg_inet.rb +89 -0
- data/lib/sequel/extensions/pg_json.rb +178 -0
- data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
- data/lib/sequel/extensions/pretty_table.rb +5 -71
- data/lib/sequel/extensions/query.rb +1 -1
- data/lib/sequel/extensions/query_literals.rb +79 -0
- data/lib/sequel/extensions/schema_caching.rb +76 -0
- data/lib/sequel/extensions/schema_dumper.rb +251 -37
- data/lib/sequel/extensions/select_remove.rb +35 -0
- data/lib/sequel/extensions/server_block.rb +139 -0
- data/lib/sequel/extensions/sql_expr.rb +4 -110
- 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 +1187 -393
- data/lib/sequel/model/base.rb +578 -170
- data/lib/sequel/model/errors.rb +1 -1
- data/lib/sequel/model/exceptions.rb +5 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model.rb +30 -11
- data/lib/sequel/no_core_ext.rb +2 -0
- data/lib/sequel/plugins/active_model.rb +13 -1
- data/lib/sequel/plugins/association_pks.rb +22 -4
- data/lib/sequel/plugins/caching.rb +25 -18
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/composition.rb +44 -12
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/defaults_setter.rb +58 -0
- data/lib/sequel/plugins/dirty.rb +214 -0
- data/lib/sequel/plugins/eager_each.rb +59 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/identity_map.rb +123 -8
- data/lib/sequel/plugins/instance_filters.rb +10 -0
- data/lib/sequel/plugins/instance_hooks.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +58 -6
- data/lib/sequel/plugins/list.rb +12 -2
- data/lib/sequel/plugins/many_through_many.rb +79 -28
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
- data/lib/sequel/plugins/nested_attributes.rb +139 -63
- data/lib/sequel/plugins/optimistic_locking.rb +8 -0
- data/lib/sequel/plugins/prepared_statements.rb +167 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +87 -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/schema.rb +7 -2
- data/lib/sequel/plugins/serialization.rb +98 -49
- data/lib/sequel/plugins/serialization_modification_detection.rb +63 -0
- data/lib/sequel/plugins/sharding.rb +21 -54
- data/lib/sequel/plugins/single_table_inheritance.rb +5 -3
- data/lib/sequel/plugins/static_cache.rb +99 -0
- data/lib/sequel/plugins/subclasses.rb +10 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -7
- data/lib/sequel/plugins/timestamps.rb +1 -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/validation_class_methods.rb +1 -1
- data/lib/sequel/plugins/xml_serializer.rb +15 -4
- data/lib/sequel/sql.rb +526 -59
- data/lib/sequel/timezones.rb +57 -38
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/db2_spec.rb +146 -0
- data/spec/adapters/firebird_spec.rb +1 -1
- data/spec/adapters/mssql_spec.rb +142 -40
- data/spec/adapters/mysql_spec.rb +380 -234
- data/spec/adapters/oracle_spec.rb +67 -77
- data/spec/adapters/postgres_spec.rb +1050 -212
- data/spec/adapters/spec_helper.rb +8 -5
- data/spec/adapters/sqlite_spec.rb +139 -27
- data/spec/core/connection_pool_spec.rb +196 -93
- data/spec/core/database_spec.rb +879 -510
- data/spec/core/dataset_spec.rb +1415 -1086
- data/spec/core/expression_filters_spec.rb +554 -109
- data/spec/core/mock_adapter_spec.rb +449 -0
- data/spec/core/object_graph_spec.rb +86 -114
- data/spec/core/schema_generator_spec.rb +4 -4
- data/spec/core/schema_spec.rb +482 -38
- data/spec/core/spec_helper.rb +6 -48
- data/spec/extensions/active_model_spec.rb +13 -0
- data/spec/extensions/arbitrary_servers_spec.rb +110 -0
- data/spec/extensions/association_autoreloading_spec.rb +18 -10
- data/spec/extensions/association_dependencies_spec.rb +15 -25
- data/spec/extensions/association_pks_spec.rb +66 -32
- data/spec/extensions/association_proxies_spec.rb +4 -4
- data/spec/extensions/caching_spec.rb +47 -51
- data/spec/extensions/class_table_inheritance_spec.rb +31 -83
- data/spec/extensions/columns_introspection_spec.rb +91 -0
- data/spec/extensions/composition_spec.rb +18 -13
- data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +119 -139
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/defaults_setter_spec.rb +64 -0
- data/spec/extensions/dirty_spec.rb +155 -0
- data/spec/extensions/eager_each_spec.rb +34 -0
- data/spec/extensions/force_encoding_spec.rb +4 -2
- data/spec/extensions/hook_class_methods_spec.rb +69 -92
- data/spec/extensions/identity_map_spec.rb +131 -22
- data/spec/extensions/inflector_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +11 -21
- data/spec/extensions/instance_hooks_spec.rb +72 -0
- data/spec/extensions/json_serializer_spec.rb +49 -6
- data/spec/extensions/lazy_attributes_spec.rb +16 -20
- data/spec/extensions/list_spec.rb +48 -39
- data/spec/extensions/many_through_many_spec.rb +283 -250
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
- data/spec/extensions/migration_spec.rb +140 -35
- data/spec/extensions/named_timezones_spec.rb +29 -11
- data/spec/extensions/nested_attributes_spec.rb +251 -89
- data/spec/extensions/null_dataset_spec.rb +85 -0
- data/spec/extensions/optimistic_locking_spec.rb +24 -21
- data/spec/extensions/pg_array_ops_spec.rb +105 -0
- data/spec/extensions/pg_array_spec.rb +196 -0
- data/spec/extensions/pg_auto_parameterize_spec.rb +65 -0
- data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
- data/spec/extensions/pg_hstore_spec.rb +195 -0
- data/spec/extensions/pg_inet_spec.rb +44 -0
- data/spec/extensions/pg_json_spec.rb +101 -0
- data/spec/extensions/pg_statement_cache_spec.rb +209 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +111 -0
- data/spec/extensions/prepared_statements_safe_spec.rb +61 -0
- data/spec/extensions/prepared_statements_spec.rb +87 -0
- data/spec/extensions/prepared_statements_with_pk_spec.rb +31 -0
- data/spec/extensions/pretty_table_spec.rb +7 -6
- data/spec/extensions/query_literals_spec.rb +168 -0
- data/spec/extensions/query_spec.rb +6 -0
- data/spec/extensions/rcte_tree_spec.rb +50 -43
- data/spec/extensions/schema_caching_spec.rb +41 -0
- data/spec/extensions/schema_dumper_spec.rb +429 -22
- data/spec/extensions/schema_spec.rb +25 -21
- data/spec/extensions/select_remove_spec.rb +38 -0
- data/spec/extensions/serialization_modification_detection_spec.rb +72 -0
- data/spec/extensions/serialization_spec.rb +85 -43
- data/spec/extensions/server_block_spec.rb +90 -0
- data/spec/extensions/sharding_spec.rb +69 -143
- data/spec/extensions/single_table_inheritance_spec.rb +23 -29
- data/spec/extensions/skip_create_refresh_spec.rb +1 -1
- data/spec/extensions/spec_helper.rb +22 -61
- data/spec/extensions/sql_expr_spec.rb +29 -60
- data/spec/extensions/static_cache_spec.rb +145 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +17 -19
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/timestamps_spec.rb +6 -6
- data/spec/extensions/to_dot_spec.rb +4 -7
- data/spec/extensions/touch_spec.rb +13 -14
- data/spec/extensions/tree_spec.rb +11 -26
- data/spec/extensions/typecast_on_load_spec.rb +9 -6
- data/spec/extensions/update_primary_key_spec.rb +30 -24
- data/spec/extensions/validation_class_methods_spec.rb +30 -51
- data/spec/extensions/validation_helpers_spec.rb +16 -35
- data/spec/extensions/xml_serializer_spec.rb +29 -4
- data/spec/files/transaction_specified_migrations/001_create_alt_basic.rb +4 -0
- data/spec/files/transaction_specified_migrations/002_create_basic.rb +4 -0
- data/spec/files/transaction_unspecified_migrations/001_create_alt_basic.rb +3 -0
- data/spec/files/transaction_unspecified_migrations/002_create_basic.rb +3 -0
- data/spec/integration/associations_test.rb +659 -21
- data/spec/integration/database_test.rb +9 -3
- data/spec/integration/dataset_test.rb +605 -91
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/migrator_test.rb +2 -3
- data/spec/integration/model_test.rb +81 -2
- data/spec/integration/plugin_test.rb +454 -143
- data/spec/integration/prepared_statement_test.rb +263 -128
- data/spec/integration/schema_test.rb +309 -43
- data/spec/integration/spec_helper.rb +40 -30
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +183 -8
- data/spec/integration/type_test.rb +18 -4
- data/spec/model/association_reflection_spec.rb +201 -7
- data/spec/model/associations_spec.rb +1067 -661
- data/spec/model/base_spec.rb +329 -95
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +677 -676
- data/spec/model/hooks_spec.rb +349 -67
- data/spec/model/model_spec.rb +240 -168
- data/spec/model/plugins_spec.rb +24 -13
- data/spec/model/record_spec.rb +490 -232
- data/spec/model/spec_helper.rb +14 -71
- data/spec/model/validations_spec.rb +11 -0
- data/spec/rcov.opts +2 -0
- metadata +178 -80
|
@@ -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
|
|
|
@@ -35,11 +35,19 @@ module Sequel
|
|
|
35
35
|
# Database#transaction, as on MSSQL if affects all future transactions
|
|
36
36
|
# on the same connection.
|
|
37
37
|
attr_accessor :transaction_isolation_level
|
|
38
|
+
|
|
39
|
+
# Whether the schema should be cached for this database. True by default
|
|
40
|
+
# for performance, can be set to false to always issue a database query to
|
|
41
|
+
# get the schema.
|
|
42
|
+
attr_accessor :cache_schema
|
|
38
43
|
|
|
39
44
|
# Runs the supplied SQL statement string on the database server.
|
|
40
|
-
#
|
|
45
|
+
# Returns self so it can be safely chained:
|
|
46
|
+
#
|
|
47
|
+
# DB << "UPDATE albums SET artist_id = NULL" << "DROP TABLE artists"
|
|
41
48
|
def <<(sql)
|
|
42
49
|
run(sql)
|
|
50
|
+
self
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
# Call the prepared statement with the given name with the given hash
|
|
@@ -47,8 +55,8 @@ module Sequel
|
|
|
47
55
|
#
|
|
48
56
|
# DB[:items].filter(:id=>1).prepare(:first, :sa)
|
|
49
57
|
# DB.call(:sa) # SELECT * FROM items WHERE id = 1
|
|
50
|
-
def call(ps_name, hash={})
|
|
51
|
-
|
|
58
|
+
def call(ps_name, hash={}, &block)
|
|
59
|
+
prepared_statement(ps_name).call(hash, &block)
|
|
52
60
|
end
|
|
53
61
|
|
|
54
62
|
# Executes the given SQL on the database. This method should be overridden in descendants.
|
|
@@ -78,16 +86,34 @@ module Sequel
|
|
|
78
86
|
execute_dui(sql, opts, &block)
|
|
79
87
|
end
|
|
80
88
|
|
|
89
|
+
# Returns an array of hashes containing foreign key information from the
|
|
90
|
+
# table. Each hash will contain at least the following fields:
|
|
91
|
+
#
|
|
92
|
+
# :columns :: An array of columns in the given table
|
|
93
|
+
# :table :: The table referenced by the columns
|
|
94
|
+
# :key :: An array of columns referenced (in the table specified by :table),
|
|
95
|
+
# but can be nil on certain adapters if the primary key is referenced.
|
|
96
|
+
#
|
|
97
|
+
# The hash may also contain entries for:
|
|
98
|
+
#
|
|
99
|
+
# :deferrable :: Whether the constraint is deferrable
|
|
100
|
+
# :name :: The name of the constraint
|
|
101
|
+
# :on_delete :: The action to take ON DELETE
|
|
102
|
+
# :on_update :: The action to take ON UPDATE
|
|
103
|
+
def foreign_key_list(table, opts={})
|
|
104
|
+
raise NotImplemented, "#foreign_key_list should be overridden by adapters"
|
|
105
|
+
end
|
|
106
|
+
|
|
81
107
|
# Returns a single value from the database, e.g.:
|
|
82
108
|
#
|
|
83
109
|
# DB.get(1) # SELECT 1
|
|
84
110
|
# # => 1
|
|
85
|
-
# DB.get{
|
|
111
|
+
# DB.get{server_version{}} # SELECT server_version()
|
|
86
112
|
def get(*args, &block)
|
|
87
113
|
dataset.get(*args, &block)
|
|
88
114
|
end
|
|
89
115
|
|
|
90
|
-
# Return a hash containing index information. Hash keys are index name symbols.
|
|
116
|
+
# Return a hash containing index information for the table. Hash keys are index name symbols.
|
|
91
117
|
# Values are subhashes with two keys, :columns and :unique. The value of :columns
|
|
92
118
|
# is an array of symbols of column names. The value of :unique is true or false
|
|
93
119
|
# depending on if the index is unique.
|
|
@@ -110,17 +136,17 @@ module Sequel
|
|
|
110
136
|
nil
|
|
111
137
|
end
|
|
112
138
|
|
|
113
|
-
# Parse the schema from the database.
|
|
114
139
|
# Returns the schema for the given table as an array with all members being arrays of length 2,
|
|
115
140
|
# the first member being the column name, and the second member being a hash of column information.
|
|
141
|
+
# The table argument can also be a dataset, as long as it only has one table.
|
|
116
142
|
# Available options are:
|
|
117
143
|
#
|
|
118
144
|
# :reload :: Ignore any cached results, and get fresh information from the database.
|
|
119
145
|
# :schema :: An explicit schema to use. It may also be implicitly provided
|
|
120
146
|
# via the table name.
|
|
121
147
|
#
|
|
122
|
-
# If schema parsing is supported by the database, the column information should at least contain the
|
|
123
|
-
# following
|
|
148
|
+
# If schema parsing is supported by the database, the column information should hash at least contain the
|
|
149
|
+
# following entries:
|
|
124
150
|
#
|
|
125
151
|
# :allow_null :: Whether NULL is an allowed value for the column.
|
|
126
152
|
# :db_type :: The database type for the column, as a database specific string.
|
|
@@ -129,7 +155,8 @@ module Sequel
|
|
|
129
155
|
# it means that primary key information is unavailable, not that the column
|
|
130
156
|
# is not a primary key.
|
|
131
157
|
# :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
|
|
158
|
+
# database defaults cannot be parsed into ruby objects, in which case nil will be
|
|
159
|
+
# used as the value.
|
|
133
160
|
# :type :: A symbol specifying the type, such as :integer or :string.
|
|
134
161
|
#
|
|
135
162
|
# Example:
|
|
@@ -152,32 +179,48 @@ module Sequel
|
|
|
152
179
|
def schema(table, opts={})
|
|
153
180
|
raise(Error, 'schema parsing is not implemented on this database') unless respond_to?(:schema_parse_table, true)
|
|
154
181
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
182
|
+
opts = opts.dup
|
|
183
|
+
if table.is_a?(Dataset)
|
|
184
|
+
o = table.opts
|
|
185
|
+
from = o[:from]
|
|
186
|
+
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)
|
|
187
|
+
tab = table.first_source_table
|
|
188
|
+
sch, table_name = schema_and_table(tab)
|
|
189
|
+
quoted_name = table.literal(tab)
|
|
190
|
+
opts[:dataset] = table
|
|
191
|
+
else
|
|
192
|
+
sch, table_name = schema_and_table(table)
|
|
193
|
+
quoted_name = quote_schema_table(table)
|
|
194
|
+
end
|
|
195
|
+
opts[:schema] = sch if sch && !opts.include?(:schema)
|
|
158
196
|
|
|
159
|
-
@schemas.delete(quoted_name) if opts[:reload]
|
|
160
|
-
return @schemas[quoted_name] if @schemas[quoted_name]
|
|
197
|
+
Sequel.synchronize{@schemas.delete(quoted_name)} if opts[:reload]
|
|
198
|
+
return Sequel.synchronize{@schemas[quoted_name]} if @schemas[quoted_name]
|
|
161
199
|
|
|
162
200
|
cols = schema_parse_table(table_name, opts)
|
|
163
201
|
raise(Error, 'schema parsing returned no columns, table probably doesn\'t exist') if cols.nil? || cols.empty?
|
|
164
202
|
cols.each{|_,c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
|
|
165
|
-
@schemas[quoted_name] = cols
|
|
203
|
+
Sequel.synchronize{@schemas[quoted_name] = cols} if cache_schema
|
|
204
|
+
cols
|
|
166
205
|
end
|
|
167
206
|
|
|
168
207
|
# Returns true if a table with the given name exists. This requires a query
|
|
169
208
|
# to the database.
|
|
170
209
|
#
|
|
171
210
|
# DB.table_exists?(:foo) # => false
|
|
211
|
+
# # SELECT NULL FROM foo LIMIT 1
|
|
212
|
+
#
|
|
213
|
+
# Note that since this does a SELECT from the table, it can give false negatives
|
|
214
|
+
# if you don't have permission to SELECT from the table.
|
|
172
215
|
def table_exists?(name)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
216
|
+
sch, table_name = schema_and_table(name)
|
|
217
|
+
name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
|
|
218
|
+
_table_exists?(from(name))
|
|
219
|
+
true
|
|
220
|
+
rescue DatabaseError
|
|
221
|
+
false
|
|
179
222
|
end
|
|
180
|
-
|
|
223
|
+
|
|
181
224
|
# Return all tables in the database as an array of symbols.
|
|
182
225
|
#
|
|
183
226
|
# DB.tables # => [:albums, :artists]
|
|
@@ -189,7 +232,7 @@ module Sequel
|
|
|
189
232
|
# either all statements are successful or none of the statements are
|
|
190
233
|
# successful. Note that MySQL MyISAM tabels do not support transactions.
|
|
191
234
|
#
|
|
192
|
-
# The following options are respected:
|
|
235
|
+
# The following general options are respected:
|
|
193
236
|
#
|
|
194
237
|
# :isolation :: The transaction isolation level to use for this transaction,
|
|
195
238
|
# should be :uncommitted, :committed, :repeatable, or :serializable,
|
|
@@ -198,11 +241,22 @@ module Sequel
|
|
|
198
241
|
# :prepare :: A string to use as the transaction identifier for a
|
|
199
242
|
# prepared transaction (two-phase commit), if the database/adapter
|
|
200
243
|
# supports prepared transactions.
|
|
244
|
+
# :rollback :: Can the set to :reraise to reraise any Sequel::Rollback exceptions
|
|
245
|
+
# raised, or :always to always rollback even if no exceptions occur
|
|
246
|
+
# (useful for testing).
|
|
201
247
|
# :server :: The server to use for the transaction.
|
|
202
248
|
# :savepoint :: Whether to create a new savepoint for this transaction,
|
|
203
249
|
# only respected if the database/adapter supports savepoints. By
|
|
204
250
|
# default Sequel will reuse an existing transaction, so if you want to
|
|
205
251
|
# use a savepoint you must use this option.
|
|
252
|
+
#
|
|
253
|
+
# PostgreSQL specific options:
|
|
254
|
+
#
|
|
255
|
+
# :deferrable :: (9.1+) If present, set to DEFERRABLE if true or NOT DEFERRABLE if false.
|
|
256
|
+
# :read_only :: If present, set to READ ONLY if true or READ WRITE if false.
|
|
257
|
+
# :synchronous :: if non-nil, set synchronous_commit
|
|
258
|
+
# appropriately. Valid values true, :on, false, :off, :local (9.1+),
|
|
259
|
+
# and :remote_write (9.2+).
|
|
206
260
|
def transaction(opts={}, &block)
|
|
207
261
|
synchronize(opts[:server]) do |conn|
|
|
208
262
|
return yield(conn) if already_in_transaction?(conn, opts)
|
|
@@ -210,47 +264,99 @@ module Sequel
|
|
|
210
264
|
end
|
|
211
265
|
end
|
|
212
266
|
|
|
267
|
+
# Return all views in the database as an array of symbols.
|
|
268
|
+
#
|
|
269
|
+
# DB.views # => [:gold_albums, :artists_with_many_albums]
|
|
270
|
+
def views(opts={})
|
|
271
|
+
raise NotImplemented, "#views should be overridden by adapters"
|
|
272
|
+
end
|
|
273
|
+
|
|
213
274
|
private
|
|
214
275
|
|
|
276
|
+
# Should raise an error if the table doesn't not exist,
|
|
277
|
+
# and not raise an error if the table does exist.
|
|
278
|
+
def _table_exists?(ds)
|
|
279
|
+
ds.get(Sequel::NULL)
|
|
280
|
+
end
|
|
281
|
+
|
|
215
282
|
# Internal generic transaction method. Any exception raised by the given
|
|
216
283
|
# block will cause the transaction to be rolled back. If the exception is
|
|
217
284
|
# not a Sequel::Rollback, the error will be reraised. If no exception occurs
|
|
218
285
|
# inside the block, the transaction is commited.
|
|
219
286
|
def _transaction(conn, opts={})
|
|
287
|
+
rollback = opts[:rollback]
|
|
220
288
|
begin
|
|
221
|
-
add_transaction
|
|
222
|
-
|
|
223
|
-
|
|
289
|
+
add_transaction(conn, opts)
|
|
290
|
+
begin_transaction(conn, opts)
|
|
291
|
+
if rollback == :always
|
|
292
|
+
begin
|
|
293
|
+
yield(conn)
|
|
294
|
+
rescue Exception => e1
|
|
295
|
+
raise e1
|
|
296
|
+
ensure
|
|
297
|
+
raise ::Sequel::Rollback unless e1
|
|
298
|
+
end
|
|
299
|
+
else
|
|
300
|
+
yield(conn)
|
|
301
|
+
end
|
|
224
302
|
rescue Exception => e
|
|
225
|
-
|
|
226
|
-
|
|
303
|
+
begin
|
|
304
|
+
rollback_transaction(conn, opts)
|
|
305
|
+
rescue Exception => e3
|
|
306
|
+
raise_error(e3, :classes=>database_error_classes, :conn=>conn)
|
|
307
|
+
end
|
|
308
|
+
transaction_error(e, :conn=>conn, :rollback=>rollback)
|
|
227
309
|
ensure
|
|
228
310
|
begin
|
|
229
|
-
|
|
230
|
-
rescue Exception =>
|
|
231
|
-
raise_error(
|
|
311
|
+
committed = commit_or_rollback_transaction(e, conn, opts)
|
|
312
|
+
rescue Exception => e2
|
|
313
|
+
raise_error(e2, :classes=>database_error_classes, :conn=>conn)
|
|
232
314
|
ensure
|
|
233
|
-
remove_transaction(
|
|
315
|
+
remove_transaction(conn, committed)
|
|
234
316
|
end
|
|
235
317
|
end
|
|
236
318
|
end
|
|
237
|
-
|
|
319
|
+
|
|
320
|
+
# Synchronize access to the current transactions, returning the hash
|
|
321
|
+
# of options for the current transaction (if any)
|
|
322
|
+
def _trans(conn)
|
|
323
|
+
Sequel.synchronize{@transactions[conn]}
|
|
324
|
+
end
|
|
325
|
+
|
|
238
326
|
# Add the current thread to the list of active transactions
|
|
239
|
-
def add_transaction
|
|
240
|
-
th = Thread.current
|
|
327
|
+
def add_transaction(conn, opts)
|
|
241
328
|
if supports_savepoints?
|
|
242
|
-
unless
|
|
243
|
-
|
|
244
|
-
|
|
329
|
+
unless _trans(conn)
|
|
330
|
+
if (prep = opts[:prepare]) && supports_prepared_transactions?
|
|
331
|
+
Sequel.synchronize{@transactions[conn] = {:savepoint_level=>0, :prepare=>prep}}
|
|
332
|
+
else
|
|
333
|
+
Sequel.synchronize{@transactions[conn] = {:savepoint_level=>0}}
|
|
334
|
+
end
|
|
245
335
|
end
|
|
336
|
+
elsif (prep = opts[:prepare]) && supports_prepared_transactions?
|
|
337
|
+
Sequel.synchronize{@transactions[conn] = {:prepare => prep}}
|
|
246
338
|
else
|
|
247
|
-
@transactions
|
|
339
|
+
Sequel.synchronize{@transactions[conn] = {}}
|
|
248
340
|
end
|
|
249
341
|
end
|
|
250
342
|
|
|
343
|
+
# Call all stored after_commit blocks for the given transaction
|
|
344
|
+
def after_transaction_commit(conn)
|
|
345
|
+
if ary = _trans(conn)[:after_commit]
|
|
346
|
+
ary.each{|b| b.call}
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Call all stored after_rollback blocks for the given transaction
|
|
351
|
+
def after_transaction_rollback(conn)
|
|
352
|
+
if ary = _trans(conn)[:after_rollback]
|
|
353
|
+
ary.each{|b| b.call}
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
251
357
|
# Whether the current thread/connection is already inside a transaction
|
|
252
358
|
def already_in_transaction?(conn, opts)
|
|
253
|
-
|
|
359
|
+
_trans(conn) && (!supports_savepoints? || !opts[:savepoint])
|
|
254
360
|
end
|
|
255
361
|
|
|
256
362
|
# SQL to start a new savepoint
|
|
@@ -267,17 +373,16 @@ module Sequel
|
|
|
267
373
|
# Start a new database transaction or a new savepoint on the given connection.
|
|
268
374
|
def begin_transaction(conn, opts={})
|
|
269
375
|
if supports_savepoints?
|
|
270
|
-
th =
|
|
271
|
-
if (depth = th[:
|
|
376
|
+
th = _trans(conn)
|
|
377
|
+
if (depth = th[:savepoint_level]) > 0
|
|
272
378
|
log_connection_execute(conn, begin_savepoint_sql(depth))
|
|
273
379
|
else
|
|
274
380
|
begin_new_transaction(conn, opts)
|
|
275
381
|
end
|
|
276
|
-
th[:
|
|
382
|
+
th[:savepoint_level] += 1
|
|
277
383
|
else
|
|
278
384
|
begin_new_transaction(conn, opts)
|
|
279
385
|
end
|
|
280
|
-
conn
|
|
281
386
|
end
|
|
282
387
|
|
|
283
388
|
# SQL to BEGIN a transaction.
|
|
@@ -335,6 +440,38 @@ module Sequel
|
|
|
335
440
|
end
|
|
336
441
|
end
|
|
337
442
|
|
|
443
|
+
if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or RUBY_ENGINE == 'rbx') and RUBY_VERSION < '1.9'
|
|
444
|
+
# Whether to commit the current transaction. On ruby 1.8 and rubinius,
|
|
445
|
+
# Thread.current.status is checked because Thread#kill skips rescue
|
|
446
|
+
# blocks (so exception would be nil), but the transaction should
|
|
447
|
+
# still be rolled back.
|
|
448
|
+
def commit_or_rollback_transaction(exception, conn, opts)
|
|
449
|
+
if exception
|
|
450
|
+
false
|
|
451
|
+
else
|
|
452
|
+
if Thread.current.status == 'aborting'
|
|
453
|
+
rollback_transaction(conn, opts)
|
|
454
|
+
false
|
|
455
|
+
else
|
|
456
|
+
commit_transaction(conn, opts)
|
|
457
|
+
true
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
else
|
|
462
|
+
# Whether to commit the current transaction. On ruby 1.9 and JRuby,
|
|
463
|
+
# transactions will be committed if Thread#kill is used on an thread
|
|
464
|
+
# that has a transaction open, and there isn't a work around.
|
|
465
|
+
def commit_or_rollback_transaction(exception, conn, opts)
|
|
466
|
+
if exception
|
|
467
|
+
false
|
|
468
|
+
else
|
|
469
|
+
commit_transaction(conn, opts)
|
|
470
|
+
true
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
|
|
338
475
|
# SQL to commit a savepoint
|
|
339
476
|
def commit_savepoint_sql(depth)
|
|
340
477
|
SQL_RELEASE_SAVEPOINT % depth
|
|
@@ -343,7 +480,7 @@ module Sequel
|
|
|
343
480
|
# Commit the active transaction on the connection
|
|
344
481
|
def commit_transaction(conn, opts={})
|
|
345
482
|
if supports_savepoints?
|
|
346
|
-
depth =
|
|
483
|
+
depth = _trans(conn)[:savepoint_level]
|
|
347
484
|
log_connection_execute(conn, depth > 1 ? commit_savepoint_sql(depth-1) : commit_transaction_sql)
|
|
348
485
|
else
|
|
349
486
|
log_connection_execute(conn, commit_transaction_sql)
|
|
@@ -364,8 +501,8 @@ module Sequel
|
|
|
364
501
|
# Return a Method object for the dataset's output_identifier_method.
|
|
365
502
|
# Used in metadata parsing to make sure the returned information is in the
|
|
366
503
|
# correct format.
|
|
367
|
-
def input_identifier_meth
|
|
368
|
-
dataset.method(:input_identifier)
|
|
504
|
+
def input_identifier_meth(ds=nil)
|
|
505
|
+
(ds || dataset).method(:input_identifier)
|
|
369
506
|
end
|
|
370
507
|
|
|
371
508
|
# Return a dataset that uses the default identifier input and output methods
|
|
@@ -382,24 +519,28 @@ module Sequel
|
|
|
382
519
|
# Return a Method object for the dataset's output_identifier_method.
|
|
383
520
|
# Used in metadata parsing to make sure the returned information is in the
|
|
384
521
|
# correct format.
|
|
385
|
-
def output_identifier_meth
|
|
386
|
-
dataset.method(:output_identifier)
|
|
522
|
+
def output_identifier_meth(ds=nil)
|
|
523
|
+
(ds || dataset).method(:output_identifier)
|
|
387
524
|
end
|
|
388
525
|
|
|
389
|
-
# SQL to ROLLBACK a transaction.
|
|
390
|
-
def rollback_transaction_sql
|
|
391
|
-
SQL_ROLLBACK
|
|
392
|
-
end
|
|
393
|
-
|
|
394
526
|
# Remove the cached schema for the given schema name
|
|
395
527
|
def remove_cached_schema(table)
|
|
396
528
|
@schemas.delete(quote_schema_table(table)) if @schemas
|
|
397
529
|
end
|
|
398
530
|
|
|
399
531
|
# Remove the current thread from the list of active transactions
|
|
400
|
-
def remove_transaction(conn)
|
|
401
|
-
|
|
402
|
-
|
|
532
|
+
def remove_transaction(conn, committed)
|
|
533
|
+
if !supports_savepoints? || ((_trans(conn)[:savepoint_level] -= 1) <= 0)
|
|
534
|
+
begin
|
|
535
|
+
if committed
|
|
536
|
+
after_transaction_commit(conn)
|
|
537
|
+
else
|
|
538
|
+
after_transaction_rollback(conn)
|
|
539
|
+
end
|
|
540
|
+
ensure
|
|
541
|
+
Sequel.synchronize{@transactions.delete(conn)}
|
|
542
|
+
end
|
|
543
|
+
end
|
|
403
544
|
end
|
|
404
545
|
|
|
405
546
|
# SQL to rollback to a savepoint
|
|
@@ -410,13 +551,18 @@ module Sequel
|
|
|
410
551
|
# Rollback the active transaction on the connection
|
|
411
552
|
def rollback_transaction(conn, opts={})
|
|
412
553
|
if supports_savepoints?
|
|
413
|
-
depth =
|
|
554
|
+
depth = _trans(conn)[:savepoint_level]
|
|
414
555
|
log_connection_execute(conn, depth > 1 ? rollback_savepoint_sql(depth-1) : rollback_transaction_sql)
|
|
415
556
|
else
|
|
416
557
|
log_connection_execute(conn, rollback_transaction_sql)
|
|
417
558
|
end
|
|
418
559
|
end
|
|
419
560
|
|
|
561
|
+
# SQL to ROLLBACK a transaction.
|
|
562
|
+
def rollback_transaction_sql
|
|
563
|
+
SQL_ROLLBACK
|
|
564
|
+
end
|
|
565
|
+
|
|
420
566
|
# Match the database's column type to a ruby type via a
|
|
421
567
|
# regular expression, and return the ruby type as a symbol
|
|
422
568
|
# such as :integer or :string.
|
|
@@ -434,13 +580,13 @@ module Sequel
|
|
|
434
580
|
:datetime
|
|
435
581
|
when /\Atime( with(out)? time zone)?\z/io
|
|
436
582
|
:time
|
|
437
|
-
when /\A(
|
|
583
|
+
when /\A(bool(ean)?)\z/io
|
|
438
584
|
:boolean
|
|
439
585
|
when /\A(real|float|double( precision)?)\z/io
|
|
440
586
|
:float
|
|
441
|
-
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(\d
|
|
442
|
-
$1 &&
|
|
443
|
-
when /bytea|
|
|
587
|
+
when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(\d+|false|true)\))?)|(?:small)?money)\z/io
|
|
588
|
+
$1 && ['0', 'false'].include?($1) ? :integer : :decimal
|
|
589
|
+
when /bytea|[bc]lob|image|(var)?binary/io
|
|
444
590
|
:blob
|
|
445
591
|
when /\Aenum/io
|
|
446
592
|
:enum
|
|
@@ -460,8 +606,12 @@ module Sequel
|
|
|
460
606
|
end
|
|
461
607
|
|
|
462
608
|
# Raise a database error unless the exception is an Rollback.
|
|
463
|
-
def transaction_error(e)
|
|
464
|
-
|
|
609
|
+
def transaction_error(e, opts={})
|
|
610
|
+
if e.is_a?(Rollback)
|
|
611
|
+
raise e if opts[:rollback] == :reraise
|
|
612
|
+
else
|
|
613
|
+
raise_error(e, opts.merge(:classes=>database_error_classes))
|
|
614
|
+
end
|
|
465
615
|
end
|
|
466
616
|
end
|
|
467
617
|
end
|
|
@@ -83,30 +83,28 @@ module Sequel
|
|
|
83
83
|
# reference table will use for its foreign key a value that does not
|
|
84
84
|
# exists(yet) on referenced table. Basically it adds
|
|
85
85
|
# DEFERRABLE INITIALLY DEFERRED on key creation.
|
|
86
|
-
# :index :: Create an index on this column.
|
|
86
|
+
# :index :: Create an index on this column. If given a hash, use the hash as the
|
|
87
|
+
# options for the index.
|
|
87
88
|
# :key :: For foreign key columns, the column in the associated table
|
|
88
89
|
# that this column references. Unnecessary if this column
|
|
89
|
-
# references the primary key of the associated table
|
|
90
|
+
# references the primary key of the associated table, except if you are
|
|
91
|
+
# using MySQL.
|
|
90
92
|
# :null :: Mark the column as allowing NULL values (if true),
|
|
91
93
|
# or not allowing NULL values (if false). If unspecified, will default
|
|
92
94
|
# to whatever the database default is.
|
|
93
95
|
# :on_delete :: Specify the behavior of this column when being deleted
|
|
94
|
-
# (:restrict, cascade, :set_null, :set_default, :no_action).
|
|
96
|
+
# (:restrict, :cascade, :set_null, :set_default, :no_action).
|
|
95
97
|
# :on_update :: Specify the behavior of this column when being updated
|
|
96
|
-
# (:restrict, cascade, :set_null, :set_default, :no_action).
|
|
98
|
+
# (:restrict, :cascade, :set_null, :set_default, :no_action).
|
|
97
99
|
# :primary_key :: Make the column as a single primary key column. This should only
|
|
98
100
|
# be used if you have a single, nonautoincrementing primary key column.
|
|
99
|
-
# :size :: The size of the column, generally used with string
|
|
100
|
-
# columns to specify the maximum number of characters the column will hold.
|
|
101
|
-
# An array of two integers can be provided to set the size and the
|
|
102
|
-
# precision, respectively, of decimal columns.
|
|
103
101
|
# :unique :: Mark the column as unique, generally has the same effect as
|
|
104
102
|
# creating a unique index on the column.
|
|
105
|
-
# :unsigned :: Make the column type unsigned, only useful for integer
|
|
106
|
-
# columns.
|
|
107
103
|
def column(name, type, opts = {})
|
|
108
104
|
columns << {:name => name, :type => type}.merge(opts)
|
|
109
|
-
|
|
105
|
+
if index_opts = opts[:index]
|
|
106
|
+
index(name, index_opts.is_a?(Hash) ? index_opts : {})
|
|
107
|
+
end
|
|
110
108
|
end
|
|
111
109
|
|
|
112
110
|
# Adds a named constraint (or unnamed if name is nil) to the DDL,
|
|
@@ -124,6 +122,13 @@ module Sequel
|
|
|
124
122
|
# foreign_key(:artist_id) # artist_id INTEGER
|
|
125
123
|
# foreign_key(:artist_id, :artists) # artist_id INTEGER REFERENCES artists
|
|
126
124
|
# foreign_key(:artist_id, :artists, :key=>:id) # artist_id INTEGER REFERENCES artists(id)
|
|
125
|
+
#
|
|
126
|
+
# If you want a foreign key constraint without adding a column (usually because it is a
|
|
127
|
+
# composite foreign key), you can provide an array of columns as the first argument, and
|
|
128
|
+
# you can provide the :name option to name the constraint:
|
|
129
|
+
#
|
|
130
|
+
# foreign_key([:artist_name, :artist_location], :artists, :name=>:artist_fk)
|
|
131
|
+
# # ADD CONSTRAINT artist_fk FOREIGN KEY (artist_name, artist_location) REFERENCES artists
|
|
127
132
|
def foreign_key(name, table=nil, opts = {})
|
|
128
133
|
opts = case table
|
|
129
134
|
when Hash
|
|
@@ -140,6 +145,12 @@ module Sequel
|
|
|
140
145
|
end
|
|
141
146
|
|
|
142
147
|
# Add a full text index on the given columns to the DDL.
|
|
148
|
+
#
|
|
149
|
+
# PostgreSQL specific options:
|
|
150
|
+
# :language :: Set a language to use for the index (default: simple).
|
|
151
|
+
#
|
|
152
|
+
# Microsoft SQL Server specific options:
|
|
153
|
+
# :key_index :: The KEY INDEX to use for the full text index.
|
|
143
154
|
def full_text_index(columns, opts = {})
|
|
144
155
|
index(columns, opts.merge(:type => :full_text))
|
|
145
156
|
end
|
|
@@ -150,12 +161,26 @@ module Sequel
|
|
|
150
161
|
end
|
|
151
162
|
|
|
152
163
|
# Add an index on the given column(s) with the given options to the DDL.
|
|
153
|
-
#
|
|
164
|
+
# General options:
|
|
154
165
|
#
|
|
166
|
+
# :name :: The name to use for the index. If not given, a default name
|
|
167
|
+
# based on the table and columns is used.
|
|
155
168
|
# :type :: The type of index to use (only supported by some databases)
|
|
156
169
|
# :unique :: Make the index unique, so duplicate values are not allowed.
|
|
157
170
|
# :where :: Create a partial index (only supported by some databases)
|
|
158
171
|
#
|
|
172
|
+
# PostgreSQL specific options:
|
|
173
|
+
#
|
|
174
|
+
# :concurrently :: Create the index concurrently, so it doesn't block
|
|
175
|
+
# operations on the table while the index is being
|
|
176
|
+
# built.
|
|
177
|
+
# :op_class :: Use a specific operator class in the index.
|
|
178
|
+
#
|
|
179
|
+
# Microsoft SQL Server specific options:
|
|
180
|
+
#
|
|
181
|
+
# :include :: Include additional column values in the index, without
|
|
182
|
+
# actually indexing on those values.
|
|
183
|
+
#
|
|
159
184
|
# index :name
|
|
160
185
|
# # CREATE INDEX table_name_index ON table (name)
|
|
161
186
|
#
|
|
@@ -281,8 +306,8 @@ module Sequel
|
|
|
281
306
|
# to the DDL for the table. See Generator#column for the available options.
|
|
282
307
|
#
|
|
283
308
|
# You can also pass an array of column names for creating composite foreign
|
|
284
|
-
# keys. In this case, it will assume the columns
|
|
285
|
-
# the constraint.
|
|
309
|
+
# keys. In this case, it will assume the columns exist and will only add
|
|
310
|
+
# the constraint. You can provide a :name option to name the constraint.
|
|
286
311
|
#
|
|
287
312
|
# NOTE: If you need to add a foreign key constraint to a single existing column
|
|
288
313
|
# use the composite key syntax even if it is only one column.
|
|
@@ -329,18 +354,33 @@ module Sequel
|
|
|
329
354
|
# Remove a column from the DDL for the table.
|
|
330
355
|
#
|
|
331
356
|
# drop_column(:artist_id) # DROP COLUMN artist_id
|
|
332
|
-
|
|
333
|
-
|
|
357
|
+
# drop_column(:artist_id, :cascade=>true) # DROP COLUMN artist_id CASCADE
|
|
358
|
+
def drop_column(name, opts={})
|
|
359
|
+
@operations << {:op => :drop_column, :name => name}.merge(opts)
|
|
334
360
|
end
|
|
335
361
|
|
|
336
|
-
# Remove a constraint from the DDL for the table.
|
|
362
|
+
# Remove a constraint from the DDL for the table. MySQL/SQLite specific options:
|
|
363
|
+
#
|
|
364
|
+
# :type :: Set the type of constraint to drop, either :primary_key, :foreign_key,
|
|
365
|
+
# or :unique.
|
|
337
366
|
#
|
|
338
367
|
# drop_constraint(:unique_name) # DROP CONSTRAINT unique_name
|
|
339
|
-
|
|
340
|
-
|
|
368
|
+
# drop_constraint(:unique_name, :cascade=>true) # DROP CONSTRAINT unique_name CASCADE
|
|
369
|
+
def drop_constraint(name, opts={})
|
|
370
|
+
@operations << {:op => :drop_constraint, :name => name}.merge(opts)
|
|
341
371
|
end
|
|
342
372
|
|
|
343
|
-
# Remove an index from the DDL for the table.
|
|
373
|
+
# Remove an index from the DDL for the table. General options:
|
|
374
|
+
#
|
|
375
|
+
# :name :: The name of the index to drop. If not given, uses the same name
|
|
376
|
+
# that would be used by add_index with the same columns.
|
|
377
|
+
#
|
|
378
|
+
# PostgreSQL specific options:
|
|
379
|
+
#
|
|
380
|
+
# :cascade :: Cascade the index drop to dependent objects.
|
|
381
|
+
# :concurrently :: Drop the index using CONCURRENTLY, which doesn't block
|
|
382
|
+
# operations on the table. Supported in PostgreSQL 9.2+.
|
|
383
|
+
# :if_exists :: Only drop the index if it already exists.
|
|
344
384
|
#
|
|
345
385
|
# drop_index(:artist_id) # DROP INDEX table_artist_id_index
|
|
346
386
|
# drop_index([:a, :b]) # DROP INDEX table_a_b_index
|
|
@@ -366,6 +406,10 @@ module Sequel
|
|
|
366
406
|
# Modify a column's type in the DDL for the table.
|
|
367
407
|
#
|
|
368
408
|
# set_column_type(:artist_name, 'char(10)') # ALTER COLUMN artist_name TYPE char(10)
|
|
409
|
+
#
|
|
410
|
+
# PostgreSQL specific options:
|
|
411
|
+
#
|
|
412
|
+
# :using :: Add a USING clause that specifies how to convert existing values to new values.
|
|
369
413
|
def set_column_type(name, type, opts={})
|
|
370
414
|
@operations << {:op => :set_column_type, :name => name, :type => type}.merge(opts)
|
|
371
415
|
end
|