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.
Files changed (68) hide show
  1. data/CHANGELOG +116 -0
  2. data/COPYING +19 -19
  3. data/README +83 -32
  4. data/Rakefile +9 -20
  5. data/bin/sequel +43 -112
  6. data/doc/cheat_sheet.rdoc +225 -0
  7. data/doc/dataset_filtering.rdoc +257 -0
  8. data/lib/sequel_core/adapters/adapter_skeleton.rb +4 -2
  9. data/lib/sequel_core/adapters/ado.rb +3 -1
  10. data/lib/sequel_core/adapters/db2.rb +4 -2
  11. data/lib/sequel_core/adapters/dbi.rb +127 -113
  12. data/lib/sequel_core/adapters/informix.rb +4 -2
  13. data/lib/sequel_core/adapters/jdbc.rb +5 -3
  14. data/lib/sequel_core/adapters/mysql.rb +112 -46
  15. data/lib/sequel_core/adapters/odbc.rb +5 -7
  16. data/lib/sequel_core/adapters/odbc_mssql.rb +12 -3
  17. data/lib/sequel_core/adapters/openbase.rb +3 -1
  18. data/lib/sequel_core/adapters/oracle.rb +11 -9
  19. data/lib/sequel_core/adapters/postgres.rb +261 -262
  20. data/lib/sequel_core/adapters/sqlite.rb +72 -22
  21. data/lib/sequel_core/connection_pool.rb +140 -73
  22. data/lib/sequel_core/core_ext.rb +201 -66
  23. data/lib/sequel_core/core_sql.rb +123 -153
  24. data/lib/sequel_core/database/schema.rb +156 -0
  25. data/lib/sequel_core/database.rb +321 -338
  26. data/lib/sequel_core/dataset/callback.rb +11 -12
  27. data/lib/sequel_core/dataset/convenience.rb +213 -240
  28. data/lib/sequel_core/dataset/pagination.rb +58 -43
  29. data/lib/sequel_core/dataset/parse_tree_sequelizer.rb +331 -0
  30. data/lib/sequel_core/dataset/query.rb +41 -0
  31. data/lib/sequel_core/dataset/schema.rb +15 -0
  32. data/lib/sequel_core/dataset/sequelizer.rb +41 -373
  33. data/lib/sequel_core/dataset/sql.rb +741 -632
  34. data/lib/sequel_core/dataset.rb +183 -168
  35. data/lib/sequel_core/deprecated.rb +1 -169
  36. data/lib/sequel_core/exceptions.rb +24 -19
  37. data/lib/sequel_core/migration.rb +44 -52
  38. data/lib/sequel_core/object_graph.rb +43 -42
  39. data/lib/sequel_core/pretty_table.rb +71 -76
  40. data/lib/sequel_core/schema/generator.rb +163 -105
  41. data/lib/sequel_core/schema/sql.rb +250 -93
  42. data/lib/sequel_core/schema.rb +2 -8
  43. data/lib/sequel_core/sql.rb +394 -0
  44. data/lib/sequel_core/worker.rb +37 -27
  45. data/lib/sequel_core.rb +99 -45
  46. data/spec/adapters/informix_spec.rb +0 -1
  47. data/spec/adapters/mysql_spec.rb +177 -124
  48. data/spec/adapters/oracle_spec.rb +0 -1
  49. data/spec/adapters/postgres_spec.rb +98 -58
  50. data/spec/adapters/sqlite_spec.rb +45 -4
  51. data/spec/blockless_filters_spec.rb +269 -0
  52. data/spec/connection_pool_spec.rb +21 -18
  53. data/spec/core_ext_spec.rb +169 -19
  54. data/spec/core_sql_spec.rb +56 -49
  55. data/spec/database_spec.rb +78 -17
  56. data/spec/dataset_spec.rb +300 -428
  57. data/spec/migration_spec.rb +1 -1
  58. data/spec/object_graph_spec.rb +5 -11
  59. data/spec/rcov.opts +1 -1
  60. data/spec/schema_generator_spec.rb +16 -4
  61. data/spec/schema_spec.rb +89 -10
  62. data/spec/sequelizer_spec.rb +56 -56
  63. data/spec/spec.opts +0 -5
  64. data/spec/spec_config.rb +7 -0
  65. data/spec/spec_config.rb.example +5 -5
  66. data/spec/spec_helper.rb +6 -0
  67. data/spec/worker_spec.rb +1 -1
  68. 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
- def method_missing(type, name = nil, opts = {})
13
- name ? column(name, type, opts) : super
14
- end
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
- def foreign_key(name, opts = {})
39
- @columns << {:name => name, :type => :integer}.merge(opts)
40
- index(name) if opts[:index]
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
- def check(*args, &block)
44
- @columns << {:name => nil, :type => :check, :check => block || args}
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
- def constraint(name, *args, &block)
48
- @columns << {:name => name, :type => :check, :check => block || args}
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.each {|c| return true if c[:name] == name}
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
- columns = [columns] unless columns.is_a?(Array)
58
- @indexes << {:columns => columns}.merge(opts)
108
+ @indexes << {:columns => Array(columns)}.merge(opts)
59
109
  end
60
110
 
61
- def full_text_index(columns, opts = {})
62
- index(columns, opts.merge(:type => :full_text))
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
- def drop_column(name)
99
- @operations << { \
100
- :op => :drop_column, \
101
- :name => name \
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
- def rename_column(name, new_name, opts = {})
106
- @operations << { \
107
- :op => :rename_column, \
108
- :name => name, \
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
- def set_column_type(name, type)
114
- @operations << { \
115
- :op => :set_column_type, \
116
- :name => name, \
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
- def set_column_default(name, default)
122
- @operations << { \
123
- :op => :set_column_default, \
124
- :name => name, \
125
- :default => default \
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
- def add_index(columns, opts = {})
130
- columns = [columns] unless columns.is_a?(Array)
131
- @operations << { \
132
- :op => :add_index, \
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
- def add_full_text_index(columns, opts = {})
138
- columns = [columns] unless columns.is_a?(Array)
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
- def add_spatial_index(columns, opts = {})
147
- columns = [columns] unless columns.is_a?(Array)
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
- columns = [columns] unless columns.is_a?(Array)
157
- @operations << { \
158
- :op => :drop_index, \
159
- :columns => columns \
160
- }
219
+ @operations << {:op => :drop_index, :columns => Array(columns)}
161
220
  end
162
221
 
163
- def add_constraint(name, *args, &block)
164
- @operations << { \
165
- :op => :add_constraint, \
166
- :name => name, \
167
- :type => :check, \
168
- :check => block || args \
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
- def drop_constraint(name)
173
- @operations << { \
174
- :op => :drop_constraint, \
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