datamapper 0.1.1 → 0.2.0
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.
- data/CHANGELOG +65 -0
- data/README +193 -1
- data/do_performance.rb +153 -0
- data/environment.rb +45 -0
- data/example.rb +119 -22
- data/lib/data_mapper.rb +36 -16
- data/lib/data_mapper/adapters/abstract_adapter.rb +8 -0
- data/lib/data_mapper/adapters/data_object_adapter.rb +360 -0
- data/lib/data_mapper/adapters/mysql_adapter.rb +30 -179
- data/lib/data_mapper/adapters/postgresql_adapter.rb +90 -199
- data/lib/data_mapper/adapters/sql/coersion.rb +32 -3
- data/lib/data_mapper/adapters/sql/commands/conditions.rb +97 -128
- data/lib/data_mapper/adapters/sql/commands/load_command.rb +234 -231
- data/lib/data_mapper/adapters/sql/commands/loader.rb +99 -0
- data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +30 -0
- data/lib/data_mapper/adapters/sql/mappings/column.rb +68 -6
- data/lib/data_mapper/adapters/sql/mappings/schema.rb +6 -3
- data/lib/data_mapper/adapters/sql/mappings/table.rb +71 -42
- data/lib/data_mapper/adapters/sql/quoting.rb +8 -2
- data/lib/data_mapper/adapters/sqlite3_adapter.rb +32 -201
- data/lib/data_mapper/associations.rb +21 -7
- data/lib/data_mapper/associations/belongs_to_association.rb +96 -80
- data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +158 -67
- data/lib/data_mapper/associations/has_many_association.rb +96 -78
- data/lib/data_mapper/associations/has_n_association.rb +64 -0
- data/lib/data_mapper/associations/has_one_association.rb +49 -79
- data/lib/data_mapper/associations/reference.rb +47 -0
- data/lib/data_mapper/base.rb +216 -50
- data/lib/data_mapper/callbacks.rb +71 -24
- data/lib/data_mapper/{session.rb → context.rb} +20 -8
- data/lib/data_mapper/database.rb +176 -45
- data/lib/data_mapper/embedded_value.rb +65 -0
- data/lib/data_mapper/identity_map.rb +12 -4
- data/lib/data_mapper/support/active_record_impersonation.rb +12 -8
- data/lib/data_mapper/support/enumerable.rb +8 -0
- data/lib/data_mapper/support/serialization.rb +13 -0
- data/lib/data_mapper/support/string.rb +1 -12
- data/lib/data_mapper/support/symbol.rb +3 -0
- data/lib/data_mapper/validations/unique_validator.rb +1 -2
- data/lib/data_mapper/validations/validation_helper.rb +18 -1
- data/performance.rb +109 -34
- data/plugins/can_has_sphinx/LICENSE +23 -0
- data/plugins/can_has_sphinx/README +4 -0
- data/plugins/can_has_sphinx/REVISION +1 -0
- data/plugins/can_has_sphinx/Rakefile +22 -0
- data/plugins/can_has_sphinx/init.rb +1 -0
- data/plugins/can_has_sphinx/install.rb +1 -0
- data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +123 -0
- data/plugins/can_has_sphinx/lib/sphinx.rb +460 -0
- data/plugins/can_has_sphinx/scripts/sphinx.sh +47 -0
- data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +41 -0
- data/plugins/dataobjects/REVISION +1 -0
- data/plugins/dataobjects/Rakefile +7 -0
- data/plugins/dataobjects/do.rb +246 -0
- data/plugins/dataobjects/do_mysql.rb +179 -0
- data/plugins/dataobjects/do_postgres.rb +181 -0
- data/plugins/dataobjects/do_sqlite3.rb +153 -0
- data/plugins/dataobjects/spec/do_spec.rb +150 -0
- data/plugins/dataobjects/spec/spec_helper.rb +81 -0
- data/plugins/dataobjects/swig_mysql/do_mysql.bundle +0 -0
- data/plugins/dataobjects/swig_mysql/extconf.rb +33 -0
- data/plugins/dataobjects/swig_mysql/mysql_c.c +18800 -0
- data/plugins/dataobjects/swig_mysql/mysql_c.i +8 -0
- data/plugins/dataobjects/swig_mysql/mysql_supp.i +46 -0
- data/plugins/dataobjects/swig_postgres/Makefile +146 -0
- data/plugins/dataobjects/swig_postgres/extconf.rb +29 -0
- data/plugins/dataobjects/swig_postgres/postgres_c.bundle +0 -0
- data/plugins/dataobjects/swig_postgres/postgres_c.c +8185 -0
- data/plugins/dataobjects/swig_postgres/postgres_c.i +73 -0
- data/plugins/dataobjects/swig_sqlite/db +0 -0
- data/plugins/dataobjects/swig_sqlite/extconf.rb +9 -0
- data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +4725 -0
- data/plugins/dataobjects/swig_sqlite/sqlite_c.i +168 -0
- data/rakefile.rb +45 -23
- data/spec/acts_as_tree_spec.rb +39 -0
- data/spec/associations_spec.rb +220 -0
- data/spec/attributes_spec.rb +15 -0
- data/spec/base_spec.rb +44 -0
- data/spec/callbacks_spec.rb +45 -0
- data/spec/can_has_sphinx.rb +6 -0
- data/spec/coersion_spec.rb +34 -0
- data/spec/conditions_spec.rb +49 -0
- data/spec/conversions_to_yaml_spec.rb +17 -0
- data/spec/count_command_spec.rb +11 -0
- data/spec/delete_command_spec.rb +1 -1
- data/spec/embedded_value_spec.rb +23 -0
- data/spec/fixtures/animals_exhibits.yaml +2 -0
- data/spec/fixtures/people.yaml +18 -1
- data/spec/{legacy.rb → legacy_spec.rb} +3 -3
- data/spec/load_command_spec.rb +157 -20
- data/spec/magic_columns_spec.rb +9 -0
- data/spec/mock_adapter.rb +20 -0
- data/spec/models/animal.rb +1 -1
- data/spec/models/animals_exhibit.rb +6 -0
- data/spec/models/exhibit.rb +2 -0
- data/spec/models/person.rb +26 -1
- data/spec/models/project.rb +19 -0
- data/spec/models/sales_person.rb +1 -0
- data/spec/models/section.rb +6 -0
- data/spec/models/zoo.rb +3 -1
- data/spec/query_spec.rb +9 -0
- data/spec/save_command_spec.rb +65 -1
- data/spec/schema_spec.rb +89 -0
- data/spec/single_table_inheritance_spec.rb +27 -0
- data/spec/spec_helper.rb +9 -55
- data/spec/{symbolic_operators.rb → symbolic_operators_spec.rb} +9 -5
- data/spec/{validates_confirmation_of.rb → validates_confirmation_of_spec.rb} +4 -3
- data/spec/{validates_format_of.rb → validates_format_of_spec.rb} +5 -4
- data/spec/{validates_length_of.rb → validates_length_of_spec.rb} +8 -7
- data/spec/{validates_uniqueness_of.rb → validates_uniqueness_of_spec.rb} +7 -10
- data/spec/{validations.rb → validations_spec.rb} +24 -6
- data/tasks/drivers.rb +20 -0
- data/tasks/fixtures.rb +42 -0
- metadata +181 -42
- data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +0 -140
- data/lib/data_mapper/adapters/sql/commands/delete_command.rb +0 -113
- data/lib/data_mapper/adapters/sql/commands/save_command.rb +0 -141
- data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +0 -33
- data/lib/data_mapper/adapters/sql_adapter.rb +0 -163
- data/lib/data_mapper/associations/advanced_has_many_association.rb +0 -55
- data/lib/data_mapper/support/blank_slate.rb +0 -3
- data/lib/data_mapper/support/proc.rb +0 -69
- data/lib/data_mapper/support/struct.rb +0 -26
- data/lib/data_mapper/unit_of_work.rb +0 -38
- data/spec/basic_finder.rb +0 -67
- data/spec/belongs_to.rb +0 -47
- data/spec/has_and_belongs_to_many.rb +0 -25
- data/spec/has_many.rb +0 -34
- data/spec/new_record.rb +0 -24
- data/spec/sub_select.rb +0 -16
- data/spec/support/string_spec.rb +0 -7
|
@@ -1,66 +1,18 @@
|
|
|
1
|
-
require 'data_mapper/adapters/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
require 'data_mapper/adapters/data_object_adapter'
|
|
2
|
+
begin
|
|
3
|
+
require 'do_sqlite3'
|
|
4
|
+
rescue
|
|
5
|
+
STDERR.puts <<-EOS
|
|
6
|
+
You must install the DataObjects::SQLite3 driver.
|
|
7
|
+
rake dm:install:sqlite3
|
|
8
|
+
EOS
|
|
9
|
+
exit
|
|
10
|
+
end
|
|
5
11
|
|
|
6
12
|
module DataMapper
|
|
7
13
|
module Adapters
|
|
8
14
|
|
|
9
|
-
class Sqlite3Adapter <
|
|
10
|
-
|
|
11
|
-
def initialize(configuration)
|
|
12
|
-
super
|
|
13
|
-
@connections = Support::ConnectionPool.new do
|
|
14
|
-
dbh = SQLite3::Database.new(configuration.database)
|
|
15
|
-
dbh.results_as_hash = true
|
|
16
|
-
dbh
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def connection
|
|
21
|
-
raise ArgumentError.new('Sqlite3Adapter#connection requires a block-parameter') unless block_given?
|
|
22
|
-
begin
|
|
23
|
-
@connections.hold { |connection| yield connection }
|
|
24
|
-
rescue SQLite3::Exception => sle
|
|
25
|
-
|
|
26
|
-
@configuration.log.fatal(sle)
|
|
27
|
-
|
|
28
|
-
@connections.available_connections.each do |sock|
|
|
29
|
-
begin
|
|
30
|
-
sock.close
|
|
31
|
-
rescue => se
|
|
32
|
-
@configuration.log.error(se)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
@connections.available_connections.clear
|
|
37
|
-
raise sle
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def query(*args)
|
|
42
|
-
reader = connection { |db| db.query(escape_sql(*args)) }
|
|
43
|
-
|
|
44
|
-
fields = nil
|
|
45
|
-
rows = []
|
|
46
|
-
|
|
47
|
-
until reader.eof?
|
|
48
|
-
hash = reader.next
|
|
49
|
-
break if hash.nil?
|
|
50
|
-
|
|
51
|
-
fields = hash.keys.select { |field| field.is_a?(String) } unless fields
|
|
52
|
-
|
|
53
|
-
rows << fields.map { |field| hash[field] }
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
reader.close
|
|
57
|
-
|
|
58
|
-
struct = Support::Struct::define(fields)
|
|
59
|
-
|
|
60
|
-
rows.map do |row|
|
|
61
|
-
struct.new(row)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
15
|
+
class Sqlite3Adapter < DataObjectAdapter
|
|
64
16
|
|
|
65
17
|
TYPES.merge!({
|
|
66
18
|
:integer => 'INTEGER'.freeze,
|
|
@@ -72,155 +24,34 @@ module DataMapper
|
|
|
72
24
|
TABLE_QUOTING_CHARACTER = '"'.freeze
|
|
73
25
|
COLUMN_QUOTING_CHARACTER = '"'.freeze
|
|
74
26
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
when "0", nil then false
|
|
80
|
-
else "Can't type-cast #{value.inspect} to a boolean"
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def type_cast_datetime(value)
|
|
85
|
-
case value
|
|
86
|
-
when DateTime then value
|
|
87
|
-
when Date then DateTime.new(value)
|
|
88
|
-
when String then DateTime::parse(value)
|
|
89
|
-
else "Can't type-cast #{value.inspect} to a datetime"
|
|
90
|
-
end
|
|
27
|
+
def create_connection
|
|
28
|
+
conn = DataObject::Sqlite3::Connection.new("dbname=#{@configuration.database}")
|
|
29
|
+
conn.open
|
|
30
|
+
return conn
|
|
91
31
|
end
|
|
92
|
-
|
|
93
|
-
module Commands
|
|
94
|
-
|
|
95
|
-
class TableExistsCommand
|
|
96
|
-
def to_sql
|
|
97
|
-
"SELECT name FROM sqlite_master WHERE type = \"table\" AND name = #{table_name}"
|
|
98
|
-
end
|
|
99
32
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
33
|
+
module Mappings
|
|
34
|
+
class Table
|
|
35
|
+
def to_exists_sql
|
|
36
|
+
@to_exists_sql || @to_exists_sql = <<-EOS.compress_lines
|
|
37
|
+
SELECT "name"
|
|
38
|
+
FROM "sqlite_master"
|
|
39
|
+
WHERE "type" = "table"
|
|
40
|
+
AND "name" = #{@adapter.quote_value(name)}
|
|
41
|
+
EOS
|
|
105
42
|
end
|
|
106
|
-
end # class
|
|
107
|
-
|
|
108
|
-
class SaveCommand
|
|
109
|
-
def to_create_table_sql
|
|
110
|
-
table = @adapter[@instance]
|
|
111
|
-
|
|
112
|
-
sql = "CREATE TABLE " << table.to_sql
|
|
113
|
-
|
|
114
|
-
sql << " (" << table.columns.map do |column|
|
|
115
|
-
column_long_form(column)
|
|
116
|
-
end.join(', ') << ")"
|
|
117
|
-
|
|
118
|
-
return sql
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def column_long_form(column)
|
|
122
|
-
long_form = "#{column.to_sql} #{@adapter.class::TYPES[column.type] || column.type}"
|
|
123
|
-
|
|
124
|
-
long_form << " NOT NULL" unless column.nullable?
|
|
125
|
-
long_form << " PRIMARY KEY" if column.key?
|
|
126
|
-
long_form << " default #{column.options[:default]}" if column.options.has_key?(:default)
|
|
127
|
-
|
|
128
|
-
return long_form
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def execute_insert(sql)
|
|
132
|
-
@adapter.connection do |db|
|
|
133
|
-
db.query(sql)
|
|
134
|
-
db.last_insert_row_id
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def execute_update(sql)
|
|
139
|
-
@adapter.connection do |db|
|
|
140
|
-
db.query(sql)
|
|
141
|
-
db.total_changes > 0
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def execute_create_table(sql)
|
|
146
|
-
@adapter.connection { |db| db.query(sql) }
|
|
147
|
-
true
|
|
148
|
-
end
|
|
149
|
-
end # class SaveCommand
|
|
43
|
+
end # class Table
|
|
150
44
|
|
|
151
|
-
class
|
|
152
|
-
def
|
|
153
|
-
"
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def execute(sql)
|
|
157
|
-
@adapter.connection do |db|
|
|
158
|
-
db.query(sql)
|
|
159
|
-
db.total_changes > 0
|
|
160
|
-
end
|
|
45
|
+
class Column
|
|
46
|
+
def serial_declaration
|
|
47
|
+
"AUTOINCREMENT"
|
|
161
48
|
end
|
|
162
49
|
|
|
163
|
-
def
|
|
164
|
-
|
|
165
|
-
true
|
|
50
|
+
def size
|
|
51
|
+
nil
|
|
166
52
|
end
|
|
167
|
-
end # class
|
|
168
|
-
|
|
169
|
-
class LoadCommand
|
|
170
|
-
def eof?(reader)
|
|
171
|
-
reader.eof?
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def close_reader(reader)
|
|
175
|
-
reader.close
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
def execute(sql)
|
|
179
|
-
@adapter.connection { |db| db.query(to_sql) }
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def fetch_one(reader)
|
|
183
|
-
load(reader.next)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
def fetch_all(reader)
|
|
187
|
-
fields = nil
|
|
188
|
-
rows = []
|
|
189
|
-
|
|
190
|
-
until reader.eof?
|
|
191
|
-
hash = reader.next
|
|
192
|
-
break if hash.nil?
|
|
193
|
-
|
|
194
|
-
fields = hash.keys.select { |field| field.is_a?(String) } unless fields
|
|
195
|
-
|
|
196
|
-
rows << fields.map { |name| hash[name] }
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
load_instances(fields, rows)
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def fetch_structs(reader)
|
|
203
|
-
fields = nil
|
|
204
|
-
rows = []
|
|
205
|
-
|
|
206
|
-
until reader.eof?
|
|
207
|
-
hash = reader.next
|
|
208
|
-
break if hash.nil?
|
|
209
|
-
|
|
210
|
-
fields = hash.keys.select { |field| field.is_a?(String) } unless fields
|
|
211
|
-
|
|
212
|
-
rows << fields.map { |name| hash[name] }
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
fields = fields.inject({}) do |h,f|
|
|
216
|
-
h[f] = fields.index(f); h
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
load_structs(fields, rows)
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
end # module Commands
|
|
53
|
+
end # class Column
|
|
54
|
+
end # module Mappings
|
|
224
55
|
|
|
225
56
|
end # class Sqlite3Adapter
|
|
226
57
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
require 'data_mapper/associations/reference'
|
|
1
2
|
require 'data_mapper/associations/has_many_association'
|
|
2
|
-
require 'data_mapper/associations/advanced_has_many_association'
|
|
3
3
|
require 'data_mapper/associations/belongs_to_association'
|
|
4
4
|
require 'data_mapper/associations/has_one_association'
|
|
5
5
|
require 'data_mapper/associations/has_and_belongs_to_many_association'
|
|
@@ -8,13 +8,27 @@ module DataMapper
|
|
|
8
8
|
module Associations
|
|
9
9
|
|
|
10
10
|
def self.included(base)
|
|
11
|
-
base.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
base.extend(ClassMethods)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module ClassMethods
|
|
15
|
+
|
|
16
|
+
def has_many(association_name, options = {})
|
|
17
|
+
database.schema[self].associations << HasManyAssociation.new(self, association_name, options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def belongs_to(association_name, options = {})
|
|
21
|
+
database.schema[self].associations << BelongsToAssociation.new(self, association_name, options)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def has_and_belongs_to_many(association_name, options = {})
|
|
25
|
+
database.schema[self].associations << HasAndBelongsToManyAssociation.new(self, association_name, options)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def has_one(association_name, options = {})
|
|
29
|
+
database.schema[self].associations << HasOneAssociation.new(self, association_name, options)
|
|
17
30
|
end
|
|
31
|
+
|
|
18
32
|
end
|
|
19
33
|
|
|
20
34
|
end
|
|
@@ -1,110 +1,126 @@
|
|
|
1
|
+
require 'data_mapper/associations/has_n_association'
|
|
2
|
+
|
|
1
3
|
module DataMapper
|
|
2
4
|
module Associations
|
|
3
5
|
|
|
4
|
-
class BelongsToAssociation
|
|
5
|
-
|
|
6
|
-
def
|
|
7
|
-
@
|
|
8
|
-
@association_name = association_name
|
|
9
|
-
@options = options
|
|
10
|
-
|
|
11
|
-
@associated_class = if options.has_key?(:class) || options.has_key?(:class_name)
|
|
12
|
-
associated_class_name = (options[:class] || options[:class_name])
|
|
13
|
-
if associated_class_name.kind_of?(String)
|
|
14
|
-
Kernel.const_get(Inflector.classify(associated_class_name))
|
|
15
|
-
else
|
|
16
|
-
associated_class_name
|
|
17
|
-
end
|
|
18
|
-
else
|
|
19
|
-
Kernel.const_get(Inflector.classify(association_name))
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def self.setup(klass, association_name, options)
|
|
24
|
-
foreign_key = options[:foreign_key] || ("#{association_name}_id")
|
|
25
|
-
klass.property foreign_key.to_sym, :integer
|
|
6
|
+
class BelongsToAssociation < HasNAssociation
|
|
7
|
+
|
|
8
|
+
def define_accessor(klass)
|
|
9
|
+
klass.property((@options[:foreign_key] || "#{name}_id").to_sym, :integer)
|
|
26
10
|
|
|
27
|
-
# Define the association instance method (i.e. Exhibit#zoo)
|
|
28
11
|
klass.class_eval <<-EOS
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
|
|
13
|
+
def create_#{@association_name}(options = {})
|
|
14
|
+
#{@association_name}_association.create(options)
|
|
31
15
|
end
|
|
32
16
|
|
|
33
|
-
def build_#{association_name}(options = {})
|
|
34
|
-
#{association_name}_association.build(options)
|
|
17
|
+
def build_#{@association_name}(options = {})
|
|
18
|
+
#{@association_name}_association.build(options)
|
|
35
19
|
end
|
|
36
20
|
|
|
37
|
-
def #{association_name}
|
|
38
|
-
#
|
|
39
|
-
#{association_name}_association.find
|
|
21
|
+
def #{@association_name}
|
|
22
|
+
#{@association_name}_association.instance
|
|
40
23
|
end
|
|
41
24
|
|
|
42
|
-
def #{association_name}=(value)
|
|
43
|
-
#{association_name}_association.set(value)
|
|
25
|
+
def #{@association_name}=(value)
|
|
26
|
+
#{@association_name}_association.set(value)
|
|
44
27
|
end
|
|
45
28
|
|
|
46
29
|
private
|
|
47
|
-
def #{association_name}_association
|
|
48
|
-
@#{association_name} || (@#{association_name} = BelongsToAssociation.new(self,
|
|
30
|
+
def #{@association_name}_association
|
|
31
|
+
@#{@association_name} || (@#{@association_name} = DataMapper::Associations::BelongsToAssociation::Instance.new(self, #{@association_name.inspect}))
|
|
49
32
|
end
|
|
50
33
|
EOS
|
|
51
|
-
|
|
52
34
|
end
|
|
53
35
|
|
|
54
|
-
def
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
unless @instance.loaded_set.nil?
|
|
58
|
-
|
|
59
|
-
# Temp variable for the instance variable name.
|
|
60
|
-
setter_method = "#{@association_name}=".to_sym
|
|
61
|
-
instance_variable_name = "@#{foreign_key}".to_sym
|
|
62
|
-
|
|
63
|
-
set = @instance.loaded_set.group_by { |instance| instance.instance_variable_get(instance_variable_name) }
|
|
64
|
-
|
|
65
|
-
# Fetch the foreign objects for all instances in the current object's loaded-set.
|
|
66
|
-
@instance.session.all(@associated_class, :id => set.keys).each do |owner|
|
|
67
|
-
set[owner.key].each do |instance|
|
|
68
|
-
instance.send(setter_method, owner)
|
|
69
|
-
end
|
|
70
|
-
end
|
|
36
|
+
def foreign_key
|
|
37
|
+
@foreign_key || @foreign_key = begin
|
|
38
|
+
table[@options[:foreign_key] || "#{name}_id".to_sym]
|
|
71
39
|
end
|
|
72
|
-
|
|
73
|
-
return @result
|
|
74
40
|
end
|
|
75
41
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@
|
|
80
|
-
|
|
42
|
+
class Instance < Associations::Reference
|
|
43
|
+
|
|
44
|
+
def instance
|
|
45
|
+
@associated || @associated = begin
|
|
46
|
+
if @instance.loaded_set.nil?
|
|
47
|
+
nil
|
|
48
|
+
else
|
|
49
|
+
|
|
50
|
+
# Temp variable for the instance variable name.
|
|
51
|
+
fk = association.foreign_key.to_sym
|
|
52
|
+
|
|
53
|
+
set = @instance.loaded_set.group_by { |instance| instance.send(fk) }
|
|
54
|
+
|
|
55
|
+
@instance.session.all(association.constant, association.association_table.key.to_sym => set.keys).each do |assoc|
|
|
56
|
+
set[assoc.key].each do |primary_instance|
|
|
57
|
+
primary_instance.send(setter_method, assoc)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
@associated
|
|
62
|
+
end
|
|
63
|
+
end
|
|
81
64
|
end
|
|
82
|
-
end
|
|
83
65
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
66
|
+
def create(options)
|
|
67
|
+
@associated = association.constant.create(options)
|
|
68
|
+
end
|
|
87
69
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
70
|
+
def build(options)
|
|
71
|
+
@associated = association.constant.new(options)
|
|
72
|
+
end
|
|
91
73
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
74
|
+
def setter_method
|
|
75
|
+
"#{@association_name}=".to_sym
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def set(val)
|
|
79
|
+
@instance.instance_variable_set(association.foreign_key.instance_variable_name, val.key)
|
|
80
|
+
@associated = val
|
|
81
|
+
end
|
|
95
82
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
module BelongsTo
|
|
99
|
-
def self.included(base)
|
|
100
|
-
base.extend(ClassMethods)
|
|
101
|
-
end
|
|
83
|
+
end # class Instance
|
|
102
84
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
85
|
+
|
|
86
|
+
# def find
|
|
87
|
+
# return @result unless @result.nil?
|
|
88
|
+
#
|
|
89
|
+
# unless @instance.loaded_set.nil?
|
|
90
|
+
#
|
|
91
|
+
# # Temp variable for the instance variable name.
|
|
92
|
+
# setter_method = "#{@association_name}=".to_sym
|
|
93
|
+
# instance_variable_name = "@#{foreign_key}".to_sym
|
|
94
|
+
#
|
|
95
|
+
# set = @instance.loaded_set.group_by { |instance| instance.instance_variable_get(instance_variable_name) }
|
|
96
|
+
#
|
|
97
|
+
# # Fetch the foreign objects for all instances in the current object's loaded-set.
|
|
98
|
+
# @instance.session.all(constant, :id => set.keys).each do |owner|
|
|
99
|
+
# set[owner.key].each do |instance|
|
|
100
|
+
# instance.send(setter_method, owner)
|
|
101
|
+
# end
|
|
102
|
+
# end
|
|
103
|
+
# end
|
|
104
|
+
#
|
|
105
|
+
# return @result
|
|
106
|
+
# end
|
|
107
|
+
|
|
108
|
+
# def create(options = {})
|
|
109
|
+
# associated = constant.new(options)
|
|
110
|
+
# if associated.save
|
|
111
|
+
# @instance.send("#{constant.foreign_key}=", associated.id)
|
|
112
|
+
# @result = associated
|
|
113
|
+
# end
|
|
114
|
+
# end
|
|
115
|
+
#
|
|
116
|
+
# def build(options = {})
|
|
117
|
+
# @result = constant.new(options)
|
|
118
|
+
# end
|
|
119
|
+
#
|
|
120
|
+
# def set(val)
|
|
121
|
+
# @result = val
|
|
122
|
+
# end
|
|
123
|
+
|
|
108
124
|
end
|
|
109
125
|
|
|
110
126
|
end
|