From 1496482f80355a8ff723e5491704f748b9d6931b Mon Sep 17 00:00:00 2001 From: avsdev-cw Date: Wed, 7 Oct 2020 15:47:34 +0100 Subject: [PATCH] Refactored fetching groups and members --- src/modb_accounting.c | 422 +++++++++++++++++----------------------- src/modb_accounting.h | 19 +- src/modb_accounting_p.c | 41 ++-- src/modb_accounting_p.h | 4 +- src/modb_types.c | 29 ++- src/modb_types.h | 2 + 6 files changed, 240 insertions(+), 277 deletions(-) diff --git a/src/modb_accounting.c b/src/modb_accounting.c index a17d59c..2eff3cf 100644 --- a/src/modb_accounting.c +++ b/src/modb_accounting.c @@ -14,18 +14,9 @@ int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_g int res; wb = where(0, "id", EQ, TYPE_UINT32, 1, id); - res = doScalarUsersQuery(sconn, modb, wb, user); + res = doScalarUsersQuery(sconn, modb, wb, with_groups, user); freeWhereBuilder(&wb); - if (res > 0 && with_groups) { - if (modbFetchUserGroups( - sconn, modb, 0, (*user)->id, &(*user)->n_groups, &(*user)->groups - ) < 0) { - freeUser(user); - return -1; - } - } - return res; } int modbUserByName(stored_conn *sconn, modb_ref *modb, const char *username, int with_groups, @@ -35,18 +26,9 @@ int modbUserByName(stored_conn *sconn, modb_ref *modb, const char *username, int int res; wb = where(0, "username", EQ, TYPE_STRING, 1, username); - res = doScalarUsersQuery(sconn, modb, wb, user); + res = doScalarUsersQuery(sconn, modb, wb, with_groups, user); freeWhereBuilder(&wb); - if (res > 0 && with_groups) { - if (modbFetchUserGroups( - sconn, modb, 0, (*user)->id, &(*user)->n_groups, &(*user)->groups - ) < 0) { - freeUser(user); - return -1; - } - } - return res; } int modbUserByEmail(stored_conn *sconn, modb_ref *modb, const char *email, int with_groups, @@ -56,18 +38,9 @@ int modbUserByEmail(stored_conn *sconn, modb_ref *modb, const char *email, int w int res; wb = where(0, "email", EQ, TYPE_STRING, 1, email); - res = doScalarUsersQuery(sconn, modb, wb, user); + res = doScalarUsersQuery(sconn, modb, wb, with_groups, user); freeWhereBuilder(&wb); - if (res > 0 && with_groups) { - if (modbFetchUserGroups( - sconn, modb, 0, (*user)->id, &(*user)->n_groups, &(*user)->groups - ) < 0) { - freeUser(user); - return -1; - } - } - return res; } int modbUserSearch(stored_conn *sconn, modb_ref *modb, const char *username_email, int with_groups, @@ -80,18 +53,9 @@ int modbUserSearch(stored_conn *sconn, modb_ref *modb, const char *username_emai where(0, "username", EQ, TYPE_STRING, 1, username_email), where(0, "email", EQ, TYPE_STRING, 1, username_email) ); - res = doScalarUsersQuery(sconn, modb, wb, user); + res = doScalarUsersQuery(sconn, modb, wb, with_groups, user); freeWhereBuilder(&wb); - if (res > 0 && with_groups) { - if (modbFetchUserGroups( - sconn, modb, 0, (*user)->id, &(*user)->n_groups, &(*user)->groups - ) < 0) { - freeUser(user); - return -1; - } - } - return res; } @@ -114,10 +78,8 @@ int modbUserList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with_ if (res > 0 && with_groups) { for (idx = 0; idx < *n_users; idx++) { user = *((*users) + idx); - if (modbFetchUserGroups( - sconn, modb, with_deleted, user->id, &user->n_groups, &user->groups - ) < 0) { - freeUsers(*users, *n_users); + if (modbFetchUserGroups(sconn, modb, user, with_deleted) < 0) { + freeUsers(users, *n_users); return -1; } } @@ -253,6 +215,88 @@ int modbUserDestroy(stored_conn *sconn, modb_ref *modb, int id) return 1; } +int modbFetchUserGroupIds(stored_conn *sconn, modb_ref *modb, + struct user_t *user, int with_deleted) +{ + char *qry; + size_t qry_len; + uint64_t qry_ret; + + str_builder *sb; + where_builder *wb; + char *table; + + column_data **col_data; + size_t n_cols; + + + if ((sb = strbld_create()) == 0) { + return -errno; + } + strbld_str(sb, "SELECT `group_id` FROM ", 0); + modbTableName_sb(sb, modb, USER_GROUPS_TABLE, strlen(USER_GROUPS_TABLE), '`'); + strbld_char(sb, ' '); + modbJoin_sb(sb, modb, "LEFT", 4, 1, + GROUPS_TABLE, strlen(GROUPS_TABLE), "id", 2, + USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE), "group_id", 8); + strbld_str(sb, " WHERE ", 0); + wb = where(0, "user_id", EQ, TYPE_ID, 1, user->id); + if (!with_deleted) { + table = modbTableName(modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE), 0); + wb = whereAnd(wb, where(table, "deleted", IS_NULL, TYPE_RAW, 0)); + free(table); + } + compileWhereBuilder_sb(wb, sb, 1); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + qry_ret = tableQuery(sconn, qry, qry_len, 0, &col_data, &n_cols); + free(qry); + + // Query failed + if (qry_ret == (uint64_t)-1) { + return -1; + } + + // Zero row result + if (qry_ret == 0) { + freeColumns(col_data, n_cols); + return 0; + } + + user->group_ids = (*col_data)->data.ptr_uint32; + user->n_groups = (*col_data)->n_values; + (*col_data)->data.ptr_uint32 = 0; + + freeColumns(col_data, n_cols); + + return 1; +} +int modbFetchUserGroups(stored_conn *sconn, modb_ref *modb, struct user_t *user, int with_deleted) +{ + int ret; + size_t idx; + + ret = modbFetchUserGroupIds(sconn, modb, user, with_deleted); + if (ret != 1) { + return ret; + } + + user->groups = allocGroups(user->n_groups); + if (user->groups == 0) { + return -1; + } + + for (idx = 0; idx < user->n_groups; idx++) { + if (modbGroupById(sconn, modb, *(user->group_ids + idx), 0, (user->groups + idx)) != 1) { + freeGroups(&user->groups, user->n_groups); + return -1; + } + } + + return ret; +} // ##### GROUPS @@ -263,18 +307,9 @@ int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_ int res; wb = where(0, "id", EQ, TYPE_UINT32, 1, id); - res = doScalarGroupsQuery(sconn, modb, wb, group); + res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); freeWhereBuilder(&wb); - if (res > 0 && with_members) { - if (modbFetchGroupUsers( - sconn, modb, 0, (*group)->id, &(*group)->n_members, &(*group)->members - ) < 0) { - freeGroup(group); - return -1; - } - } - return res; } int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int with_members, @@ -284,18 +319,9 @@ int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int wi int res; wb = where(0, "name", EQ, TYPE_STRING, 1, name); - res = doScalarGroupsQuery(sconn, modb, wb, group); + res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); freeWhereBuilder(&wb); - if (res > 0 && with_members) { - if (modbFetchGroupUsers( - sconn, modb, 0, (*group)->id, &(*group)->n_members, &(*group)->members - ) < 0) { - freeGroup(group); - return -1; - } - } - return res; } @@ -318,10 +344,8 @@ int modbGroupList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with if (res > 0 && with_members) { for (idx = 0; idx < *n_groups; idx++) { group = *((*groups) + idx); - if (modbFetchGroupUsers( - sconn, modb, with_deleted, group->id, &group->n_members, &group->members - ) < 0) { - freeGroups(*groups, *n_groups); + if (modbFetchGroupUsers(sconn, modb, group, with_deleted) < 0) { + freeGroups(groups, *n_groups); *groups = 0; *n_groups = 0; return -1; @@ -454,6 +478,91 @@ int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, int id) return 1; } +int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, struct group_t *group, + int with_deleted) +{ + char *qry; + size_t qry_len; + uint64_t qry_ret; + + str_builder *sb; + where_builder *wb; + char *table; + + column_data **col_data; + size_t n_cols; + + + if ((sb = strbld_create()) == 0) { + return -errno; + } + strbld_str(sb, "SELECT `user_id` FROM ", 0); + modbTableName_sb(sb, modb, USER_GROUPS_TABLE, strlen(USER_GROUPS_TABLE), '`'); + strbld_char(sb, ' '); + modbJoin_sb(sb, modb, "LEFT", 4, 1, + USERS_TABLE, strlen(USERS_TABLE), "id", 2, + USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE), "user_id", 8); + strbld_str(sb, " WHERE ", 0); + wb = where(0, "group_id", EQ, TYPE_ID, 1, group->id); + if (!with_deleted) { + table = modbTableName(modb, USERS_TABLE, STR_LEN(USERS_TABLE), 0); + wb = whereAnd(wb, where(table, "deleted", IS_NULL, TYPE_RAW, 0)); + free(table); + } + compileWhereBuilder_sb(wb, sb, 1); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + qry_ret = tableQuery(sconn, qry, qry_len, 0, &col_data, &n_cols); + free(qry); + + // Query failed + if (qry_ret == (uint64_t)-1) { + return -1; + } + + // Zero row result + if (qry_ret == 0) { + freeColumns(col_data, n_cols); + return 0; + } + + group->member_ids = (*col_data)->data.ptr_uint32; + group->n_members = (*col_data)->n_values; + (*col_data)->data.ptr_uint32 = 0; + + freeColumns(col_data, n_cols); + + return 1; +} +int modbFetchGroupUsers(stored_conn *sconn, modb_ref *modb, struct group_t *group, + int with_deleted) +{ + int ret; + size_t idx; + + ret = modbFetchGroupUserIds(sconn, modb, group, with_deleted); + if (ret != 1) { + return ret; + } + + group->members = allocUsers(group->n_members); + if (group->members == 0) { + ret = -1; + } + + for (idx = 0; idx < group->n_members; idx++) { + if (modbUserById(sconn, modb, *(group->member_ids + idx), 0, (group->members + idx)) != 1) { + freeUsers(&group->members, group->n_members); + group->members = 0; + ret = -1; + } + } + + return ret; +} + // ##### USER<->GROUP RELATIONS @@ -526,183 +635,6 @@ int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, return qry_ret; } - -int modbFetchUserGroupIds(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int user_id, size_t *n_groups, unsigned int **group_ids) -{ - char *qry; - size_t qry_len; - uint64_t qry_ret; - - str_builder *sb; - where_builder *wb; - char *table; - - column_data **col_data; - size_t n_cols; - - - if ((sb = strbld_create()) == 0) { - return -errno; - } - strbld_str(sb, "SELECT `group_id` FROM ", 0); - modbTableName_sb(sb, modb, USER_GROUPS_TABLE, strlen(USER_GROUPS_TABLE), '`'); - strbld_char(sb, ' '); - modbJoin_sb(sb, modb, "LEFT", 4, 1, - GROUPS_TABLE, strlen(GROUPS_TABLE), "id", 2, - USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE), "group_id", 8); - strbld_str(sb, " WHERE ", 0); - wb = where(0, "user_id", EQ, TYPE_ID, 1, user_id); - if (!with_deleted) { - table = modbTableName(modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE), 0); - wb = whereAnd(wb, where(table, "deleted", IS_NULL, TYPE_RAW, 0)); - free(table); - } - compileWhereBuilder_sb(wb, sb, 1); - if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { - return -1; - } - - qry_ret = tableQuery(sconn, qry, qry_len, 0, &col_data, &n_cols); - free(qry); - - // Query failed - if (qry_ret == (uint64_t)-1) { - return -1; - } - - // Zero row result - if (qry_ret == 0) { - freeColumns(col_data, n_cols); - return 0; - } - - *group_ids = (*col_data)->data.ptr_uint32; - *n_groups = (*col_data)->n_values; - (*col_data)->data.ptr_uint32 = 0; - - freeColumns(col_data, n_cols); - - return 1; -} -int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int group_id, size_t *n_users, unsigned int **user_ids) -{ - char *qry; - size_t qry_len; - uint64_t qry_ret; - - str_builder *sb; - where_builder *wb; - char *table; - - column_data **col_data; - size_t n_cols; - - - if ((sb = strbld_create()) == 0) { - return -errno; - } - strbld_str(sb, "SELECT `user_id` FROM ", 0); - modbTableName_sb(sb, modb, USER_GROUPS_TABLE, strlen(USER_GROUPS_TABLE), '`'); - strbld_char(sb, ' '); - modbJoin_sb(sb, modb, "LEFT", 4, 1, - USERS_TABLE, strlen(USERS_TABLE), "id", 2, - USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE), "user_id", 8); - strbld_str(sb, " WHERE ", 0); - wb = where(0, "group_id", EQ, TYPE_ID, 1, group_id); - if (!with_deleted) { - table = modbTableName(modb, USERS_TABLE, STR_LEN(USERS_TABLE), 0); - wb = whereAnd(wb, where(table, "deleted", IS_NULL, TYPE_RAW, 0)); - free(table); - } - compileWhereBuilder_sb(wb, sb, 1); - if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { - return -1; - } - - qry_ret = tableQuery(sconn, qry, qry_len, 0, &col_data, &n_cols); - free(qry); - - // Query failed - if (qry_ret == (uint64_t)-1) { - return -1; - } - - // Zero row result - if (qry_ret == 0) { - freeColumns(col_data, n_cols); - return 0; - } - - *user_ids = (*col_data)->data.ptr_uint32; - *n_users = (*col_data)->n_values; - (*col_data)->data.ptr_uint32 = 0; - - freeColumns(col_data, n_cols); - - return 1; -} -int modbFetchUserGroups(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int user_id, size_t *n_groups, struct group_t ***groups) -{ - unsigned int *group_ids; - int ret; - size_t idx; - - ret = modbFetchUserGroupIds(sconn, modb, with_deleted, user_id, n_groups, &group_ids); - if (ret != 1) { - return ret; - } - - *groups = allocGroups(*n_groups); - if (*groups == 0) { - ret = -1; - } - - for (idx = 0; idx < *n_groups; idx++) { - if (modbGroupById(sconn, modb, *(group_ids + idx), 0, (*groups) + idx) != 1) { - freeGroups(*groups, *n_groups); - *groups = 0; - *n_groups = 0; - ret = -1; - } - } - free(group_ids); - - return ret; -} -int modbFetchGroupUsers(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int group_id, size_t *n_users, struct user_t ***users) -{ - unsigned int *user_ids; - int ret; - size_t idx; - - ret = modbFetchGroupUserIds(sconn, modb, with_deleted, group_id, n_users, &user_ids); - if (ret != 1) { - return ret; - } - - *users = allocUsers(*n_users); - if (*users == 0) { - ret = -1; - } - - for (idx = 0; idx < *n_users; idx++) { - if (modbUserById(sconn, modb, *(user_ids + idx), 0, (*users) + idx) != 1) { - freeUsers(*users, *n_users); - *users = 0; - *n_users = 0; - ret = -1; - } - } - free(user_ids); - - return ret; -} - - int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, unsigned int user_id, unsigned int group_id) { diff --git a/src/modb_accounting.h b/src/modb_accounting.h index f7d818b..a4ab9f3 100644 --- a/src/modb_accounting.h +++ b/src/modb_accounting.h @@ -25,6 +25,10 @@ int64_t modbUserUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, int modbUserDelete(stored_conn *sconn, modb_ref *modb, int id); int modbUserDestroy(stored_conn *sconn, modb_ref *modb, int id); +int modbFetchUserGroupIds(stored_conn *sconn, modb_ref *modb, + struct user_t *user, int with_deleted); +int modbFetchUserGroups(stored_conn *sconn, modb_ref *modb, struct user_t *user, int with_deleted); + // MODB Groups int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_members, @@ -42,6 +46,11 @@ int64_t modbGroupUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, int modbGroupDelete(stored_conn *sconn, modb_ref *modb, int id); int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, int id); +int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, struct group_t *group, + int with_deleted); +int modbFetchGroupUsers(stored_conn *sconn, modb_ref *modb, struct group_t *group, + int with_deleted); + // MODB Users <-> Groups int modbSyncUserGroups(stored_conn *sconn, modb_ref *modb, @@ -54,16 +63,6 @@ int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, unsigned int group_id, size_t n_users, ...); -int modbFetchUserGroupIds(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int user_id, size_t *n_groups, unsigned int **group_ids); -int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int group_id, size_t *n_users, unsigned int **user_ids); -int modbFetchUserGroups(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int user_id, size_t *n_groups, struct group_t ***groups); -int modbFetchGroupUsers(stored_conn *sconn, modb_ref *modb, int with_deleted, - unsigned int group_id, size_t *n_users, struct user_t ***users); - - int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, unsigned int user_id, unsigned int group_id); int modbLink_Group_User(stored_conn *sconn, modb_ref *modb, diff --git a/src/modb_accounting_p.c b/src/modb_accounting_p.c index 27499fd..e82a24d 100644 --- a/src/modb_accounting_p.c +++ b/src/modb_accounting_p.c @@ -4,6 +4,7 @@ #include "modb_p.h" #include "modb_accounting_p.h" +#include "modb_accounting.h" // ##### USERS @@ -36,19 +37,19 @@ int tableRowsToUsers(column_data **col_data, size_t n_cols, for (idx = 0; idx < n_rows; idx++) { user = allocUser(); if (user == 0) { - freeUsers(*users, idx - 1); + freeUsers(users, idx - 1); return -1; } user->id = *(col_id->data.ptr_uint32 + idx); if (strmemcpy(*(col_username->data.ptr_str + idx), *(col_username->data_lens + idx), &user->username, &user->username_len) != 0) { - freeUsers(*users, idx); + freeUsers(users, idx); return -1; } if (strmemcpy(*(col_email->data.ptr_str + idx), *(col_email->data_lens + idx), &user->email, &user->email_len) != 0) { - freeUsers(*users, idx); + freeUsers(users, idx); return -1; } user->created_on = *(col_created->data.ptr_uint32 + idx); @@ -117,7 +118,7 @@ int doUsersQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, return (int)qry_ret; } int doScalarUsersQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, struct user_t **user) + where_builder *wb, int with_groups, struct user_t **user) { int res; struct user_t **users; @@ -128,9 +129,16 @@ int doScalarUsersQuery(stored_conn *sconn, modb_ref *modb, return res; } - *user = *users; - *users = 0; - freeUsers(users, n_users); + *user = *(users + 0); + *(users + 0) = 0; + freeUsers(&users, n_users); + + if (with_groups) { + if (modbFetchUserGroups(sconn, modb, *user, 0) < 0) { + freeUser(user); + return -1; + } + } return res; } @@ -164,14 +172,14 @@ int tableRowsToGroups(column_data **col_data, size_t n_cols, for (idx = 0; idx < n_rows; idx++) { if ((group = allocGroup()) == 0) { - freeGroups(*groups, idx - 1); + freeGroups(groups, idx - 1); return -1; } group->id = *(col_id->data.ptr_uint32 + idx); if (strmemcpy(*(col_name->data.ptr_str + idx), *(col_name->data_lens + idx), &group->name, &group->name_len) != 0) { - freeGroups(*groups, idx); + freeGroups(groups, idx); return -1; } group->created_on = *(col_created->data.ptr_uint32 + idx); @@ -240,7 +248,7 @@ int doGroupsQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, return (int)qry_ret; } int doScalarGroupsQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, struct group_t **group) + where_builder *wb, int with_members, struct group_t **group) { int res; struct group_t **groups; @@ -251,9 +259,16 @@ int doScalarGroupsQuery(stored_conn *sconn, modb_ref *modb, return res; } - *group = *groups; - *groups = 0; - freeGroups(groups, n_groups); + *group = *(groups + 0); + *(groups + 0) = 0; + freeGroups(&groups, n_groups); + + if (with_members) { + if (modbFetchGroupUsers(sconn, modb, *group, 0) < 0) { + freeGroup(group); + return -1; + } + } return res; } diff --git a/src/modb_accounting_p.h b/src/modb_accounting_p.h index 9911a19..11a9174 100644 --- a/src/modb_accounting_p.h +++ b/src/modb_accounting_p.h @@ -10,7 +10,7 @@ int tableRowsToUsers(column_data **col_data, size_t n_cols, int doUsersQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, struct user_t ***users, size_t *n_users); int doScalarUsersQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, struct user_t **user); + where_builder *wb, int with_groups, struct user_t **user); // ##### GROUPS int tableRowsToGroups(column_data **col_data, size_t n_cols, @@ -18,6 +18,6 @@ int tableRowsToGroups(column_data **col_data, size_t n_cols, int doGroupsQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, struct group_t ***groups, size_t *n_groups); int doScalarGroupsQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, struct group_t **group); + where_builder *wb, int with_members, struct group_t **group); #endif // H__MODB_ACCOUNTING_P__ diff --git a/src/modb_types.c b/src/modb_types.c index 021b4f5..afc175a 100644 --- a/src/modb_types.c +++ b/src/modb_types.c @@ -37,8 +37,13 @@ void freeUser(struct user_t **user_ptr) struct user_t *user = *user_ptr; if (user->n_groups > 0) { - freeGroups(user->groups, user->n_groups); - user->groups = 0; + if (user->group_ids != 0) { + free(user->group_ids); + user->group_ids = 0; + } + if (user->groups != 0) { + freeGroups(&user->groups, user->n_groups); + } user->n_groups = 0; } @@ -55,9 +60,10 @@ void freeUser(struct user_t **user_ptr) free(user); *user_ptr = 0; } -void freeUsers(struct user_t **users, size_t n_users) +void freeUsers(struct user_t ***users_ptr, size_t n_users) { size_t idx; + struct user_t ** users = *users_ptr; for (idx = 0; idx < n_users; idx++) { if (*(users + idx) != 0) { @@ -66,6 +72,7 @@ void freeUsers(struct user_t **users, size_t n_users) } free(users); + *users_ptr = 0; } @@ -99,8 +106,13 @@ void freeGroup(struct group_t **group_ptr) struct group_t *group = *group_ptr; if (group->n_members > 0) { - freeUsers(group->members, group->n_members); - group->members = 0; + if (group->member_ids != 0) { + free(group->member_ids); + group->member_ids = 0; + } + if (group->members != 0) { + freeUsers(&group->members, group->n_members); + } group->n_members = 0; } @@ -112,15 +124,18 @@ void freeGroup(struct group_t **group_ptr) free(group); *group_ptr = 0; } -void freeGroups(struct group_t **groups, size_t n_groups) +void freeGroups(struct group_t ***groups_ptr, size_t n_groups) { size_t idx; + struct group_t **groups = *groups_ptr; for (idx = 0; idx < n_groups; idx++) { if (*(groups + idx) != 0) { - freeGroup((groups + idx)); + freeGroup(groups + idx); } } free(groups); + *groups_ptr = 0; +} } diff --git a/src/modb_types.h b/src/modb_types.h index 38617d7..2203784 100644 --- a/src/modb_types.h +++ b/src/modb_types.h @@ -23,6 +23,7 @@ struct user_t { unsigned int updated_on; unsigned int deleted_on; + unsigned int *group_ids; struct group_t **groups; size_t n_groups; }; @@ -37,6 +38,7 @@ struct group_t { unsigned int updated_on; unsigned int deleted_on; + unsigned int *member_ids; struct user_t **members; size_t n_members; };