sequel 2.11.0 → 2.12.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 +168 -0
- data/README.rdoc +77 -95
- data/Rakefile +100 -80
- data/bin/sequel +2 -1
- data/doc/advanced_associations.rdoc +23 -32
- data/doc/cheat_sheet.rdoc +23 -40
- data/doc/dataset_filtering.rdoc +6 -6
- data/doc/prepared_statements.rdoc +22 -22
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/schema.rdoc +3 -1
- data/doc/sharding.rdoc +8 -8
- data/doc/virtual_rows.rdoc +65 -0
- data/lib/sequel.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/ado.rb +3 -3
- data/lib/{sequel_core → sequel}/adapters/db2.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/dbi.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do.rb +9 -5
- data/lib/{sequel_core → sequel}/adapters/do/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/postgres.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/do/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/firebird.rb +84 -80
- data/lib/{sequel_core → sequel}/adapters/informix.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc.rb +21 -14
- data/lib/{sequel_core → sequel}/adapters/jdbc/h2.rb +14 -13
- data/lib/{sequel_core → sequel}/adapters/jdbc/mysql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/oracle.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/postgresql.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/jdbc/sqlite.rb +1 -1
- data/lib/{sequel_core → sequel}/adapters/mysql.rb +60 -39
- data/lib/{sequel_core → sequel}/adapters/odbc.rb +8 -4
- data/lib/{sequel_core → sequel}/adapters/openbase.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/oracle.rb +38 -7
- data/lib/{sequel_core → sequel}/adapters/postgres.rb +24 -24
- data/lib/{sequel_core → sequel}/adapters/shared/mssql.rb +5 -5
- data/lib/{sequel_core → sequel}/adapters/shared/mysql.rb +126 -71
- data/lib/{sequel_core → sequel}/adapters/shared/oracle.rb +7 -10
- data/lib/{sequel_core → sequel}/adapters/shared/postgres.rb +159 -125
- data/lib/{sequel_core → sequel}/adapters/shared/progress.rb +1 -2
- data/lib/{sequel_core → sequel}/adapters/shared/sqlite.rb +72 -67
- data/lib/{sequel_core → sequel}/adapters/sqlite.rb +11 -7
- data/lib/{sequel_core → sequel}/adapters/utils/date_format.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/stored_procedures.rb +0 -0
- data/lib/{sequel_core → sequel}/adapters/utils/unsupported.rb +19 -0
- data/lib/{sequel_core → sequel}/connection_pool.rb +7 -5
- data/lib/sequel/core.rb +221 -0
- data/lib/{sequel_core → sequel}/core_sql.rb +91 -49
- data/lib/{sequel_core → sequel}/database.rb +264 -149
- data/lib/{sequel_core/schema/generator.rb → sequel/database/schema_generator.rb} +6 -2
- data/lib/{sequel_core/database/schema.rb → sequel/database/schema_methods.rb} +12 -12
- data/lib/sequel/database/schema_sql.rb +224 -0
- data/lib/{sequel_core → sequel}/dataset.rb +78 -236
- data/lib/{sequel_core → sequel}/dataset/convenience.rb +99 -61
- data/lib/{sequel_core/object_graph.rb → sequel/dataset/graph.rb} +16 -14
- data/lib/{sequel_core → sequel}/dataset/prepared_statements.rb +1 -1
- data/lib/{sequel_core → sequel}/dataset/sql.rb +150 -99
- data/lib/sequel/deprecated.rb +593 -0
- data/lib/sequel/deprecated_migration.rb +91 -0
- data/lib/sequel/exceptions.rb +48 -0
- data/lib/sequel/extensions/blank.rb +42 -0
- data/lib/{sequel_model → sequel/extensions}/inflector.rb +8 -1
- data/lib/{sequel_core → sequel/extensions}/migration.rb +1 -1
- data/lib/{sequel_core/dataset → sequel/extensions}/pagination.rb +0 -0
- data/lib/{sequel_core → sequel/extensions}/pretty_table.rb +7 -0
- data/lib/{sequel_core/dataset → sequel/extensions}/query.rb +7 -0
- data/lib/sequel/extensions/string_date_time.rb +47 -0
- data/lib/sequel/metaprogramming.rb +43 -0
- data/lib/sequel/model.rb +110 -0
- data/lib/sequel/model/associations.rb +1300 -0
- data/lib/sequel/model/base.rb +937 -0
- data/lib/sequel/model/deprecated.rb +204 -0
- data/lib/sequel/model/deprecated_hooks.rb +103 -0
- data/lib/sequel/model/deprecated_inflector.rb +335 -0
- data/lib/sequel/model/deprecated_validations.rb +388 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/{sequel_model → sequel/model}/exceptions.rb +4 -4
- data/lib/sequel/model/inflections.rb +208 -0
- data/lib/sequel/model/plugins.rb +76 -0
- data/lib/sequel/plugins/caching.rb +122 -0
- data/lib/sequel/plugins/hook_class_methods.rb +122 -0
- data/lib/sequel/plugins/schema.rb +53 -0
- data/lib/sequel/plugins/serialization.rb +117 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +63 -0
- data/lib/sequel/plugins/validation_class_methods.rb +384 -0
- data/lib/sequel/plugins/validation_helpers.rb +150 -0
- data/lib/{sequel_core → sequel}/sql.rb +125 -190
- data/lib/{sequel_core → sequel}/version.rb +2 -1
- data/lib/sequel_core.rb +1 -172
- data/lib/sequel_model.rb +1 -91
- data/spec/adapters/firebird_spec.rb +5 -5
- data/spec/adapters/informix_spec.rb +1 -1
- data/spec/adapters/mysql_spec.rb +128 -42
- data/spec/adapters/oracle_spec.rb +47 -19
- data/spec/adapters/postgres_spec.rb +64 -52
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +12 -17
- data/spec/{sequel_core → core}/connection_pool_spec.rb +10 -10
- data/spec/{sequel_core → core}/core_ext_spec.rb +19 -19
- data/spec/{sequel_core → core}/core_sql_spec.rb +68 -71
- data/spec/{sequel_core → core}/database_spec.rb +135 -99
- data/spec/{sequel_core → core}/dataset_spec.rb +398 -242
- data/spec/{sequel_core → core}/expression_filters_spec.rb +13 -13
- data/spec/core/migration_spec.rb +263 -0
- data/spec/{sequel_core → core}/object_graph_spec.rb +10 -10
- data/spec/{sequel_core → core}/pretty_table_spec.rb +2 -2
- data/spec/{sequel_core → core}/schema_generator_spec.rb +0 -0
- data/spec/{sequel_core → core}/schema_spec.rb +8 -10
- data/spec/{sequel_core → core}/spec_helper.rb +29 -2
- data/spec/{sequel_core → core}/version_spec.rb +0 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/caching_spec.rb +201 -0
- data/spec/{sequel_model/hooks_spec.rb → extensions/hook_class_methods_spec.rb} +8 -23
- data/spec/{sequel_model → extensions}/inflector_spec.rb +3 -0
- data/spec/{sequel_core → extensions}/migration_spec.rb +4 -4
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/{sequel_model → extensions}/schema_spec.rb +22 -1
- data/spec/extensions/serialization_spec.rb +109 -0
- data/spec/extensions/single_table_inheritance_spec.rb +53 -0
- data/spec/{sequel_model → extensions}/spec_helper.rb +13 -4
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/{sequel_model/validations_spec.rb → extensions/validation_class_methods_spec.rb} +15 -103
- data/spec/extensions/validation_helpers_spec.rb +291 -0
- data/spec/integration/dataset_test.rb +31 -0
- data/spec/integration/eager_loader_test.rb +17 -30
- data/spec/integration/schema_test.rb +8 -5
- data/spec/integration/spec_helper.rb +17 -0
- data/spec/integration/transaction_test.rb +68 -0
- data/spec/{sequel_model → model}/association_reflection_spec.rb +0 -0
- data/spec/{sequel_model → model}/associations_spec.rb +23 -10
- data/spec/{sequel_model → model}/base_spec.rb +29 -20
- data/spec/{sequel_model → model}/caching_spec.rb +16 -14
- data/spec/{sequel_model → model}/dataset_methods_spec.rb +0 -0
- data/spec/{sequel_model → model}/eager_loading_spec.rb +8 -8
- data/spec/model/hooks_spec.rb +472 -0
- data/spec/model/inflector_spec.rb +126 -0
- data/spec/{sequel_model → model}/model_spec.rb +25 -20
- data/spec/model/plugins_spec.rb +142 -0
- data/spec/{sequel_model → model}/record_spec.rb +121 -62
- data/spec/model/schema_spec.rb +92 -0
- data/spec/model/spec_helper.rb +124 -0
- data/spec/model/validations_spec.rb +1080 -0
- metadata +136 -107
- data/lib/sequel_core/core_ext.rb +0 -217
- data/lib/sequel_core/dataset/callback.rb +0 -13
- data/lib/sequel_core/dataset/schema.rb +0 -15
- data/lib/sequel_core/deprecated.rb +0 -26
- data/lib/sequel_core/exceptions.rb +0 -44
- data/lib/sequel_core/schema.rb +0 -2
- data/lib/sequel_core/schema/sql.rb +0 -325
- data/lib/sequel_model/association_reflection.rb +0 -267
- data/lib/sequel_model/associations.rb +0 -499
- data/lib/sequel_model/base.rb +0 -539
- data/lib/sequel_model/caching.rb +0 -82
- data/lib/sequel_model/dataset_methods.rb +0 -26
- data/lib/sequel_model/eager_loading.rb +0 -370
- data/lib/sequel_model/hooks.rb +0 -101
- data/lib/sequel_model/plugins.rb +0 -62
- data/lib/sequel_model/record.rb +0 -568
- data/lib/sequel_model/schema.rb +0 -49
- data/lib/sequel_model/validations.rb +0 -429
- data/spec/sequel_model/plugins_spec.rb +0 -80
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
class Migration
|
|
3
|
+
def initialize(db)
|
|
4
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
5
|
+
require 'sequel/extensions/migration'
|
|
6
|
+
@db = db
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.apply(db, direction)
|
|
10
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
11
|
+
require 'sequel/extensions/migration'
|
|
12
|
+
apply(db, direction)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.descendants
|
|
16
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
17
|
+
require 'sequel/extensions/migration'
|
|
18
|
+
@descendants ||= []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.inherited(base)
|
|
22
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
23
|
+
require 'sequel/extensions/migration'
|
|
24
|
+
descendants << base
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def down
|
|
28
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
29
|
+
require 'sequel/extensions/migration'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def method_missing(method_sym, *args, &block)
|
|
33
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
34
|
+
require 'sequel/extensions/migration'
|
|
35
|
+
@db.send(method_sym, *args, &block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def up
|
|
39
|
+
Deprecation.deprecate('Sequel::Migration', "require 'sequel/extensions/migration' first")
|
|
40
|
+
require 'sequel/extensions/migration'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module Migrator
|
|
45
|
+
def self.apply(db, directory, target = nil, current = nil)
|
|
46
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
47
|
+
require 'sequel/extensions/migration'
|
|
48
|
+
apply(db, directory, target, current)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.get_current_migration_version(db)
|
|
52
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
53
|
+
require 'sequel/extensions/migration'
|
|
54
|
+
r = schema_info_dataset(db).first
|
|
55
|
+
r ? r[:version] : 0
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.latest_migration_version(directory)
|
|
59
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
60
|
+
require 'sequel/extensions/migration'
|
|
61
|
+
l = migration_files(directory).last
|
|
62
|
+
l ? File.basename(l).to_i : nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.migration_classes(directory, target, current, direction)
|
|
66
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
67
|
+
require 'sequel/extensions/migration'
|
|
68
|
+
migration_classes(directory, target, current, direction)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.migration_files(directory, range = nil)
|
|
72
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
73
|
+
require 'sequel/extensions/migration'
|
|
74
|
+
migration_files(directory, range)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.schema_info_dataset(db)
|
|
78
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
79
|
+
require 'sequel/extensions/migration'
|
|
80
|
+
db.create_table(:schema_info) {integer :version} unless db.table_exists?(:schema_info)
|
|
81
|
+
db[:schema_info]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def self.set_current_migration_version(db, version)
|
|
85
|
+
Deprecation.deprecate('Sequel::Migrator', "require 'sequel/extensions/migration' first")
|
|
86
|
+
require 'sequel/extensions/migration'
|
|
87
|
+
dataset = schema_info_dataset(db)
|
|
88
|
+
dataset.send(dataset.first ? :update : :<<, :version => version)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
# The default exception class for exceptions raised by Sequel.
|
|
3
|
+
# All exception classes defined by Sequel are descendants of this class.
|
|
4
|
+
class Error < ::StandardError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# Raised when the adapter requested doesn't exist or can't be loaded.
|
|
8
|
+
class AdapterNotFound < Error ; end
|
|
9
|
+
|
|
10
|
+
# Generic error raised by the database adapters, indicating a
|
|
11
|
+
# problem originating from the database server. Usually raised
|
|
12
|
+
# because incorrect SQL syntax is used.
|
|
13
|
+
class DatabaseError < Error; end
|
|
14
|
+
|
|
15
|
+
# Error raised when the Sequel is unable to connect to the database with the
|
|
16
|
+
# connection parameters it was given.
|
|
17
|
+
class DatabaseConnectionError < DatabaseError; end
|
|
18
|
+
|
|
19
|
+
# Error that should be raised by adapters when they determine that the connection
|
|
20
|
+
# to the database has been lost. Instructs the connection pool code to
|
|
21
|
+
# remove that connection from the pool so that other connections can be acquired
|
|
22
|
+
# automatically.
|
|
23
|
+
class DatabaseDisconnectError < DatabaseError; end
|
|
24
|
+
|
|
25
|
+
# Raised on an invalid operation, such as trying to update or delete
|
|
26
|
+
# a joined or grouped dataset.
|
|
27
|
+
class InvalidOperation < Error; end
|
|
28
|
+
|
|
29
|
+
# Raised when attempting an invalid type conversion.
|
|
30
|
+
class InvalidValue < Error ; end
|
|
31
|
+
|
|
32
|
+
# Raised when the connection pool cannot acquire a database connection
|
|
33
|
+
# before the timeout.
|
|
34
|
+
class PoolTimeout < Error ; end
|
|
35
|
+
|
|
36
|
+
# Exception that you should raise to signal a rollback of the current transaction.
|
|
37
|
+
# The transaction block will catch this exception, rollback the current transaction,
|
|
38
|
+
# and won't reraise it.
|
|
39
|
+
class Rollback < Error ; end
|
|
40
|
+
|
|
41
|
+
class Error
|
|
42
|
+
AdapterNotFound = Sequel::AdapterNotFound
|
|
43
|
+
InvalidOperation = Sequel::InvalidOperation
|
|
44
|
+
InvalidValue = Sequel::InvalidValue
|
|
45
|
+
PoolTimeoutError = Sequel::PoolTimeout
|
|
46
|
+
Rollback = Sequel::Rollback
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class FalseClass
|
|
2
|
+
# false is always blank
|
|
3
|
+
def blank?
|
|
4
|
+
true
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Helpers from Metaid and a bit more
|
|
9
|
+
class Object
|
|
10
|
+
# Objects are blank if they respond true to empty?
|
|
11
|
+
def blank?
|
|
12
|
+
respond_to?(:empty?) && empty?
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class NilClass
|
|
17
|
+
# nil is always blank
|
|
18
|
+
def blank?
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class Numeric
|
|
24
|
+
# Numerics are never blank (not even 0)
|
|
25
|
+
def blank?
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class String
|
|
31
|
+
# Strings are blank if they are empty or include only whitespace
|
|
32
|
+
def blank?
|
|
33
|
+
strip.empty?
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class TrueClass
|
|
38
|
+
# true is never blank
|
|
39
|
+
def blank?
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -21,7 +21,9 @@ class String
|
|
|
21
21
|
module Inflections
|
|
22
22
|
@plurals, @singulars, @uncountables = [], [], []
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
class << self
|
|
25
|
+
attr_reader :plurals, :singulars, :uncountables
|
|
26
|
+
end
|
|
25
27
|
|
|
26
28
|
# Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
|
|
27
29
|
# the options are: :plurals, :singulars, :uncountables
|
|
@@ -30,6 +32,7 @@ class String
|
|
|
30
32
|
# clear :all
|
|
31
33
|
# clear :plurals
|
|
32
34
|
def self.clear(scope = :all)
|
|
35
|
+
Sequel::Inflections.clear(scope)
|
|
33
36
|
case scope
|
|
34
37
|
when :all
|
|
35
38
|
@plurals, @singulars, @uncountables = [], [], []
|
|
@@ -45,6 +48,7 @@ class String
|
|
|
45
48
|
# irregular 'octopus', 'octopi'
|
|
46
49
|
# irregular 'person', 'people'
|
|
47
50
|
def self.irregular(singular, plural)
|
|
51
|
+
Sequel::Inflections.irregular(singular, plural)
|
|
48
52
|
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
|
49
53
|
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
|
50
54
|
end
|
|
@@ -55,6 +59,7 @@ class String
|
|
|
55
59
|
# Example:
|
|
56
60
|
# plural(/(x|ch|ss|sh)$/i, '\1es')
|
|
57
61
|
def self.plural(rule, replacement)
|
|
62
|
+
Sequel::Inflections.plural(rule, replacement)
|
|
58
63
|
@plurals.insert(0, [rule, replacement])
|
|
59
64
|
end
|
|
60
65
|
|
|
@@ -64,6 +69,7 @@ class String
|
|
|
64
69
|
# Example:
|
|
65
70
|
# singular(/([^aeiouy]|qu)ies$/i, '\1y')
|
|
66
71
|
def self.singular(rule, replacement)
|
|
72
|
+
Sequel::Inflections.singular(rule, replacement)
|
|
67
73
|
@singulars.insert(0, [rule, replacement])
|
|
68
74
|
end
|
|
69
75
|
|
|
@@ -74,6 +80,7 @@ class String
|
|
|
74
80
|
# uncountable "money", "information"
|
|
75
81
|
# uncountable %w( money information rice )
|
|
76
82
|
def self.uncountable(*words)
|
|
83
|
+
Sequel::Inflections.uncountable(*words)
|
|
77
84
|
(@uncountables << words).flatten!
|
|
78
85
|
end
|
|
79
86
|
|
|
@@ -35,7 +35,7 @@ module Sequel
|
|
|
35
35
|
# To apply a migration to a database, you can invoke the #apply with
|
|
36
36
|
# the target database instance and the direction :up or :down, e.g.:
|
|
37
37
|
#
|
|
38
|
-
# DB = Sequel.
|
|
38
|
+
# DB = Sequel.connect('sqlite://mydb')
|
|
39
39
|
# CreateSessions.apply(DB, :up)
|
|
40
40
|
#
|
|
41
41
|
# See Sequel::Schema::Generator for the syntax to use for creating tables,
|
|
File without changes
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
module Sequel
|
|
2
|
+
class Dataset
|
|
3
|
+
# Pretty prints the records in the dataset as plain-text table.
|
|
4
|
+
def print(*cols)
|
|
5
|
+
Sequel::PrettyTable.print(naked.all, cols.empty? ? columns : cols)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
2
9
|
module PrettyTable
|
|
3
10
|
# Prints nice-looking plain-text tables via puts
|
|
4
11
|
#
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
module Sequel
|
|
2
|
+
class Database
|
|
3
|
+
# Return a dataset modified by the query block
|
|
4
|
+
def query(&block)
|
|
5
|
+
dataset.query(&block)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
2
9
|
class Dataset
|
|
3
10
|
# Translates a query block into a dataset. Query blocks can be useful
|
|
4
11
|
# when expressing complex SELECT statements, e.g.:
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# This file contains the previous extensions to String for date/time
|
|
2
|
+
# conversions. These are provided mainly for backward compatibility,
|
|
3
|
+
# Sequel now uses a module level method instead of extending string
|
|
4
|
+
# to handle the internal conversions.
|
|
5
|
+
|
|
6
|
+
class String
|
|
7
|
+
# Converts a string into a Date object.
|
|
8
|
+
def to_date
|
|
9
|
+
begin
|
|
10
|
+
Date.parse(self, Sequel.convert_two_digit_years)
|
|
11
|
+
rescue => e
|
|
12
|
+
raise Sequel::InvalidValue, "Invalid Date value '#{self}' (#{e.message})"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Converts a string into a DateTime object.
|
|
17
|
+
def to_datetime
|
|
18
|
+
begin
|
|
19
|
+
DateTime.parse(self, Sequel.convert_two_digit_years)
|
|
20
|
+
rescue => e
|
|
21
|
+
raise Sequel::InvalidValue, "Invalid DateTime value '#{self}' (#{e.message})"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Converts a string into a Time or DateTime object, depending on the
|
|
26
|
+
# value of Sequel.datetime_class
|
|
27
|
+
def to_sequel_time
|
|
28
|
+
begin
|
|
29
|
+
if Sequel.datetime_class == DateTime
|
|
30
|
+
DateTime.parse(self, Sequel.convert_two_digit_years)
|
|
31
|
+
else
|
|
32
|
+
Sequel.datetime_class.parse(self)
|
|
33
|
+
end
|
|
34
|
+
rescue => e
|
|
35
|
+
raise Sequel::InvalidValue, "Invalid #{Sequel.datetime_class} value '#{self}' (#{e.message})"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Converts a string into a Time object.
|
|
40
|
+
def to_time
|
|
41
|
+
begin
|
|
42
|
+
Time.parse(self)
|
|
43
|
+
rescue => e
|
|
44
|
+
raise Sequel::InvalidValue, "Invalid Time value '#{self}' (#{e.message})"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Sequel
|
|
2
|
+
# Contains methods that ease metaprogramming, used by some of Sequel's classes.
|
|
3
|
+
module Metaprogramming
|
|
4
|
+
# Add methods to the object's metaclass
|
|
5
|
+
def meta_def(name, &block)
|
|
6
|
+
meta_eval{define_method(name, &block)}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Make a singleton/class attribute accessor method(s).
|
|
12
|
+
# Replaces the construct:
|
|
13
|
+
#
|
|
14
|
+
# class << self
|
|
15
|
+
# attr_accessor *meths
|
|
16
|
+
# end
|
|
17
|
+
def metaattr_accessor(*meths)
|
|
18
|
+
meta_eval{attr_accessor(*meths)}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Make a singleton/class attribute reader method(s).
|
|
22
|
+
# Replaces the construct:
|
|
23
|
+
#
|
|
24
|
+
# class << self
|
|
25
|
+
# attr_reader *meths
|
|
26
|
+
# end
|
|
27
|
+
def metaattr_reader(*meths)
|
|
28
|
+
meta_eval{attr_reader(*meths)}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Evaluate the block in the context of the object's metaclass
|
|
32
|
+
def meta_eval(&block)
|
|
33
|
+
metaclass.instance_eval(&block)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The hidden singleton lurks behind everyone
|
|
37
|
+
def metaclass
|
|
38
|
+
class << self
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/sequel/model.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require 'sequel/core'
|
|
2
|
+
|
|
3
|
+
module Sequel
|
|
4
|
+
# Lets you create a Model subclass with its dataset already set.
|
|
5
|
+
# source can be an existing dataset or a symbol (in which case
|
|
6
|
+
# it will create a dataset using the default database with
|
|
7
|
+
# the given symbol as the table name).
|
|
8
|
+
#
|
|
9
|
+
# The purpose of this method is to set the dataset automatically
|
|
10
|
+
# for a model class, if the table name doesn't match the implicit
|
|
11
|
+
# name. This is neater than using set_dataset inside the class,
|
|
12
|
+
# doesn't require a bogus query for the schema, and allows
|
|
13
|
+
# it to work correctly in a system that uses code reloading.
|
|
14
|
+
#
|
|
15
|
+
# Example:
|
|
16
|
+
# class Comment < Sequel::Model(:something)
|
|
17
|
+
# table_name # => :something
|
|
18
|
+
# end
|
|
19
|
+
def self.Model(source)
|
|
20
|
+
Model::ANONYMOUS_MODEL_CLASSES[source] ||= Class.new(Model).set_dataset(source)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Sequel::Model is an object relational mapper built on top of Sequel core. Each
|
|
24
|
+
# model class is backed by a dataset instance, and many dataset methods can be
|
|
25
|
+
# called directly on the class. Model datasets return rows as model instances,
|
|
26
|
+
# which have fairly standard ORM instance behavior.
|
|
27
|
+
#
|
|
28
|
+
# Sequel::Model is built completely out of plugins, the only method not part of a
|
|
29
|
+
# plugin is the plugin method itself. Plugins can override any class, instance, or
|
|
30
|
+
# dataset method defined by a previous plugin and call super to get the default
|
|
31
|
+
# behavior.
|
|
32
|
+
#
|
|
33
|
+
# You can set the SEQUEL_NO_ASSOCIATIONS constant or environment variable to
|
|
34
|
+
# make Sequel not load the associations plugin by default.
|
|
35
|
+
class Model
|
|
36
|
+
# Map that stores model classes created with Sequel::Model(), to allow the reopening
|
|
37
|
+
# of classes when dealing with code reloading.
|
|
38
|
+
ANONYMOUS_MODEL_CLASSES = {}
|
|
39
|
+
|
|
40
|
+
# Class methods added to model that call the method of the same name on the dataset
|
|
41
|
+
DATASET_METHODS = %w'<< all avg count delete distinct eager eager_graph
|
|
42
|
+
each each_page empty? except exclude filter first from from_self
|
|
43
|
+
full_outer_join get graph group group_and_count group_by having import
|
|
44
|
+
inner_join insert insert_multiple intersect interval join join_table
|
|
45
|
+
last left_outer_join limit map multi_insert naked order order_by
|
|
46
|
+
order_more paginate print query range reverse_order right_outer_join
|
|
47
|
+
select select_all select_more server set set_graph_aliases
|
|
48
|
+
single_value to_csv to_hash transform union unfiltered unordered
|
|
49
|
+
update where with_sql'.map{|x| x.to_sym}
|
|
50
|
+
|
|
51
|
+
# Class instance variables to set to nil when a subclass is created, for -w compliance
|
|
52
|
+
EMPTY_INSTANCE_VARIABLES = [:@overridable_methods_module, :@db]
|
|
53
|
+
|
|
54
|
+
# Empty instance methods to create that the user can override to get hook/callback behavior.
|
|
55
|
+
# Just like any other method defined by Sequel, if you override one of these, you should
|
|
56
|
+
# call super to get the default behavior (while empty by default, they can also be defined
|
|
57
|
+
# by plugins).
|
|
58
|
+
HOOKS = [:after_initialize, :before_create, :after_create, :before_update,
|
|
59
|
+
:after_update, :before_save, :after_save, :before_destroy, :after_destroy,
|
|
60
|
+
:before_validation, :after_validation]
|
|
61
|
+
|
|
62
|
+
# Class instance variables that are inherited in subclasses. If the value is :dup, dup is called
|
|
63
|
+
# on the superclass's instance variable when creating the instance variable in the subclass.
|
|
64
|
+
# If the value is nil, the superclass's instance variable is used directly in the subclass.
|
|
65
|
+
INHERITED_INSTANCE_VARIABLES = {:@allowed_columns=>:dup, :@dataset_methods=>:dup,
|
|
66
|
+
:@dataset_method_modules=>:dup, :@primary_key=>nil, :@use_transactions=>nil,
|
|
67
|
+
:@raise_on_save_failure=>nil, :@restricted_columns=>:dup, :@restrict_primary_key=>nil,
|
|
68
|
+
:@simple_pk=>nil, :@simple_table=>nil, :@strict_param_setting=>nil,
|
|
69
|
+
:@typecast_empty_string_to_nil=>nil, :@typecast_on_assignment=>nil,
|
|
70
|
+
:@raise_on_typecast_failure=>nil}
|
|
71
|
+
|
|
72
|
+
# Regexp that determines if a method name is normal in the sense that
|
|
73
|
+
# it could be called directly in ruby code without using send. Used to
|
|
74
|
+
# avoid problems when using eval with a string to define methods.
|
|
75
|
+
NORMAL_METHOD_NAME_REGEXP = /\A[A-Za-z_][A-Za-z0-9_]*\z/
|
|
76
|
+
|
|
77
|
+
# The setter methods (methods ending with =) that are never allowed
|
|
78
|
+
# to be called automatically via set/update/new/etc..
|
|
79
|
+
RESTRICTED_SETTER_METHODS = %w"== === []= taguri= typecast_empty_string_to_nil= typecast_on_assignment= strict_param_setting= raise_on_save_failure= raise_on_typecast_failure="
|
|
80
|
+
|
|
81
|
+
# Regular expression that determines if the method is a valid setter name
|
|
82
|
+
# (i.e. it ends with =).
|
|
83
|
+
SETTER_METHOD_REGEXP = /=\z/
|
|
84
|
+
|
|
85
|
+
@allowed_columns = nil
|
|
86
|
+
@db = nil
|
|
87
|
+
@db_schema = nil
|
|
88
|
+
@dataset_method_modules = []
|
|
89
|
+
@dataset_methods = {}
|
|
90
|
+
@overridable_methods_module = nil
|
|
91
|
+
@primary_key = :id
|
|
92
|
+
@raise_on_save_failure = true
|
|
93
|
+
@raise_on_typecast_failure = true
|
|
94
|
+
@restrict_primary_key = true
|
|
95
|
+
@restricted_columns = nil
|
|
96
|
+
@simple_pk = nil
|
|
97
|
+
@simple_table = nil
|
|
98
|
+
@strict_param_setting = true
|
|
99
|
+
@typecast_empty_string_to_nil = true
|
|
100
|
+
@typecast_on_assignment = true
|
|
101
|
+
@use_transactions = true
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
require %w"inflections plugins base exceptions errors", "model"
|
|
105
|
+
if !defined?(::SEQUEL_NO_ASSOCIATIONS) && !ENV.has_key?('SEQUEL_NO_ASSOCIATIONS')
|
|
106
|
+
require 'associations', 'model'
|
|
107
|
+
Model.plugin Model::Associations
|
|
108
|
+
end
|
|
109
|
+
require 'deprecated', 'model'
|
|
110
|
+
end
|