activerecord 1.6.0 → 1.7.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 +78 -0
- data/README +20 -29
- data/RUNNING_UNIT_TESTS +1 -2
- data/examples/validation.rb +0 -3
- data/install.rb +3 -16
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +2 -2
- data/lib/active_record/associations.rb +8 -8
- data/lib/active_record/associations/association_collection.rb +1 -1
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
- data/lib/active_record/base.rb +117 -43
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -14
- data/lib/active_record/connection_adapters/db2_adapter.rb +33 -22
- data/lib/active_record/connection_adapters/mysql_adapter.rb +74 -33
- data/lib/active_record/connection_adapters/oci_adapter.rb +265 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -4
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +158 -67
- data/lib/active_record/deprecated_associations.rb +4 -4
- data/lib/active_record/fixtures.rb +12 -5
- data/lib/active_record/locking.rb +22 -22
- data/lib/active_record/observer.rb +6 -3
- data/lib/active_record/timestamp.rb +15 -5
- data/lib/active_record/transactions.rb +4 -4
- data/lib/active_record/validations.rb +272 -189
- data/lib/active_record/wrappings.rb +2 -2
- data/rakefile +17 -2
- data/test/aaa_create_tables_test.rb +58 -0
- data/test/abstract_unit.rb +3 -2
- data/test/aggregations_test.rb +0 -1
- data/test/associations_test.rb +27 -28
- data/test/base_test.rb +74 -2
- data/test/binary_test.rb +6 -2
- data/test/class_inheritable_attributes_test.rb +1 -1
- data/test/column_alias_test.rb +9 -2
- data/test/connections/native_oci/connection.rb +25 -0
- data/test/connections/native_sqlite/connection.rb +4 -1
- data/test/connections/native_sqlite3/connection.rb +4 -2
- data/test/deprecated_associations_test.rb +4 -5
- data/test/finder_test.rb +20 -4
- data/test/fixtures/db_definitions/create_oracle_db.bat +5 -0
- data/test/fixtures/db_definitions/create_oracle_db.sh +5 -0
- data/test/fixtures/db_definitions/db2.drop.sql +18 -0
- data/test/fixtures/db_definitions/db2.sql +1 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +1 -0
- data/test/fixtures/db_definitions/drop_oracle_tables.sql +35 -0
- data/test/fixtures/db_definitions/drop_oracle_tables2.sql +3 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +18 -0
- data/test/fixtures/db_definitions/mysql.sql +2 -1
- data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql2.sql +1 -0
- data/test/fixtures/db_definitions/oci.drop.sql +18 -0
- data/test/fixtures/db_definitions/oci.sql +167 -0
- data/test/fixtures/db_definitions/oci2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oci2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +18 -0
- data/test/fixtures/db_definitions/postgresql.sql +2 -1
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +2 -1
- data/test/fixtures/db_definitions/sqlite.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlserver.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +1 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/topics.yml +3 -3
- data/test/lifecycle_test.rb +0 -1
- data/test/modules_test.rb +0 -1
- data/test/reflection_test.rb +0 -1
- data/test/validations_test.rb +229 -41
- metadata +36 -28
- data/dev-utils/eval_debugger.rb +0 -14
- data/lib/active_record/support/binding_of_caller.rb +0 -83
- data/lib/active_record/support/breakpoint.rb +0 -518
- data/lib/active_record/support/class_attribute_accessors.rb +0 -57
- data/lib/active_record/support/class_inheritable_attributes.rb +0 -117
- data/lib/active_record/support/clean_logger.rb +0 -10
- data/lib/active_record/support/core_ext.rb +0 -1
- data/lib/active_record/support/core_ext/hash.rb +0 -5
- data/lib/active_record/support/core_ext/hash/keys.rb +0 -35
- data/lib/active_record/support/core_ext/numeric.rb +0 -7
- data/lib/active_record/support/core_ext/numeric/bytes.rb +0 -33
- data/lib/active_record/support/core_ext/numeric/time.rb +0 -59
- data/lib/active_record/support/core_ext/object_and_class.rb +0 -24
- data/lib/active_record/support/core_ext/string.rb +0 -5
- data/lib/active_record/support/core_ext/string/inflections.rb +0 -45
- data/lib/active_record/support/dependencies.rb +0 -63
- data/lib/active_record/support/inflector.rb +0 -84
- data/lib/active_record/support/misc.rb +0 -8
- data/lib/active_record/support/module_attribute_accessors.rb +0 -57
@@ -1,57 +0,0 @@
|
|
1
|
-
# Extends the class object with class and instance accessors for class attributes,
|
2
|
-
# just like the native attr* accessors for instance attributes.
|
3
|
-
class Class # :nodoc:
|
4
|
-
def cattr_reader(*syms)
|
5
|
-
syms.each do |sym|
|
6
|
-
class_eval <<-EOS
|
7
|
-
if ! defined? @@#{sym.id2name}
|
8
|
-
@@#{sym.id2name} = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.#{sym.id2name}
|
12
|
-
@@#{sym}
|
13
|
-
end
|
14
|
-
|
15
|
-
def #{sym.id2name}
|
16
|
-
@@#{sym}
|
17
|
-
end
|
18
|
-
|
19
|
-
def call_#{sym.id2name}
|
20
|
-
case @@#{sym.id2name}
|
21
|
-
when Symbol then send(@@#{sym})
|
22
|
-
when Proc then @@#{sym}.call(self)
|
23
|
-
when String then @@#{sym}
|
24
|
-
else nil
|
25
|
-
end
|
26
|
-
end
|
27
|
-
EOS
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def cattr_writer(*syms)
|
32
|
-
syms.each do |sym|
|
33
|
-
class_eval <<-EOS
|
34
|
-
if ! defined? @@#{sym.id2name}
|
35
|
-
@@#{sym.id2name} = nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.#{sym.id2name}=(obj)
|
39
|
-
@@#{sym.id2name} = obj
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.set_#{sym.id2name}(obj)
|
43
|
-
@@#{sym.id2name} = obj
|
44
|
-
end
|
45
|
-
|
46
|
-
def #{sym.id2name}=(obj)
|
47
|
-
@@#{sym} = obj
|
48
|
-
end
|
49
|
-
EOS
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def cattr_accessor(*syms)
|
54
|
-
cattr_reader(*syms)
|
55
|
-
cattr_writer(*syms)
|
56
|
-
end
|
57
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
# Retain for backward compatibility. Methods are now included in Class.
|
2
|
-
module ClassInheritableAttributes # :nodoc:
|
3
|
-
end
|
4
|
-
|
5
|
-
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
|
6
|
-
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
|
7
|
-
# to, for example, an array without those additions being shared with either their parent, siblings, or
|
8
|
-
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
|
9
|
-
class Class # :nodoc:
|
10
|
-
def class_inheritable_reader(*syms)
|
11
|
-
syms.each do |sym|
|
12
|
-
class_eval <<-EOS
|
13
|
-
def self.#{sym}
|
14
|
-
read_inheritable_attribute(:#{sym})
|
15
|
-
end
|
16
|
-
|
17
|
-
def #{sym}
|
18
|
-
self.class.#{sym}
|
19
|
-
end
|
20
|
-
EOS
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def class_inheritable_writer(*syms)
|
25
|
-
syms.each do |sym|
|
26
|
-
class_eval <<-EOS
|
27
|
-
def self.#{sym}=(obj)
|
28
|
-
write_inheritable_attribute(:#{sym}, obj)
|
29
|
-
end
|
30
|
-
|
31
|
-
def #{sym}=(obj)
|
32
|
-
self.class.#{sym} = obj
|
33
|
-
end
|
34
|
-
EOS
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def class_inheritable_array_writer(*syms)
|
39
|
-
syms.each do |sym|
|
40
|
-
class_eval <<-EOS
|
41
|
-
def self.#{sym}=(obj)
|
42
|
-
write_inheritable_array(:#{sym}, obj)
|
43
|
-
end
|
44
|
-
|
45
|
-
def #{sym}=(obj)
|
46
|
-
self.class.#{sym} = obj
|
47
|
-
end
|
48
|
-
EOS
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def class_inheritable_hash_writer(*syms)
|
53
|
-
syms.each do |sym|
|
54
|
-
class_eval <<-EOS
|
55
|
-
def self.#{sym}=(obj)
|
56
|
-
write_inheritable_hash(:#{sym}, obj)
|
57
|
-
end
|
58
|
-
|
59
|
-
def #{sym}=(obj)
|
60
|
-
self.class.#{sym} = obj
|
61
|
-
end
|
62
|
-
EOS
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def class_inheritable_accessor(*syms)
|
67
|
-
class_inheritable_reader(*syms)
|
68
|
-
class_inheritable_writer(*syms)
|
69
|
-
end
|
70
|
-
|
71
|
-
def class_inheritable_array(*syms)
|
72
|
-
class_inheritable_reader(*syms)
|
73
|
-
class_inheritable_array_writer(*syms)
|
74
|
-
end
|
75
|
-
|
76
|
-
def class_inheritable_hash(*syms)
|
77
|
-
class_inheritable_reader(*syms)
|
78
|
-
class_inheritable_hash_writer(*syms)
|
79
|
-
end
|
80
|
-
|
81
|
-
def inheritable_attributes
|
82
|
-
@inheritable_attributes ||= {}
|
83
|
-
end
|
84
|
-
|
85
|
-
def write_inheritable_attribute(key, value)
|
86
|
-
inheritable_attributes[key] = value
|
87
|
-
end
|
88
|
-
|
89
|
-
def write_inheritable_array(key, elements)
|
90
|
-
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
|
91
|
-
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
|
92
|
-
end
|
93
|
-
|
94
|
-
def write_inheritable_hash(key, hash)
|
95
|
-
write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
|
96
|
-
write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
|
97
|
-
end
|
98
|
-
|
99
|
-
def read_inheritable_attribute(key)
|
100
|
-
inheritable_attributes[key]
|
101
|
-
end
|
102
|
-
|
103
|
-
def reset_inheritable_attributes
|
104
|
-
inheritable_attributes.clear
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
def inherited_with_inheritable_attributes(child)
|
109
|
-
inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
|
110
|
-
child.instance_variable_set('@inheritable_attributes', inheritable_attributes.dup)
|
111
|
-
end
|
112
|
-
|
113
|
-
if respond_to?(:inherited)
|
114
|
-
alias_method :inherited_without_inheritable_attributes, :inherited
|
115
|
-
end
|
116
|
-
alias_method :inherited, :inherited_with_inheritable_attributes
|
117
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module ActiveSupport #:nodoc:
|
2
|
-
module CoreExtensions #:nodoc:
|
3
|
-
module Hash #:nodoc:
|
4
|
-
module Keys
|
5
|
-
|
6
|
-
# Return a new hash with all keys converted to symbols.
|
7
|
-
def symbolize_keys
|
8
|
-
inject({}) do |options, (key, value)|
|
9
|
-
options[key.to_sym] = value
|
10
|
-
options
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# Destructively convert all keys to symbols.
|
15
|
-
def symbolize_keys!
|
16
|
-
keys.each do |key|
|
17
|
-
unless key.is_a?(Symbol)
|
18
|
-
self[key.to_sym] = self[key]
|
19
|
-
delete(key)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
alias_method :to_options, :symbolize_keys
|
26
|
-
alias_method :to_options!, :symbolize_keys!
|
27
|
-
|
28
|
-
def assert_valid_keys(valid_keys)
|
29
|
-
unknown_keys = keys - valid_keys
|
30
|
-
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module ActiveSupport #:nodoc:
|
2
|
-
module CoreExtensions #:nodoc:
|
3
|
-
module Numeric #:nodoc:
|
4
|
-
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
5
|
-
module Bytes
|
6
|
-
def bytes
|
7
|
-
self
|
8
|
-
end
|
9
|
-
alias :byte :bytes
|
10
|
-
|
11
|
-
def kilobytes
|
12
|
-
self * 1024
|
13
|
-
end
|
14
|
-
alias :kilobyte :kilobytes
|
15
|
-
|
16
|
-
def megabytes
|
17
|
-
self * 1024.kilobytes
|
18
|
-
end
|
19
|
-
alias :megabyte :megabytes
|
20
|
-
|
21
|
-
def gigabytes
|
22
|
-
self * 1024.megabytes
|
23
|
-
end
|
24
|
-
alias :gigabyte :gigabytes
|
25
|
-
|
26
|
-
def terabytes
|
27
|
-
self * 1024.gigabytes
|
28
|
-
end
|
29
|
-
alias :terabyte :terabytes
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module ActiveSupport #:nodoc:
|
2
|
-
module CoreExtensions #:nodoc:
|
3
|
-
module Numeric #:nodoc:
|
4
|
-
# Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years
|
5
|
-
module Time
|
6
|
-
def minutes
|
7
|
-
self * 60
|
8
|
-
end
|
9
|
-
alias :minute :minutes
|
10
|
-
|
11
|
-
def hours
|
12
|
-
self * 60.minutes
|
13
|
-
end
|
14
|
-
alias :hour :hours
|
15
|
-
|
16
|
-
def days
|
17
|
-
self * 24.hours
|
18
|
-
end
|
19
|
-
alias :day :days
|
20
|
-
|
21
|
-
def weeks
|
22
|
-
self * 7.days
|
23
|
-
end
|
24
|
-
alias :week :weeks
|
25
|
-
|
26
|
-
def fortnights
|
27
|
-
self * 2.weeks
|
28
|
-
end
|
29
|
-
alias :fortnight :fortnights
|
30
|
-
|
31
|
-
def months
|
32
|
-
self * 30.days
|
33
|
-
end
|
34
|
-
alias :month :months
|
35
|
-
|
36
|
-
def years
|
37
|
-
self * 365.days
|
38
|
-
end
|
39
|
-
alias :year :years
|
40
|
-
|
41
|
-
# Reads best without arguments: 10.minutes.ago
|
42
|
-
def ago(time = ::Time.now)
|
43
|
-
time - self
|
44
|
-
end
|
45
|
-
|
46
|
-
# Reads best with argument: 10.minutes.until(time)
|
47
|
-
alias :until :ago
|
48
|
-
|
49
|
-
# Reads best with argument: 10.minutes.since(time)
|
50
|
-
def since(time = ::Time.now)
|
51
|
-
time + self
|
52
|
-
end
|
53
|
-
|
54
|
-
# Reads best without arguments: 10.minutes.from_now
|
55
|
-
alias :from_now :since
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
class Object #:nodoc:
|
2
|
-
def remove_subclasses_of(superclass)
|
3
|
-
subclasses_of(superclass).each { |subclass| Object.send(:remove_const, subclass) rescue nil }
|
4
|
-
end
|
5
|
-
|
6
|
-
def subclasses_of(superclass)
|
7
|
-
subclasses = []
|
8
|
-
ObjectSpace.each_object(Class) do |k|
|
9
|
-
next if !k.ancestors.include?(superclass) || superclass == k || k.to_s.include?("::") || subclasses.include?(k.to_s)
|
10
|
-
subclasses << k.to_s
|
11
|
-
end
|
12
|
-
subclasses
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Class #:nodoc:
|
17
|
-
def remove_subclasses
|
18
|
-
Object.remove_subclasses_of(self)
|
19
|
-
end
|
20
|
-
|
21
|
-
def subclasses
|
22
|
-
Object.subclasses_of(self)
|
23
|
-
end
|
24
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../../inflector'
|
2
|
-
module ActiveSupport #:nodoc:
|
3
|
-
module CoreExtensions #:nodoc:
|
4
|
-
module String #:nodoc:
|
5
|
-
# Makes it possible to do "posts".singularize that returns "post" and "MegaCoolClass".underscore that returns "mega_cool_class".
|
6
|
-
module Inflections
|
7
|
-
def pluralize
|
8
|
-
Inflector.pluralize(self)
|
9
|
-
end
|
10
|
-
|
11
|
-
def singularize
|
12
|
-
Inflector.singularize(self)
|
13
|
-
end
|
14
|
-
|
15
|
-
def camelize
|
16
|
-
Inflector.camelize(self)
|
17
|
-
end
|
18
|
-
|
19
|
-
def underscore
|
20
|
-
Inflector.underscore(self)
|
21
|
-
end
|
22
|
-
|
23
|
-
def demodulize
|
24
|
-
Inflector.demodulize(self)
|
25
|
-
end
|
26
|
-
|
27
|
-
def tableize
|
28
|
-
Inflector.tableize(self)
|
29
|
-
end
|
30
|
-
|
31
|
-
def classify
|
32
|
-
Inflector.classify(self)
|
33
|
-
end
|
34
|
-
|
35
|
-
def humanize
|
36
|
-
Inflector.humanize(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
40
|
-
Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/module_attribute_accessors'
|
2
|
-
|
3
|
-
module Dependencies
|
4
|
-
extend self
|
5
|
-
|
6
|
-
@@loaded = [ ]
|
7
|
-
mattr_accessor :loaded
|
8
|
-
|
9
|
-
@@mechanism = :load
|
10
|
-
mattr_accessor :mechanism
|
11
|
-
|
12
|
-
def load?
|
13
|
-
mechanism == :load
|
14
|
-
end
|
15
|
-
|
16
|
-
def depend_on(file_name, swallow_load_errors = false)
|
17
|
-
if !loaded.include?(file_name)
|
18
|
-
loaded << file_name
|
19
|
-
begin
|
20
|
-
require_or_load(file_name)
|
21
|
-
rescue LoadError
|
22
|
-
raise unless swallow_load_errors
|
23
|
-
rescue Object => e
|
24
|
-
raise ScriptError, "#{e.message}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def associate_with(file_name)
|
30
|
-
depend_on(file_name, true)
|
31
|
-
end
|
32
|
-
|
33
|
-
def clear
|
34
|
-
self.loaded = [ ]
|
35
|
-
end
|
36
|
-
|
37
|
-
def require_or_load(file_name)
|
38
|
-
load? ? load("#{file_name}.rb") : require(file_name)
|
39
|
-
end
|
40
|
-
|
41
|
-
def remove_subclasses_for(*classes)
|
42
|
-
classes.each { |klass| klass.remove_subclasses }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
Object.send(:define_method, :require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
|
47
|
-
Object.send(:define_method, :require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
|
48
|
-
Object.send(:define_method, :require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
49
|
-
|
50
|
-
class Object #:nodoc:
|
51
|
-
class << self
|
52
|
-
# Use const_missing to autoload associations so we don't have to
|
53
|
-
# require_association when using single-table inheritance.
|
54
|
-
def const_missing(class_id)
|
55
|
-
begin
|
56
|
-
require_or_load(class_id.to_s.demodulize.underscore)
|
57
|
-
if Object.const_defined?(class_id) then return Object.const_get(class_id) else raise LoadError end
|
58
|
-
rescue LoadError
|
59
|
-
raise NameError, "uninitialized constant #{class_id}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|