--- a/test/main.c Wed Dec 11 21:53:31 2024 +0100 +++ b/test/main.c Fri Dec 13 11:24:55 2024 +0100 @@ -50,12 +50,16 @@ "zip text, " "city text);"; +const char *sql_create_table_role = +"create table if not exists Role (" +"role_id integer primary key autoincrement, " +"person_id integer, " +"name text);"; + const char *sql_check_table = "select person_id from Person limit 1;"; - - const char *sql_create_test_data1 = "insert into address (street, zip, city) " "values " @@ -65,8 +69,16 @@ const char *sql_create_test_data2 = "insert into person (name, email, age, iscustomer, hash, address_id) " "values " -"('alice', 'alice@example.com', 30, 1, 123456789, (select address_id from address where street = 'street 1')), " -"('bob', 'bob@example.com', 25, 0, 987654321, (select address_id from address where street = 'street 2'));"; +"('alice', 'alice@example.com', 30, 0, 123456789, (select address_id from address where street = 'street 1')), " +"('bob', 'bob@example.com', 25, 1, 987654321, (select address_id from address where street = 'street 2'));"; + +const char *sql_create_test_data3 = +"insert into role (person_id, name) " +"values " +"(1, 'finance'), " +"(1, 'dev'), " +"(1, 'manager'), " +"(2, 'extern');"; typedef struct Address { int64_t address_id; @@ -86,8 +98,15 @@ uint64_t hash; Address *address; + + CxList *roles; } Person; +typedef struct Role { + int64_t role_id; + int64_t person_id; + cxmutstr name; +} Role; static int create_test_data(sqlite3 *db); @@ -102,6 +121,8 @@ dbuClassAdd(address, Address, zip); dbuClassAdd(address, Address, city); + DBUClass *role = dbuRegisterClass(ctx, "role", Role, role_id); + DBUClass *person = dbuRegisterClass(ctx, "person", Person, person_id); dbuClassAdd(person, Person, name); dbuClassAdd(person, Person, email); @@ -109,7 +130,10 @@ dbuClassAdd(person, Person, iscustomer); dbuClassAdd(person, Person, hash); dbuClassAddObj(person, "address_id", offsetof(Person, address), address); + dbuClassAddCxLinkedList(person, "person_id", offsetof(Person, roles), role); + dbuClassAddForeignKey(role, Role, person_id, person); + dbuClassAdd(role, Role, name); // Open or create the database sqlite3 *db; @@ -128,7 +152,11 @@ DBUQuery *query = conn->createQuery(conn, NULL); dbuQuerySetSQL(query, "select p.*, a.address_id as [__address__address_id], a.street, a.zip, a.city from Person p inner join Address a on p.address_id = a.address_id;"); + DBUQuery *roleQuery = conn->createQuery(conn, NULL); + dbuQuerySetSQL(roleQuery, "select * from role;"); + DBUObjectBuilder *builder = dbuObjectBuilder(person, query, cxDefaultAllocator); + dbuObjectBuilderAddAdditionalQuery(builder, role, roleQuery); CxList *persons = dbuObjectBuilderGetList(builder); if(persons) { CxIterator i = cxListIterator(persons); @@ -147,7 +175,13 @@ static int create_test_data(sqlite3 *db) { char *err_msg = NULL; - int rc = sqlite3_exec(db, sql_create_table_person, 0, 0, &err_msg); + sqlite3_stmt *stmt; + int rc = sqlite3_prepare_v2(db, sql_check_table, -1, &stmt, 0); + if(rc == SQLITE_OK) { + return 0; + } + + rc = sqlite3_exec(db, sql_create_table_person, 0, 0, &err_msg); if(rc != SQLITE_OK) { fprintf(stderr, "SQLite error: %s\n", err_msg); sqlite3_free(err_msg); @@ -163,25 +197,14 @@ return 1; } - - sqlite3_stmt *stmt; - rc = sqlite3_prepare_v2(db, sql_check_table, -1, &stmt, 0); + rc = sqlite3_exec(db, sql_create_table_role, 0, 0, &err_msg); if(rc != SQLITE_OK) { - fprintf(stderr, "SQLite error: %s\n", sqlite3_errmsg(db)); + fprintf(stderr, "SQLite error: %s\n", err_msg); + sqlite3_free(err_msg); sqlite3_close(db); return 1; } - int exists = 0; - if(sqlite3_step(stmt) == SQLITE_ROW) { - exists = 1; - } - sqlite3_finalize(stmt); - - if(exists) { - return 0; - } - rc = sqlite3_exec(db, sql_create_test_data1, 0, 0, &err_msg); if(rc != SQLITE_OK) { fprintf(stderr, "SQLite error: %s\n", err_msg); @@ -198,5 +221,13 @@ return 1; } + rc = sqlite3_exec(db, sql_create_test_data3, 0, 0, &err_msg); + if(rc != SQLITE_OK) { + fprintf(stderr, "SQLite error: %s\n", err_msg); + sqlite3_free(err_msg); + sqlite3_close(db); + return 1; + } + return 0; }