Files
rmodb/src/R_modb_groups.c
2020-10-15 14:47:19 +01:00

196 lines
5.4 KiB
C

#include <strings.h>
#include "modb_database.h"
#include "modb_ref.h"
#include "R_helpers_p.h"
#include "R_list_item.h"
#include "R_timestamp.h"
#include "R_modb_groups.h"
#include "R_modb_users.h"
SEXP groupToR(struct group_t *group, int with_members)
{
SEXP r_group;
SEXP r_group_name = R_NilValue;
SEXP r_members = R_NilValue;
SEXP r_attrib_names;
SEXP r_class;
int n_protect = 0;
size_t idx;
r_group_name = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_group_name, 0, PROTECT(Rf_mkChar(group->name)));
n_protect += 2;
r_group = PROTECT(Rf_allocVector(VECSXP, 5 + (with_members ? 1 : 0)));
SET_VECTOR_ELT(r_group, 0, PROTECT(Rf_ScalarInteger((int)group->id)));
SET_VECTOR_ELT(r_group, 1, r_group_name);
SET_VECTOR_ELT(r_group, 2, PROTECT(R_Timestamp(group->created_on)));
SET_VECTOR_ELT(r_group, 3, PROTECT(R_Timestamp(group->updated_on)));
SET_VECTOR_ELT(r_group, 4, PROTECT(R_Timestamp(group->deleted_on)));
n_protect += 1 + 4;
r_attrib_names = PROTECT(Rf_allocVector(STRSXP, 5 + (with_members ? 1 : 0)));
SET_STRING_ELT(r_attrib_names, 0, PROTECT(Rf_mkChar("id")));
SET_STRING_ELT(r_attrib_names, 1, PROTECT(Rf_mkChar("name")));
SET_STRING_ELT(r_attrib_names, 2, PROTECT(Rf_mkChar("created_on")));
SET_STRING_ELT(r_attrib_names, 3, PROTECT(Rf_mkChar("updated_on")));
SET_STRING_ELT(r_attrib_names, 4, PROTECT(Rf_mkChar("deleted_on")));
n_protect += 1 + 5;
if (with_members) {
r_members = PROTECT(Rf_allocVector(VECSXP, (int)group->n_members));
for (idx = 0; idx < group->n_members; idx++) {
SET_VECTOR_ELT(r_members, (int)idx, PROTECT(userToR(*(group->members + idx), 0)));
}
SET_VECTOR_ELT(r_group, 5, r_members);
n_protect += 1 + (int)group->n_members;
SET_STRING_ELT(r_attrib_names, 5, PROTECT(Rf_mkChar("members")));
n_protect++;
}
Rf_setAttrib(r_group, R_NamesSymbol, r_attrib_names);
r_class = PROTECT(Rf_allocVector(STRSXP, 2));
SET_STRING_ELT(r_class, 0, PROTECT(Rf_mkChar("list")));
SET_STRING_ELT(r_class, 1, PROTECT(Rf_mkChar("modb_group")));
n_protect += 1 + 2;
Rf_setAttrib(r_group, R_ClassSymbol, r_class);
UNPROTECT(n_protect);
return r_group;
}
SEXP rmodb_groupId(SEXP r_conn_ref, SEXP r_name)
{
stored_conn *sconn;
modb_ref modb;
const char *name = 0;
struct group_t *group = 0;
SEXP r_group_id;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
name = Rf_translateCharUTF8(STRING_ELT(r_name, 0));
if (modbGroupByName(sconn, &modb, name, 0, &group) <= 0) {
return Rf_ScalarInteger(-1);
}
r_group_id = PROTECT(Rf_ScalarInteger((int)group->id));
freeGroup(&group);
UNPROTECT(1);
return r_group_id;
}
SEXP rmodb_groups(SEXP r_conn_ref, SEXP r_with_members, SEXP r_with_deleted)
{
stored_conn *sconn;
modb_ref modb;
int with_deleted, with_members = 0;
struct group_t **groups = 0;
size_t n_groups = 0;
size_t idx;
SEXP r_groups;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
with_deleted = Rf_asLogical(r_with_deleted);
with_members = Rf_asLogical(r_with_members);
if (modbGroupList(sconn, &modb, with_deleted, with_members, &groups, &n_groups) < 0) {
return R_NilValue;
}
if (n_groups == 0) {
return Rf_allocVector(VECSXP, 0);
}
r_groups = PROTECT(Rf_allocVector(VECSXP, (int)n_groups));
for (idx = 0; idx < n_groups; idx++) {
SET_VECTOR_ELT(r_groups, (int)idx, PROTECT(groupToR(*(groups + idx), with_members)));
}
freeGroups(&groups, n_groups);
UNPROTECT((int)(1 + n_groups));
return r_groups;
}
SEXP rmodb_group(SEXP r_conn_ref, SEXP r_id, SEXP r_with_members)
{
stored_conn *sconn;
modb_ref modb;
unsigned int group_id = 0;
int with_members = 0;
struct group_t *group = 0;
SEXP r_group;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
group_id = (unsigned int)Rf_asInteger(r_id);
with_members = Rf_asLogical(r_with_members);
if (modbGroupById(sconn, &modb, group_id, with_members, &group) <= 0) {
return R_NilValue;
}
r_group = PROTECT(groupToR(group, with_members));
freeGroup(&group);
UNPROTECT(1);
return r_group;
}
SEXP rmodb_createGroup(SEXP r_conn_ref, SEXP r_id, SEXP r_name)
{
stored_conn *sconn;
modb_ref modb;
struct group_t group;
int64_t res;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
bzero(&group, sizeof(struct group_t));
group.id = (unsigned int)Rf_asInteger(r_id);
group.name_c = Rf_translateCharUTF8(STRING_ELT(r_name, 0));
res = modbGroupCreate(sconn, &modb, &group);
return Rf_ScalarReal((double)res);
}
SEXP rmodb_deleteGroup(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int group_id = 0;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
group_id = (unsigned int)Rf_asInteger(r_id);
return Rf_ScalarLogical(modbGroupDelete(sconn, &modb, group_id));
}