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.

Files changed (96) hide show
  1. data/CHANGELOG +78 -0
  2. data/README +20 -29
  3. data/RUNNING_UNIT_TESTS +1 -2
  4. data/examples/validation.rb +0 -3
  5. data/install.rb +3 -16
  6. data/lib/active_record.rb +11 -4
  7. data/lib/active_record/aggregations.rb +2 -2
  8. data/lib/active_record/associations.rb +8 -8
  9. data/lib/active_record/associations/association_collection.rb +1 -1
  10. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
  11. data/lib/active_record/base.rb +117 -43
  12. data/lib/active_record/callbacks.rb +2 -2
  13. data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -14
  14. data/lib/active_record/connection_adapters/db2_adapter.rb +33 -22
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +74 -33
  16. data/lib/active_record/connection_adapters/oci_adapter.rb +265 -0
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -3
  18. data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -4
  19. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +158 -67
  20. data/lib/active_record/deprecated_associations.rb +4 -4
  21. data/lib/active_record/fixtures.rb +12 -5
  22. data/lib/active_record/locking.rb +22 -22
  23. data/lib/active_record/observer.rb +6 -3
  24. data/lib/active_record/timestamp.rb +15 -5
  25. data/lib/active_record/transactions.rb +4 -4
  26. data/lib/active_record/validations.rb +272 -189
  27. data/lib/active_record/wrappings.rb +2 -2
  28. data/rakefile +17 -2
  29. data/test/aaa_create_tables_test.rb +58 -0
  30. data/test/abstract_unit.rb +3 -2
  31. data/test/aggregations_test.rb +0 -1
  32. data/test/associations_test.rb +27 -28
  33. data/test/base_test.rb +74 -2
  34. data/test/binary_test.rb +6 -2
  35. data/test/class_inheritable_attributes_test.rb +1 -1
  36. data/test/column_alias_test.rb +9 -2
  37. data/test/connections/native_oci/connection.rb +25 -0
  38. data/test/connections/native_sqlite/connection.rb +4 -1
  39. data/test/connections/native_sqlite3/connection.rb +4 -2
  40. data/test/deprecated_associations_test.rb +4 -5
  41. data/test/finder_test.rb +20 -4
  42. data/test/fixtures/db_definitions/create_oracle_db.bat +5 -0
  43. data/test/fixtures/db_definitions/create_oracle_db.sh +5 -0
  44. data/test/fixtures/db_definitions/db2.drop.sql +18 -0
  45. data/test/fixtures/db_definitions/db2.sql +1 -0
  46. data/test/fixtures/db_definitions/db22.drop.sql +2 -0
  47. data/test/fixtures/db_definitions/db22.sql +1 -0
  48. data/test/fixtures/db_definitions/drop_oracle_tables.sql +35 -0
  49. data/test/fixtures/db_definitions/drop_oracle_tables2.sql +3 -0
  50. data/test/fixtures/db_definitions/mysql.drop.sql +18 -0
  51. data/test/fixtures/db_definitions/mysql.sql +2 -1
  52. data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
  53. data/test/fixtures/db_definitions/mysql2.sql +1 -0
  54. data/test/fixtures/db_definitions/oci.drop.sql +18 -0
  55. data/test/fixtures/db_definitions/oci.sql +167 -0
  56. data/test/fixtures/db_definitions/oci2.drop.sql +2 -0
  57. data/test/fixtures/db_definitions/oci2.sql +6 -0
  58. data/test/fixtures/db_definitions/postgresql.drop.sql +18 -0
  59. data/test/fixtures/db_definitions/postgresql.sql +2 -1
  60. data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
  61. data/test/fixtures/db_definitions/postgresql2.sql +2 -1
  62. data/test/fixtures/db_definitions/sqlite.drop.sql +18 -0
  63. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  64. data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
  65. data/test/fixtures/db_definitions/sqlite2.sql +1 -0
  66. data/test/fixtures/db_definitions/sqlserver.drop.sql +18 -0
  67. data/test/fixtures/db_definitions/sqlserver.sql +1 -0
  68. data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
  69. data/test/fixtures/db_definitions/sqlserver2.sql +1 -0
  70. data/test/fixtures/fixture_database.sqlite +0 -0
  71. data/test/fixtures/fixture_database_2.sqlite +0 -0
  72. data/test/fixtures/topics.yml +3 -3
  73. data/test/lifecycle_test.rb +0 -1
  74. data/test/modules_test.rb +0 -1
  75. data/test/reflection_test.rb +0 -1
  76. data/test/validations_test.rb +229 -41
  77. metadata +36 -28
  78. data/dev-utils/eval_debugger.rb +0 -14
  79. data/lib/active_record/support/binding_of_caller.rb +0 -83
  80. data/lib/active_record/support/breakpoint.rb +0 -518
  81. data/lib/active_record/support/class_attribute_accessors.rb +0 -57
  82. data/lib/active_record/support/class_inheritable_attributes.rb +0 -117
  83. data/lib/active_record/support/clean_logger.rb +0 -10
  84. data/lib/active_record/support/core_ext.rb +0 -1
  85. data/lib/active_record/support/core_ext/hash.rb +0 -5
  86. data/lib/active_record/support/core_ext/hash/keys.rb +0 -35
  87. data/lib/active_record/support/core_ext/numeric.rb +0 -7
  88. data/lib/active_record/support/core_ext/numeric/bytes.rb +0 -33
  89. data/lib/active_record/support/core_ext/numeric/time.rb +0 -59
  90. data/lib/active_record/support/core_ext/object_and_class.rb +0 -24
  91. data/lib/active_record/support/core_ext/string.rb +0 -5
  92. data/lib/active_record/support/core_ext/string/inflections.rb +0 -45
  93. data/lib/active_record/support/dependencies.rb +0 -63
  94. data/lib/active_record/support/inflector.rb +0 -84
  95. data/lib/active_record/support/misc.rb +0 -8
  96. 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,10 +0,0 @@
1
- require 'logger'
2
-
3
- class Logger #:nodoc:
4
- private
5
- remove_const "Format"
6
- Format = "%s\n"
7
- def format_message(severity, timestamp, msg, progname)
8
- Format % [msg]
9
- end
10
- end
@@ -1 +0,0 @@
1
- Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].each { |file| require(file) }
@@ -1,5 +0,0 @@
1
- require File.dirname(__FILE__) + '/hash/keys'
2
-
3
- class Hash #:nodoc:
4
- include ActiveSupport::CoreExtensions::Hash::Keys
5
- end
@@ -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,7 +0,0 @@
1
- require File.dirname(__FILE__) + '/numeric/time'
2
- require File.dirname(__FILE__) + '/numeric/bytes'
3
-
4
- class Numeric #:nodoc:
5
- include ActiveSupport::CoreExtensions::Numeric::Time
6
- include ActiveSupport::CoreExtensions::Numeric::Bytes
7
- 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,5 +0,0 @@
1
- require File.dirname(__FILE__) + '/string/inflections'
2
-
3
- class String #:nodoc:
4
- include ActiveSupport::CoreExtensions::String::Inflections
5
- 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