datamapper 0.3.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. data/History.txt +0 -0
  2. data/Manifest.txt +5 -0
  3. data/README.txt +11 -0
  4. data/Rakefile +70 -0
  5. data/lib/datamapper.rb +8 -0
  6. metadata +152 -319
  7. data/CHANGELOG +0 -145
  8. data/FAQ +0 -96
  9. data/MIT-LICENSE +0 -22
  10. data/QUICKLINKS +0 -12
  11. data/README +0 -105
  12. data/environment.rb +0 -62
  13. data/example.rb +0 -156
  14. data/lib/data_mapper.rb +0 -88
  15. data/lib/data_mapper/adapters/abstract_adapter.rb +0 -43
  16. data/lib/data_mapper/adapters/data_object_adapter.rb +0 -480
  17. data/lib/data_mapper/adapters/mysql_adapter.rb +0 -72
  18. data/lib/data_mapper/adapters/postgresql_adapter.rb +0 -258
  19. data/lib/data_mapper/adapters/sql/coersion.rb +0 -134
  20. data/lib/data_mapper/adapters/sql/commands/load_command.rb +0 -545
  21. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +0 -34
  22. data/lib/data_mapper/adapters/sql/mappings/column.rb +0 -279
  23. data/lib/data_mapper/adapters/sql/mappings/conditions.rb +0 -172
  24. data/lib/data_mapper/adapters/sql/mappings/schema.rb +0 -60
  25. data/lib/data_mapper/adapters/sql/mappings/table.rb +0 -459
  26. data/lib/data_mapper/adapters/sql/quoting.rb +0 -24
  27. data/lib/data_mapper/adapters/sqlite3_adapter.rb +0 -159
  28. data/lib/data_mapper/associations.rb +0 -106
  29. data/lib/data_mapper/associations/belongs_to_association.rb +0 -160
  30. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +0 -437
  31. data/lib/data_mapper/associations/has_many_association.rb +0 -283
  32. data/lib/data_mapper/associations/has_n_association.rb +0 -143
  33. data/lib/data_mapper/associations/reference.rb +0 -47
  34. data/lib/data_mapper/attributes.rb +0 -73
  35. data/lib/data_mapper/auto_migrations.rb +0 -36
  36. data/lib/data_mapper/base.rb +0 -17
  37. data/lib/data_mapper/callbacks.rb +0 -107
  38. data/lib/data_mapper/context.rb +0 -112
  39. data/lib/data_mapper/database.rb +0 -234
  40. data/lib/data_mapper/dependency_queue.rb +0 -28
  41. data/lib/data_mapper/embedded_value.rb +0 -145
  42. data/lib/data_mapper/identity_map.rb +0 -47
  43. data/lib/data_mapper/is/tree.rb +0 -121
  44. data/lib/data_mapper/migration.rb +0 -155
  45. data/lib/data_mapper/persistence.rb +0 -852
  46. data/lib/data_mapper/property.rb +0 -310
  47. data/lib/data_mapper/query.rb +0 -164
  48. data/lib/data_mapper/support/blank.rb +0 -35
  49. data/lib/data_mapper/support/connection_pool.rb +0 -117
  50. data/lib/data_mapper/support/enumerable.rb +0 -35
  51. data/lib/data_mapper/support/errors.rb +0 -16
  52. data/lib/data_mapper/support/inflector.rb +0 -265
  53. data/lib/data_mapper/support/object.rb +0 -54
  54. data/lib/data_mapper/support/serialization.rb +0 -96
  55. data/lib/data_mapper/support/silence.rb +0 -10
  56. data/lib/data_mapper/support/string.rb +0 -72
  57. data/lib/data_mapper/support/struct.rb +0 -7
  58. data/lib/data_mapper/support/symbol.rb +0 -82
  59. data/lib/data_mapper/support/typed_set.rb +0 -65
  60. data/lib/data_mapper/types/base.rb +0 -44
  61. data/lib/data_mapper/types/string.rb +0 -34
  62. data/lib/data_mapper/validatable_extensions/errors.rb +0 -12
  63. data/lib/data_mapper/validatable_extensions/macros.rb +0 -7
  64. data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +0 -62
  65. data/lib/data_mapper/validatable_extensions/validation_base.rb +0 -18
  66. data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +0 -43
  67. data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +0 -7
  68. data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +0 -7
  69. data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +0 -7
  70. data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +0 -28
  71. data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +0 -15
  72. data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +0 -7
  73. data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +0 -7
  74. data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +0 -7
  75. data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +0 -40
  76. data/lib/data_mapper/validations.rb +0 -20
  77. data/lib/data_mapper/validations/number_validator.rb +0 -40
  78. data/lib/data_mapper/validations/string_validator.rb +0 -20
  79. data/lib/data_mapper/validations/validator.rb +0 -13
  80. data/performance.rb +0 -307
  81. data/plugins/can_has_sphinx/LICENSE +0 -23
  82. data/plugins/can_has_sphinx/README +0 -4
  83. data/plugins/can_has_sphinx/REVISION +0 -1
  84. data/plugins/can_has_sphinx/Rakefile +0 -22
  85. data/plugins/can_has_sphinx/init.rb +0 -1
  86. data/plugins/can_has_sphinx/install.rb +0 -1
  87. data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +0 -123
  88. data/plugins/can_has_sphinx/lib/sphinx.rb +0 -460
  89. data/plugins/can_has_sphinx/scripts/sphinx.sh +0 -47
  90. data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +0 -41
  91. data/profile_data_mapper.rb +0 -40
  92. data/rakefile.rb +0 -159
  93. data/spec/acts_as_tree_spec.rb +0 -67
  94. data/spec/adapters/data_object_adapter_spec.rb +0 -31
  95. data/spec/associations/belongs_to_association_spec.rb +0 -98
  96. data/spec/associations/has_and_belongs_to_many_association_spec.rb +0 -377
  97. data/spec/associations/has_many_association_spec.rb +0 -337
  98. data/spec/attributes_spec.rb +0 -52
  99. data/spec/auto_migrations_spec.rb +0 -101
  100. data/spec/callbacks_spec.rb +0 -186
  101. data/spec/can_has_sphinx.rb +0 -5
  102. data/spec/coersion_spec.rb +0 -41
  103. data/spec/column_spec.rb +0 -114
  104. data/spec/count_command_spec.rb +0 -45
  105. data/spec/database_spec.rb +0 -18
  106. data/spec/dataobjects_spec.rb +0 -27
  107. data/spec/delete_command_spec.rb +0 -11
  108. data/spec/dependency_spec.rb +0 -29
  109. data/spec/embedded_value_spec.rb +0 -161
  110. data/spec/fixtures/animals.yaml +0 -33
  111. data/spec/fixtures/animals_exhibits.yaml +0 -2
  112. data/spec/fixtures/careers.yaml +0 -5
  113. data/spec/fixtures/comments.yaml +0 -1
  114. data/spec/fixtures/exhibits.yaml +0 -90
  115. data/spec/fixtures/fruit.yaml +0 -6
  116. data/spec/fixtures/people.yaml +0 -37
  117. data/spec/fixtures/posts.yaml +0 -3
  118. data/spec/fixtures/projects.yaml +0 -13
  119. data/spec/fixtures/sections.yaml +0 -5
  120. data/spec/fixtures/serializers.yaml +0 -6
  121. data/spec/fixtures/tasks.yaml +0 -6
  122. data/spec/fixtures/tasks_tasks.yaml +0 -2
  123. data/spec/fixtures/tomatoes.yaml +0 -1
  124. data/spec/fixtures/users.yaml +0 -1
  125. data/spec/fixtures/zoos.yaml +0 -24
  126. data/spec/is_a_tree_spec.rb +0 -149
  127. data/spec/legacy_spec.rb +0 -16
  128. data/spec/load_command_spec.rb +0 -322
  129. data/spec/magic_columns_spec.rb +0 -26
  130. data/spec/migration_spec.rb +0 -267
  131. data/spec/mock_adapter.rb +0 -20
  132. data/spec/models/animal.rb +0 -12
  133. data/spec/models/candidate.rb +0 -8
  134. data/spec/models/career.rb +0 -7
  135. data/spec/models/chain.rb +0 -8
  136. data/spec/models/comment.rb +0 -6
  137. data/spec/models/exhibit.rb +0 -14
  138. data/spec/models/fence.rb +0 -7
  139. data/spec/models/fruit.rb +0 -8
  140. data/spec/models/job.rb +0 -8
  141. data/spec/models/person.rb +0 -30
  142. data/spec/models/post.rb +0 -14
  143. data/spec/models/project.rb +0 -41
  144. data/spec/models/sales_person.rb +0 -5
  145. data/spec/models/section.rb +0 -8
  146. data/spec/models/serializer.rb +0 -5
  147. data/spec/models/task.rb +0 -9
  148. data/spec/models/tomato.rb +0 -27
  149. data/spec/models/user.rb +0 -12
  150. data/spec/models/zoo.rb +0 -13
  151. data/spec/natural_key_spec.rb +0 -36
  152. data/spec/paranoia_spec.rb +0 -38
  153. data/spec/persistence_spec.rb +0 -479
  154. data/spec/postgres_spec.rb +0 -96
  155. data/spec/property_spec.rb +0 -151
  156. data/spec/query_spec.rb +0 -77
  157. data/spec/save_command_spec.rb +0 -94
  158. data/spec/schema_spec.rb +0 -8
  159. data/spec/serialize_spec.rb +0 -19
  160. data/spec/single_table_inheritance_spec.rb +0 -43
  161. data/spec/spec_helper.rb +0 -45
  162. data/spec/support/blank_spec.rb +0 -8
  163. data/spec/support/inflector_spec.rb +0 -41
  164. data/spec/support/object_spec.rb +0 -9
  165. data/spec/support/serialization_spec.rb +0 -61
  166. data/spec/support/silence_spec.rb +0 -15
  167. data/spec/support/string_spec.rb +0 -7
  168. data/spec/support/struct_spec.rb +0 -12
  169. data/spec/support/typed_set_spec.rb +0 -66
  170. data/spec/symbolic_operators_spec.rb +0 -27
  171. data/spec/table_spec.rb +0 -79
  172. data/spec/types/string.rb +0 -81
  173. data/spec/validates_confirmation_of_spec.rb +0 -55
  174. data/spec/validates_format_of_spec.rb +0 -78
  175. data/spec/validates_length_of_spec.rb +0 -117
  176. data/spec/validates_uniqueness_of_spec.rb +0 -92
  177. data/spec/validations/number_validator.rb +0 -59
  178. data/spec/validations/string_validator.rb +0 -14
  179. data/spec/validations_spec.rb +0 -141
  180. data/tasks/fixtures.rb +0 -53
@@ -1,24 +0,0 @@
1
- module DataMapper
2
- module Adapters
3
- module Sql
4
-
5
- # Quoting is a mixin that extends your DataMapper::Database singleton-class
6
- # to allow for object-name and value quoting to be exposed to the queries.
7
- #
8
- # DESIGN: Is there any need for this outside of the query objects? Should
9
- # we just include it in our query object subclasses and not rely on a Quoting
10
- # mixin being part of the "standard" Adapter interface?
11
- module Quoting
12
-
13
- def quote_table_name(name)
14
- name.ensure_wrapped_with(self.class::TABLE_QUOTING_CHARACTER)
15
- end
16
-
17
- def quote_column_name(name)
18
- name.ensure_wrapped_with(self.class::COLUMN_QUOTING_CHARACTER)
19
- end
20
-
21
- end # module Quoting
22
- end
23
- end
24
- end
@@ -1,159 +0,0 @@
1
- require 'data_mapper/adapters/data_object_adapter'
2
- begin
3
- gem 'do_sqlite3', '<= 0.2.5'
4
- require 'do_sqlite3'
5
- rescue LoadError
6
- STDERR.puts <<-EOS
7
- You must install the DataObjects::SQLite3 driver.
8
- gem install do_sqlite3
9
- EOS
10
- exit
11
- end
12
-
13
- module DataMapper
14
- module Adapters
15
-
16
- class Sqlite3Adapter < DataObjectAdapter
17
-
18
- TYPES.merge!({
19
- :integer => 'INTEGER'.freeze,
20
- :string => 'TEXT'.freeze,
21
- :text => 'TEXT'.freeze,
22
- :class => 'TEXT'.freeze,
23
- :boolean => 'INTEGER'.freeze
24
- })
25
-
26
- TABLE_QUOTING_CHARACTER = '"'.freeze
27
- COLUMN_QUOTING_CHARACTER = '"'.freeze
28
- TRUE_ALIASES << 't'.freeze
29
- FALSE_ALIASES << 'f'.freeze
30
-
31
- def create_connection
32
- conn = DataObject::Sqlite3::Connection.new("dbname=#{@configuration.database}")
33
- conn.logger = self.logger
34
- conn.open if conn.respond_to?(:open)
35
- return conn
36
- end
37
-
38
- def batch_insertable?
39
- false
40
- end
41
-
42
- module Mappings
43
-
44
- class Schema
45
- def to_tables_sql
46
- @to_tables_sql || @to_tables_sql = <<-EOS.compress_lines
47
- SELECT "name"
48
- FROM sqlite_master
49
- where "type"= "table"
50
- and "name" <> "sqlite_sequence"
51
- EOS
52
- end
53
- alias_method :database_tables, :get_database_tables
54
- end # class Schema
55
-
56
- class Table
57
- def to_exists_sql
58
- @to_exists_sql || @to_exists_sql = <<-EOS.compress_lines
59
- SELECT "name"
60
- FROM "#{temporary? ? 'sqlite_temp_master' : 'sqlite_master'}"
61
- WHERE "type" = "table"
62
- AND "name" = ?
63
- EOS
64
- end
65
-
66
- def to_column_exists_sql
67
- @to_column_exists_sql || @to_column_exists_sql = <<-EOS.compress_lines
68
- PRAGMA TABLE_INFO(?)
69
- EOS
70
- end
71
-
72
- def to_truncate_sql
73
- "DELETE FROM #{to_sql}"
74
- end
75
-
76
- alias_method :to_columns_sql, :to_column_exists_sql
77
-
78
- def unquote_default(default)
79
- default.gsub(/(^'|'$)/, "") rescue default
80
- end
81
-
82
- end # class Table
83
-
84
- class Column
85
- def serial_declaration
86
- "AUTOINCREMENT"
87
- end
88
-
89
- def size
90
- nil
91
- end
92
-
93
- def alter!
94
- @adapter.connection do |db|
95
- flush_sql_caches!
96
- backup_table = @adapter.table("#{@table.name}_backup")
97
-
98
- @table.columns.each do |column|
99
- backup_table.add_column(column.name, column.type, column.options)
100
- end
101
-
102
- backup_table.temporary = true
103
-
104
- backup_table.create!
105
-
106
- sql = <<-EOS.compress_lines
107
- INSERT INTO #{backup_table.to_sql} SELECT #{@table.columns.map { |c| c.to_sql }.join(', ')} FROM #{@table.to_sql};
108
- DROP TABLE #{@table.to_sql};
109
- #{@table.to_create_sql};
110
- INSERT INTO #{@table.to_sql} SELECT #{backup_table.columns.map { |c| c.to_sql }.join(', ')} FROM #{backup_table.to_sql};
111
- EOS
112
-
113
- sql.split(';').each do |part|
114
- db.create_command(part).execute_non_query
115
- end
116
-
117
- backup_table.drop!
118
- flush_sql_caches!
119
- end
120
- end
121
-
122
- def drop!
123
- @adapter.connection do |db|
124
- @table.columns.delete(self)
125
- flush_sql_caches!
126
-
127
- backup_table = @adapter.table("#{@table.name}_backup")
128
-
129
- @table.columns.each do |column|
130
- backup_table.add_column(column.name, column.type, column.options)
131
- end
132
-
133
- backup_table.temporary = true
134
-
135
- backup_table.create!
136
-
137
- sql = <<-EOS.compress_lines
138
- INSERT INTO #{backup_table.to_sql} SELECT #{@table.columns.map { |c| c.to_sql }.join(', ')} FROM #{@table.to_sql};
139
- DROP TABLE #{@table.to_sql};
140
- #{@table.to_create_sql};
141
- INSERT INTO #{@table.to_sql} SELECT #{backup_table.columns.map { |c| c.to_sql }.join(', ')} FROM #{backup_table.to_sql};
142
- EOS
143
-
144
- sql.split(';').each do |part|
145
- db.create_command(part).execute_non_query
146
- end
147
-
148
- backup_table.drop!
149
- flush_sql_caches!
150
- end
151
- end
152
-
153
- end # class Column
154
- end # module Mappings
155
-
156
- end # class Sqlite3Adapter
157
-
158
- end # module Adapters
159
- end # module DataMapper
@@ -1,106 +0,0 @@
1
- require 'data_mapper/associations/reference'
2
- require 'data_mapper/associations/has_many_association'
3
- require 'data_mapper/associations/belongs_to_association'
4
- require 'data_mapper/associations/has_and_belongs_to_many_association'
5
-
6
- module DataMapper
7
- module Associations
8
-
9
- # Extends +base+ with methods for setting up associations between different models.
10
- def self.included(base)
11
- base.extend(ClassMethods)
12
- end
13
-
14
- module ClassMethods
15
- # Adds the following methods for query of a single associated object:
16
- # * <tt>collection(</tt> - returns a set containing the associated objects. Returns
17
- # an empty set if no objects are found.
18
- # * <tt>collection << object</tt> - adds an object to the collection.
19
- # * <tt>collection = [objects]</tt> - replaces the collections content by deleting and
20
- # adding objects as appropriate.
21
- # * <tt>collection.empty?</tt> - returns +true+ if there is no associated objects.
22
- # * <tt>collection.size</tt> - returns the number of associated objects.
23
- #
24
- # Options are:
25
- # * <tt>:class</tt> - specify the class name of the association. So has_many :animals will by
26
- # default be linked to the Animal class, but if you want the association to use a
27
- # different class, you'll have to specify it with this option. DM also lets you specify
28
- # this with <tt>:class_name</tt>, for AR compability.
29
- # * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default
30
- # this is guessed to be the name of this class in lower-case and _id suffixed.
31
- # * <tt>:dependent</tt> - if set to :destroy, the associated objects have their destroy! methods
32
- # called in a chain meaning all callbacks are also called for each object.
33
- # if set to :delete, the associated objects are deleted from the database
34
- # without their callbacks being triggered.
35
- # if set to :protect and the collection is not empty an AssociatedProtectedError will be raised.
36
- # if set to :nullify, the associated objects foreign key is set to NULL.
37
- # default is :nullify
38
- #
39
- # Option examples:
40
- # has_many :favourite_fruits, :class => 'Fruit', :dependent => :destroy
41
- def has_many(association_name, options = {})
42
- database.schema[self].associations << HasManyAssociation.new(self, association_name, options)
43
- end
44
-
45
- # Adds the following methods for query of a single associated object:
46
- # * <tt>association(</tt> - returns the associated object. Returns an empty set if no
47
- # object is found.
48
- # * <tt>association=(associate)</tt> - assigns the associate object, extracts the
49
- # primary key, and sets it as the foreign key.
50
- # * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
51
- #
52
- # The declaration can also include an options hash to specialize the behavior of the
53
- # association.
54
- #
55
- # Options are:
56
- # * <tt>:class</tt> - specify the class name of the association. So has_one :animal will by
57
- # default be linked to the Animal class, but if you want the association to use a
58
- # different class, you'll have to specify it with this option. DM also lets you specify
59
- # this with <tt>:class_name</tt>, for AR compability.
60
- # * <tt>:foreign_key</tt> - specify the foreign key used for the association. By default
61
- # this is guessed to be the name of this class in lower-case and _id suffixed.
62
- # * <tt>:dependent</tt> - has_one is secretly a has_many so this option performs the same
63
- # as the has_many
64
- #
65
- # Option examples:
66
- # has_one :favourite_fruit, :class => 'Fruit', :foreign_key => 'devourer_id'
67
- def has_one(association_name, options = {})
68
- database.schema[self].associations << HasManyAssociation.new(self, association_name, options)
69
- end
70
-
71
- # Adds the following methods for query of a single associated object:
72
- # * <tt>association(</tt> - returns the associated object. Returns an empty set if no
73
- # object is found.
74
- # * <tt>association=(associate)</tt> - assigns the associate object, extracts the
75
- # primary key, and sets it as the foreign key.
76
- # * <tt>association.nil?</tt> - returns +true+ if there is no associated object.
77
- # * <tt>build_association</tt> - builds a new object of the associated type, without
78
- # saving it to the database.
79
- # * <tt>create_association</tt> - creates and saves a new object of the associated type.
80
- def belongs_to(association_name, options = {})
81
- database.schema[self].associations << BelongsToAssociation.new(self, association_name, options)
82
- end
83
-
84
- # Associates two classes via an intermediate join table.
85
- #
86
- # Options are:
87
- # * <tt>:dependent</tt> - if set to :destroy, the associated objects have their destroy! methods
88
- # called in a chain meaning all callbacks are also called for each object. Beware that this
89
- # is a cascading delete and will affect all records that have a remote relationship with the
90
- # record being destroyed!
91
- # if set to :delete, the associated objects are deleted from the database without their
92
- # callbacks being triggered. This does NOT cascade the deletes. All associated objects will
93
- # have their relationships removed from other records before being deleted. The record calling
94
- # destroy will only delete those records directly associated to it.
95
- # if set to :protect and the collection is not empty an AssociatedProtectedError will be raised.
96
- # if set to :nullify, the join table will have the relationship records removed which is
97
- # effectively nullifying the foreign key.
98
- # default is :nullify
99
- def has_and_belongs_to_many(association_name, options = {})
100
- database.schema[self].associations << HasAndBelongsToManyAssociation.new(self, association_name, options)
101
- end
102
-
103
- end
104
-
105
- end
106
- end
@@ -1,160 +0,0 @@
1
- require 'data_mapper/associations/has_n_association'
2
-
3
- module DataMapper
4
- module Associations
5
-
6
- class BelongsToAssociation < HasNAssociation
7
-
8
- def define_accessor(klass)
9
- klass.class_eval <<-EOS
10
-
11
- def create_#{@association_name}(options = {})
12
- #{@association_name}_association.create(options)
13
- end
14
-
15
- def build_#{@association_name}(options = {})
16
- #{@association_name}_association.build(options)
17
- end
18
-
19
- def #{@association_name}
20
- #{@association_name}_association.instance
21
- end
22
-
23
- def #{@association_name}=(value)
24
- #{@association_name}_association.set(value)
25
- end
26
-
27
- private
28
- def #{@association_name}_association
29
- @#{@association_name} || (@#{@association_name} = DataMapper::Associations::BelongsToAssociation::Instance.new(self, #{@association_name.inspect}))
30
- end
31
- EOS
32
- end
33
-
34
- # Reverse the natural order for BelongsToAssociations
35
- alias constant associated_constant
36
- def associated_constant
37
- @constant
38
- end
39
-
40
- def foreign_key_name
41
- @foreign_key_name || @foreign_key_name = (@options[:foreign_key] || "#{name}_#{key_table.key.name}".to_sym)
42
- end
43
-
44
- def complementary_association
45
- @complementary_association || begin
46
- @complementary_association = key_table.associations.find do |mapping|
47
- mapping.is_a?(HasManyAssociation) &&
48
- mapping.foreign_key_column.name == foreign_key_column.name &&
49
- mapping.associated_table.name == associated_table.name
50
- end
51
-
52
- if @complementary_association
53
- class << self
54
- attr_accessor :complementary_association
55
- end
56
- end
57
-
58
- return @complementary_association
59
- end
60
- end
61
-
62
- def to_sql # :nodoc:
63
- "JOIN #{key_table.to_sql} ON #{foreign_key_column.to_sql(true)} = #{primary_key_column.to_sql(true)}"
64
- end
65
-
66
- class Instance < Associations::Reference
67
-
68
- def dirty?(cleared = ::Set.new)
69
- @associated && (@new_member || @key_not_set)
70
- end
71
-
72
- def validate_recursively(event, cleared)
73
- @associated.nil? || cleared.include?(@associated) || @associated.validate_recursively(event, cleared)
74
- end
75
-
76
- def save_without_validation(database_context, cleared)
77
- @new_member = false
78
- unless @associated.nil?
79
- @instance.instance_variable_set(
80
- association.foreign_key_column.instance_variable_name,
81
- @associated.key
82
- )
83
- @instance.database_context.adapter.save_without_validation(database_context, @instance, cleared)
84
- end
85
- end
86
-
87
- def reload!
88
- @new_member = false
89
- @associated = nil
90
- instance
91
- end
92
-
93
- def instance
94
- @associated || @associated = begin
95
- if @instance.loaded_set.nil?
96
- nil
97
- else
98
-
99
- # Temp variable for the instance variable name.
100
- fk = association.foreign_key_column.to_sym
101
-
102
- set = @instance.loaded_set.group_by { |instance| instance.send(fk) }
103
-
104
- @instance.database_context.all(association.constant, association.associated_table.key.to_sym => set.keys).each do |assoc|
105
- set[assoc.key].each do |primary_instance|
106
- primary_instance.send("#{@association_name}_association").shallow_append(assoc)
107
- end
108
- end
109
-
110
- @associated
111
- end
112
- end
113
- end
114
-
115
- def create(options)
116
- @associated = association.associated_constant.create(options)
117
- end
118
-
119
- def build(options)
120
- @associated = association.associated_constant.new(options)
121
- end
122
-
123
- def setter_method
124
- "#{@association_name}=".to_sym
125
- end
126
-
127
- def set(member)
128
- shallow_append(member)
129
-
130
- if complement = association.complementary_association
131
- member.send(complement.name).shallow_append(@instance)
132
- end
133
-
134
- return self
135
- end
136
-
137
- def shallow_append(val)
138
- raise RecursionError.new if val == @instance
139
- @instance.instance_variable_set(association.foreign_key_column.instance_variable_name, val.key)
140
- @associated = val
141
- @key_not_set = true if val.key.nil?
142
- return self
143
- end
144
-
145
- def deactivate
146
- end
147
-
148
- private
149
-
150
- def ensure_foreign_key!
151
- if @associated
152
- @instance.instance_variable_set(association.foreign_key.instance_variable_name, @associated.key)
153
- end
154
- end
155
-
156
- end # class Instance
157
- end
158
-
159
- end
160
- end