dbutils/object.c

changeset 8
bd08116b8af4
parent 7
c98ff52cd806
child 9
5785a693834c
equal deleted inserted replaced
7:c98ff52cd806 8:bd08116b8af4
94 static DBUObject valuelist_result_create(DBUObjectResult *result, DBUClass *type, const CxAllocator *a) { 94 static DBUObject valuelist_result_create(DBUObjectResult *result, DBUClass *type, const CxAllocator *a) {
95 memset(result->userdata2, 0, result->int1); 95 memset(result->userdata2, 0, result->int1);
96 return result->userdata2; 96 return result->userdata2;
97 } 97 }
98 98
99 static int list_result_add(DBUObjectResult *result, DBUObject parent, void *obj, CxList *fk, const CxAllocator *a) { 99 static int list_result_add(DBUObjectResult *result, DBUObject parent, DBUClass *type, void *obj, CxList *fk, const CxAllocator *a) {
100 return cxListAdd(result->userdata1, obj); 100 return cxListAdd(result->userdata1, obj);
101 } 101 }
102 102
103 CxList* dbuObjectBuilderGetList(DBUObjectBuilder *builder) { 103 CxList* dbuObjectBuilderGetList(DBUObjectBuilder *builder) {
104 CxList *result_list = cxArrayListCreate(builder->allocator, NULL, CX_STORE_POINTERS, 8); 104 CxList *result_list = cxArrayListCreate(builder->allocator, NULL, CX_STORE_POINTERS, 8);
157 157
158 158
159 159
160 /* ------------------------- Object Builder -----------------------------*/ 160 /* ------------------------- Object Builder -----------------------------*/
161 161
162 static int add_to_parent(DBUObjectResult *result, DBUObject parent, void *obj, CxList *fk, const CxAllocator *a) { 162 static int add_to_parent(DBUObjectResult *result, DBUObject parent, DBUClass *type, void *obj, CxList *fklist, const CxAllocator *a) {
163 DBUBuilderQuery *query = result->userdata1; 163 DBUBuilderQuery *query = result->userdata1;
164 164 DBUObjectBuilder *builder = result->userdata2;
165 CxIterator i = cxListIterator(fklist);
166 cx_foreach(DBUFK*, fk, i) {
167 // check if the elm can be added
168 DBUField *field = cxMapGet(fk->cls->obj_fields, type->name);
169 if(!field) {
170 continue;
171 }
172
173 // find cached object for all foreign keys
174 DBUBuilderObjCache *parent_cached = cxMapGet(builder->cache, fk->cache_key);
175 if(!parent_cached) {
176 continue;
177 }
178
179 if(field->builder.add) {
180 field->builder.add(&field->builder, parent_cached->obj, type, obj, NULL, a);
181 }
182 }
165 183
166 return 0; 184 return 0;
167 } 185 }
168 186
169 int dbuObjectExec(DBUObjectBuilder *builder, DBUObjectResult *objresult) { 187 int dbuObjectExec(DBUObjectBuilder *builder, DBUObjectResult *objresult) {
178 if(!ret) { 196 if(!ret) {
179 CxIterator i = cxListIterator(builder->additionalQueries); 197 CxIterator i = cxListIterator(builder->additionalQueries);
180 cx_foreach(DBUBuilderQuery *, q, i) { 198 cx_foreach(DBUBuilderQuery *, q, i) {
181 DBUObjectResult result = { 199 DBUObjectResult result = {
182 .userdata1 = q, 200 .userdata1 = q,
183 .userdata2 = NULL, 201 .userdata2 = builder,
184 .int1 = CX_STORE_POINTERS, 202 .int1 = CX_STORE_POINTERS,
185 .create = result_create_obj, 203 .create = result_create_obj,
186 .add = add_to_parent 204 .add = add_to_parent
187 }; 205 };
188 206
196 if(builder->cache) { 214 if(builder->cache) {
197 cxMapDestroy(builder->cache); 215 cxMapDestroy(builder->cache);
198 } 216 }
199 builder->cache = NULL; 217 builder->cache = NULL;
200 return ret; 218 return ret;
219 }
220
221 void dbufkelm_free(DBUFK *elm) {
222 free(elm->cache_key);
201 } 223 }
202 224
203 int dbuObjectExecuteQuery(DBUObjectBuilder *builder, DBUQuery *query, DBUClass *type, DBUObjectResult *objresult) { 225 int dbuObjectExecuteQuery(DBUObjectBuilder *builder, DBUQuery *query, DBUClass *type, DBUObjectResult *objresult) {
204 DBUClass *cls = type; 226 DBUClass *cls = type;
205 227
268 } 290 }
269 } 291 }
270 292
271 const CxAllocator *a = builder->allocator; 293 const CxAllocator *a = builder->allocator;
272 294
273 CxList *fklist = cxArrayListCreateSimple(CX_STORE_POINTERS, 4); 295 CxList *fklist = cxArrayListCreateSimple(sizeof(DBUFK), 4);
274 fklist->collection.simple_destructor = free; 296 fklist->collection.simple_destructor = (cx_destructor_func)dbufkelm_free;
275 297
276 // get result 298 // get result
277 int err = 0; 299 int err = 0;
278 while(result->hasData(result)) { 300 while(result->hasData(result)) {
301
279 // create main result obj 302 // create main result obj
280 void *obj = objresult->create(objresult, cls, a); 303 void *obj = objresult->create(objresult, cls, a);
281 if(!obj) { 304 if(!obj) {
282 break; 305 break;
283 } 306 }
324 cxstring text = result->getText(result, i); 347 cxstring text = result->getText(result, i);
325 field.field->initValue(field.field, a, current_obj, text.ptr, text.length); 348 field.field->initValue(field.field, a, current_obj, text.ptr, text.length);
326 349
327 // if obj caching is enabled and the current field contains 350 // if obj caching is enabled and the current field contains
328 // the primary key, add this object to the cache 351 // the primary key, add this object to the cache
329 if(builder->cache && field.field == current_cls->primary_key) { 352 if(builder->cache) {
330 if(field.field == current_cls->primary_key) { 353 if(field.field == current_cls->primary_key) {
331 cxmutstr cache_key = cx_asprintf("%.*s::%.*s", 354 cxmutstr cache_key = cx_asprintf("%.*s::%.*s",
332 (int)current_cls->name.length, current_cls->name.ptr, 355 (int)current_cls->name.length, current_cls->name.ptr,
333 (int)text.length, text.ptr); 356 (int)text.length, text.ptr);
334 if(!cache_key.ptr) { 357 if(!cache_key.ptr) {
335 err = 1; 358 err = 1;
336 break; 359 break;
337 } 360 }
338 int r = cxMapPut(builder->cache, cache_key, current_obj); 361 DBUBuilderObjCache cache_elm;
362 cache_elm.class = current_cls;
363 cache_elm.obj = current_obj;
364 int r = cxMapPut(builder->cache, cache_key, &cache_elm);
339 free(cache_key.ptr); 365 free(cache_key.ptr);
340 if(r) { 366 if(r) {
341 err = 1; 367 err = 1;
342 break; 368 break;
343 } 369 }
344 } else if(field.field->foreignKeyClass) { 370 } else if(field.field->foreignKeyClass) {
345 cxmutstr fkey = cx_asprintf("%.*s::%.*s", 371 cxmutstr fkey = cx_asprintf("%.*s::%.*s",
346 (int)field.field->foreignKeyClass->name.length, current_cls->name.ptr, 372 (int)field.field->foreignKeyClass->name.length, field.field->foreignKeyClass->name.ptr,
347 (int)text.length, text.ptr); 373 (int)text.length, text.ptr);
348 cxListAdd(fklist, fkey.ptr); 374 DBUFK fkelm;
375 fkelm.cache_key = fkey.ptr;
376 fkelm.cls = field.field->foreignKeyClass;
377 cxListAdd(fklist, &fkelm);
349 } 378 }
350 } 379 }
351 } 380 }
352 } 381 }
353 } 382 }
354 383
355 if(err) { 384 if(err) {
356 break; 385 break;
357 } 386 }
358 387
359 objresult->add(objresult, NULL, obj, fklist, a); 388 objresult->add(objresult, NULL, cls, obj, fklist, a);
360 389
361 cxListClear(fklist); 390 cxListClear(fklist);
362 391
363 // load next row 392 // load next row
364 result->nextRow(result); 393 result->nextRow(result);

mercurial