sequel_core 1.5.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +116 -0
- data/COPYING +19 -19
- data/README +83 -32
- data/Rakefile +9 -20
- data/bin/sequel +43 -112
- data/doc/cheat_sheet.rdoc +225 -0
- data/doc/dataset_filtering.rdoc +257 -0
- data/lib/sequel_core/adapters/adapter_skeleton.rb +4 -2
- data/lib/sequel_core/adapters/ado.rb +3 -1
- data/lib/sequel_core/adapters/db2.rb +4 -2
- data/lib/sequel_core/adapters/dbi.rb +127 -113
- data/lib/sequel_core/adapters/informix.rb +4 -2
- data/lib/sequel_core/adapters/jdbc.rb +5 -3
- data/lib/sequel_core/adapters/mysql.rb +112 -46
- data/lib/sequel_core/adapters/odbc.rb +5 -7
- data/lib/sequel_core/adapters/odbc_mssql.rb +12 -3
- data/lib/sequel_core/adapters/openbase.rb +3 -1
- data/lib/sequel_core/adapters/oracle.rb +11 -9
- data/lib/sequel_core/adapters/postgres.rb +261 -262
- data/lib/sequel_core/adapters/sqlite.rb +72 -22
- data/lib/sequel_core/connection_pool.rb +140 -73
- data/lib/sequel_core/core_ext.rb +201 -66
- data/lib/sequel_core/core_sql.rb +123 -153
- data/lib/sequel_core/database/schema.rb +156 -0
- data/lib/sequel_core/database.rb +321 -338
- data/lib/sequel_core/dataset/callback.rb +11 -12
- data/lib/sequel_core/dataset/convenience.rb +213 -240
- data/lib/sequel_core/dataset/pagination.rb +58 -43
- data/lib/sequel_core/dataset/parse_tree_sequelizer.rb +331 -0
- data/lib/sequel_core/dataset/query.rb +41 -0
- data/lib/sequel_core/dataset/schema.rb +15 -0
- data/lib/sequel_core/dataset/sequelizer.rb +41 -373
- data/lib/sequel_core/dataset/sql.rb +741 -632
- data/lib/sequel_core/dataset.rb +183 -168
- data/lib/sequel_core/deprecated.rb +1 -169
- data/lib/sequel_core/exceptions.rb +24 -19
- data/lib/sequel_core/migration.rb +44 -52
- data/lib/sequel_core/object_graph.rb +43 -42
- data/lib/sequel_core/pretty_table.rb +71 -76
- data/lib/sequel_core/schema/generator.rb +163 -105
- data/lib/sequel_core/schema/sql.rb +250 -93
- data/lib/sequel_core/schema.rb +2 -8
- data/lib/sequel_core/sql.rb +394 -0
- data/lib/sequel_core/worker.rb +37 -27
- data/lib/sequel_core.rb +99 -45
- data/spec/adapters/informix_spec.rb +0 -1
- data/spec/adapters/mysql_spec.rb +177 -124
- data/spec/adapters/oracle_spec.rb +0 -1
- data/spec/adapters/postgres_spec.rb +98 -58
- data/spec/adapters/sqlite_spec.rb +45 -4
- data/spec/blockless_filters_spec.rb +269 -0
- data/spec/connection_pool_spec.rb +21 -18
- data/spec/core_ext_spec.rb +169 -19
- data/spec/core_sql_spec.rb +56 -49
- data/spec/database_spec.rb +78 -17
- data/spec/dataset_spec.rb +300 -428
- data/spec/migration_spec.rb +1 -1
- data/spec/object_graph_spec.rb +5 -11
- data/spec/rcov.opts +1 -1
- data/spec/schema_generator_spec.rb +16 -4
- data/spec/schema_spec.rb +89 -10
- data/spec/sequelizer_spec.rb +56 -56
- data/spec/spec.opts +0 -5
- data/spec/spec_config.rb +7 -0
- data/spec/spec_config.rb.example +5 -5
- data/spec/spec_helper.rb +6 -0
- data/spec/worker_spec.rb +1 -1
- metadata +78 -63
@@ -1,6 +1,19 @@
|
|
1
1
|
module Sequel
|
2
|
+
# The Schema module holds the schema generators and the SQL code relating
|
3
|
+
# to SQL DDL (Data Definition Language).
|
2
4
|
module Schema
|
5
|
+
# Schema::Generator is used to create tables. It takes a Database
|
6
|
+
# object and a block of column/index/constraint specifications, and
|
7
|
+
# creates a table in the database based on the specifications.
|
8
|
+
#
|
9
|
+
# Schema::Generator has some methods but also includes method_missing,
|
10
|
+
# allowing users to specify column type as a method instead of using
|
11
|
+
# the column method, which makes for a nicer DSL.
|
12
|
+
#
|
13
|
+
# See Database#create_table.
|
3
14
|
class Generator
|
15
|
+
# Set the database in which to create the table, and evaluate the block
|
16
|
+
# in the context of this object.
|
4
17
|
def initialize(db, &block)
|
5
18
|
@db = db
|
6
19
|
@columns = []
|
@@ -9,171 +22,216 @@ module Sequel
|
|
9
22
|
instance_eval(&block) if block
|
10
23
|
end
|
11
24
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def primary_key_name
|
17
|
-
@primary_key ? @primary_key[:name] : nil
|
18
|
-
end
|
19
|
-
|
20
|
-
def primary_key(name, *args)
|
21
|
-
@primary_key = @db.serial_primary_key_options.merge({:name => name})
|
22
|
-
|
23
|
-
if opts = args.pop
|
24
|
-
opts = {:type => opts} unless opts.is_a?(Hash)
|
25
|
-
if type = args.pop
|
26
|
-
opts.merge!(:type => type)
|
27
|
-
end
|
28
|
-
@primary_key.merge!(opts)
|
29
|
-
end
|
30
|
-
@primary_key
|
25
|
+
# Add a unnamed constraint to the DDL, specified by the given block
|
26
|
+
# or args.
|
27
|
+
def check(*args, &block)
|
28
|
+
constraint(nil, *args, &block)
|
31
29
|
end
|
32
|
-
|
30
|
+
|
31
|
+
# Add a column with the given name, type, and opts to the DDL.
|
32
|
+
#
|
33
|
+
# You can also create columns via method missing, so the following are
|
34
|
+
# equivalent:
|
35
|
+
#
|
36
|
+
# column :number, :integer
|
37
|
+
# integer :number
|
38
|
+
#
|
39
|
+
# The following options are supported:
|
40
|
+
#
|
41
|
+
# * :default - The default value for the column.
|
42
|
+
# * :index - Create an index on this column.
|
43
|
+
# * :key - For foreign key columns, the column in the associated table
|
44
|
+
# that this column references. Unnecessary if this column
|
45
|
+
# references the primary key of the associated table.
|
46
|
+
# * :null - Mark the column as allowing NULL values (if true),
|
47
|
+
# or not allowing NULL values (if false). If unspecified, will default
|
48
|
+
# to whatever the database default is.
|
49
|
+
# * :on_delete - Specify the behavior of this column when being deleted.
|
50
|
+
# See Schema::SQL#on_delete_clause for options.
|
51
|
+
# * :size - The size of the column, generally used with string
|
52
|
+
# columns to specify the maximum number of characters the column will hold.
|
53
|
+
# * :unique - Mark the column is unique, generally has the same effect as
|
54
|
+
# creating a unique index on the column.
|
55
|
+
# * :unsigned - Make the column type unsigned, only useful for integer
|
56
|
+
# columns.
|
33
57
|
def column(name, type, opts = {})
|
34
58
|
@columns << {:name => name, :type => type}.merge(opts)
|
35
59
|
index(name) if opts[:index]
|
36
60
|
end
|
37
61
|
|
38
|
-
|
39
|
-
|
40
|
-
|
62
|
+
# Adds a named constraint (or unnamed if name is nil) to the DDL,
|
63
|
+
# with the given block or args.
|
64
|
+
def constraint(name, *args, &block)
|
65
|
+
@columns << {:name => name, :type => :check, :check => block || args}
|
41
66
|
end
|
42
67
|
|
43
|
-
|
44
|
-
|
68
|
+
# Return the DDL created by the generator as a array of two elements,
|
69
|
+
# the first being the columns and the second being the indexes.
|
70
|
+
def create_info
|
71
|
+
@columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
|
72
|
+
[@columns, @indexes]
|
45
73
|
end
|
46
74
|
|
47
|
-
|
48
|
-
|
75
|
+
# Add a foreign key in the table that references another table to the DDL. See column
|
76
|
+
# for available options.
|
77
|
+
def foreign_key(name, table=nil, opts = {})
|
78
|
+
opts = case table
|
79
|
+
when Hash
|
80
|
+
table.merge(opts)
|
81
|
+
when Symbol
|
82
|
+
opts.merge(:table=>table)
|
83
|
+
when NilClass
|
84
|
+
opts
|
85
|
+
else
|
86
|
+
raise(Error, "The seconds argument to foreign_key should be a Hash, Symbol, or nil")
|
87
|
+
end
|
88
|
+
column(name, :integer, opts)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Add a full text index on the given columns to the DDL.
|
92
|
+
def full_text_index(columns, opts = {})
|
93
|
+
index(columns, opts.merge(:type => :full_text))
|
49
94
|
end
|
50
95
|
|
96
|
+
# True if the DDL includes the creation of a column with the given name.
|
51
97
|
def has_column?(name)
|
52
|
-
@columns.
|
53
|
-
false
|
98
|
+
@columns.any?{|c| c[:name] == name}
|
54
99
|
end
|
55
100
|
|
101
|
+
# Add an index on the given column(s) with the given options to the DDL.
|
102
|
+
# The available options are:
|
103
|
+
#
|
104
|
+
# * :type - The type of index to use (only supported by some databases)
|
105
|
+
# * :unique - Make the index unique, so duplicate values are not allowed.
|
106
|
+
# * :where - Create a partial index (only supported by some databases)
|
56
107
|
def index(columns, opts = {})
|
57
|
-
|
58
|
-
@indexes << {:columns => columns}.merge(opts)
|
108
|
+
@indexes << {:columns => Array(columns)}.merge(opts)
|
59
109
|
end
|
60
110
|
|
61
|
-
|
62
|
-
|
111
|
+
# Add a column with the given type, name, and opts to the DDL. See column for available
|
112
|
+
# options.
|
113
|
+
def method_missing(type, name = nil, opts = {})
|
114
|
+
name ? column(name, type, opts) : super
|
63
115
|
end
|
64
116
|
|
117
|
+
# Add a column with the given name and primary key options to the DDL. You
|
118
|
+
# can optionally provide a type argument and/or an options hash argument
|
119
|
+
# to change the primary key options. See column for available options.
|
120
|
+
def primary_key(name, *args)
|
121
|
+
@primary_key = @db.serial_primary_key_options.merge({:name => name})
|
122
|
+
|
123
|
+
if opts = args.pop
|
124
|
+
opts = {:type => opts} unless opts.is_a?(Hash)
|
125
|
+
if type = args.pop
|
126
|
+
opts.merge!(:type => type)
|
127
|
+
end
|
128
|
+
@primary_key.merge!(opts)
|
129
|
+
end
|
130
|
+
@primary_key
|
131
|
+
end
|
132
|
+
|
133
|
+
# The name of the primary key for this table, if it has a primary key.
|
134
|
+
def primary_key_name
|
135
|
+
@primary_key[:name] if @primary_key
|
136
|
+
end
|
137
|
+
|
138
|
+
# Add a spatial index on the given columns to the DDL.
|
65
139
|
def spatial_index(columns, opts = {})
|
66
140
|
index(columns, opts.merge(:type => :spatial))
|
67
141
|
end
|
68
142
|
|
143
|
+
# Add a unique index on the given columns to the DDL.
|
69
144
|
def unique(columns, opts = {})
|
70
145
|
index(columns, opts.merge(:unique => true))
|
71
146
|
end
|
72
|
-
|
73
|
-
def create_info
|
74
|
-
if @primary_key && !has_column?(@primary_key[:name])
|
75
|
-
@columns.unshift(@primary_key)
|
76
|
-
end
|
77
|
-
[@columns, @indexes]
|
78
|
-
end
|
79
147
|
end
|
80
148
|
|
149
|
+
# The Schema::AlterTableGenerator creates DDL operations on existing tables,
|
150
|
+
# such as adding/removing/modifying columns/indexes/constraints.
|
81
151
|
class AlterTableGenerator
|
152
|
+
# An array of DDL operations to perform
|
82
153
|
attr_reader :operations
|
83
154
|
|
155
|
+
# Set the Database object to which to apply the DDL, and evaluate the
|
156
|
+
# block in the context of this object.
|
84
157
|
def initialize(db, &block)
|
85
158
|
@db = db
|
86
159
|
@operations = []
|
87
160
|
instance_eval(&block) if block
|
88
161
|
end
|
89
162
|
|
163
|
+
# Add a column with the given name, type, and opts to the DDL for the table.
|
164
|
+
# See Generator#column for the available options.
|
90
165
|
def add_column(name, type, opts = {})
|
91
|
-
@operations << {
|
92
|
-
:op => :add_column, \
|
93
|
-
:name => name, \
|
94
|
-
:type => type \
|
95
|
-
}.merge(opts)
|
166
|
+
@operations << {:op => :add_column, :name => name, :type => type}.merge(opts)
|
96
167
|
end
|
97
168
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
169
|
+
# Add a constraint with the given name and args to the DDL for the table.
|
170
|
+
# See Generator#constraint.
|
171
|
+
def add_constraint(name, *args, &block)
|
172
|
+
@operations << {:op => :add_constraint, :name => name, :type => :check, \
|
173
|
+
:check => block || args}
|
174
|
+
end
|
175
|
+
|
176
|
+
# Add a foreign key with the given name and referencing the given table
|
177
|
+
# to the DDL for the table. See Generator#column for the available options.
|
178
|
+
def add_foreign_key(name, table, opts = {})
|
179
|
+
add_column(name, :integer, {:table=>table}.merge(opts))
|
103
180
|
end
|
104
181
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
:new_name => new_name \
|
110
|
-
}.merge(opts)
|
182
|
+
# Add a full text index on the given columns to the DDL for the table.
|
183
|
+
# See Generator#index for available options.
|
184
|
+
def add_full_text_index(columns, opts = {})
|
185
|
+
add_index(columns, {:type=>:full_text}.merge(opts))
|
111
186
|
end
|
112
187
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
:type => type \
|
118
|
-
}
|
188
|
+
# Add an index on the given columns to the DDL for the table. See
|
189
|
+
# Generator#index for available options.
|
190
|
+
def add_index(columns, opts = {})
|
191
|
+
@operations << {:op => :add_index, :columns => Array(columns)}.merge(opts)
|
119
192
|
end
|
120
193
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
}
|
194
|
+
# Add a primary key to the DDL for the table. See Generator#column
|
195
|
+
# for the available options.
|
196
|
+
def add_primary_key(name, opts = {})
|
197
|
+
opts = @db.serial_primary_key_options.merge(opts)
|
198
|
+
add_column(name, opts.delete(:type), opts)
|
127
199
|
end
|
128
200
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
:columns => columns \
|
134
|
-
}.merge(opts)
|
201
|
+
# Add a spatial index on the given columns to the DDL for the table.
|
202
|
+
# See Generator#index for available options.
|
203
|
+
def add_spatial_index(columns, opts = {})
|
204
|
+
add_index(columns, {:type=>:spatial}.merge(opts))
|
135
205
|
end
|
136
206
|
|
137
|
-
|
138
|
-
|
139
|
-
@operations << {
|
140
|
-
:op => :add_index, \
|
141
|
-
:columns => columns, \
|
142
|
-
:type => :full_text \
|
143
|
-
}.merge(opts)
|
207
|
+
# Remove a column from the DDL for the table.
|
208
|
+
def drop_column(name)
|
209
|
+
@operations << {:op => :drop_column, :name => name}
|
144
210
|
end
|
145
211
|
|
146
|
-
|
147
|
-
|
148
|
-
@operations << {
|
149
|
-
:op => :add_index, \
|
150
|
-
:columns => columns, \
|
151
|
-
:type => :spatial \
|
152
|
-
}.merge(opts)
|
212
|
+
# Remove a constraint from the DDL for the table.
|
213
|
+
def drop_constraint(name)
|
214
|
+
@operations << {:op => :drop_constraint, :name => name}
|
153
215
|
end
|
154
216
|
|
217
|
+
# Remove an index from the DDL for the table.
|
155
218
|
def drop_index(columns)
|
156
|
-
|
157
|
-
@operations << { \
|
158
|
-
:op => :drop_index, \
|
159
|
-
:columns => columns \
|
160
|
-
}
|
219
|
+
@operations << {:op => :drop_index, :columns => Array(columns)}
|
161
220
|
end
|
162
221
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
222
|
+
# Modify a column's name in the DDL for the table.
|
223
|
+
def rename_column(name, new_name, opts = {})
|
224
|
+
@operations << {:op => :rename_column, :name => name, :new_name => new_name}.merge(opts)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Modify a column's default value in the DDL for the table.
|
228
|
+
def set_column_default(name, default)
|
229
|
+
@operations << {:op => :set_column_default, :name => name, :default => default}
|
170
230
|
end
|
171
231
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
:name => name \
|
176
|
-
}
|
232
|
+
# Modify a column's type in the DDL for the table.
|
233
|
+
def set_column_type(name, type)
|
234
|
+
@operations << {:op => :set_column_type, :name => name, :type => type}
|
177
235
|
end
|
178
236
|
end
|
179
237
|
end
|