Split accounting into groups and users
This commit is contained in:
@@ -1,287 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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__
|
|
||||||
515
src/modb_groups.c
Normal file
515
src/modb_groups.c
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
63
src/modb_groups.h
Normal file
63
src/modb_groups.h
Normal file
@@ -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__
|
||||||
@@ -3,7 +3,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "modb_metadata.h"
|
#include "modb_metadata.h"
|
||||||
#include "modb_accounting.h"
|
#include "modb_users.h"
|
||||||
|
#include "modb_groups.h"
|
||||||
#include "modb_p.h"
|
#include "modb_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
135
src/modb_types.c
135
src/modb_types.c
@@ -4,142 +4,11 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "modb_types.h"
|
#include "modb_types.h"
|
||||||
|
#include "modb_groups.h"
|
||||||
|
#include "modb_users.h"
|
||||||
#include "strext.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 *allocMetadata(void)
|
||||||
{
|
{
|
||||||
struct metadata_t *metadata;
|
struct metadata_t *metadata;
|
||||||
|
|||||||
@@ -10,39 +10,6 @@ struct modb_ref_t {
|
|||||||
};
|
};
|
||||||
typedef struct modb_ref_t modb_ref;
|
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 {
|
struct metadata_t {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
@@ -108,16 +75,6 @@ struct metadata_ext_t {
|
|||||||
// size_t value_len;
|
// 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 *allocMetadata(void);
|
||||||
struct metadata_t **allocMetadataList(size_t n_metadatas);
|
struct metadata_t **allocMetadataList(size_t n_metadatas);
|
||||||
void freeMetadata(struct metadata_t **metadata);
|
void freeMetadata(struct metadata_t **metadata);
|
||||||
|
|||||||
@@ -1,12 +1,225 @@
|
|||||||
#include <string.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "modb_accounting.h"
|
#include "modb_users.h"
|
||||||
|
#include "modb_groups.h"
|
||||||
#include "modb_p.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,
|
int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_groups,
|
||||||
struct user_t **user)
|
struct user_t **user)
|
||||||
{
|
{
|
||||||
@@ -336,311 +549,3 @@ int modbUnlink_User_Group(stored_conn *sconn, modb_ref *modb,
|
|||||||
|
|
||||||
return (int)qry_ret;
|
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;
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,35 @@
|
|||||||
#ifndef H__MODB_ACCOUNTING__
|
#ifndef H__MODB_USERS__
|
||||||
#define H__MODB_ACCOUNTING__
|
#define H__MODB_USERS__
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "modb_types.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
|
// MODB Users
|
||||||
int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_groups,
|
int modbUserById(stored_conn *sconn, modb_ref *modb, unsigned int id, int with_groups,
|
||||||
struct user_t **user);
|
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,
|
int modbUnlink_User_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
unsigned int user_id, unsigned int group_id);
|
unsigned int user_id, unsigned int group_id);
|
||||||
|
|
||||||
|
#endif // H__MODB_USERS__
|
||||||
// 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__
|
|
||||||
Reference in New Issue
Block a user