@@ -104,7 +104,7 @@ class Model {
104
104
}
105
105
106
106
class FindBase extends Select {
107
- final Type _modelType;
107
+ Type _modelType;
108
108
final Table table;
109
109
110
110
FindBase (Type modelType)
@@ -131,6 +131,15 @@ class FindBase extends Select {
131
131
132
132
static Future <List > _executeFind (Type modelType, Select selectSql) async {
133
133
Table modelTable = AnnotationsParser .getTableForType (modelType);
134
+
135
+ if (modelTable == null ) {
136
+ ClassMirror modelMirror = reflectClass (modelType);
137
+ String modelClassName = MirrorSystem .getName (modelMirror.simpleName);
138
+
139
+ throw new Exception (
140
+ 'Can\' t find ORM annotations for class $modelClassName ' );
141
+ }
142
+
134
143
ClassMirror modelMirror = reflectClass (modelType);
135
144
136
145
List <dynamic > foundInstances = new List <dynamic >();
@@ -147,7 +156,7 @@ class FindBase extends Select {
147
156
for (Field field in modelTable.fields) {
148
157
var fieldValue = row[field.fieldName];
149
158
150
- if (field is ListReferenceField ) {
159
+ if (field is ListJoinField ) {
151
160
fieldValue = []; // just create new list. It will be populated later.
152
161
}
153
162
@@ -161,17 +170,36 @@ class FindBase extends Select {
161
170
foundInstances.add (newInstance.reflectee);
162
171
}
163
172
164
- if (hasReferenceFields) {
165
- for (Field field in modelTable.fields) {
166
- if (field is ListReferenceField ) {
167
- ListReferenceField listField = field;
168
- ListReferenceTable listTable = field.referenceTable;
173
+ foundInstances = await _populate (foundInstances);
174
+
175
+ return foundInstances;
176
+ }
177
+
178
+ static Future _populate (List modelsFound) async {
179
+ if (modelsFound.length < 1 ) {
180
+ return modelsFound;
181
+ }
182
+
183
+ Table modelTable = AnnotationsParser .getTableForInstance (modelsFound[0 ]);
184
+ Field modelPrimaryKeyField = modelTable.getPrimaryKeyField ();
185
+
186
+ List modelsIds =
187
+ new List .from (modelsFound.map ((m) => orm.getPrimaryKeyValue (m)));
188
+
189
+ for (Field field in modelTable.fields) {
190
+ if (field is ListJoinField ) {
191
+ ListJoinField listField = field;
192
+
193
+ if (field.joinTable is ListJoinValuesTable ) {
194
+ // When list members are simple types and are stored right inside
195
+ // join table
196
+ ListJoinValuesTable listTable = field.joinTable;
169
197
170
198
Select referenceSelect = new Select (['*' ]);
171
- referenceSelect.table = listField.referenceTable ;
172
- referenceSelect.where (new In (
173
- listTable.primaryKeyReferenceField.fieldName,
174
- resulRowsPromaryKeys));
199
+ referenceSelect.table = listField.joinTable ;
200
+ referenceSelect.where (
201
+ new In ( listTable.primaryKeyReferenceField.fieldName, modelsIds));
202
+
175
203
var results = await orm.getDefaultAdapter ().select (referenceSelect);
176
204
177
205
// now we have all values from reference table for all results from original select.
@@ -180,21 +208,84 @@ class FindBase extends Select {
180
208
var modelId = row[listTable.primaryKeyReferenceField.fieldName];
181
209
var value = row[listTable.valueField.fieldName];
182
210
183
- for (var foundInstance in foundInstances ) {
211
+ for (var foundInstance in modelsFound ) {
184
212
var foundInstanceId = AnnotationsParser .getPropertyValueForField (
185
- selectSql.table.getPrimaryKeyField (), foundInstance);
213
+ modelPrimaryKeyField, foundInstance);
214
+
186
215
if (foundInstanceId == modelId) {
187
216
var list = AnnotationsParser .getPropertyValueForField (
188
217
field, foundInstance);
189
218
list.add (value);
190
219
}
191
220
}
192
221
}
222
+ } else if (field.joinTable is ListJoinModelsTable ) {
223
+ ListJoinModelsTable listTable = field.joinTable;
224
+
225
+ // first - select list members ids from join table
226
+ Select listMembersIdsSelect = new Select (['*' ]);
227
+ listMembersIdsSelect.table = listField.joinTable;
228
+ listMembersIdsSelect.where (new In (
229
+ listTable.listHolderPrimaryKeyReference.fieldName, modelsIds));
230
+
231
+ // raw list of list members ids. Each item in this list will have a
232
+ // map with list holder id and list member id.
233
+ List rawListMembersIds =
234
+ await orm.getDefaultAdapter ().select (listMembersIdsSelect);
235
+
236
+ // Just gather all list members ids in a simple list
237
+ List allListMemberIds = [];
238
+
239
+ // Make a map which keys are model ids and values are lists with found
240
+ // list members
241
+ Map <dynamic , List > listMembersIdByModelId = {};
242
+
243
+ rawListMembersIds.forEach ((m) {
244
+ allListMemberIds
245
+ .add (m[listTable.listMembersPrimaryKeyReference.fieldName]);
246
+
247
+ var modelId = m[listTable.listHolderPrimaryKeyReference.fieldName];
248
+
249
+ if (! listMembersIdByModelId.containsKey (modelId)) {
250
+ listMembersIdByModelId[modelId] = [];
251
+ }
252
+
253
+ listMembersIdByModelId[modelId]
254
+ .add (m[listTable.listMembersPrimaryKeyReference.fieldName]);
255
+ });
256
+
257
+ if (allListMemberIds.length > 0 ) {
258
+ // find all list members for all found models
259
+ Find findMembers = new Find (listTable.listMembersTable.modelType);
260
+ findMembers.where (new In (
261
+ listTable.listMembersTable
262
+ .getPrimaryKeyField ()
263
+ .fieldName,
264
+ allListMemberIds));
265
+
266
+ List allListMembers = await findMembers.execute ();
267
+
268
+ // now lets move found list members to models lists
269
+
270
+ for (var foundInstance in modelsFound) {
271
+ var foundInstanceId = AnnotationsParser .getPropertyValueForField (
272
+ modelPrimaryKeyField, foundInstance);
273
+
274
+ List listMemberIdsForFoundModel = listMembersIdByModelId[foundInstanceId];
275
+ List listMembers = new List .from (allListMembers.where ((m) {
276
+ return listMemberIdsForFoundModel.contains (
277
+ orm.getPrimaryKeyValue (m));
278
+ }));
279
+
280
+ AnnotationsParser .setPropertyValueForField (
281
+ field, listMembers, foundInstance);
282
+ }
283
+ }
193
284
}
194
285
}
195
286
}
196
287
197
- return foundInstances ;
288
+ return modelsFound ;
198
289
}
199
290
}
200
291
0 commit comments