| 128 int64_t role_id; |
130 int64_t role_id; |
| 129 int64_t person_id; |
131 int64_t person_id; |
| 130 cxmutstr name; |
132 cxmutstr name; |
| 131 } Role; |
133 } Role; |
| 132 |
134 |
| |
135 typedef struct Resource { |
| |
136 int64_t resource_id; |
| |
137 int64_t parent_id; |
| |
138 char *nodename; |
| |
139 char *content; |
| |
140 bool iscollection; |
| |
141 } Resource; |
| |
142 |
| |
143 typedef struct Note { |
| |
144 int64_t note_id; |
| |
145 int64_t resource_id; |
| |
146 char *tags; |
| |
147 int type; |
| |
148 |
| |
149 Resource *resource; |
| |
150 } Note; |
| |
151 |
| 133 int init_db_tests(void) { |
152 int init_db_tests(void) { |
| 134 ctx = dbuContextCreate(); |
153 ctx = dbuContextCreate(); |
| 135 |
154 |
| 136 country = dbuRegisterClass(ctx, "country", Country, country_id); |
155 country = dbuRegisterClass(ctx, "country", Country, country_id); |
| 137 dbuClassAdd(country, Country, name); |
156 dbuClassAdd(country, Country, name); |
| 138 |
157 |
| 139 address = dbuRegisterClass(ctx, "address", Address, address_id); |
158 address = dbuRegisterClass(ctx, "address", Address, address_id); |
| 140 dbuClassAdd(address, Address, street); |
159 dbuClassAdd(address, Address, street); |
| 141 dbuClassAdd(address, Address, zip); |
160 dbuClassAdd(address, Address, zip); |
| 142 dbuClassAdd(address, Address, city); |
161 dbuClassAdd(address, Address, city); |
| 143 dbuClassAddObj(address, "country_id", offsetof(Address, country), country); |
162 dbuClassAddObj(address, "country", offsetof(Address, country), country); |
| 144 |
163 |
| 145 role = dbuRegisterClass(ctx, "role", Role, role_id); |
164 role = dbuRegisterClass(ctx, "role", Role, role_id); |
| 146 dbuClassAdd(role, Role, person_id); |
165 dbuClassAdd(role, Role, person_id); |
| 147 dbuClassAdd(role, Role, name); |
166 dbuClassAdd(role, Role, name); |
| 148 |
167 |
| 150 dbuClassAdd(person, Person, name); |
169 dbuClassAdd(person, Person, name); |
| 151 dbuClassAdd(person, Person, email); |
170 dbuClassAdd(person, Person, email); |
| 152 dbuClassAdd(person, Person, age); |
171 dbuClassAdd(person, Person, age); |
| 153 dbuClassAdd(person, Person, iscustomer); |
172 dbuClassAdd(person, Person, iscustomer); |
| 154 dbuClassAdd(person, Person, hash); |
173 dbuClassAdd(person, Person, hash); |
| 155 dbuClassAddObj(person, "address_id", offsetof(Person, address), address); |
174 dbuClassAddObj(person, "address", offsetof(Person, address), address); |
| 156 dbuClassAddCxLinkedList(person, "person_id", offsetof(Person, roles), role); |
175 dbuClassAddCxLinkedList(person, "person_id", offsetof(Person, roles), role); |
| 157 |
176 |
| 158 dbuClassAddForeignKey(role, Role, person_id, person); |
177 dbuClassAddForeignKey(role, Role, person_id, person); |
| 159 dbuClassAdd(role, Role, name); |
178 dbuClassAdd(role, Role, name); |
| |
179 |
| |
180 resource = dbuRegisterClass(ctx, "resource", Resource, resource_id); |
| |
181 dbuClassAdd(resource, Resource, parent_id); |
| |
182 dbuClassAdd(resource, Resource, nodename); |
| |
183 dbuClassAdd(resource, Resource, content); |
| |
184 dbuClassAdd(resource, Resource, iscollection); |
| |
185 |
| |
186 note = dbuRegisterClass(ctx, "note", Note, note_id); |
| |
187 dbuClassAdd(note, Note, resource_id); |
| |
188 dbuClassAdd(note, Note, tags); |
| |
189 dbuClassAdd(note, Note, type); |
| |
190 dbuClassAddObj(note, "resource", offsetof(Note, resource), resource); |
| |
191 |
| 160 |
192 |
| 161 return 0; |
193 return 0; |
| 162 } |
194 } |
| 163 |
195 |
| 164 void cleanup_db_tests(void) { |
196 void cleanup_db_tests(void) { |
| 407 } |
439 } |
| 408 |
440 |
| 409 cxMempoolFree(mp); |
441 cxMempoolFree(mp); |
| 410 } |
442 } |
| 411 |
443 |
| |
444 CX_TEST(testMultiTableQuery3) { |
| |
445 CxMempool *mp = cxMempoolCreateSimple(64); |
| |
446 |
| |
447 CX_TEST_DO { |
| |
448 const char *sql1 = |
| |
449 "select n.*, r.resource_id as [__resource__resource_id], r.parent_id, " \ |
| |
450 "r.nodename, r.content, r.iscollection " \ |
| |
451 "from resource r inner join note n on r.resource_id = n.resource_id " \ |
| |
452 "where parent_id = (select resource_id from resource where nodename = 'Collection1') ;"; |
| |
453 DBUQuery *q = dbuQueryCreate(conn, mp->allocator, sql1); |
| |
454 DBUObjectBuilder *builder = dbuObjectBuilder(note, q, mp->allocator); |
| |
455 CxList *notes = dbuObjectBuilderGetList(builder); |
| |
456 dbuObjectBuilderDestroy(builder); |
| |
457 |
| |
458 CX_TEST_ASSERT(notes); |
| |
459 CX_TEST_ASSERT(cxListSize(notes) == 2); |
| |
460 |
| |
461 Note *n0 = cxListAt(notes, 0); |
| |
462 Note *n1 = cxListAt(notes, 1); |
| |
463 |
| |
464 CX_TEST_ASSERT(n0); |
| |
465 CX_TEST_ASSERT(n1); |
| |
466 |
| |
467 CX_TEST_ASSERT(n0->note_id > 0); |
| |
468 CX_TEST_ASSERT(n0->resource_id > 0); |
| |
469 CX_TEST_ASSERT(!cx_strcmp(n0->tags, "todo, test")); |
| |
470 CX_TEST_ASSERT(n0->type == 1); |
| |
471 CX_TEST_ASSERT(n0->resource); |
| |
472 CX_TEST_ASSERT(n0->resource_id == n0->resource->resource_id); |
| |
473 CX_TEST_ASSERT(!cx_strcmp(n0->resource->nodename, "note1")); |
| |
474 CX_TEST_ASSERT(!n0->resource->iscollection); |
| |
475 CX_TEST_ASSERT(n0->resource->parent_id > 0); |
| |
476 CX_TEST_ASSERT(!cx_strcmp(n0->resource->content, "Hello World!")); |
| |
477 |
| |
478 CX_TEST_ASSERT(n1->note_id > 0); |
| |
479 CX_TEST_ASSERT(n1->resource_id > 0); |
| |
480 CX_TEST_ASSERT(!cx_strcmp(n1->tags, "work, project2501, ai")); |
| |
481 CX_TEST_ASSERT(n1->type == 2); |
| |
482 CX_TEST_ASSERT(n1->resource); |
| |
483 CX_TEST_ASSERT(n1->resource_id == n1->resource->resource_id); |
| |
484 CX_TEST_ASSERT(!cx_strcmp(n1->resource->nodename, "note2")); |
| |
485 CX_TEST_ASSERT(!n1->resource->iscollection); |
| |
486 CX_TEST_ASSERT(n1->resource->parent_id > 0); |
| |
487 CX_TEST_ASSERT(!cx_strcmp(n1->resource->content, "Test String")); |
| |
488 } |
| |
489 |
| |
490 cxMempoolFree(mp); |
| |
491 } |
| |
492 |
| 412 CX_TEST(testMultiTableQueryUnknownResult1) { |
493 CX_TEST(testMultiTableQueryUnknownResult1) { |
| 413 CxMempool *mp = cxMempoolCreateSimple(64); |
494 CxMempool *mp = cxMempoolCreateSimple(64); |
| 414 |
495 |
| 415 CX_TEST_DO { |
496 CX_TEST_DO { |
| 416 // select persons, addresses and countries |
497 // select persons, addresses and countries |