Code for metadata and objects
This commit is contained in:
536
src/modb_metadata.c
Normal file
536
src/modb_metadata.c
Normal file
@@ -0,0 +1,536 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "modb_metadata.h"
|
||||||
|
#include "modb_accounting.h"
|
||||||
|
#include "modb_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
int tableRowsToMetadataList(column_data **col_data, size_t n_cols,
|
||||||
|
struct metadata_t ***metadata_list, size_t *n_metadatas)
|
||||||
|
{
|
||||||
|
column_data *col_id, *col_title, *col_owner_id, *col_created, *col_updated, *col_deleted;
|
||||||
|
size_t n_rows, idx;
|
||||||
|
struct metadata_t *metadata;
|
||||||
|
|
||||||
|
n_rows = (*col_data)->n_values;
|
||||||
|
if (n_rows == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_id = findColumnByName(col_data, n_cols, "mdo_id");
|
||||||
|
col_title = findColumnByName(col_data, n_cols, "title");
|
||||||
|
col_owner_id = findColumnByName(col_data, n_cols, "owner_id");
|
||||||
|
col_created = findColumnByName(col_data, n_cols, "created");
|
||||||
|
col_updated = findColumnByName(col_data, n_cols, "updated");
|
||||||
|
col_deleted = findColumnByName(col_data, n_cols, "deleted");
|
||||||
|
|
||||||
|
*metadata_list = (struct metadata_t **)malloc(sizeof(struct metadata_t *) * n_rows);
|
||||||
|
if (*metadata_list == 0) {
|
||||||
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
memset(*metadata_list, 0, sizeof(struct metadata_t *) * n_rows);
|
||||||
|
|
||||||
|
for (idx = 0; idx < n_rows; idx++) {
|
||||||
|
metadata = allocMetadata();
|
||||||
|
if (metadata == 0) {
|
||||||
|
freeMetadataList(metadata_list, idx - 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata->id = *(col_id->data.ptr_uint32 + idx);
|
||||||
|
|
||||||
|
if (!moveColumnStrPointer(col_title, idx, 1, &metadata->title, &metadata->title_len)) {
|
||||||
|
freeMetadataList(metadata_list, idx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata->owner_id = *(col_owner_id->data.ptr_uint32 + idx);
|
||||||
|
|
||||||
|
metadata->created_on = *(col_created->data.ptr_int64 + idx);
|
||||||
|
if (!columnRowIsNull(col_updated, idx)) {
|
||||||
|
metadata->updated_on = *(col_updated->data.ptr_int64 + idx);
|
||||||
|
}
|
||||||
|
if (!columnRowIsNull(col_deleted, idx)) {
|
||||||
|
metadata->deleted_on = *(col_deleted->data.ptr_int64 + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(*metadata_list + idx) = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n_metadatas = n_rows;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int doMetadataListQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb,
|
||||||
|
struct metadata_t ***metadata_list, size_t *n_metadatas)
|
||||||
|
{
|
||||||
|
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, METADATA_TABLE, strlen(METADATA_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 = tableRowsToMetadataList(col_data, n_cols, metadata_list, n_metadatas);
|
||||||
|
freeColumns(col_data, n_cols);
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int doScalarMetadataListQuery(stored_conn *sconn, modb_ref *modb,
|
||||||
|
where_builder *wb, struct metadata_t **metadata)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
struct metadata_t **metadata_list;
|
||||||
|
size_t n_metadatas;
|
||||||
|
|
||||||
|
res = doMetadataListQuery(sconn, modb, wb, &metadata_list, &n_metadatas);
|
||||||
|
if (res <= 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
*metadata = *(metadata_list + 0);
|
||||||
|
*(metadata_list + 0) = 0;
|
||||||
|
freeMetadataList(&metadata_list, n_metadatas);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int modbMetadataById(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct metadata_t **metadata)
|
||||||
|
{
|
||||||
|
where_builder *wb = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
wb = where(0, "mdo_id", EQ, TYPE_ID, 1, id);
|
||||||
|
res = doScalarMetadataListQuery(sconn, modb, wb, metadata);
|
||||||
|
freeWhereBuilder(&wb);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int modbMetadataList(stored_conn *sconn, modb_ref *modb, int with_deleted,
|
||||||
|
struct metadata_t ***metadata_list, size_t *n_metadatas)
|
||||||
|
{
|
||||||
|
where_builder *wb = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (with_deleted == 0) {
|
||||||
|
wb = where(0, "deleted_on", IS_NULL, TYPE_RAW, 0, 0);
|
||||||
|
}
|
||||||
|
res = doMetadataListQuery(sconn, modb, wb, metadata_list, n_metadatas);
|
||||||
|
if (wb != 0) {
|
||||||
|
freeWhereBuilder(&wb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t modbMetadataCreate(stored_conn *sconn, modb_ref *modb,
|
||||||
|
const struct metadata_t *const metadata)
|
||||||
|
{
|
||||||
|
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, METADATA_TABLE, strlen(METADATA_TABLE));
|
||||||
|
|
||||||
|
strbld_str(sb, "INSERT INTO ", 0);
|
||||||
|
escapeTableName_sb(sb, table, table_len);
|
||||||
|
strbld_str(sb, " (`mdo_id`, `type`, `title`, `owner_id`) VALUES (", 0);
|
||||||
|
db_value_sb(sb, TYPE_ID, 1, metadata->id);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
db_value_sb(sb, TYPE_STRING, 2, metadata->type, metadata->type_len);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
db_value_sb(sb, TYPE_STRING, 2, metadata->title, metadata->title_len);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
if (metadata->owner != 0) {
|
||||||
|
db_value_sb(sb, TYPE_ID, 1, metadata->owner->id);
|
||||||
|
} else {
|
||||||
|
db_value_sb(sb, TYPE_ID, 1, metadata->owner_id);
|
||||||
|
}
|
||||||
|
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 modbMetadataReplace(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const struct metadata_t *const metadata)
|
||||||
|
{
|
||||||
|
str_builder *sb;
|
||||||
|
char *table, *set;
|
||||||
|
size_t table_len, set_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
if ((sb = strbld_create()) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (metadata->id != 0 && metadata->id != id) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "mdo_id", TYPE_ID, 1, metadata->id);
|
||||||
|
}
|
||||||
|
if (metadata->type != 0) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "type", TYPE_STRING, 2, metadata->type, metadata->type_len);
|
||||||
|
}
|
||||||
|
if (metadata->title != 0) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "title", TYPE_STRING, 2, metadata->title, metadata->title_len);
|
||||||
|
}
|
||||||
|
if (metadata->owner != 0) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "owner_id", TYPE_ID, 1, metadata->owner->id);
|
||||||
|
} else if (metadata->owner_id != 0) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "owner_id", TYPE_ID, 1, metadata->owner_id);
|
||||||
|
}
|
||||||
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = updateQuery(
|
||||||
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
free(set);
|
||||||
|
|
||||||
|
return qry_ret;
|
||||||
|
}
|
||||||
|
int64_t modbMetadataUpdateType(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *type, size_t type_len)
|
||||||
|
{
|
||||||
|
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, "mdo_id", TYPE_ID, 1, id);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr(&set, &set_len, "type", TYPE_STRING, 2, type, type_len);
|
||||||
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = updateQuery(
|
||||||
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
free(set);
|
||||||
|
|
||||||
|
return qry_ret;
|
||||||
|
}
|
||||||
|
int64_t modbMetadataUpdateTitle(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *title, size_t title_len)
|
||||||
|
{
|
||||||
|
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, "mdo_id", TYPE_ID, 1, id);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr(&set, &set_len, "title", TYPE_STRING, 2, title, title_len);
|
||||||
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = updateQuery(
|
||||||
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
free(set);
|
||||||
|
|
||||||
|
return qry_ret;
|
||||||
|
}
|
||||||
|
int64_t modbMetadataUpdateOwner(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct user_t *owner)
|
||||||
|
{
|
||||||
|
return modbMetadataUpdateOwnerId(sconn, modb, id, owner->id);
|
||||||
|
}
|
||||||
|
int64_t modbMetadataUpdateOwnerId(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
unsigned int owner_id)
|
||||||
|
{
|
||||||
|
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, "mdo_id", TYPE_ID, 1, id);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr(&set, &set_len, "owner_id", TYPE_ID, 1, owner_id);
|
||||||
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = updateQuery(
|
||||||
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
free(set);
|
||||||
|
|
||||||
|
return qry_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int modbMetadataDelete(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = softDeleteByIdQuery(sconn, table, table_len, "id", id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int modbMetadataDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, METADATA_TABLE, STR_LEN(METADATA_TABLE));
|
||||||
|
qry_ret = deleteByIdQuery(sconn, table, table_len, "id", id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int modbFetchMetadataGroupIds(stored_conn *sconn, modb_ref *modb,
|
||||||
|
struct metadata_t *metadata, int with_deleted)
|
||||||
|
{
|
||||||
|
char *g_table, *ug_table;
|
||||||
|
size_t g_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(&g_table, &g_len, modb, GROUPS_TABLE, STR_LEN(GROUPS_TABLE));
|
||||||
|
modbTableName(&ug_table, &ug_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
|
||||||
|
strbld_str(sb, "SELECT ", 0);
|
||||||
|
escapeColumnName_sb(sb, 0, 0, "group_id", 0);
|
||||||
|
strbld_str(sb, " FROM ", 0);
|
||||||
|
escapeTableName_sb(sb, ug_table, ug_len);
|
||||||
|
joinStr_sb(sb, " LEFT", 5, 1, g_table, g_len, "id", 2, ug_table, ug_len, "group_id", 8);
|
||||||
|
wb = where(0, "mdo_id", EQ, TYPE_ID, 1, metadata->id);
|
||||||
|
if (!with_deleted) {
|
||||||
|
wb = whereAnd(wb, where(g_table, "deleted", IS_NULL, TYPE_RAW, 0));
|
||||||
|
}
|
||||||
|
compileWhereBuilder_sb(sb, wb, 1);
|
||||||
|
|
||||||
|
modbFreeTableName(&g_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata->group_ids = (*col_data)->data.ptr_uint32;
|
||||||
|
metadata->n_groups = (*col_data)->n_values;
|
||||||
|
(*col_data)->data.ptr_uint32 = 0;
|
||||||
|
|
||||||
|
freeColumns(col_data, n_cols);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int modbFetchMetadataGroups(stored_conn *sconn, modb_ref *modb, struct metadata_t *metadata,
|
||||||
|
int with_deleted)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
ret = modbFetchMetadataGroupIds(sconn, modb, metadata, with_deleted);
|
||||||
|
if (ret != 1) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata->groups = allocGroups(metadata->n_groups);
|
||||||
|
if (metadata->groups == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (idx = 0; idx < metadata->n_groups; idx++) {
|
||||||
|
if (modbGroupById(
|
||||||
|
sconn, modb, *(metadata->group_ids + idx), 0, (metadata->groups + idx)
|
||||||
|
) != 1) {
|
||||||
|
freeGroups(&metadata->groups, metadata->n_groups);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int modbSyncMetadataGroups(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, size_t n_groups, unsigned int *group_ids)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
qry_ret = syncIdMap(
|
||||||
|
sconn, table, table_len, "mdo_id", "group_id", metadata_id, n_groups, group_ids
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int modbSyncMetadataGroups_va(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, size_t n_groups, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
va_start(args, n_groups);
|
||||||
|
modbTableName(&table, &table_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
qry_ret = syncIdMap_va(
|
||||||
|
sconn, table, table_len, "mdo_id", "group_id", metadata_id, n_groups, args
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int modbIsLinked_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
qry_ret = hasIdMap(sconn, table, table_len, "mdo_id", "group_id", metadata_id, group_id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int modbLink_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
qry_ret = hasIdMap(sconn, table, table_len, "mdo_id", "group_id", metadata_id, group_id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int modbUnlink_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, MDO_GROUPS_TABLE, STR_LEN(MDO_GROUPS_TABLE));
|
||||||
|
qry_ret = hasIdMap(sconn, table, table_len, "mdo_id", "group_id", metadata_id, group_id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
53
src/modb_metadata.h
Normal file
53
src/modb_metadata.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef H__MODB_METADATA__
|
||||||
|
#define H__MODB_METADATA__
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
#include "modb_types.h"
|
||||||
|
|
||||||
|
// MODB MetadataList
|
||||||
|
int modbMetadataById(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct metadata_t **metadata);
|
||||||
|
// MetadataList by owner
|
||||||
|
// MetadataList by group
|
||||||
|
// MetadataList by owner/owner groups
|
||||||
|
|
||||||
|
int modbMetadataList(stored_conn *sconn, modb_ref *modb, int with_deleted,
|
||||||
|
struct metadata_t ***metadata_list, size_t *n_metadata_list);
|
||||||
|
|
||||||
|
int64_t modbMetadataCreate(stored_conn *sconn, modb_ref *modb,
|
||||||
|
const struct metadata_t *const metadata);
|
||||||
|
|
||||||
|
int64_t modbMetadataReplace(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const struct metadata_t *const metadata);
|
||||||
|
int64_t modbMetadataUpdateType(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *type, size_t type_len);
|
||||||
|
int64_t modbMetadataUpdateTitle(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *title, size_t title_len);
|
||||||
|
int64_t modbMetadataUpdateOwner(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct user_t *owner);
|
||||||
|
int64_t modbMetadataUpdateOwnerId(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
unsigned int owner_id);
|
||||||
|
|
||||||
|
int modbMetadataDelete(stored_conn *sconn, modb_ref *modb, unsigned int id);
|
||||||
|
int modbMetadataDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id);
|
||||||
|
|
||||||
|
|
||||||
|
// MODB Metadata -> Groups
|
||||||
|
int modbFetchMetadataGroupIds(stored_conn *sconn, modb_ref *modb,
|
||||||
|
struct metadata_t *metadata, int with_deleted);
|
||||||
|
int modbFetchMetadataGroups(stored_conn *sconn, modb_ref *modb, struct metadata_t *metadata,
|
||||||
|
int with_deleted);
|
||||||
|
|
||||||
|
int modbSyncMetadataGroups(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, size_t n_groups, unsigned int *group_id);
|
||||||
|
int modbSyncMetadataGroups_va(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, size_t n_groups, ...);
|
||||||
|
|
||||||
|
int modbIsLinked_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id);
|
||||||
|
int modbLink_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id);
|
||||||
|
int modbUnlink_Metadata_Group(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int metadata_id, unsigned int group_id);
|
||||||
|
|
||||||
|
#endif // H__MODB_METADATA__
|
||||||
244
src/modb_objects.c
Normal file
244
src/modb_objects.c
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "modb_objects.h"
|
||||||
|
#include "modb_p.h"
|
||||||
|
|
||||||
|
|
||||||
|
int tableRowsToObjects(column_data **col_data, size_t n_cols,
|
||||||
|
struct object_t ***objects, size_t *n_objects)
|
||||||
|
{
|
||||||
|
column_data *col_id, *col_object;
|
||||||
|
size_t n_rows, idx;
|
||||||
|
struct object_t *object;
|
||||||
|
|
||||||
|
n_rows = (*col_data)->n_values;
|
||||||
|
if (n_rows == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
col_id = findColumnByName(col_data, n_cols, "mdo_id");
|
||||||
|
col_object = findColumnByName(col_data, n_cols, "object");
|
||||||
|
|
||||||
|
*objects = (struct object_t **)malloc(sizeof(struct object_t *) * n_rows);
|
||||||
|
if (*objects == 0) {
|
||||||
|
fprintf(stderr, "[%d]malloc: (%d) %s\n", __LINE__, errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(*objects, 0, sizeof(struct object_t *) * n_rows);
|
||||||
|
|
||||||
|
for (idx = 0; idx < n_rows; idx++) {
|
||||||
|
object = allocObject();
|
||||||
|
if (object == 0) {
|
||||||
|
freeObjects(objects, idx - 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->id = *(col_id->data.ptr_uint32 + idx);
|
||||||
|
|
||||||
|
if (!moveColumnBlobPointer(col_object, idx, 1, &object->data, &object->data_len)) {
|
||||||
|
freeObjects(objects, idx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(*objects + idx) = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n_objects = n_rows;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int doObjectsQuery(stored_conn *sconn, modb_ref *modb, where_builder *wb,
|
||||||
|
struct object_t ***objects, size_t *n_objects)
|
||||||
|
{
|
||||||
|
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, OBJECTS_TABLE, strlen(OBJECTS_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 -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = tableRowsToObjects(col_data, n_cols, objects, n_objects);
|
||||||
|
freeColumns(col_data, n_cols);
|
||||||
|
|
||||||
|
if (res <= 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int doScalarObjectsQuery(stored_conn *sconn, modb_ref *modb,
|
||||||
|
where_builder *wb, struct object_t **object)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
struct object_t **objects;
|
||||||
|
size_t n_objects;
|
||||||
|
|
||||||
|
res = doObjectsQuery(sconn, modb, wb, &objects, &n_objects);
|
||||||
|
if (res <= 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
*object = *(objects + 0);
|
||||||
|
*(objects + 0) = 0;
|
||||||
|
freeObjects(&objects, n_objects);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int modbObjectById(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct object_t **object)
|
||||||
|
{
|
||||||
|
where_builder *wb = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
wb = where(0, "mdo_id", EQ, TYPE_UINT32, 1, id);
|
||||||
|
res = doScalarObjectsQuery(sconn, modb, wb, object);
|
||||||
|
freeWhereBuilder(&wb);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int modbObjectList(stored_conn *sconn, modb_ref *modb, int with_deleted,
|
||||||
|
struct object_t ***objects, size_t *n_objects)
|
||||||
|
{
|
||||||
|
where_builder *wb = 0;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (with_deleted == 0) {
|
||||||
|
wb = where(0, "deleted_on", IS_NULL, TYPE_RAW, 0, 0);
|
||||||
|
}
|
||||||
|
res = doObjectsQuery(sconn, modb, wb, objects, n_objects);
|
||||||
|
if (wb != 0) {
|
||||||
|
freeWhereBuilder(&wb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t modbObjectCreate(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int id, const char *data, size_t data_len)
|
||||||
|
{
|
||||||
|
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, OBJECTS_TABLE, strlen(OBJECTS_TABLE));
|
||||||
|
|
||||||
|
strbld_str(sb, "INSERT INTO ", 0);
|
||||||
|
escapeTableName_sb(sb, table, table_len);
|
||||||
|
strbld_str(sb, " (`mdo_id`, `object`) VALUES (", 0);
|
||||||
|
db_value_sb(sb, TYPE_ID, 1, id);
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
db_value_sb(sb, TYPE_BLOB, 2, data, data_len);
|
||||||
|
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 modbObjectUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *data, size_t data_len)
|
||||||
|
{
|
||||||
|
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, "mdo_id", TYPE_ID, 1, id);
|
||||||
|
if (data != 0) {
|
||||||
|
strbld_char(sb, ',');
|
||||||
|
columnSetValueStr_sb(sb, "object", TYPE_BLOB, 2, data, data_len);
|
||||||
|
}
|
||||||
|
if (strbld_finalize_or_destroy(&sb, &set, &set_len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, OBJECTS_TABLE, strlen(OBJECTS_TABLE));
|
||||||
|
qry_ret = updateQuery(
|
||||||
|
sconn, table, table_len, set, set_len, where(0, "mdo_id", EQ, TYPE_ID, 1, id)
|
||||||
|
);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
free(set);
|
||||||
|
|
||||||
|
return qry_ret;
|
||||||
|
}
|
||||||
|
int modbObjectDelete(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, OBJECTS_TABLE, STR_LEN(OBJECTS_TABLE));
|
||||||
|
qry_ret = softDeleteByIdQuery(sconn, table, table_len, "id", id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
|
int modbObjectDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id)
|
||||||
|
{
|
||||||
|
char *table;
|
||||||
|
size_t table_len;
|
||||||
|
int64_t qry_ret;
|
||||||
|
|
||||||
|
modbTableName(&table, &table_len, modb, OBJECTS_TABLE, STR_LEN(OBJECTS_TABLE));
|
||||||
|
qry_ret = deleteByIdQuery(sconn, table, table_len, "id", id);
|
||||||
|
modbFreeTableName(&table);
|
||||||
|
|
||||||
|
return (int)qry_ret;
|
||||||
|
}
|
||||||
26
src/modb_objects.h
Normal file
26
src/modb_objects.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef H__MODB_OBJECTS__
|
||||||
|
#define H__MODB_OBJECTS__
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
#include "modb_types.h"
|
||||||
|
|
||||||
|
// object from row
|
||||||
|
|
||||||
|
// MODB Objects
|
||||||
|
int modbObjectById(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
struct object_t **object);
|
||||||
|
// Objects by owner
|
||||||
|
// Objects by group
|
||||||
|
// Objects by owner/owner groups
|
||||||
|
|
||||||
|
int modbObjectList(stored_conn *sconn, modb_ref *modb, int with_deleted,
|
||||||
|
struct object_t ***objects, size_t *n_objects);
|
||||||
|
|
||||||
|
int64_t modbObjectCreate(stored_conn *sconn, modb_ref *modb,
|
||||||
|
unsigned int id, const char *data, size_t data_len);
|
||||||
|
int64_t modbObjectUpdate(stored_conn *sconn, modb_ref *modb, unsigned int id,
|
||||||
|
const char *data, size_t data_len);
|
||||||
|
int modbObjectDelete(stored_conn *sconn, modb_ref *modb, unsigned int id);
|
||||||
|
int modbObjectDestroy(stored_conn *sconn, modb_ref *modb, unsigned int id);
|
||||||
|
|
||||||
|
#endif // H__MODB_OBJECTS__
|
||||||
Reference in New Issue
Block a user