activerecord 1.10.1 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +187 -19
- data/RUNNING_UNIT_TESTS +11 -0
- data/lib/active_record.rb +3 -1
- data/lib/active_record/acts/list.rb +25 -14
- data/lib/active_record/acts/nested_set.rb +4 -4
- data/lib/active_record/acts/tree.rb +18 -1
- data/lib/active_record/associations.rb +90 -17
- data/lib/active_record/associations/association_collection.rb +44 -5
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +17 -4
- data/lib/active_record/associations/has_many_association.rb +13 -3
- data/lib/active_record/associations/has_one_association.rb +19 -0
- data/lib/active_record/base.rb +292 -268
- data/lib/active_record/callbacks.rb +14 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +137 -75
- data/lib/active_record/connection_adapters/db2_adapter.rb +10 -8
- data/lib/active_record/connection_adapters/mysql_adapter.rb +91 -64
- data/lib/active_record/connection_adapters/oci_adapter.rb +6 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +113 -60
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +15 -12
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +159 -132
- data/lib/active_record/fixtures.rb +59 -12
- data/lib/active_record/locking.rb +10 -9
- data/lib/active_record/migration.rb +112 -5
- data/lib/active_record/query_cache.rb +64 -0
- data/lib/active_record/timestamp.rb +10 -8
- data/lib/active_record/validations.rb +121 -26
- data/rakefile +16 -10
- data/test/aaa_create_tables_test.rb +26 -48
- data/test/abstract_unit.rb +3 -0
- data/test/aggregations_test.rb +19 -19
- data/test/association_callbacks_test.rb +110 -0
- data/test/associations_go_eager_test.rb +48 -14
- data/test/associations_test.rb +344 -142
- data/test/base_test.rb +150 -31
- data/test/binary_test.rb +7 -0
- data/test/callbacks_test.rb +24 -5
- data/test/column_alias_test.rb +2 -2
- data/test/connections/native_sqlserver_odbc/connection.rb +26 -0
- data/test/deprecated_associations_test.rb +27 -28
- data/test/deprecated_finder_test.rb +8 -9
- data/test/finder_test.rb +52 -17
- data/test/fixtures/author.rb +39 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/categories_posts.yml +8 -0
- data/test/fixtures/category.rb +2 -0
- data/test/fixtures/comment.rb +3 -1
- data/test/fixtures/comments.yml +43 -1
- data/test/fixtures/companies.yml +14 -0
- data/test/fixtures/company.rb +1 -1
- data/test/fixtures/computers.yml +2 -1
- data/test/fixtures/db_definitions/db2.sql +7 -2
- data/test/fixtures/db_definitions/mysql.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql.sql +11 -6
- data/test/fixtures/db_definitions/oci.sql +7 -2
- data/test/fixtures/db_definitions/postgresql.drop.sql +3 -1
- data/test/fixtures/db_definitions/postgresql.sql +8 -5
- data/test/fixtures/db_definitions/sqlite.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite.sql +9 -4
- data/test/fixtures/db_definitions/sqlserver.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver.sql +12 -7
- data/test/fixtures/developer.rb +8 -1
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/post.rb +8 -2
- data/test/fixtures/posts.yml +21 -0
- data/test/fixtures/project.rb +14 -1
- data/test/fixtures/subscriber.rb +3 -0
- data/test/fixtures_test.rb +14 -0
- data/test/inheritance_test.rb +30 -22
- data/test/lifecycle_test.rb +3 -4
- data/test/locking_test.rb +2 -4
- data/test/migration_test.rb +186 -0
- data/test/mixin_nested_set_test.rb +19 -19
- data/test/mixin_test.rb +88 -88
- data/test/modules_test.rb +5 -10
- data/test/multiple_db_test.rb +2 -0
- data/test/pk_test.rb +8 -12
- data/test/reflection_test.rb +8 -4
- data/test/schema_test_postgresql.rb +63 -0
- data/test/thread_safety_test.rb +4 -1
- data/test/transactions_test.rb +9 -2
- data/test/unconnected_test.rb +1 -0
- data/test/validations_test.rb +151 -8
- metadata +11 -5
- data/test/migration_mysql.rb +0 -104
@@ -153,7 +153,7 @@ module ActiveRecord
|
|
153
153
|
#
|
154
154
|
# == The after_find and after_initialize exceptions
|
155
155
|
#
|
156
|
-
# Because after_find and after_initialize is called for each object instantiated found by a finder, such as Base.
|
156
|
+
# Because after_find and after_initialize is called for each object instantiated found by a finder, such as Base.find(:all), we've had
|
157
157
|
# to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, after_find and
|
158
158
|
# after_initialize will only be run if an explicit implementation is defined (<tt>def after_find</tt>). In that case, all of the
|
159
159
|
# callback types will be called.
|
@@ -213,17 +213,13 @@ module ActiveRecord
|
|
213
213
|
module ClassMethods #:nodoc:
|
214
214
|
def instantiate_with_callbacks(record)
|
215
215
|
object = instantiate_without_callbacks(record)
|
216
|
-
|
217
|
-
if object.
|
216
|
+
|
217
|
+
if object.respond_to_without_attributes?(:after_find)
|
218
218
|
object.send(:callback, :after_find)
|
219
|
-
else
|
220
|
-
object.send(:invoke_and_notify, :after_find)
|
221
219
|
end
|
222
220
|
|
223
|
-
if object.
|
221
|
+
if object.respond_to_without_attributes?(:after_initialize)
|
224
222
|
object.send(:callback, :after_initialize)
|
225
|
-
else
|
226
|
-
object.send(:invoke_and_notify, :after_initialize)
|
227
223
|
end
|
228
224
|
|
229
225
|
object
|
@@ -231,14 +227,15 @@ module ActiveRecord
|
|
231
227
|
end
|
232
228
|
|
233
229
|
# Is called when the object was instantiated by one of the finders, like Base.find.
|
234
|
-
#
|
230
|
+
#def after_find() end
|
235
231
|
|
236
232
|
# Is called after the object has been instantiated by a call to Base.new.
|
237
|
-
#
|
233
|
+
#def after_initialize() end
|
234
|
+
|
238
235
|
def initialize_with_callbacks(attributes = nil) #:nodoc:
|
239
236
|
initialize_without_callbacks(attributes)
|
240
237
|
result = yield self if block_given?
|
241
|
-
|
238
|
+
callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
|
242
239
|
result
|
243
240
|
end
|
244
241
|
|
@@ -328,6 +325,8 @@ module ActiveRecord
|
|
328
325
|
|
329
326
|
private
|
330
327
|
def callback(method)
|
328
|
+
notify(method)
|
329
|
+
|
331
330
|
callbacks_for(method).each do |callback|
|
332
331
|
result = case callback
|
333
332
|
when Symbol
|
@@ -346,8 +345,9 @@ module ActiveRecord
|
|
346
345
|
return false if result == false
|
347
346
|
end
|
348
347
|
|
349
|
-
|
350
|
-
|
348
|
+
send(method) if respond_to_without_attributes?(method)
|
349
|
+
|
350
|
+
return true
|
351
351
|
end
|
352
352
|
|
353
353
|
def callbacks_for(method)
|
@@ -355,8 +355,8 @@ module ActiveRecord
|
|
355
355
|
end
|
356
356
|
|
357
357
|
def invoke_and_notify(method)
|
358
|
-
send(method) if respond_to_without_attributes?(method)
|
359
358
|
notify(method)
|
359
|
+
send(method) if respond_to_without_attributes?(method)
|
360
360
|
end
|
361
361
|
|
362
362
|
def notify(method) #:nodoc:
|
@@ -16,7 +16,7 @@ def require_library_or_gem(library_name)
|
|
16
16
|
raise cannot_require
|
17
17
|
end
|
18
18
|
# 2. Rubygems is installed and loaded. Try to load the library again
|
19
|
-
begin
|
19
|
+
begin
|
20
20
|
require library_name
|
21
21
|
rescue LoadError => gem_not_installed
|
22
22
|
raise cannot_require
|
@@ -32,7 +32,7 @@ module ActiveRecord
|
|
32
32
|
@config, @adapter_method = config, adapter_method
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# The class -> [adapter_method, config] map
|
37
37
|
@@defined_connections = {}
|
38
38
|
|
@@ -92,32 +92,32 @@ module ActiveRecord
|
|
92
92
|
# for (not necessarily the current class).
|
93
93
|
def self.retrieve_connection #:nodoc:
|
94
94
|
klass = self
|
95
|
-
|
96
|
-
|
97
|
-
if Thread.current['active_connections'][klass]
|
98
|
-
return
|
99
|
-
elsif @@defined_connections[klass]
|
100
|
-
klass.connection =
|
95
|
+
ar_super = ActiveRecord::Base.superclass
|
96
|
+
until klass == ar_super
|
97
|
+
if conn = (Thread.current['active_connections'] ||= {})[klass]
|
98
|
+
return conn
|
99
|
+
elsif conn = @@defined_connections[klass]
|
100
|
+
klass.connection = conn
|
101
101
|
return self.connection
|
102
102
|
end
|
103
103
|
klass = klass.superclass
|
104
104
|
end
|
105
105
|
raise ConnectionNotEstablished
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
# Returns true if a connection that's accessible to this class have already been opened.
|
109
109
|
def self.connected?
|
110
110
|
klass = self
|
111
111
|
until klass == ActiveRecord::Base.superclass
|
112
112
|
if Thread.current['active_connections'].is_a?(Hash) && Thread.current['active_connections'][klass]
|
113
|
-
return true
|
113
|
+
return true
|
114
114
|
else
|
115
115
|
klass = klass.superclass
|
116
116
|
end
|
117
117
|
end
|
118
118
|
return false
|
119
119
|
end
|
120
|
-
|
120
|
+
|
121
121
|
# Remove the connection for this class. This will close the active
|
122
122
|
# connection and the defined connection (if they exist). The result
|
123
123
|
# can be used as argument for establish_connection, for easy
|
@@ -129,7 +129,7 @@ module ActiveRecord
|
|
129
129
|
Thread.current['active_connections'][klass] = nil
|
130
130
|
conn.config if conn
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
# Set the connection for the class.
|
134
134
|
def self.connection=(spec)
|
135
135
|
raise ConnectionNotEstablished unless spec
|
@@ -152,14 +152,10 @@ module ActiveRecord
|
|
152
152
|
# The type parameter should either contain :integer, :float, :datetime, :date, :text, or :string
|
153
153
|
# The sql_type is just used for extracting the limit, such as 10 in "varchar(10)"
|
154
154
|
def initialize(name, default, sql_type = nil)
|
155
|
-
@name, @default, @type = name, default, simplified_type(sql_type)
|
155
|
+
@name, @default, @type = name, type_cast(default), simplified_type(sql_type)
|
156
156
|
@limit = extract_limit(sql_type) unless sql_type.nil?
|
157
157
|
end
|
158
158
|
|
159
|
-
def default
|
160
|
-
type_cast(@default)
|
161
|
-
end
|
162
|
-
|
163
159
|
def klass
|
164
160
|
case type
|
165
161
|
when :integer then Fixnum
|
@@ -173,7 +169,7 @@ module ActiveRecord
|
|
173
169
|
when :boolean then Object
|
174
170
|
end
|
175
171
|
end
|
176
|
-
|
172
|
+
|
177
173
|
def type_cast(value)
|
178
174
|
if value.nil? then return nil end
|
179
175
|
case type
|
@@ -190,18 +186,18 @@ module ActiveRecord
|
|
190
186
|
else value
|
191
187
|
end
|
192
188
|
end
|
193
|
-
|
189
|
+
|
194
190
|
def human_name
|
195
191
|
Base.human_attribute_name(@name)
|
196
192
|
end
|
197
|
-
|
193
|
+
|
198
194
|
def string_to_binary(value)
|
199
195
|
value
|
200
|
-
end
|
196
|
+
end
|
201
197
|
|
202
198
|
def binary_to_string(value)
|
203
199
|
value
|
204
|
-
end
|
200
|
+
end
|
205
201
|
|
206
202
|
private
|
207
203
|
def string_to_date(string)
|
@@ -210,7 +206,7 @@ module ActiveRecord
|
|
210
206
|
# treat 0000-00-00 as nil
|
211
207
|
Date.new(date_array[0], date_array[1], date_array[2]) rescue nil
|
212
208
|
end
|
213
|
-
|
209
|
+
|
214
210
|
def string_to_time(string)
|
215
211
|
return string unless string.is_a?(String)
|
216
212
|
time_array = ParseDate.parsedate(string.to_s).compact
|
@@ -224,12 +220,12 @@ module ActiveRecord
|
|
224
220
|
# pad the resulting array with dummy date information
|
225
221
|
time_array[0] = 2000; time_array[1] = 1; time_array[2] = 1;
|
226
222
|
Time.send(Base.default_timezone, *time_array) rescue nil
|
227
|
-
end
|
228
|
-
|
223
|
+
end
|
224
|
+
|
229
225
|
def extract_limit(sql_type)
|
230
226
|
$1.to_i if sql_type =~ /\((.*)\)/
|
231
227
|
end
|
232
|
-
|
228
|
+
|
233
229
|
def simplified_type(field_type)
|
234
230
|
case field_type
|
235
231
|
when /int/i
|
@@ -262,8 +258,6 @@ module ActiveRecord
|
|
262
258
|
class AbstractAdapter
|
263
259
|
@@row_even = true
|
264
260
|
|
265
|
-
include Benchmark
|
266
|
-
|
267
261
|
def initialize(connection, logger = nil) # :nodoc:
|
268
262
|
@connection, @logger = connection, logger
|
269
263
|
@runtime = 0
|
@@ -271,7 +265,7 @@ module ActiveRecord
|
|
271
265
|
|
272
266
|
# Returns an array of record hashes with the column names as a keys and fields as values.
|
273
267
|
def select_all(sql, name = nil) end
|
274
|
-
|
268
|
+
|
275
269
|
# Returns a record hash with the column names as a keys and fields as values.
|
276
270
|
def select_one(sql, name = nil) end
|
277
271
|
|
@@ -310,8 +304,8 @@ module ActiveRecord
|
|
310
304
|
|
311
305
|
# Begins the transaction (and turns off auto-committing).
|
312
306
|
def begin_db_transaction() end
|
313
|
-
|
314
|
-
# Commits the transaction (and turns on auto-committing).
|
307
|
+
|
308
|
+
# Commits the transaction (and turns on auto-committing).
|
315
309
|
def commit_db_transaction() end
|
316
310
|
|
317
311
|
# Rolls back the transaction (and turns on auto-committing). Must be done if the transaction block
|
@@ -320,7 +314,7 @@ module ActiveRecord
|
|
320
314
|
|
321
315
|
def quote(value, column = nil)
|
322
316
|
case value
|
323
|
-
when String
|
317
|
+
when String
|
324
318
|
if column && column.type == :binary
|
325
319
|
"'#{quote_string(column.string_to_binary(value))}'" # ' (for ruby-mode)
|
326
320
|
else
|
@@ -330,7 +324,7 @@ module ActiveRecord
|
|
330
324
|
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
|
331
325
|
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
|
332
326
|
when Float, Fixnum, Bignum then value.to_s
|
333
|
-
when Date then "'#{value.to_s}'"
|
327
|
+
when Date then "'#{value.to_s}'"
|
334
328
|
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
|
335
329
|
else "'#{quote_string(value.to_yaml)}'"
|
336
330
|
end
|
@@ -352,36 +346,37 @@ module ActiveRecord
|
|
352
346
|
# Returns a string of the CREATE TABLE SQL statements for recreating the entire structure of the database.
|
353
347
|
def structure_dump() end
|
354
348
|
|
355
|
-
def add_limit!(sql,
|
356
|
-
|
357
|
-
|
358
|
-
add_limit_with_offset!(sql, limit.to_i, offset.to_i)
|
359
|
-
else
|
360
|
-
add_limit_without_offset!(sql, limit)
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
def add_limit_with_offset!(sql, limit, offset)
|
365
|
-
sql << " LIMIT #{limit} OFFSET #{offset}"
|
349
|
+
def add_limit!(sql, options)
|
350
|
+
return unless options
|
351
|
+
add_limit_offset!(sql, options)
|
366
352
|
end
|
367
|
-
|
368
|
-
def
|
369
|
-
|
353
|
+
|
354
|
+
def add_limit_offset!(sql, options)
|
355
|
+
return if options[:limit].nil?
|
356
|
+
sql << " LIMIT #{options[:limit]}"
|
357
|
+
sql << " OFFSET #{options[:offset]}" if options.has_key?(:offset) and !options[:offset].nil?
|
370
358
|
end
|
371
359
|
|
360
|
+
|
372
361
|
def initialize_schema_information
|
373
362
|
begin
|
374
|
-
execute "CREATE TABLE schema_info (version #{
|
363
|
+
execute "CREATE TABLE schema_info (version #{type_to_sql(:integer)})"
|
375
364
|
insert "INSERT INTO schema_info (version) VALUES(0)"
|
376
365
|
rescue ActiveRecord::StatementInvalid
|
377
366
|
# Schema has been intialized
|
378
367
|
end
|
379
368
|
end
|
380
|
-
|
381
|
-
def create_table(name, options =
|
382
|
-
|
383
|
-
table_definition
|
384
|
-
|
369
|
+
|
370
|
+
def create_table(name, options = {})
|
371
|
+
table_definition = TableDefinition.new(self)
|
372
|
+
table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false
|
373
|
+
|
374
|
+
yield table_definition
|
375
|
+
create_sql = "CREATE TABLE #{name} ("
|
376
|
+
create_sql << table_definition.to_sql
|
377
|
+
create_sql << ") #{options[:options]}"
|
378
|
+
|
379
|
+
execute create_sql
|
385
380
|
end
|
386
381
|
|
387
382
|
def drop_table(name)
|
@@ -390,29 +385,68 @@ module ActiveRecord
|
|
390
385
|
|
391
386
|
def add_column(table_name, column_name, type, options = {})
|
392
387
|
native_type = native_database_types[type]
|
393
|
-
add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{
|
394
|
-
add_column_sql
|
395
|
-
add_column_sql << " DEFAULT '#{options[:default]}'" if options[:default]
|
388
|
+
add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{type_to_sql(type, options[:limit])}"
|
389
|
+
add_column_options!(add_column_sql, options)
|
396
390
|
execute(add_column_sql)
|
397
391
|
end
|
398
|
-
|
392
|
+
|
399
393
|
def remove_column(table_name, column_name)
|
400
394
|
execute "ALTER TABLE #{table_name} DROP #{column_name}"
|
395
|
+
end
|
396
|
+
|
397
|
+
def change_column(table_name, column_name, type, options = {})
|
398
|
+
raise NotImplementedError, "change_column is not implemented"
|
399
|
+
end
|
400
|
+
|
401
|
+
def change_column_default(table_name, column_name, default)
|
402
|
+
raise NotImplementedError, "change_column_default is not implemented"
|
403
|
+
end
|
404
|
+
|
405
|
+
def supports_migrations?
|
406
|
+
false
|
407
|
+
end
|
408
|
+
|
409
|
+
def rename_column(table_name, column_name, new_column_name)
|
410
|
+
raise NotImplementedError, "rename_column is not implemented"
|
401
411
|
end
|
402
412
|
|
413
|
+
def add_index(table_name, column_name, index_type = '')
|
414
|
+
execute "CREATE #{index_type} INDEX #{table_name}_#{column_name.to_a.first}_index ON #{table_name} (#{column_name.to_a.join(", ")})"
|
415
|
+
end
|
403
416
|
|
404
|
-
|
405
|
-
|
406
|
-
|
417
|
+
def remove_index(table_name, column_name)
|
418
|
+
execute "DROP INDEX #{table_name}_#{column_name}_index ON #{table_name}"
|
419
|
+
end
|
420
|
+
|
421
|
+
def supports_migrations?
|
422
|
+
false
|
423
|
+
end
|
424
|
+
|
425
|
+
def native_database_types
|
426
|
+
{}
|
427
|
+
end
|
428
|
+
|
429
|
+
def type_to_sql(type, limit = nil)
|
430
|
+
native = native_database_types[type]
|
431
|
+
limit ||= native[:limit]
|
432
|
+
column_type_sql = native[:name]
|
433
|
+
column_type_sql << "(#{limit})" if limit
|
434
|
+
column_type_sql
|
435
|
+
end
|
436
|
+
|
437
|
+
protected
|
438
|
+
def log(sql, name)
|
407
439
|
begin
|
408
|
-
if
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
440
|
+
if block_given?
|
441
|
+
if @logger and @logger.level <= Logger::INFO
|
442
|
+
result = nil
|
443
|
+
seconds = Benchmark.realtime { result = yield }
|
444
|
+
@runtime += seconds
|
445
|
+
log_info(sql, name, seconds)
|
446
|
+
result
|
447
|
+
else
|
448
|
+
yield
|
449
|
+
end
|
416
450
|
else
|
417
451
|
log_info(sql, name, 0)
|
418
452
|
nil
|
@@ -424,11 +458,11 @@ module ActiveRecord
|
|
424
458
|
end
|
425
459
|
|
426
460
|
def log_info(sql, name, runtime)
|
427
|
-
|
461
|
+
return unless @logger
|
428
462
|
|
429
|
-
@logger.
|
463
|
+
@logger.debug(
|
430
464
|
format_log_entry(
|
431
|
-
"#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})",
|
465
|
+
"#{name.nil? ? "SQL" : name} (#{sprintf("%f", runtime)})",
|
432
466
|
sql.gsub(/ +/, " ")
|
433
467
|
)
|
434
468
|
)
|
@@ -441,7 +475,7 @@ module ActiveRecord
|
|
441
475
|
else
|
442
476
|
@@row_even = true; caller_color = "1;36"; message_color = "4;35"; dump_color = "0;37"
|
443
477
|
end
|
444
|
-
|
478
|
+
|
445
479
|
log_entry = " \e[#{message_color}m#{message}\e[m"
|
446
480
|
log_entry << " \e[#{dump_color}m%s\e[m" % dump if dump.kind_of?(String) && !dump.nil?
|
447
481
|
log_entry << " \e[#{dump_color}m%p\e[m" % dump if !dump.kind_of?(String) && !dump.nil?
|
@@ -450,19 +484,47 @@ module ActiveRecord
|
|
450
484
|
"%s %s" % [message, dump]
|
451
485
|
end
|
452
486
|
end
|
487
|
+
|
488
|
+
def add_column_options!(sql, options)
|
489
|
+
sql << " DEFAULT '#{options[:default]}'" unless options[:default].nil?
|
490
|
+
end
|
453
491
|
end
|
454
492
|
|
455
493
|
class TableDefinition
|
456
494
|
attr_accessor :columns
|
457
|
-
|
458
|
-
def initialize
|
495
|
+
|
496
|
+
def initialize(base)
|
459
497
|
@columns = []
|
498
|
+
@base = base
|
499
|
+
end
|
500
|
+
|
501
|
+
def primary_key(name)
|
502
|
+
@columns << "#{name} #{native[:primary_key]}"
|
503
|
+
self
|
460
504
|
end
|
461
505
|
|
462
506
|
def column(name, type, options = {})
|
463
|
-
|
507
|
+
limit = options[:limit] || native[type.to_sym][:limit]
|
508
|
+
|
509
|
+
column_sql = "#{name} #{type_to_sql(type.to_sym, options[:limit])}"
|
510
|
+
column_sql << " DEFAULT '#{options[:default]}'" if options[:default]
|
511
|
+
@columns << column_sql
|
464
512
|
self
|
465
513
|
end
|
514
|
+
|
515
|
+
def to_sql
|
516
|
+
@columns.join(", ")
|
517
|
+
end
|
518
|
+
|
519
|
+
private
|
520
|
+
|
521
|
+
def type_to_sql(name, limit)
|
522
|
+
@base.type_to_sql(name, limit)
|
523
|
+
end
|
524
|
+
|
525
|
+
def native
|
526
|
+
@base.native_database_types
|
527
|
+
end
|
466
528
|
end
|
467
529
|
end
|
468
530
|
end
|