#include #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)); }