Wed, 31 Dec 2025 15:40:44 +0100
fix that NULL as __tabname did not work as table separator in queries
| dbutils/object.c | file | annotate | diff | comparison | revisions | |
| test/database.c | file | annotate | diff | comparison | revisions |
--- a/dbutils/object.c Tue Dec 30 21:07:45 2025 +0100 +++ b/dbutils/object.c Wed Dec 31 15:40:44 2025 +0100 @@ -341,7 +341,7 @@ // collect all foreign keys per row CxList *fklist = cxArrayListCreate(NULL, sizeof(DBUFK), 4); fklist->collection.simple_destructor = (cx_destructor_func)dbufkelm_free; - + // get result int err = 0; while(result->hasData(result)) { @@ -377,6 +377,7 @@ } void *current_obj = obj; + void *parent_obj = obj; void *child_obj = NULL; DBUClass *current_cls = cls; for(int i=skip_fields;i<numcols;i++) { @@ -404,10 +405,21 @@ } } - current_cls = field.cls; if(field.field) { // check if an object of this class can be added to the main obj DBUField *obj_field = cxMapGet(cls->obj_fields, field.cls->name); + if(!obj_field) { + // priority 2: can this class be added to the current class? + obj_field = cxMapGet(current_cls->obj_fields, field.cls->name); + if(obj_field) { + parent_obj = current_obj; + } + } else { + parent_obj = obj; + } + + current_cls = field.cls; + if(obj_field && obj_field->initObjValue) { //printf("create child obj [%s]\n", field.cls->name.ptr); child_obj = objresult->create(objresult, field.cls, a); @@ -421,7 +433,7 @@ field.cls->init(child_obj, a); // TODO: check return } - obj_field->initObjValue(obj_field, a, obj, child_obj); + obj_field->initObjValue(obj_field, a, parent_obj, child_obj); } else { //printf("list field\n"); @@ -454,6 +466,7 @@ } else { cxstring text = result->getText(result, i); //printf("getText(%d) = %s\n", i, text.ptr); + //printf("init obj: [%d] %p {%s}\n", i, current_obj, text.ptr); field.field->initValue(field.field, a, current_obj, text.ptr, text.length); // if obj caching is enabled and the current field contains
--- a/test/database.c Tue Dec 30 21:07:45 2025 +0100 +++ b/test/database.c Wed Dec 31 15:40:44 2025 +0100 @@ -310,45 +310,6 @@ CX_TEST_ASSERT(!cx_strcmp(p1->address->city, "city 18")); dbuObjectBuilderDestroy(builder); - - const char *sql2 = "select p.*, " - "a.address_id as [__address__address_id], a.street, a.zip, a.city, " - "c.country_id as [__country__country_id], c.name " - "from Person p inner join Address a on p.address_id = a.address_id inner join Country c on a.country_id = c.country_id " - "order by p.person_id;"; - DBUQuery *query2 = dbuQueryCreate(conn, mp->allocator, sql2); - DBUObjectBuilder *builder2 = dbuObjectBuilder(person, query2, mp->allocator); - CxList *persons2 = dbuObjectBuilderGetList(builder2); - - CX_TEST_ASSERT(persons2); - CX_TEST_ASSERT(cxListSize(persons2) == 2); - - p0 = cxListAt(persons2, 0); - p1 = cxListAt(persons2, 1); - CX_TEST_ASSERT(p0); - CX_TEST_ASSERT(p1); - CX_TEST_ASSERT(!cx_strcmp(p0->name, "alice")); - CX_TEST_ASSERT(!cx_strcmp(p1->name, "bob")); - CX_TEST_ASSERT(!cx_strcmp(p0->email, "alice@example.com")); - CX_TEST_ASSERT(!cx_strcmp(p1->email, "bob@example.com")); - CX_TEST_ASSERT(p0->age == 30); - CX_TEST_ASSERT(p1->age == 25); - CX_TEST_ASSERT(p0->iscustomer == 0); - CX_TEST_ASSERT(p1->iscustomer == 1); - CX_TEST_ASSERT(p0->hash == 123456789); - CX_TEST_ASSERT(p1->hash == 987654321); - - CX_TEST_ASSERT(p0->address != NULL); - CX_TEST_ASSERT(p1->address != NULL); - - CX_TEST_ASSERT(!cx_strcmp(p0->address->street, "street 1")); - CX_TEST_ASSERT(!cx_strcmp(p1->address->street, "street 2")); - CX_TEST_ASSERT(!cx_strcmp(p0->address->zip, "12343")); - CX_TEST_ASSERT(!cx_strcmp(p1->address->zip, "23456")); - CX_TEST_ASSERT(!cx_strcmp(p0->address->city, "city 17")); - CX_TEST_ASSERT(!cx_strcmp(p1->address->city, "city 18")); - - dbuObjectBuilderDestroy(builder2); } cxMempoolFree(mp); @@ -395,6 +356,11 @@ CX_TEST_ASSERT(!cx_strcmp(p0->address->city, "city 17")); CX_TEST_ASSERT(!cx_strcmp(p1->address->city, "city 18")); + CX_TEST_ASSERT(p0->address->country); + CX_TEST_ASSERT(p1->address->country); + CX_TEST_ASSERT(!cx_strcmp(p0->address->country->name, "Germany")); + CX_TEST_ASSERT(!cx_strcmp(p1->address->country->name, "Germany")); + dbuObjectBuilderDestroy(builder); }