diff --git a/src/modb_accounting_p.c b/src/modb_accounting_p.c deleted file mode 100644 index a4ae2a2..0000000 --- a/src/modb_accounting_p.c +++ /dev/null @@ -1,287 +0,0 @@ -#include -#include -#include - -#include "modb_p.h" -#include "modb_accounting_p.h" -#include "modb_accounting.h" - - -// ##### USERS -int tableRowsToUsers(column_data **col_data, size_t n_cols, - struct user_t ***users, size_t *n_users) -{ - column_data *col_id, *col_username, *col_email, *col_created, *col_updated, *col_deleted; - size_t n_rows, idx; - struct user_t *user; - - n_rows = (*col_data)->n_values; - if (n_rows == 0) { - return 0; - } - - col_id = findColumnByName(col_data, n_cols, "id"); - col_username = findColumnByName(col_data, n_cols, "username"); - col_email = findColumnByName(col_data, n_cols, "email"); - col_created = findColumnByName(col_data, n_cols, "created"); - col_updated = findColumnByName(col_data, n_cols, "updated"); - col_deleted = findColumnByName(col_data, n_cols, "deleted"); - - *users = (struct user_t **)malloc(sizeof(struct user_t *) * n_rows); - if (*users == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return -1; - } - memset(*users, 0, sizeof(struct user_t *) * n_rows); - - for (idx = 0; idx < n_rows; idx++) { - user = allocUser(); - if (user == 0) { - freeUsers(users, idx - 1); - return -1; - } - - user->id = *(col_id->data.ptr_uint32 + idx); - - if (!moveColumnStrPointer(col_username, idx, 1, &user->username, &user->username_len)) { - freeUsers(users, idx); - return -1; - } - - if (!moveColumnStrPointer(col_email, idx, 1, &user->email, &user->email_len)) { - freeUsers(users, idx); - return -1; - } - - user->created_on = *(col_created->data.ptr_int64 + idx); - if (!columnRowIsNull(col_updated, idx)) { - user->updated_on = *(col_updated->data.ptr_int64 + idx); - } - if (!columnRowIsNull(col_deleted, idx)) { - user->deleted_on = *(col_deleted->data.ptr_int64 + idx); - } - - *(*users + idx) = user; - } - - *n_users = n_rows; - - return 1; -} -int doUsersQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, - struct user_t ***users, size_t *n_users) -{ - char *table; - size_t table_len; - char *qry; - size_t qry_len; - uint64_t qry_ret; - int res; - - str_builder *sb; - - column_data **col_data; - size_t n_cols; - - - if ((sb = strbld_create()) == 0) { - return -1; - } - modbTableName(&table, &table_len, modb, USERS_TABLE, strlen(USERS_TABLE)); - - strbld_str(sb, "SELECT * FROM ", 0); - escapeTableName_sb(sb, table, table_len); - if (wb != 0) { - compileWhereBuilder_sb(sb, wb, 0); - } - - modbFreeTableName(&table); - 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; - } - - res = tableRowsToUsers(col_data, n_cols, users, n_users); - freeColumns(col_data, n_cols); - - if (res <= 0) { - return res; - } - - return (int)qry_ret; -} -int doScalarUsersQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, int with_groups, struct user_t **user) -{ - int res; - struct user_t **users; - size_t n_users; - - res = doUsersQuery(sconn, modb, wb, &users, &n_users); - if (res <= 0) { - return res; - } - - *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; -} - - -// ##### GROUPS -int tableRowsToGroups(column_data **col_data, size_t n_cols, - struct group_t ***groups, size_t *n_groups) -{ - column_data *col_id, *col_name, *col_created, *col_updated, *col_deleted; - size_t n_rows, idx; - struct group_t *group; - - n_rows = (*col_data)->n_values; - if (n_rows == 0) { - return 0; - } - - col_id = findColumnByName(col_data, n_cols, "id"); - col_name = findColumnByName(col_data, n_cols, "name"); - col_created = findColumnByName(col_data, n_cols, "created"); - col_updated = findColumnByName(col_data, n_cols, "updated"); - col_deleted = findColumnByName(col_data, n_cols, "deleted"); - - *groups = (struct group_t **)malloc(sizeof(struct group_t *) * n_rows); - if (*groups == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return -1; - } - memset(*groups, 0, sizeof(struct group_t *) * n_rows); - - for (idx = 0; idx < n_rows; idx++) { - if ((group = allocGroup()) == 0) { - freeGroups(groups, idx - 1); - return -1; - } - - group->id = *(col_id->data.ptr_uint32 + idx); - - if (!moveColumnStrPointer(col_name, idx, 1, &group->name, &group->name_len)) { - freeGroups(groups, idx); - return -1; - } - - group->created_on = *(col_created->data.ptr_int64 + idx); - if (!columnRowIsNull(col_updated, idx)) { - group->updated_on = *(col_updated->data.ptr_int64 + idx); - } - if (!columnRowIsNull(col_deleted, idx)) { - group->deleted_on = *(col_deleted->data.ptr_int64 + idx); - } - - *(*groups + idx) = group; - } - - *n_groups = n_rows; - - return 1; -} -int doGroupsQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, - struct group_t ***groups, size_t *n_groups) -{ - char *table; - size_t table_len; - char *qry; - size_t qry_len; - uint64_t qry_ret; - int res; - - str_builder *sb; - - column_data **col_data; - size_t n_cols; - - - if ((sb = strbld_create()) == 0) { - return -1; - } - modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); - - strbld_str(sb, "SELECT * FROM ", 0); - escapeTableName_sb(sb, table, table_len); - if (wb != 0) { - compileWhereBuilder_sb(sb, wb, 0); - } - - modbFreeTableName(&table); - 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; - } - - res = tableRowsToGroups(col_data, n_cols, groups, n_groups); - freeColumns(col_data, n_cols); - - if (res <= 0) { - return res; - } - - return (int)qry_ret; -} -int doScalarGroupsQuery(stored_conn *sconn, modb_ref *modb, - where_builder *wb, int with_members, struct group_t **group) -{ - int res; - struct group_t **groups; - size_t n_groups; - - res = doGroupsQuery(sconn, modb, wb, &groups, &n_groups); - if (res <= 0) { - return res; - } - - *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 deleted file mode 100644 index 11a9174..0000000 --- a/src/modb_accounting_p.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef H__MODB_ACCOUNTING_P__ -#define H__MODB_ACCOUNTING_P__ - -#include "database.h" -#include "modb_types.h" - -// ##### USERS -int tableRowsToUsers(column_data **col_data, size_t n_cols, - struct user_t ***users, size_t *n_users); -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, int with_groups, struct user_t **user); - -// ##### GROUPS -int tableRowsToGroups(column_data **col_data, size_t n_cols, - struct group_t ***groups, size_t *n_groups); -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, int with_members, struct group_t **group); - -#endif // H__MODB_ACCOUNTING_P__ diff --git a/src/modb_groups.c b/src/modb_groups.c new file mode 100644 index 0000000..be060da --- /dev/null +++ b/src/modb_groups.c @@ -0,0 +1,515 @@ + +#include +#include +#include + +#include "modb_groups.h" +#include "modb_users.h" +#include "modb_p.h" + + +// ##### PRIVATE +int tableRowsToGroups(column_data **col_data, size_t n_cols, + struct group_t ***groups, size_t *n_groups) +{ + column_data *col_id, *col_name, *col_created, *col_updated, *col_deleted; + size_t n_rows, idx; + struct group_t *group; + + n_rows = (*col_data)->n_values; + if (n_rows == 0) { + return 0; + } + + col_id = findColumnByName(col_data, n_cols, "id"); + col_name = findColumnByName(col_data, n_cols, "name"); + col_created = findColumnByName(col_data, n_cols, "created"); + col_updated = findColumnByName(col_data, n_cols, "updated"); + col_deleted = findColumnByName(col_data, n_cols, "deleted"); + + *groups = (struct group_t **)malloc(sizeof(struct group_t *) * n_rows); + if (*groups == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return -1; + } + memset(*groups, 0, sizeof(struct group_t *) * n_rows); + + for (idx = 0; idx < n_rows; idx++) { + if ((group = allocGroup()) == 0) { + freeGroups(groups, idx - 1); + return -1; + } + + group->id = *(col_id->data.ptr_uint32 + idx); + + if (!moveColumnStrPointer(col_name, idx, 1, &group->name, &group->name_len)) { + freeGroups(groups, idx); + return -1; + } + + group->created_on = *(col_created->data.ptr_int64 + idx); + if (!columnRowIsNull(col_updated, idx)) { + group->updated_on = *(col_updated->data.ptr_int64 + idx); + } + if (!columnRowIsNull(col_deleted, idx)) { + group->deleted_on = *(col_deleted->data.ptr_int64 + idx); + } + + *(*groups + idx) = group; + } + + *n_groups = n_rows; + + return 1; +} +int doGroupsQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, + struct group_t ***groups, size_t *n_groups) +{ + char *table; + size_t table_len; + char *qry; + size_t qry_len; + uint64_t qry_ret; + int res; + + str_builder *sb; + + column_data **col_data; + size_t n_cols; + + + if ((sb = strbld_create()) == 0) { + return -1; + } + modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); + + strbld_str(sb, "SELECT * FROM ", 0); + escapeTableName_sb(sb, table, table_len); + if (wb != 0) { + compileWhereBuilder_sb(sb, wb, 0); + } + + modbFreeTableName(&table); + 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; + } + + res = tableRowsToGroups(col_data, n_cols, groups, n_groups); + freeColumns(col_data, n_cols); + + if (res <= 0) { + return res; + } + + return (int)qry_ret; +} +int doScalarGroupsQuery(stored_conn *sconn, modb_ref *modb, + where_builder *wb, int with_members, struct group_t **group) +{ + int res; + struct group_t **groups; + size_t n_groups; + + res = doGroupsQuery(sconn, modb, wb, &groups, &n_groups); + if (res <= 0) { + return res; + } + + *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; +} + + +// ##### PUBLIC +struct group_t *allocGroup(void) +{ + struct group_t *group; + + group = malloc(sizeof(struct group_t)); + if (group == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + } + memset(group, 0, sizeof(struct group_t)); + + return group; +} +struct group_t **allocGroups(size_t n_groups) +{ + struct group_t **groups; + + groups = (struct group_t **)malloc(sizeof(struct group_t *) * n_groups); + if (groups == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return 0; + } + memset(groups, 0, sizeof(struct group_t *) * n_groups); + + return groups; +} +void freeGroup(struct group_t **group_ptr) +{ + struct group_t *group = *group_ptr; + + if (group->n_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; + } + + if (group->name != 0) { + free(group->name); + group->name = 0; + } + + free(group); + *group_ptr = 0; +} +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); + } + } + + free(groups); + *groups_ptr = 0; +} + + +int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_members, + struct group_t **group) +{ + where_builder *wb = 0; + int res; + + wb = where(0, "id", EQ, TYPE_ID, 1, id); + res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); + freeWhereBuilder(&wb); + + return res; +} +int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int with_members, + struct group_t **group) +{ + where_builder *wb = 0; + int res; + + wb = where(0, "name", EQ, TYPE_STRING, 1, name); + res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); + freeWhereBuilder(&wb); + + return res; +} + +int modbGroupList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with_members, + struct group_t ***groups, size_t *n_groups) +{ + where_builder *wb = 0; + int res; + size_t idx; + struct group_t *group; + + if (with_deleted == 0) { + wb = where(0, "deleted_on", IS_NULL, TYPE_RAW, 0, 0); + } + res = doGroupsQuery(sconn, modb, wb, groups, n_groups); + if (wb != 0) { + freeWhereBuilder(&wb); + } + + if (res > 0 && with_members) { + for (idx = 0; idx < *n_groups; idx++) { + group = *((*groups) + idx); + if (modbFetchGroupUsers(sconn, modb, group, with_deleted) < 0) { + freeGroups(groups, *n_groups); + *groups = 0; + *n_groups = 0; + return -1; + } + } + } + + return res; +} + +int64_t modbGroupCreate(stored_conn *sconn, modb_ref *modb, + unsigned int id, const char *name) +{ + str_builder *sb; + char *table; + size_t table_len; + char *qry; + size_t qry_len; + uint64_t qry_ret; + + if ((sb = strbld_create()) == 0) { + return -1; + } + modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); + + strbld_str(sb, "INSERT INTO ", 0); + escapeTableName_sb(sb, table, table_len); + strbld_str(sb, " (`id`, `name`) VALUES (", 0); + db_value_sb(sb, TYPE_ID, 1, id); + strbld_char(sb, ','); + db_value_sb(sb, TYPE_STRING, 1, name); + strbld_char(sb, ')'); + + modbFreeTableName(&table); + if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { + return -1; + } + + qry_ret = simpleQuery(sconn, qry, qry_len); + free(qry); + + return (int64_t)qry_ret; +} +int64_t modbGroupUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, + const char *name) +{ + str_builder *sb; + char *table, *set; + size_t table_len, set_len; + int64_t qry_ret; + + if ((sb = strbld_create()) == 0) { + return 0; + } + columnSetValueStr_sb(sb, "id", TYPE_ID, 1, id); + if (name != 0) { + strbld_char(sb, ','); + columnSetValueStr_sb(sb, "name", TYPE_STRING, 1, name); + } + if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) { + return 0; + } + + modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); + qry_ret = updateQuery(sconn, table, table_len, set, set_len, where(0, "id", EQ, TYPE_ID, 1, id)); + modbFreeTableName(&table); + + free(set); + + return qry_ret; +} +int modbGroupDelete(stored_conn *sconn, modb_ref *modb, unsigned int id) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE)); + qry_ret = softDeleteByIdQuery(sconn, table, table_len, "id", id); + modbFreeTableName(&table); + + return (int)qry_ret; +} +int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE)); + qry_ret = deleteByIdQuery(sconn, table, table_len, "id", id); + modbFreeTableName(&table); + + return (int)qry_ret; +} + + +int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, struct group_t *group, + int with_deleted) +{ + char *u_table, *ug_table; + size_t u_len, ug_len; + + char *qry; + size_t qry_len; + uint64_t qry_ret; + + str_builder *sb; + where_builder *wb; + + column_data **col_data; + size_t n_cols; + + + if ((sb = strbld_create()) == 0) { + return -1; + } + modbTableName(&u_table, &u_len, modb, USERS_TABLE, STR_LEN(USERS_TABLE)); + modbTableName(&ug_table, &ug_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + + strbld_str(sb, "SELECT ", 0); + escapeColumnName_sb(sb, 0, 0, "user_id", 0); + strbld_str(sb, " FROM ", 0); + escapeTableName_sb(sb, ug_table, ug_len); + joinStr_sb(sb, " LEFT", 5, 1, u_table, u_len, "id", 2, ug_table, ug_len, "user_id", 8); + wb = where(0, "group_id", EQ, TYPE_ID, 1, group->id); + if (!with_deleted) { + wb = whereAnd(wb, where(u_table, "deleted", IS_NULL, TYPE_RAW, 0)); + } + compileWhereBuilder_sb(sb, wb, 1); + + modbFreeTableName(&u_table); + modbFreeTableName(&ug_table); + 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 +int modbSyncGroupUsers(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, size_t n_users, unsigned int *user_ids) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + qry_ret = syncIdMap(sconn, table, table_len, "group_id", "user_id", group_id, n_users, user_ids); + modbFreeTableName(&table); + + return (int)qry_ret; +} +int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, size_t n_users, ...) +{ + va_list args; + char *table; + size_t table_len; + int64_t qry_ret; + + va_start(args, n_users); + modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + qry_ret = syncIdMap_va(sconn, table, table_len, "group_id", "user_id", group_id, n_users, args); + modbFreeTableName(&table); + va_end(args); + + return (int)qry_ret; +} + +int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + qry_ret = hasIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); + modbFreeTableName(&table); + + return (int)qry_ret; +} +int modbLink_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + qry_ret = addIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); + modbFreeTableName(&table); + + return (int)qry_ret; +} +int modbUnlink_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id) +{ + char *table; + size_t table_len; + int64_t qry_ret; + + modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); + qry_ret = addIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); + modbFreeTableName(&table); + + return (int)qry_ret; +} diff --git a/src/modb_groups.h b/src/modb_groups.h new file mode 100644 index 0000000..859a616 --- /dev/null +++ b/src/modb_groups.h @@ -0,0 +1,63 @@ +#ifndef H__MODB_GROUPS__ +#define H__MODB_GROUPS__ + +#include "database.h" +#include "modb_types.h" + +// Group object +struct group_t { + unsigned int id; + + char *name; + size_t name_len; + + int64_t created_on; + int64_t updated_on; + int64_t deleted_on; + + unsigned int *member_ids; + struct user_t **members; + size_t n_members; +}; + +struct group_t *allocGroup(void); +struct group_t **allocGroups(size_t n_groups); +void freeGroup(struct group_t **group); +void freeGroups(struct group_t ***groups_ptr, size_t n_groups); + + +// MODB Groups +int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_members, + struct group_t **group); +int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int with_members, + struct group_t **group); + +int modbGroupList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with_members, + struct group_t ***groups, size_t *n_groups); + +int64_t modbGroupCreate(stored_conn *sconn, modb_ref *modb, + unsigned int id, const char *name); +int64_t modbGroupUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, + const char *name); +int modbGroupDelete(stored_conn *sconn, modb_ref *modb, unsigned int id); +int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, unsigned 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 Groups -> Users +int modbSyncGroupUsers(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, size_t n_users, unsigned int *user_id); +int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, size_t n_users, ...); + +int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id); +int modbLink_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id); +int modbUnlink_Group_User(stored_conn *sconn, modb_ref *modb, + unsigned int group_id, unsigned int user_id); + +#endif // H__MODB_GROUPS__ diff --git a/src/modb_metadata.c b/src/modb_metadata.c index 358db6b..b8e352d 100644 --- a/src/modb_metadata.c +++ b/src/modb_metadata.c @@ -3,7 +3,8 @@ #include #include "modb_metadata.h" -#include "modb_accounting.h" +#include "modb_users.h" +#include "modb_groups.h" #include "modb_p.h" diff --git a/src/modb_types.c b/src/modb_types.c index b7758b7..36d2fe6 100644 --- a/src/modb_types.c +++ b/src/modb_types.c @@ -4,142 +4,11 @@ #include #include "modb_types.h" +#include "modb_groups.h" +#include "modb_users.h" #include "strext.h" -struct user_t *allocUser(void) -{ - struct user_t *user; - - user = malloc(sizeof(struct user_t)); - if (user == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - } - memset(user, 0, sizeof(struct user_t)); - - return user; -} -struct user_t **allocUsers(size_t n_users) -{ - struct user_t **users; - - users = (struct user_t **)malloc(sizeof(struct user_t *) * n_users); - if (users == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return 0; - } - memset(users, 0, sizeof(struct user_t *) * n_users); - - return users; -} -void freeUser(struct user_t **user_ptr) -{ - struct user_t *user = *user_ptr; - - if (user->n_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; - } - - if (user->email != 0) { - free(user->email); - user->email = 0; - } - - if (user->username != 0) { - free(user->username); - user->username = 0; - } - - free(user); - *user_ptr = 0; -} -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) { - freeUser((users + idx)); - } - } - - free(users); - *users_ptr = 0; -} - - -struct group_t *allocGroup(void) -{ - struct group_t *group; - - group = malloc(sizeof(struct group_t)); - if (group == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - } - memset(group, 0, sizeof(struct group_t)); - - return group; -} -struct group_t **allocGroups(size_t n_groups) -{ - struct group_t **groups; - - groups = (struct group_t **)malloc(sizeof(struct group_t *) * n_groups); - if (groups == 0) { - fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); - return 0; - } - memset(groups, 0, sizeof(struct group_t *) * n_groups); - - return groups; -} -void freeGroup(struct group_t **group_ptr) -{ - struct group_t *group = *group_ptr; - - if (group->n_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; - } - - if (group->name != 0) { - free(group->name); - group->name = 0; - } - - free(group); - *group_ptr = 0; -} -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); - } - } - - free(groups); - *groups_ptr = 0; -} - - struct metadata_t *allocMetadata(void) { struct metadata_t *metadata; diff --git a/src/modb_types.h b/src/modb_types.h index 5eb4dc4..01ab2a4 100644 --- a/src/modb_types.h +++ b/src/modb_types.h @@ -10,39 +10,6 @@ struct modb_ref_t { }; typedef struct modb_ref_t modb_ref; -struct user_t { - unsigned int id; - - char *username; - size_t username_len; - - char *email; - size_t email_len; - - int64_t created_on; - int64_t updated_on; - int64_t deleted_on; - - unsigned int *group_ids; - struct group_t **groups; - size_t n_groups; -}; - -struct group_t { - unsigned int id; - - char *name; - size_t name_len; - - int64_t created_on; - int64_t updated_on; - int64_t deleted_on; - - unsigned int *member_ids; - struct user_t **members; - size_t n_members; -}; - struct metadata_t { unsigned int id; @@ -108,16 +75,6 @@ struct metadata_ext_t { // size_t value_len; //}; -struct user_t *allocUser(void); -struct user_t **allocUsers(size_t n_users); -void freeUser(struct user_t **user); -void freeUsers(struct user_t ***users_ptr, size_t n_users); - -struct group_t *allocGroup(void); -struct group_t **allocGroups(size_t n_groups); -void freeGroup(struct group_t **group); -void freeGroups(struct group_t ***groups_ptr, size_t n_groups); - struct metadata_t *allocMetadata(void); struct metadata_t **allocMetadataList(size_t n_metadatas); void freeMetadata(struct metadata_t **metadata); diff --git a/src/modb_accounting.c b/src/modb_users.c similarity index 57% rename from src/modb_accounting.c rename to src/modb_users.c index f178619..fa34e13 100644 --- a/src/modb_accounting.c +++ b/src/modb_users.c @@ -1,12 +1,225 @@ -#include +#include #include +#include -#include "modb_accounting.h" +#include "modb_users.h" +#include "modb_groups.h" #include "modb_p.h" -#include "modb_accounting_p.h" -// ##### USERS +// ##### PRIVATE +int tableRowsToUsers(column_data **col_data, size_t n_cols, + struct user_t ***users, size_t *n_users) +{ + column_data *col_id, *col_username, *col_email, *col_created, *col_updated, *col_deleted; + size_t n_rows, idx; + struct user_t *user; + + n_rows = (*col_data)->n_values; + if (n_rows == 0) { + return 0; + } + + col_id = findColumnByName(col_data, n_cols, "id"); + col_username = findColumnByName(col_data, n_cols, "username"); + col_email = findColumnByName(col_data, n_cols, "email"); + col_created = findColumnByName(col_data, n_cols, "created"); + col_updated = findColumnByName(col_data, n_cols, "updated"); + col_deleted = findColumnByName(col_data, n_cols, "deleted"); + + *users = (struct user_t **)malloc(sizeof(struct user_t *) * n_rows); + if (*users == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return -1; + } + memset(*users, 0, sizeof(struct user_t *) * n_rows); + + for (idx = 0; idx < n_rows; idx++) { + user = allocUser(); + if (user == 0) { + freeUsers(users, idx - 1); + return -1; + } + + user->id = *(col_id->data.ptr_uint32 + idx); + + if (!moveColumnStrPointer(col_username, idx, 1, &user->username, &user->username_len)) { + freeUsers(users, idx); + return -1; + } + + if (!moveColumnStrPointer(col_email, idx, 1, &user->email, &user->email_len)) { + freeUsers(users, idx); + return -1; + } + + user->created_on = *(col_created->data.ptr_int64 + idx); + if (!columnRowIsNull(col_updated, idx)) { + user->updated_on = *(col_updated->data.ptr_int64 + idx); + } + if (!columnRowIsNull(col_deleted, idx)) { + user->deleted_on = *(col_deleted->data.ptr_int64 + idx); + } + + *(*users + idx) = user; + } + + *n_users = n_rows; + + return 1; +} +int doUsersQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb, + struct user_t ***users, size_t *n_users) +{ + char *table; + size_t table_len; + char *qry; + size_t qry_len; + uint64_t qry_ret; + int res; + + str_builder *sb; + + column_data **col_data; + size_t n_cols; + + + if ((sb = strbld_create()) == 0) { + return -1; + } + modbTableName(&table, &table_len, modb, USERS_TABLE, strlen(USERS_TABLE)); + + strbld_str(sb, "SELECT * FROM ", 0); + escapeTableName_sb(sb, table, table_len); + if (wb != 0) { + compileWhereBuilder_sb(sb, wb, 0); + } + + modbFreeTableName(&table); + 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; + } + + res = tableRowsToUsers(col_data, n_cols, users, n_users); + freeColumns(col_data, n_cols); + + if (res <= 0) { + return res; + } + + return (int)qry_ret; +} +int doScalarUsersQuery(stored_conn *sconn, modb_ref *modb, + where_builder *wb, int with_groups, struct user_t **user) +{ + int res; + struct user_t **users; + size_t n_users; + + res = doUsersQuery(sconn, modb, wb, &users, &n_users); + if (res <= 0) { + return res; + } + + *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; +} + + +// ##### PUBLIC +struct user_t *allocUser(void) +{ + struct user_t *user; + + user = malloc(sizeof(struct user_t)); + if (user == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + } + memset(user, 0, sizeof(struct user_t)); + + return user; +} +struct user_t **allocUsers(size_t n_users) +{ + struct user_t **users; + + users = (struct user_t **)malloc(sizeof(struct user_t *) * n_users); + if (users == 0) { + fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno)); + return 0; + } + memset(users, 0, sizeof(struct user_t *) * n_users); + + return users; +} +void freeUser(struct user_t **user_ptr) +{ + struct user_t *user = *user_ptr; + + if (user->n_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; + } + + if (user->email != 0) { + free(user->email); + user->email = 0; + } + + if (user->username != 0) { + free(user->username); + user->username = 0; + } + + free(user); + *user_ptr = 0; +} +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) { + freeUser((users + idx)); + } + } + + free(users); + *users_ptr = 0; +} + + int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_groups, struct user_t **user) { @@ -336,311 +549,3 @@ int modbUnlink_User_Group(stored_conn *sconn, modb_ref *modb, return (int)qry_ret; } - - - -// ##### GROUPS -int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_members, - struct group_t **group) -{ - where_builder *wb = 0; - int res; - - wb = where(0, "id", EQ, TYPE_ID, 1, id); - res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); - freeWhereBuilder(&wb); - - return res; -} -int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int with_members, - struct group_t **group) -{ - where_builder *wb = 0; - int res; - - wb = where(0, "name", EQ, TYPE_STRING, 1, name); - res = doScalarGroupsQuery(sconn, modb, wb, with_members, group); - freeWhereBuilder(&wb); - - return res; -} - -int modbGroupList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with_members, - struct group_t ***groups, size_t *n_groups) -{ - where_builder *wb = 0; - int res; - size_t idx; - struct group_t *group; - - if (with_deleted == 0) { - wb = where(0, "deleted_on", IS_NULL, TYPE_RAW, 0, 0); - } - res = doGroupsQuery(sconn, modb, wb, groups, n_groups); - if (wb != 0) { - freeWhereBuilder(&wb); - } - - if (res > 0 && with_members) { - for (idx = 0; idx < *n_groups; idx++) { - group = *((*groups) + idx); - if (modbFetchGroupUsers(sconn, modb, group, with_deleted) < 0) { - freeGroups(groups, *n_groups); - *groups = 0; - *n_groups = 0; - return -1; - } - } - } - - return res; -} - -int64_t modbGroupCreate(stored_conn *sconn, modb_ref *modb, - unsigned int id, const char *name) -{ - str_builder *sb; - char *table; - size_t table_len; - char *qry; - size_t qry_len; - uint64_t qry_ret; - - if ((sb = strbld_create()) == 0) { - return -1; - } - modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); - - strbld_str(sb, "INSERT INTO ", 0); - escapeTableName_sb(sb, table, table_len); - strbld_str(sb, " (`id`, `name`) VALUES (", 0); - db_value_sb(sb, TYPE_ID, 1, id); - strbld_char(sb, ','); - db_value_sb(sb, TYPE_STRING, 1, name); - strbld_char(sb, ')'); - - modbFreeTableName(&table); - if (strbld_finalize_or_destroy(&sb, &qry, &qry_len) != 0) { - return -1; - } - - qry_ret = simpleQuery(sconn, qry, qry_len); - free(qry); - - return (int64_t)qry_ret; -} -int64_t modbGroupUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, - const char *name) -{ - str_builder *sb; - char *table, *set; - size_t table_len, set_len; - int64_t qry_ret; - - if ((sb = strbld_create()) == 0) { - return 0; - } - columnSetValueStr_sb(sb, "id", TYPE_ID, 1, id); - if (name != 0) { - strbld_char(sb, ','); - columnSetValueStr_sb(sb, "name", TYPE_STRING, 1, name); - } - if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) { - return 0; - } - - modbTableName(&table, &table_len, modb, GROUPS_TABLE, strlen(GROUPS_TABLE)); - qry_ret = updateQuery(sconn, table, table_len, set, set_len, where(0, "id", EQ, TYPE_ID, 1, id)); - modbFreeTableName(&table); - - free(set); - - return qry_ret; -} -int modbGroupDelete(stored_conn *sconn, modb_ref *modb, unsigned int id) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE)); - qry_ret = softDeleteByIdQuery(sconn, table, table_len, "id", id); - modbFreeTableName(&table); - - return (int)qry_ret; -} -int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE)); - qry_ret = deleteByIdQuery(sconn, table, table_len, "id", id); - modbFreeTableName(&table); - - return (int)qry_ret; -} - - -int modbFetchGroupUserIds(stored_conn *sconn, modb_ref *modb, struct group_t *group, - int with_deleted) -{ - char *u_table, *ug_table; - size_t u_len, ug_len; - - char *qry; - size_t qry_len; - uint64_t qry_ret; - - str_builder *sb; - where_builder *wb; - - column_data **col_data; - size_t n_cols; - - - if ((sb = strbld_create()) == 0) { - return -1; - } - modbTableName(&u_table, &u_len, modb, USERS_TABLE, STR_LEN(USERS_TABLE)); - modbTableName(&ug_table, &ug_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - - strbld_str(sb, "SELECT ", 0); - escapeColumnName_sb(sb, 0, 0, "user_id", 0); - strbld_str(sb, " FROM ", 0); - escapeTableName_sb(sb, ug_table, ug_len); - joinStr_sb(sb, " LEFT", 5, 1, u_table, u_len, "id", 2, ug_table, ug_len, "user_id", 8); - wb = where(0, "group_id", EQ, TYPE_ID, 1, group->id); - if (!with_deleted) { - wb = whereAnd(wb, where(u_table, "deleted", IS_NULL, TYPE_RAW, 0)); - } - compileWhereBuilder_sb(sb, wb, 1); - - modbFreeTableName(&u_table); - modbFreeTableName(&ug_table); - 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 -int modbSyncGroupUsers(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, size_t n_users, unsigned int *user_ids) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - qry_ret = syncIdMap(sconn, table, table_len, "group_id", "user_id", group_id, n_users, user_ids); - modbFreeTableName(&table); - - return (int)qry_ret; -} -int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, size_t n_users, ...) -{ - va_list args; - char *table; - size_t table_len; - int64_t qry_ret; - - va_start(args, n_users); - modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - qry_ret = syncIdMap_va(sconn, table, table_len, "group_id", "user_id", group_id, n_users, args); - modbFreeTableName(&table); - va_end(args); - - return (int)qry_ret; -} - -int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - qry_ret = hasIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); - modbFreeTableName(&table); - - return (int)qry_ret; -} -int modbLink_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - qry_ret = addIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); - modbFreeTableName(&table); - - return (int)qry_ret; -} -int modbUnlink_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id) -{ - char *table; - size_t table_len; - int64_t qry_ret; - - modbTableName(&table, &table_len, modb, USER_GROUPS_TABLE, STR_LEN(USER_GROUPS_TABLE)); - qry_ret = addIdMap(sconn, table, table_len, "group_id", "user_id", group_id, user_id); - modbFreeTableName(&table); - - return (int)qry_ret; -} diff --git a/src/modb_accounting.h b/src/modb_users.h similarity index 53% rename from src/modb_accounting.h rename to src/modb_users.h index 7d1a330..d67296a 100644 --- a/src/modb_accounting.h +++ b/src/modb_users.h @@ -1,10 +1,35 @@ -#ifndef H__MODB_ACCOUNTING__ -#define H__MODB_ACCOUNTING__ +#ifndef H__MODB_USERS__ +#define H__MODB_USERS__ #include "database.h" #include "modb_types.h" +// User object +struct user_t { + unsigned int id; + + char *username; + size_t username_len; + + char *email; + size_t email_len; + + int64_t created_on; + int64_t updated_on; + int64_t deleted_on; + + unsigned int *group_ids; + struct group_t **groups; + size_t n_groups; +}; + +struct user_t *allocUser(void); +struct user_t **allocUsers(size_t n_users); +void freeUser(struct user_t **user); +void freeUsers(struct user_t ***users_ptr, size_t n_users); + + // MODB Users int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_groups, struct user_t **user); @@ -43,40 +68,4 @@ int modbLink_User_Group(stored_conn *sconn, modb_ref *modb, int modbUnlink_User_Group(stored_conn *sconn, modb_ref *modb, unsigned int user_id, unsigned int group_id); - -// MODB Groups -int modbGroupById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_members, - struct group_t **group); -int modbGroupByName(stored_conn *sconn, modb_ref *modb, const char *name, int with_members, - struct group_t **group); - -int modbGroupList(stored_conn *sconn, modb_ref *modb, int with_deleted, int with_members, - struct group_t ***groups, size_t *n_groups); - -int64_t modbGroupCreate(stored_conn *sconn, modb_ref *modb, - unsigned int id, const char *name); -int64_t modbGroupUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id, - const char *name); -int modbGroupDelete(stored_conn *sconn, modb_ref *modb, unsigned int id); -int modbGroupDestroy(stored_conn *sconn, modb_ref *modb, unsigned 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 Groups -> Users -int modbSyncGroupUsers(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, size_t n_users, unsigned int *user_id); -int modbSyncGroupUsers_va(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, size_t n_users, ...); - -int modbIsLinked_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id); -int modbLink_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id); -int modbUnlink_Group_User(stored_conn *sconn, modb_ref *modb, - unsigned int group_id, unsigned int user_id); - - -#endif // H__MODB_ACCOUNTING__ +#endif // H__MODB_USERS__