activerecord 1.7.0 → 1.8.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 +55 -0
- data/lib/active_record.rb +5 -7
- data/lib/active_record/aggregations.rb +2 -1
- data/lib/active_record/associations.rb +2 -1
- data/lib/active_record/associations/association_proxy.rb +4 -0
- data/lib/active_record/associations/has_many_association.rb +6 -4
- data/lib/active_record/associations/has_one_association.rb +7 -2
- data/lib/active_record/base.rb +36 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +58 -10
- data/lib/active_record/connection_adapters/mysql_adapter.rb +30 -9
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +17 -0
- data/lib/active_record/fixtures.rb +108 -31
- data/lib/active_record/migration.rb +94 -0
- data/lib/active_record/reflection.rb +10 -4
- data/lib/active_record/validations.rb +76 -42
- data/rakefile +2 -2
- data/test/aaa_create_tables_test.rb +4 -4
- data/test/aggregations_test.rb +18 -4
- data/test/associations_test.rb +2 -1
- data/test/base_test.rb +10 -0
- data/test/fixtures/company.rb +1 -1
- data/test/fixtures/customer.rb +17 -0
- data/test/fixtures/customers.yml +1 -0
- data/test/fixtures/db_definitions/db2.sql +1 -0
- data/test/fixtures/db_definitions/mysql.sql +1 -0
- data/test/fixtures/db_definitions/oci.sql +1 -0
- data/test/fixtures/db_definitions/postgresql.sql +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/db_definitions/sqlserver.sql +1 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
- data/test/fixtures_test.rb +30 -1
- data/test/migration_mysql.rb +104 -0
- data/test/reflection_test.rb +8 -4
- data/test/validations_test.rb +38 -0
- metadata +9 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,58 @@
|
|
1
|
+
*1.8.0* (7th March, 2005)
|
2
|
+
|
3
|
+
* Added ActiveRecord::Base.colorize_logging to control whether to use colors in logs or not (on by default)
|
4
|
+
|
5
|
+
* Added support for timestamp with time zone in PostgreSQL #560 [Scott Barron]
|
6
|
+
|
7
|
+
* Added MultiparameterAssignmentErrors and AttributeAssignmentError exceptions #777 [demetrius]. Documentation:
|
8
|
+
|
9
|
+
* +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the
|
10
|
+
+attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+
|
11
|
+
objects that should be inspected to determine which attributes triggered the errors.
|
12
|
+
* +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method.
|
13
|
+
You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
|
14
|
+
|
15
|
+
* Fixed that postgresql adapter would fails when reading bytea fields with null value #771 [rodrigo k]
|
16
|
+
|
17
|
+
* Added transactional fixtures that uses rollback to undo changes to fixtures instead of DELETE/INSERT -- it's much faster. See documentation under Fixtures #760 [bitsweat]
|
18
|
+
|
19
|
+
* Added destruction of dependent objects in has_one associations when a new assignment happens #742 [mindel]. Example:
|
20
|
+
|
21
|
+
class Account < ActiveRecord::Base
|
22
|
+
has_one :credit_card, :dependent => true
|
23
|
+
end
|
24
|
+
class CreditCard < ActiveRecord::Base
|
25
|
+
belongs_to :account
|
26
|
+
end
|
27
|
+
|
28
|
+
account.credit_card # => returns existing credit card, lets say id = 12
|
29
|
+
account.credit_card = CreditCard.create("number" => "123")
|
30
|
+
account.save # => CC with id = 12 is destroyed
|
31
|
+
|
32
|
+
|
33
|
+
* Added validates_numericality_of #716 [skanthak/c.r.mcgrath]. Docuemntation:
|
34
|
+
|
35
|
+
Validates whether the value of the specified attribute is numeric by trying to convert it to
|
36
|
+
a float with Kernel.Float (if <tt>integer</tt> is false) or applying it to the regular expression
|
37
|
+
<tt>/^[\+\-]?\d+$/</tt> (if <tt>integer</tt> is set to true).
|
38
|
+
|
39
|
+
class Person < ActiveRecord::Base
|
40
|
+
validates_numericality_of :value, :on => :create
|
41
|
+
end
|
42
|
+
|
43
|
+
Configuration options:
|
44
|
+
* <tt>message</tt> - A custom error message (default is: "is not a number")
|
45
|
+
* <tt>on</tt> Specifies when this validation is active (default is :save, other options :create, :update)
|
46
|
+
* <tt>only_integer</tt> Specifies whether the value has to be an integer, e.g. an integral value (default is false)
|
47
|
+
|
48
|
+
|
49
|
+
* Fixed that HasManyAssociation#count was using :finder_sql rather than :counter_sql if it was available #445 [Scott Barron]
|
50
|
+
|
51
|
+
* Added better defaults for composed_of, so statements like composed_of :time_zone, :mapping => %w( time_zone time_zone ) can be written without the mapping part (it's now assumed)
|
52
|
+
|
53
|
+
* Added MacroReflection#macro which will return a symbol describing the macro used (like :composed_of or :has_many) #718, #248 [james@slashetc.com]
|
54
|
+
|
55
|
+
|
1
56
|
*1.7.0* (24th February, 2005)
|
2
57
|
|
3
58
|
* Changed the auto-timestamping feature to use ActiveRecord::Base.default_timezone instead of entertaining the parallel ActiveRecord::Base.timestamps_gmt method. The latter is now deprecated and will throw a warning on use (but still work) #710 [Jamis Buck]
|
data/lib/active_record.rb
CHANGED
@@ -23,16 +23,13 @@
|
|
23
23
|
|
24
24
|
|
25
25
|
$:.unshift(File.dirname(__FILE__))
|
26
|
+
$:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib")
|
26
27
|
|
27
28
|
begin
|
28
|
-
require 'active_support'
|
29
|
+
require 'active_support'
|
29
30
|
rescue LoadError
|
30
|
-
|
31
|
-
|
32
|
-
rescue LoadError
|
33
|
-
require 'rubygems'
|
34
|
-
require_gem 'activesupport'
|
35
|
-
end
|
31
|
+
require 'rubygems'
|
32
|
+
require_gem 'activesupport'
|
36
33
|
end
|
37
34
|
|
38
35
|
require 'active_record/base'
|
@@ -47,6 +44,7 @@ require 'active_record/timestamp'
|
|
47
44
|
require 'active_record/acts/list'
|
48
45
|
require 'active_record/acts/tree'
|
49
46
|
require 'active_record/locking'
|
47
|
+
require 'active_record/migration'
|
50
48
|
|
51
49
|
ActiveRecord::Base.class_eval do
|
52
50
|
include ActiveRecord::Validations
|
@@ -118,12 +118,13 @@ module ActiveRecord
|
|
118
118
|
# composed_of :temperature, :mapping => %w(reading celsius)
|
119
119
|
# composed_of :balance, :class_name => "Money", :mapping => %w(balance amount)
|
120
120
|
# composed_of :address, :mapping => [ %w(address_street street), %w(address_city city) ]
|
121
|
+
# composed_of :gps_location
|
121
122
|
def composed_of(part_id, options = {})
|
122
123
|
validate_options([ :class_name, :mapping ], options.keys)
|
123
124
|
|
124
125
|
name = part_id.id2name
|
125
126
|
class_name = options[:class_name] || name_to_class_name(name)
|
126
|
-
mapping = options[:mapping]
|
127
|
+
mapping = options[:mapping] || [ name, name ]
|
127
128
|
|
128
129
|
reader_method(name, class_name, mapping)
|
129
130
|
writer_method(name, class_name, mapping)
|
@@ -270,7 +270,8 @@ module ActiveRecord
|
|
270
270
|
# sql fragment, such as "rank = 5".
|
271
271
|
# * <tt>:order</tt> - specify the order from which the associated object will be picked at the top. Specified as
|
272
272
|
# an "ORDER BY" sql fragment, such as "last_name, first_name DESC"
|
273
|
-
# * <tt>:dependent</tt> - if set to true the associated object is destroyed
|
273
|
+
# * <tt>:dependent</tt> - if set to true, the associated object is destroyed when this object is. It's also destroyed if another
|
274
|
+
# association is assigned.
|
274
275
|
# * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default this is guessed to be the name
|
275
276
|
# of this class in lower-case and "_id" suffixed. So a +Person+ class that makes a has_one association will use "person_id"
|
276
277
|
# as the default foreign_key.
|
@@ -24,8 +24,8 @@ module ActiveRecord
|
|
24
24
|
if @options[:finder_sql]
|
25
25
|
records = @association_class.find_by_sql(@finder_sql)
|
26
26
|
else
|
27
|
-
sql = @finder_sql
|
28
|
-
sql
|
27
|
+
sql = @finder_sql
|
28
|
+
sql += " AND #{sanitize_sql(runtime_conditions)}" if runtime_conditions
|
29
29
|
orderings ||= @options[:order]
|
30
30
|
records = @association_class.find_all(sql, orderings, limit, joins)
|
31
31
|
end
|
@@ -33,11 +33,13 @@ module ActiveRecord
|
|
33
33
|
|
34
34
|
# Count the number of associated records. All arguments are optional.
|
35
35
|
def count(runtime_conditions = nil)
|
36
|
-
if @options[:
|
36
|
+
if @options[:counter_sql]
|
37
|
+
@association_class.count_by_sql(@counter_sql)
|
38
|
+
elsif @options[:finder_sql]
|
37
39
|
@association_class.count_by_sql(@finder_sql)
|
38
40
|
else
|
39
41
|
sql = @finder_sql
|
40
|
-
sql
|
42
|
+
sql += " AND #{sanitize_sql(runtime_conditions)}" if runtime_conditions
|
41
43
|
@association_class.count(sql)
|
42
44
|
end
|
43
45
|
end
|
@@ -10,8 +10,13 @@ module ActiveRecord
|
|
10
10
|
def replace(obj, dont_save = false)
|
11
11
|
load_target
|
12
12
|
unless @target.nil?
|
13
|
-
|
14
|
-
|
13
|
+
if dependent? && !dont_save
|
14
|
+
@target.destroy unless @target.new_record?
|
15
|
+
@owner.clear_association_cache
|
16
|
+
else
|
17
|
+
@target[@association_class_primary_key_name] = nil
|
18
|
+
@target.save unless @owner.new_record?
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
if obj.nil?
|
data/lib/active_record/base.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'active_support/class_attribute_accessors'
|
2
|
-
require 'active_support/class_inheritable_attributes'
|
3
|
-
require 'active_support/inflector'
|
4
1
|
require 'yaml'
|
5
2
|
|
6
3
|
module ActiveRecord #:nodoc:
|
@@ -29,6 +26,22 @@ module ActiveRecord #:nodoc:
|
|
29
26
|
class StaleObjectError < ActiveRecordError #:nodoc:
|
30
27
|
end
|
31
28
|
|
29
|
+
class AttributeAssignmentError < ActiveRecordError #:nodoc:
|
30
|
+
attr_reader :exception, :attribute
|
31
|
+
def initialize(message, exception, attribute)
|
32
|
+
@exception = exception
|
33
|
+
@attribute = attribute
|
34
|
+
@message = message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class MultiparameterAssignmentErrors < ActiveRecordError #:nodoc:
|
39
|
+
attr_reader :errors
|
40
|
+
def initialize(errors)
|
41
|
+
@errors = errors
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
32
45
|
# Active Record objects doesn't specify their attributes directly, but rather infer them from the table definition with
|
33
46
|
# which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change
|
34
47
|
# is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain
|
@@ -187,7 +200,11 @@ module ActiveRecord #:nodoc:
|
|
187
200
|
# Either the row with the given ID doesn't exist or the row didn't meet the additional restrictions.
|
188
201
|
# * +StatementInvalid+ -- the database server rejected the SQL statement. The precise error is added in the message.
|
189
202
|
# Either the record with the given ID doesn't exist or the record didn't meet the additional restrictions.
|
190
|
-
#
|
203
|
+
# * +MultiparameterAssignmentErrors+ -- collection of errors that occurred during a mass assignment using the
|
204
|
+
# +attributes=+ method. The +errors+ property of this exception contains an array of +AttributeAssignmentError+
|
205
|
+
# objects that should be inspected to determine which attributes triggered the errors.
|
206
|
+
# * +AttributeAssignmentError+ -- an error occurred while doing a mass assignment through the +attributes=+ method.
|
207
|
+
# You can inspect the +attribute+ property of the exception object to determine which attribute triggered the error.
|
191
208
|
# *Note*: The attributes listed are class-level attributes (accessible from both the class and instance level).
|
192
209
|
# So it's possible to assign a logger to the class through Base.logger= which will then be used by all
|
193
210
|
# instances in the current object space.
|
@@ -247,6 +264,12 @@ module ActiveRecord #:nodoc:
|
|
247
264
|
cattr_accessor :pluralize_table_names
|
248
265
|
@@pluralize_table_names = true
|
249
266
|
|
267
|
+
# Determines whether or not to use ANSI codes to colorize the logging statements committed by the connection adapter. These colors
|
268
|
+
# makes it much easier to overview things during debugging (when used through a reader like +tail+ and on a black background), but
|
269
|
+
# may complicate matters if you use software like syslog. This is true, by default.
|
270
|
+
cattr_accessor :colorize_logging
|
271
|
+
@@colorize_logging = true
|
272
|
+
|
250
273
|
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling dates and times from the database.
|
251
274
|
# This is set to :local by default.
|
252
275
|
cattr_accessor :default_timezone
|
@@ -1254,14 +1277,22 @@ module ActiveRecord #:nodoc:
|
|
1254
1277
|
|
1255
1278
|
# Includes an ugly hack for Time.local instead of Time.new because the latter is reserved by Time itself.
|
1256
1279
|
def execute_callstack_for_multiparameter_attributes(callstack)
|
1280
|
+
errors = []
|
1257
1281
|
callstack.each do |name, values|
|
1258
1282
|
klass = (self.class.reflect_on_aggregation(name) || column_for_attribute(name)).klass
|
1259
1283
|
if values.empty?
|
1260
1284
|
send(name + "=", nil)
|
1261
1285
|
else
|
1262
|
-
|
1286
|
+
begin
|
1287
|
+
send(name + "=", Time == klass ? klass.local(*values) : klass.new(*values))
|
1288
|
+
rescue => ex
|
1289
|
+
errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
|
1290
|
+
end
|
1263
1291
|
end
|
1264
1292
|
end
|
1293
|
+
unless errors.empty?
|
1294
|
+
raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
1295
|
+
end
|
1265
1296
|
end
|
1266
1297
|
|
1267
1298
|
def extract_callstack_for_multiparameter_attributes(pairs)
|
@@ -356,6 +356,38 @@ module ActiveRecord
|
|
356
356
|
sql << " LIMIT #{limit}"
|
357
357
|
end
|
358
358
|
|
359
|
+
|
360
|
+
def initialize_schema_information
|
361
|
+
begin
|
362
|
+
execute "CREATE TABLE schema_info (version #{native_database_types[:integer]})"
|
363
|
+
insert "INSERT INTO schema_info (version) VALUES(0)"
|
364
|
+
rescue ActiveRecord::StatementInvalid
|
365
|
+
# Schema has been intialized
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def create_table(name)
|
370
|
+
execute "CREATE TABLE #{name} (id #{native_database_types[:primary_key]})"
|
371
|
+
table_definition = yield TableDefinition.new
|
372
|
+
table_definition.columns.each { |column_name, type, options| add_column(name, column_name, type, options) }
|
373
|
+
end
|
374
|
+
|
375
|
+
def drop_table(name)
|
376
|
+
execute "DROP TABLE #{name}"
|
377
|
+
end
|
378
|
+
|
379
|
+
def add_column(table_name, column_name, type, options = {})
|
380
|
+
add_column_sql = "ALTER TABLE #{table_name} ADD #{column_name} #{native_database_types[type]}"
|
381
|
+
add_column_sql << "(#{limit})" if options[:limit]
|
382
|
+
add_column_sql << " DEFAULT '#{options[:default]}'" if options[:default]
|
383
|
+
execute(add_column_sql)
|
384
|
+
end
|
385
|
+
|
386
|
+
def remove_column(table_name, column_name)
|
387
|
+
execute "ALTER TABLE #{table_name} DROP #{column_name}"
|
388
|
+
end
|
389
|
+
|
390
|
+
|
359
391
|
protected
|
360
392
|
def log(sql, name, connection = nil)
|
361
393
|
connection ||= @connection
|
@@ -390,18 +422,34 @@ module ActiveRecord
|
|
390
422
|
end
|
391
423
|
|
392
424
|
def format_log_entry(message, dump = nil)
|
393
|
-
if
|
394
|
-
@@row_even
|
425
|
+
if ActiveRecord::Base.colorize_logging
|
426
|
+
if @@row_even then
|
427
|
+
@@row_even = false; caller_color = "1;32"; message_color = "4;33"; dump_color = "1;37"
|
428
|
+
else
|
429
|
+
@@row_even = true; caller_color = "1;36"; message_color = "4;35"; dump_color = "0;37"
|
430
|
+
end
|
431
|
+
|
432
|
+
log_entry = " \e[#{message_color}m#{message}\e[m"
|
433
|
+
log_entry << " \e[#{dump_color}m%s\e[m" % dump if dump.kind_of?(String) && !dump.nil?
|
434
|
+
log_entry << " \e[#{dump_color}m%p\e[m" % dump if !dump.kind_of?(String) && !dump.nil?
|
435
|
+
log_entry
|
395
436
|
else
|
396
|
-
|
437
|
+
"%s %s" % [message, dump]
|
397
438
|
end
|
398
|
-
|
399
|
-
log_entry = " \e[#{message_color}m#{message}\e[m"
|
400
|
-
log_entry << " \e[#{dump_color}m%s\e[m" % dump if dump.kind_of?(String) && !dump.nil?
|
401
|
-
log_entry << " \e[#{dump_color}m%p\e[m" % dump if !dump.kind_of?(String) && !dump.nil?
|
402
|
-
log_entry
|
403
439
|
end
|
404
440
|
end
|
405
|
-
|
441
|
+
|
442
|
+
class TableDefinition
|
443
|
+
attr_accessor :columns
|
444
|
+
|
445
|
+
def initialize
|
446
|
+
@columns = []
|
447
|
+
end
|
448
|
+
|
449
|
+
def column(name, type, options = {})
|
450
|
+
@columns << [ name, type, options ]
|
451
|
+
self
|
452
|
+
end
|
453
|
+
end
|
406
454
|
end
|
407
|
-
end
|
455
|
+
end
|
@@ -63,12 +63,33 @@ module ActiveRecord
|
|
63
63
|
"Lost connection to MySQL server during query",
|
64
64
|
"MySQL server has gone away"
|
65
65
|
]
|
66
|
-
|
66
|
+
|
67
|
+
def native_database_types
|
68
|
+
{
|
69
|
+
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
|
70
|
+
:string => "varchar(255)",
|
71
|
+
:text => "text",
|
72
|
+
:integer => "int(11)",
|
73
|
+
:float => "float",
|
74
|
+
:datetime => "datetime",
|
75
|
+
:timestamp => "datetime",
|
76
|
+
:time => "datetime",
|
77
|
+
:date => "date",
|
78
|
+
:binary => "blob",
|
79
|
+
:boolean => "tinyint(1)"
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
67
83
|
def initialize(connection, logger, connection_options=nil)
|
68
84
|
super(connection, logger)
|
69
85
|
@connection_options = connection_options
|
70
86
|
end
|
71
87
|
|
88
|
+
def adapter_name
|
89
|
+
'MySQL'
|
90
|
+
end
|
91
|
+
|
92
|
+
|
72
93
|
def select_all(sql, name = nil)
|
73
94
|
select(sql, name)
|
74
95
|
end
|
@@ -111,6 +132,7 @@ module ActiveRecord
|
|
111
132
|
|
112
133
|
alias_method :delete, :update
|
113
134
|
|
135
|
+
|
114
136
|
def begin_db_transaction
|
115
137
|
begin
|
116
138
|
execute "BEGIN"
|
@@ -134,15 +156,17 @@ module ActiveRecord
|
|
134
156
|
# Transactions aren't supported
|
135
157
|
end
|
136
158
|
end
|
159
|
+
|
137
160
|
|
138
161
|
def quote_column_name(name)
|
139
162
|
return "`#{name}`"
|
140
163
|
end
|
141
164
|
|
142
|
-
def
|
143
|
-
|
165
|
+
def quote_string(s)
|
166
|
+
Mysql::quote(s)
|
144
167
|
end
|
145
|
-
|
168
|
+
|
169
|
+
|
146
170
|
def structure_dump
|
147
171
|
select_all("SHOW TABLES").inject("") do |structure, table|
|
148
172
|
structure += select_one("SHOW CREATE TABLE #{table.to_a.first.last}")["Create Table"] + ";\n\n"
|
@@ -161,11 +185,8 @@ module ActiveRecord
|
|
161
185
|
def create_database(name)
|
162
186
|
execute "CREATE DATABASE #{name}"
|
163
187
|
end
|
164
|
-
|
165
|
-
|
166
|
-
Mysql::quote(s)
|
167
|
-
end
|
168
|
-
|
188
|
+
|
189
|
+
|
169
190
|
private
|
170
191
|
def select(sql, name = nil)
|
171
192
|
result = nil
|
@@ -143,11 +143,11 @@ module ActiveRecord
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def escape_bytea(s)
|
146
|
-
s.gsub(/\\/) { '\\\\\\\\' }.gsub(/[^\\]/) { |c| sprintf('\\\\%03o', c[0].to_i) }
|
146
|
+
s.gsub(/\\/) { '\\\\\\\\' }.gsub(/[^\\]/) { |c| sprintf('\\\\%03o', c[0].to_i) } unless s.nil?
|
147
147
|
end
|
148
148
|
|
149
149
|
def unescape_bytea(s)
|
150
|
-
s.gsub(/\\([0-9][0-9][0-9])/) { $1.oct.chr }.gsub(/\\\\/) { '\\' }
|
150
|
+
s.gsub(/\\([0-9][0-9][0-9])/) { $1.oct.chr }.gsub(/\\\\/) { '\\' } unless s.nil?
|
151
151
|
end
|
152
152
|
|
153
153
|
def split_table_schema(table_name)
|
@@ -188,6 +188,7 @@ module ActiveRecord
|
|
188
188
|
when 'numeric', 'real', 'money' then 'float'
|
189
189
|
when 'character varying', 'interval' then 'string'
|
190
190
|
when 'timestamp without time zone' then 'datetime'
|
191
|
+
when 'timestamp with time zone' then 'datetime'
|
191
192
|
when 'bytea' then 'binary'
|
192
193
|
else field_type
|
193
194
|
end
|
@@ -87,6 +87,22 @@ module ActiveRecord
|
|
87
87
|
#
|
88
88
|
# * <tt>:dbfile</tt> -- Path to the database file.
|
89
89
|
class SQLiteAdapter < AbstractAdapter
|
90
|
+
def native_database_types
|
91
|
+
{
|
92
|
+
:primary_key => "INTEGER PRIMARY KEY NOT NULL",
|
93
|
+
:string => "VARCHAR(255)",
|
94
|
+
:text => "TEXT",
|
95
|
+
:integer => "INTEGER",
|
96
|
+
:float => "float",
|
97
|
+
:datetime => "DATETIME",
|
98
|
+
:timestamp => "DATETIME",
|
99
|
+
:time => "DATETIME",
|
100
|
+
:date => "DATE",
|
101
|
+
:binary => "BLOB",
|
102
|
+
:boolean => "INTEGER"
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
90
106
|
def execute(sql, name = nil)
|
91
107
|
log(sql, name) { @connection.execute(sql) }
|
92
108
|
end
|
@@ -150,6 +166,7 @@ module ActiveRecord
|
|
150
166
|
'SQLite'
|
151
167
|
end
|
152
168
|
|
169
|
+
|
153
170
|
protected
|
154
171
|
def table_structure(table_name)
|
155
172
|
execute "PRAGMA table_info(#{table_name})"
|