sequel 3.47.0 → 3.48.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +230 -0
- data/README.rdoc +31 -40
- data/Rakefile +1 -14
- data/doc/active_record.rdoc +29 -29
- data/doc/association_basics.rdoc +4 -13
- data/doc/cheat_sheet.rdoc +8 -6
- data/doc/code_order.rdoc +89 -0
- data/doc/core_extensions.rdoc +3 -3
- data/doc/dataset_basics.rdoc +7 -8
- data/doc/dataset_filtering.rdoc +7 -2
- data/doc/mass_assignment.rdoc +2 -3
- data/doc/migration.rdoc +8 -8
- data/doc/model_hooks.rdoc +11 -7
- data/doc/object_model.rdoc +2 -2
- data/doc/opening_databases.rdoc +5 -14
- data/doc/prepared_statements.rdoc +5 -9
- data/doc/querying.rdoc +23 -28
- data/doc/reflection.rdoc +11 -0
- data/doc/release_notes/3.48.0.txt +477 -0
- data/doc/schema_modification.rdoc +12 -5
- data/doc/security.rdoc +2 -2
- data/doc/sharding.rdoc +1 -2
- data/doc/sql.rdoc +10 -13
- data/doc/testing.rdoc +8 -4
- data/doc/transactions.rdoc +2 -2
- data/doc/validations.rdoc +40 -17
- data/doc/virtual_rows.rdoc +2 -2
- data/lib/sequel/adapters/ado.rb +25 -20
- data/lib/sequel/adapters/ado/access.rb +1 -0
- data/lib/sequel/adapters/ado/mssql.rb +1 -0
- data/lib/sequel/adapters/db2.rb +9 -7
- data/lib/sequel/adapters/dbi.rb +16 -16
- data/lib/sequel/adapters/do.rb +17 -18
- data/lib/sequel/adapters/do/mysql.rb +1 -0
- data/lib/sequel/adapters/do/postgres.rb +2 -0
- data/lib/sequel/adapters/do/sqlite.rb +1 -0
- data/lib/sequel/adapters/firebird.rb +5 -7
- data/lib/sequel/adapters/ibmdb.rb +23 -20
- data/lib/sequel/adapters/informix.rb +8 -2
- data/lib/sequel/adapters/jdbc.rb +39 -35
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
- data/lib/sequel/adapters/jdbc/db2.rb +1 -0
- data/lib/sequel/adapters/jdbc/derby.rb +1 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +1 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
- data/lib/sequel/adapters/jdbc/informix.rb +1 -0
- data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
- data/lib/sequel/adapters/jdbc/progress.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
- data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
- data/lib/sequel/adapters/mock.rb +30 -31
- data/lib/sequel/adapters/mysql.rb +6 -7
- data/lib/sequel/adapters/mysql2.rb +5 -6
- data/lib/sequel/adapters/odbc.rb +22 -20
- data/lib/sequel/adapters/odbc/mssql.rb +1 -0
- data/lib/sequel/adapters/openbase.rb +4 -1
- data/lib/sequel/adapters/oracle.rb +10 -8
- data/lib/sequel/adapters/postgres.rb +12 -10
- data/lib/sequel/adapters/shared/access.rb +6 -0
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +14 -8
- data/lib/sequel/adapters/shared/mysql.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +2 -0
- data/lib/sequel/adapters/shared/postgres.rb +14 -4
- data/lib/sequel/adapters/shared/progress.rb +1 -0
- data/lib/sequel/adapters/shared/sqlite.rb +4 -3
- data/lib/sequel/adapters/sqlite.rb +6 -7
- data/lib/sequel/adapters/swift.rb +20 -21
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +2 -0
- data/lib/sequel/adapters/swift/sqlite.rb +1 -0
- data/lib/sequel/adapters/tinytds.rb +5 -6
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
- data/lib/sequel/connection_pool.rb +1 -1
- data/lib/sequel/core.rb +57 -50
- data/lib/sequel/database/connecting.rb +9 -10
- data/lib/sequel/database/dataset.rb +11 -6
- data/lib/sequel/database/dataset_defaults.rb +61 -69
- data/lib/sequel/database/features.rb +21 -0
- data/lib/sequel/database/misc.rb +23 -3
- data/lib/sequel/database/query.rb +13 -7
- data/lib/sequel/database/schema_methods.rb +6 -6
- data/lib/sequel/database/transactions.rb +1 -0
- data/lib/sequel/dataset/actions.rb +51 -38
- data/lib/sequel/dataset/features.rb +1 -0
- data/lib/sequel/dataset/graph.rb +9 -33
- data/lib/sequel/dataset/misc.rb +30 -5
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +91 -27
- data/lib/sequel/dataset/sql.rb +40 -6
- data/lib/sequel/deprecated.rb +74 -0
- data/lib/sequel/deprecated_core_extensions.rb +135 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -5
- data/lib/sequel/extensions/core_extensions.rb +10 -3
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
- data/lib/sequel/extensions/filter_having.rb +58 -0
- data/lib/sequel/extensions/graph_each.rb +63 -0
- data/lib/sequel/extensions/hash_aliases.rb +44 -0
- data/lib/sequel/extensions/looser_typecasting.rb +14 -3
- data/lib/sequel/extensions/migration.rb +2 -3
- data/lib/sequel/extensions/named_timezones.rb +14 -1
- data/lib/sequel/extensions/null_dataset.rb +7 -1
- data/lib/sequel/extensions/pagination.rb +15 -5
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
- data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
- data/lib/sequel/extensions/pg_json.rb +7 -7
- data/lib/sequel/extensions/pg_range_ops.rb +8 -2
- data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
- data/lib/sequel/extensions/pretty_table.rb +13 -4
- data/lib/sequel/extensions/query.rb +21 -4
- data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
- data/lib/sequel/extensions/schema_caching.rb +10 -7
- data/lib/sequel/extensions/schema_dumper.rb +35 -48
- data/lib/sequel/extensions/select_remove.rb +13 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
- data/lib/sequel/extensions/set_overrides.rb +43 -0
- data/lib/sequel/extensions/to_dot.rb +6 -0
- data/lib/sequel/model.rb +12 -6
- data/lib/sequel/model/associations.rb +80 -38
- data/lib/sequel/model/base.rb +137 -52
- data/lib/sequel/model/errors.rb +7 -2
- data/lib/sequel/plugins/active_model.rb +13 -0
- data/lib/sequel/plugins/after_initialize.rb +43 -0
- data/lib/sequel/plugins/association_proxies.rb +63 -7
- data/lib/sequel/plugins/auto_validations.rb +56 -16
- data/lib/sequel/plugins/blacklist_security.rb +63 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
- data/lib/sequel/plugins/constraint_validations.rb +50 -8
- data/lib/sequel/plugins/dataset_associations.rb +2 -0
- data/lib/sequel/plugins/hook_class_methods.rb +7 -1
- data/lib/sequel/plugins/identity_map.rb +4 -0
- data/lib/sequel/plugins/json_serializer.rb +32 -13
- data/lib/sequel/plugins/optimistic_locking.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +4 -4
- data/lib/sequel/plugins/scissors.rb +33 -0
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
- data/lib/sequel/plugins/tree.rb +5 -1
- data/lib/sequel/plugins/validation_class_methods.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +15 -11
- data/lib/sequel/plugins/xml_serializer.rb +12 -3
- data/lib/sequel/sql.rb +12 -2
- data/lib/sequel/timezones.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/mssql_spec.rb +24 -57
- data/spec/adapters/postgres_spec.rb +27 -55
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/bin_spec.rb +251 -0
- data/spec/core/database_spec.rb +46 -32
- data/spec/core/dataset_spec.rb +233 -181
- data/spec/core/deprecated_spec.rb +78 -0
- data/spec/core/expression_filters_spec.rb +3 -4
- data/spec/core/mock_adapter_spec.rb +9 -9
- data/spec/core/object_graph_spec.rb +9 -19
- data/spec/core/schema_spec.rb +3 -1
- data/spec/core/spec_helper.rb +19 -0
- data/spec/core_extensions_spec.rb +80 -30
- data/spec/extensions/after_initialize_spec.rb +24 -0
- data/spec/extensions/association_proxies_spec.rb +37 -1
- data/spec/extensions/auto_validations_spec.rb +20 -4
- data/spec/extensions/blacklist_security_spec.rb +87 -0
- data/spec/extensions/boolean_readers_spec.rb +2 -1
- data/spec/extensions/class_table_inheritance_spec.rb +7 -0
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
- data/spec/extensions/core_refinements_spec.rb +7 -7
- data/spec/extensions/dataset_associations_spec.rb +2 -2
- data/spec/extensions/date_arithmetic_spec.rb +1 -1
- data/spec/extensions/defaults_setter_spec.rb +2 -1
- data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
- data/spec/extensions/filter_having_spec.rb +40 -0
- data/spec/extensions/graph_each_spec.rb +109 -0
- data/spec/extensions/hash_aliases_spec.rb +16 -0
- data/spec/extensions/hook_class_methods_spec.rb +2 -2
- data/spec/extensions/identity_map_spec.rb +3 -3
- data/spec/extensions/json_serializer_spec.rb +19 -19
- data/spec/extensions/lazy_attributes_spec.rb +1 -0
- data/spec/extensions/list_spec.rb +13 -13
- data/spec/extensions/looser_typecasting_spec.rb +10 -3
- data/spec/extensions/many_through_many_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +7 -7
- data/spec/extensions/named_timezones_spec.rb +6 -0
- data/spec/extensions/nested_attributes_spec.rb +2 -2
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pagination_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
- data/spec/extensions/pg_range_ops_spec.rb +4 -2
- data/spec/extensions/pg_row_plugin_spec.rb +1 -1
- data/spec/extensions/pretty_table_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_caching_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +27 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/scissors_spec.rb +26 -0
- data/spec/extensions/select_remove_spec.rb +1 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
- data/spec/extensions/set_overrides_spec.rb +45 -0
- data/spec/extensions/single_table_inheritance_spec.rb +10 -0
- data/spec/extensions/spec_helper.rb +24 -1
- data/spec/extensions/static_cache_spec.rb +1 -1
- data/spec/extensions/string_stripper_spec.rb +2 -1
- data/spec/extensions/to_dot_spec.rb +1 -1
- data/spec/extensions/typecast_on_load_spec.rb +3 -2
- data/spec/extensions/update_primary_key_spec.rb +2 -2
- data/spec/extensions/validation_class_methods_spec.rb +19 -19
- data/spec/extensions/validation_helpers_spec.rb +30 -21
- data/spec/extensions/xml_serializer_spec.rb +5 -5
- data/spec/integration/associations_test.rb +10 -30
- data/spec/integration/dataset_test.rb +20 -24
- data/spec/integration/eager_loader_test.rb +5 -5
- data/spec/integration/model_test.rb +3 -3
- data/spec/integration/plugin_test.rb +7 -39
- data/spec/integration/schema_test.rb +4 -38
- data/spec/integration/spec_helper.rb +2 -1
- data/spec/model/association_reflection_spec.rb +70 -5
- data/spec/model/associations_spec.rb +11 -11
- data/spec/model/base_spec.rb +25 -8
- data/spec/model/class_dataset_methods_spec.rb +143 -0
- data/spec/model/dataset_methods_spec.rb +1 -1
- data/spec/model/eager_loading_spec.rb +25 -25
- data/spec/model/hooks_spec.rb +1 -1
- data/spec/model/model_spec.rb +22 -7
- data/spec/model/plugins_spec.rb +1 -6
- data/spec/model/record_spec.rb +37 -29
- data/spec/model/spec_helper.rb +23 -1
- data/spec/model/validations_spec.rb +15 -17
- metadata +32 -3
@@ -79,8 +79,14 @@ module Sequel
|
|
79
79
|
OPERATORS.keys.each do |f|
|
80
80
|
class_eval("def #{f}(v); operator(:#{f}, v) end", __FILE__, __LINE__)
|
81
81
|
end
|
82
|
-
|
83
|
-
|
82
|
+
def starts_before(v)
|
83
|
+
Sequel::Deprecation.deprecate('Postgres::PGRangeOp#starts_before', "Please switch to Postgres::PGRangeOp#ends_before")
|
84
|
+
ends_before(v)
|
85
|
+
end
|
86
|
+
def ends_after(v)
|
87
|
+
Sequel::Deprecation.deprecate('Postgres::PGRangeOp#ends_after', "Please switch to Postgres::PGRangeOp#starts_after")
|
88
|
+
starts_after(v)
|
89
|
+
end
|
84
90
|
|
85
91
|
# These operators are already supported by the wrapper, but for ranges they
|
86
92
|
# return ranges, so wrap the results in another RangeOp.
|
@@ -228,6 +228,7 @@ module Sequel
|
|
228
228
|
# Set the statement_cache for the connection, using the database's
|
229
229
|
# :statement_cache_opts option.
|
230
230
|
def self.extended(c)
|
231
|
+
Sequel::Deprecation.deprecate('The pg_statement_cache extension', 'Please stop loading it') unless defined?(SEQUEL_EXTENSIONS_NO_DEPRECATION_WARNING)
|
231
232
|
c.instance_variable_set(:@statement_cache, StatementCache.new(c.sequel_db.opts[:statement_cache_opts] || {}){|name| c.deallocate(name)})
|
232
233
|
end
|
233
234
|
|
@@ -9,22 +9,31 @@
|
|
9
9
|
# |2 |test |
|
10
10
|
# +--+-------+
|
11
11
|
#
|
12
|
-
#
|
12
|
+
# You can load this extension into specific datasets:
|
13
13
|
#
|
14
|
-
#
|
14
|
+
# ds = DB[:table]
|
15
|
+
# ds.extension(:pretty_table)
|
16
|
+
#
|
17
|
+
# Or you can load it into all of a database's datasets, which
|
18
|
+
# is probably the desired behavior if you are using this extension:
|
19
|
+
#
|
20
|
+
# DB.extension(:pretty_table)
|
15
21
|
|
16
22
|
module Sequel
|
17
23
|
extension :_pretty_table
|
18
24
|
|
25
|
+
module DatasetPrinter
|
26
|
+
end
|
27
|
+
|
19
28
|
class Dataset
|
20
29
|
# Pretty prints the records in the dataset as plain-text table.
|
21
30
|
def print(*cols)
|
31
|
+
Sequel::Deprecation.deprecate('Loading the pretty_table extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(DatasetPrinter)
|
22
32
|
ds = naked
|
23
33
|
rows = ds.all
|
24
34
|
Sequel::PrettyTable.print(rows, cols.empty? ? ds.columns : cols)
|
25
35
|
end
|
26
36
|
end
|
27
37
|
|
28
|
-
|
29
|
-
Dataset.register_extension(:pretty_table){}
|
38
|
+
Dataset.register_extension(:pretty_table, DatasetPrinter)
|
30
39
|
end
|
@@ -2,18 +2,34 @@
|
|
2
2
|
# a different way to construct queries instead of the usual
|
3
3
|
# method chaining. See Sequel::Dataset#query for details.
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# You can load this extension into specific datasets:
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# ds = DB[:table]
|
8
|
+
# ds.extension(:query)
|
9
|
+
#
|
10
|
+
# Or you can load it into all of a database's datasets, which
|
11
|
+
# is probably the desired behavior if you are using this extension:
|
12
|
+
#
|
13
|
+
# DB.extension(:query)
|
8
14
|
|
9
15
|
module Sequel
|
16
|
+
module DatabaseQuery
|
17
|
+
def self.extended(db)
|
18
|
+
db.extend_datasets(DatasetQuery)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
class Database
|
11
23
|
# Return a dataset modified by the query block
|
12
24
|
def query(&block)
|
25
|
+
Sequel::Deprecation.deprecate('Loading the query extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(DatabaseQuery)
|
13
26
|
dataset.query(&block)
|
14
27
|
end
|
15
28
|
end
|
16
29
|
|
30
|
+
module DatasetQuery
|
31
|
+
end
|
32
|
+
|
17
33
|
class Dataset
|
18
34
|
# Translates a query block into a dataset. Query blocks are an
|
19
35
|
# alternative to Sequel's usual method chaining, by using
|
@@ -29,6 +45,7 @@ module Sequel
|
|
29
45
|
#
|
30
46
|
# dataset = DB[:items].select(:x, :y, :z).filter{(x > 1) & (y > 2)}.reverse(:z)
|
31
47
|
def query(&block)
|
48
|
+
Sequel::Deprecation.deprecate('Loading the query extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(DatasetQuery)
|
32
49
|
query = Query.new(self)
|
33
50
|
query.instance_eval(&block)
|
34
51
|
query.dataset
|
@@ -52,6 +69,6 @@ module Sequel
|
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
55
|
-
Dataset.register_extension(:query)
|
56
|
-
Database.register_extension(:query)
|
72
|
+
Dataset.register_extension(:query, DatasetQuery)
|
73
|
+
Database.register_extension(:query, DatabaseQuery)
|
57
74
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# The ruby18_symbol_extensions adds the <, <=, >, >= to Symbol
|
2
|
+
# to reflect the mathmatical operators. It also adds the [] method
|
3
|
+
# to Symbol for creating SQL functions.
|
4
|
+
#
|
5
|
+
# Usage of this extension is not recommended. This extension will
|
6
|
+
# only load on ruby 1.8, so you will not be able to upgrade to
|
7
|
+
# newer ruby versions if you use it. If you still want to use it,
|
8
|
+
# you can load it via:
|
9
|
+
#
|
10
|
+
# Sequel.extension :ruby18_symbol_extensions
|
11
|
+
|
12
|
+
raise(Sequel::Error, "The ruby18_symbol_extensions is only available on ruby 1.8.") unless RUBY_VERSION < '1.9.0'
|
13
|
+
|
14
|
+
class Symbol
|
15
|
+
include Sequel::SQL::InequalityMethods
|
16
|
+
|
17
|
+
# Create an SQL Function with the receiver as the function name
|
18
|
+
# and the given arguments.
|
19
|
+
def [](*args)
|
20
|
+
Sequel::SQL::Function.new(self, *args)
|
21
|
+
end
|
22
|
+
end
|
@@ -6,10 +6,8 @@
|
|
6
6
|
#
|
7
7
|
# Basic usage in application code:
|
8
8
|
#
|
9
|
-
# Sequel.extension :schema_caching
|
10
|
-
#
|
11
9
|
# DB = Sequel.connect('...')
|
12
|
-
#
|
10
|
+
# DB.extension :schema_caching
|
13
11
|
# DB.load_schema_cache('/path/to/schema.dump')
|
14
12
|
#
|
15
13
|
# # load model files
|
@@ -23,10 +21,8 @@
|
|
23
21
|
# all tables, and you don't worry about race conditions, you can
|
24
22
|
# choose to use the following in your application code:
|
25
23
|
#
|
26
|
-
# Sequel.extension :schema_caching
|
27
|
-
#
|
28
24
|
# DB = Sequel.connect('...')
|
29
|
-
#
|
25
|
+
# DB.extension :schema_caching
|
30
26
|
# DB.load_schema_cache?('/path/to/schema.dump')
|
31
27
|
#
|
32
28
|
# # load model files
|
@@ -47,9 +43,13 @@
|
|
47
43
|
# you should not attempt to load the schema from a untrusted file.
|
48
44
|
|
49
45
|
module Sequel
|
46
|
+
module SchemaCaching
|
47
|
+
end
|
48
|
+
|
50
49
|
class Database
|
51
50
|
# Dump the cached schema to the filename given in Marshal format.
|
52
51
|
def dump_schema_cache(file)
|
52
|
+
Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
|
53
53
|
File.open(file, 'wb'){|f| f.write(Marshal.dump(@schemas))}
|
54
54
|
nil
|
55
55
|
end
|
@@ -57,12 +57,14 @@ module Sequel
|
|
57
57
|
# Dump the cached schema to the filename given unless the file
|
58
58
|
# already exists.
|
59
59
|
def dump_schema_cache?(file)
|
60
|
+
Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
|
60
61
|
dump_schema_cache(file) unless File.exist?(file)
|
61
62
|
end
|
62
63
|
|
63
64
|
# Replace the schema cache with the data from the given file, which
|
64
65
|
# should be in Marshal format.
|
65
66
|
def load_schema_cache(file)
|
67
|
+
Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
|
66
68
|
@schemas = Marshal.load(File.read(file))
|
67
69
|
nil
|
68
70
|
end
|
@@ -70,9 +72,10 @@ module Sequel
|
|
70
72
|
# Replace the schema cache with the data from the given file if the
|
71
73
|
# file exists.
|
72
74
|
def load_schema_cache?(file)
|
75
|
+
Sequel::Deprecation.deprecate('Loading the schema_caching extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaCaching)
|
73
76
|
load_schema_cache(file) if File.exist?(file)
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
Database.register_extension(:schema_caching)
|
80
|
+
Database.register_extension(:schema_caching, SchemaCaching)
|
78
81
|
end
|
@@ -6,11 +6,14 @@
|
|
6
6
|
#
|
7
7
|
# To load the extension:
|
8
8
|
#
|
9
|
-
#
|
9
|
+
# DB.extension :schema_dumper
|
10
10
|
|
11
11
|
Sequel.extension :eval_inspect
|
12
12
|
|
13
13
|
module Sequel
|
14
|
+
module SchemaDumper
|
15
|
+
end
|
16
|
+
|
14
17
|
class Database
|
15
18
|
# Dump foreign key constraints for all tables as a migration. This complements
|
16
19
|
# the :foreign_keys=>false option to dump_schema_migration. This only dumps
|
@@ -20,6 +23,7 @@ module Sequel
|
|
20
23
|
# Note that the migration this produces does not have a down
|
21
24
|
# block, so you cannot reverse it.
|
22
25
|
def dump_foreign_key_migration(options={})
|
26
|
+
Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
|
23
27
|
ts = tables(options)
|
24
28
|
<<END_MIG
|
25
29
|
Sequel.migration do
|
@@ -38,6 +42,7 @@ END_MIG
|
|
38
42
|
# set to :namespace, prepend the table name to the index name if the
|
39
43
|
# database does not use a global index namespace.
|
40
44
|
def dump_indexes_migration(options={})
|
45
|
+
Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
|
41
46
|
ts = tables(options)
|
42
47
|
<<END_MIG
|
43
48
|
Sequel.migration do
|
@@ -62,6 +67,7 @@ END_MIG
|
|
62
67
|
# :index_names :: If set to false, don't record names of indexes. If
|
63
68
|
# set to :namespace, prepend the table name to the index name.
|
64
69
|
def dump_schema_migration(options={})
|
70
|
+
Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
|
65
71
|
options = options.dup
|
66
72
|
if options[:indexes] == false && !options.has_key?(:foreign_keys)
|
67
73
|
# Unless foreign_keys option is specifically set, disable if indexes
|
@@ -91,6 +97,7 @@ END_MIG
|
|
91
97
|
# Return a string with a create table block that will recreate the given
|
92
98
|
# table's schema. Takes the same options as dump_schema_migration.
|
93
99
|
def dump_table_schema(table, options={})
|
100
|
+
Sequel::Deprecation.deprecate('Loading the schema_dumper extension globally', "Please use Database#extension to load the extension into this database") unless is_a?(SchemaDumper)
|
94
101
|
table = table.value.to_s if table.is_a?(SQL::Identifier)
|
95
102
|
gen = dump_table_generator(table, options)
|
96
103
|
commands = [gen.dump_columns, gen.dump_constraints, gen.dump_indexes].reject{|x| x == ''}.join("\n\n")
|
@@ -209,13 +216,11 @@ END_MIG
|
|
209
216
|
# For the table given, get the list of foreign keys and return an alter_table
|
210
217
|
# string that would add the foreign keys if run in a migration.
|
211
218
|
def dump_table_foreign_keys(table, options={})
|
212
|
-
|
219
|
+
if supports_foreign_key_parsing?
|
213
220
|
fks = foreign_key_list(table, options).sort_by{|fk| fk[:columns].map{|c| c.to_s}}
|
214
|
-
rescue Sequel::NotImplemented
|
215
|
-
return ''
|
216
221
|
end
|
217
222
|
|
218
|
-
if fks.empty?
|
223
|
+
if fks.nil? || fks.empty?
|
219
224
|
''
|
220
225
|
else
|
221
226
|
dump_add_fk_constraints(table, fks)
|
@@ -233,40 +238,32 @@ END_MIG
|
|
233
238
|
m = method(:recreate_column)
|
234
239
|
im = method(:index_to_generator_opts)
|
235
240
|
|
236
|
-
if options[:indexes] != false
|
237
|
-
|
238
|
-
indexes = indexes(table).sort_by{|k,v| k.to_s}
|
239
|
-
rescue Sequel::NotImplemented
|
240
|
-
nil
|
241
|
-
end
|
241
|
+
if options[:indexes] != false && supports_index_parsing?
|
242
|
+
indexes = indexes(table).sort_by{|k,v| k.to_s}
|
242
243
|
end
|
243
244
|
|
244
|
-
if options[:foreign_keys] != false
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
245
|
+
if options[:foreign_keys] != false && supports_foreign_key_parsing?
|
246
|
+
fk_list = foreign_key_list(table)
|
247
|
+
|
248
|
+
if (sfk = options[:skipped_foreign_keys]) && (sfkt = sfk[table])
|
249
|
+
fk_list.delete_if{|fk| sfkt.has_key?(fk[:columns])}
|
250
|
+
end
|
251
251
|
|
252
|
-
|
253
|
-
|
252
|
+
composite_fks, single_fks = fk_list.partition{|h| h[:columns].length > 1}
|
253
|
+
fk_hash = {}
|
254
254
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
255
|
+
single_fks.each do |fk|
|
256
|
+
column = fk.delete(:columns).first
|
257
|
+
fk.delete(:name)
|
258
|
+
fk_hash[column] = fk
|
259
|
+
end
|
260
260
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
end
|
261
|
+
s = s.map do |name, info|
|
262
|
+
if fk_info = fk_hash[name]
|
263
|
+
[name, fk_info.merge(info)]
|
264
|
+
else
|
265
|
+
[name, info]
|
267
266
|
end
|
268
|
-
rescue Sequel::NotImplemented
|
269
|
-
nil
|
270
267
|
end
|
271
268
|
end
|
272
269
|
|
@@ -281,11 +278,12 @@ END_MIG
|
|
281
278
|
# Return a string that containing add_index/drop_index method calls for
|
282
279
|
# creating the index migration.
|
283
280
|
def dump_table_indexes(table, meth, options={})
|
284
|
-
|
281
|
+
if supports_index_parsing?
|
285
282
|
indexes = indexes(table).sort_by{|k,v| k.to_s}
|
286
|
-
|
283
|
+
else
|
287
284
|
return ''
|
288
285
|
end
|
286
|
+
|
289
287
|
im = method(:index_to_generator_opts)
|
290
288
|
gen = create_table_generator do
|
291
289
|
indexes.each{|iname, iopts| send(:index, iopts[:columns], im.call(table, iname, iopts, options))}
|
@@ -311,18 +309,7 @@ END_MIG
|
|
311
309
|
# Sort the tables so that referenced tables are created before tables that
|
312
310
|
# reference them, and then by name. If foreign keys are disabled, just sort by name.
|
313
311
|
def sort_dumped_tables(tables, options={})
|
314
|
-
|
315
|
-
begin
|
316
|
-
foreign_key_list(:some_table_that_does_not_exist)
|
317
|
-
true
|
318
|
-
rescue Sequel::NotImplemented
|
319
|
-
false
|
320
|
-
rescue
|
321
|
-
true
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
if sort_topologically
|
312
|
+
if options[:foreign_keys] != false && supports_foreign_key_parsing?
|
326
313
|
table_fks = {}
|
327
314
|
tables.each{|t| table_fks[t] = foreign_key_list(t)}
|
328
315
|
# Remove self referential foreign keys, not important when sorting.
|
@@ -484,5 +471,5 @@ END_MIG
|
|
484
471
|
end
|
485
472
|
end
|
486
473
|
|
487
|
-
Database.register_extension(:schema_dumper)
|
474
|
+
Database.register_extension(:schema_dumper, SchemaDumper)
|
488
475
|
end
|
@@ -2,11 +2,20 @@
|
|
2
2
|
# columns from a dataset. It's not part of Sequel core as it is rarely needed and has
|
3
3
|
# some corner cases where it can't work correctly.
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# You can load this extension into specific datasets:
|
6
6
|
#
|
7
|
-
#
|
7
|
+
# ds = DB[:table]
|
8
|
+
# ds.extension(:select_remove)
|
9
|
+
#
|
10
|
+
# Or you can load it into all of a database's datasets, which
|
11
|
+
# is probably the desired behavior if you are using this extension:
|
12
|
+
#
|
13
|
+
# DB.extension(:select_remove)
|
8
14
|
|
9
15
|
module Sequel
|
16
|
+
module SelectRemove
|
17
|
+
end
|
18
|
+
|
10
19
|
class Dataset
|
11
20
|
# Remove columns from the list of selected columns. If any of the currently selected
|
12
21
|
# columns use expressions/aliases, this will remove selected columns with the given
|
@@ -29,6 +38,7 @@ module Sequel
|
|
29
38
|
#
|
30
39
|
# There may be other cases where this method does not work correctly, use it with caution.
|
31
40
|
def select_remove(*cols)
|
41
|
+
Sequel::Deprecation.deprecate('Loading the select_remove extension globally', "Please use Database/Dataset#extension to load the extension into this dataset") unless is_a?(SelectRemove)
|
32
42
|
if (sel = @opts[:select]) && !sel.empty?
|
33
43
|
select(*(columns.zip(sel).reject{|c, s| cols.include?(c)}.map{|c, s| s} - cols))
|
34
44
|
else
|
@@ -37,6 +47,5 @@ module Sequel
|
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
40
|
-
|
41
|
-
Dataset.register_extension(:select_remove){}
|
50
|
+
Dataset.register_extension(:select_remove, SelectRemove)
|
42
51
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# This adds the following dataset methods:
|
2
|
+
#
|
3
|
+
# []= :: filter with the first argument, update with the second
|
4
|
+
# insert_multiple :: insert multiple rows at once
|
5
|
+
# set :: alias for update
|
6
|
+
# to_csv :: return string in csv format for the dataset
|
7
|
+
# db= :: change the dataset's database
|
8
|
+
# opts= :: change the dataset's opts
|
9
|
+
#
|
10
|
+
# It is only recommended to use this for backwards compatibility.
|
11
|
+
#
|
12
|
+
# You can load this extension into specific datasets:
|
13
|
+
#
|
14
|
+
# ds = DB[:table]
|
15
|
+
# ds.extension(:sequel_3_dataset_methods)
|
16
|
+
#
|
17
|
+
# Or you can load it into all of a database's datasets, which
|
18
|
+
# is probably the desired behavior if you are using this extension:
|
19
|
+
#
|
20
|
+
# DB.extension(:sequel_3_dataset_methods)
|
21
|
+
|
22
|
+
module Sequel
|
23
|
+
module Sequel3DatasetMethods
|
24
|
+
COMMA = Dataset::COMMA
|
25
|
+
# The database related to this dataset. This is the Database instance that
|
26
|
+
# will execute all of this dataset's queries.
|
27
|
+
attr_writer :db
|
28
|
+
|
29
|
+
# The hash of options for this dataset, keys are symbols.
|
30
|
+
attr_writer :opts
|
31
|
+
|
32
|
+
# Update all records matching the conditions with the values specified.
|
33
|
+
# Returns the number of rows affected.
|
34
|
+
#
|
35
|
+
# DB[:table][:id=>1] = {:id=>2} # UPDATE table SET id = 2 WHERE id = 1
|
36
|
+
# # => 1 # number of rows affected
|
37
|
+
def []=(conditions, values)
|
38
|
+
filter(conditions).update(values)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Inserts multiple values. If a block is given it is invoked for each
|
42
|
+
# item in the given array before inserting it. See +multi_insert+ as
|
43
|
+
# a possibly faster version that may be able to insert multiple
|
44
|
+
# records in one SQL statement (if supported by the database).
|
45
|
+
# Returns an array of primary keys of inserted rows.
|
46
|
+
#
|
47
|
+
# DB[:table].insert_multiple([{:x=>1}, {:x=>2}])
|
48
|
+
# # => [4, 5]
|
49
|
+
# # INSERT INTO table (x) VALUES (1)
|
50
|
+
# # INSERT INTO table (x) VALUES (2)
|
51
|
+
#
|
52
|
+
# DB[:table].insert_multiple([{:x=>1}, {:x=>2}]){|row| row[:y] = row[:x] * 2; row }
|
53
|
+
# # => [6, 7]
|
54
|
+
# # INSERT INTO table (x, y) VALUES (1, 2)
|
55
|
+
# # INSERT INTO table (x, y) VALUES (2, 4)
|
56
|
+
def insert_multiple(array, &block)
|
57
|
+
if block
|
58
|
+
array.map{|i| insert(block.call(i))}
|
59
|
+
else
|
60
|
+
array.map{|i| insert(i)}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return a copy of the dataset with unqualified identifiers in the
|
65
|
+
# SELECT, WHERE, GROUP, HAVING, and ORDER clauses qualified by the
|
66
|
+
# given table. If no columns are currently selected, select all
|
67
|
+
# columns of the given table.
|
68
|
+
#
|
69
|
+
# DB[:items].filter(:id=>1).qualify_to(:i)
|
70
|
+
# # SELECT i.* FROM items WHERE (i.id = 1)
|
71
|
+
def qualify_to(table)
|
72
|
+
qualify(table)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Qualify the dataset to its current first source. This is useful
|
76
|
+
# if you have unqualified identifiers in the query that all refer to
|
77
|
+
# the first source, and you want to join to another table which
|
78
|
+
# has columns with the same name as columns in the current dataset.
|
79
|
+
# See +qualify_to+.
|
80
|
+
#
|
81
|
+
# DB[:items].filter(:id=>1).qualify_to_first_source
|
82
|
+
# # SELECT items.* FROM items WHERE (items.id = 1)
|
83
|
+
def qualify_to_first_source
|
84
|
+
qualify
|
85
|
+
end
|
86
|
+
|
87
|
+
# Alias for update, but not aliased directly so subclasses
|
88
|
+
# don't have to override both methods.
|
89
|
+
def set(*args)
|
90
|
+
update(*args)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns a string in CSV format containing the dataset records. By
|
94
|
+
# default the CSV representation includes the column titles in the
|
95
|
+
# first line. You can turn that off by passing false as the
|
96
|
+
# include_column_titles argument.
|
97
|
+
#
|
98
|
+
# This does not use a CSV library or handle quoting of values in
|
99
|
+
# any way. If any values in any of the rows could include commas or line
|
100
|
+
# endings, you shouldn't use this.
|
101
|
+
#
|
102
|
+
# puts DB[:table].to_csv # SELECT * FROM table
|
103
|
+
# # id,name
|
104
|
+
# # 1,Jim
|
105
|
+
# # 2,Bob
|
106
|
+
def to_csv(include_column_titles = true)
|
107
|
+
n = naked
|
108
|
+
cols = n.columns
|
109
|
+
csv = ''
|
110
|
+
csv << "#{cols.join(COMMA)}\r\n" if include_column_titles
|
111
|
+
n.each{|r| csv << "#{cols.collect{|c| r[c]}.join(COMMA)}\r\n"}
|
112
|
+
csv
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
Dataset.register_extension(:sequel_3_dataset_methods, Sequel3DatasetMethods)
|
117
|
+
end
|