R->c c->R code

This commit is contained in:
2020-10-15 14:47:19 +01:00
parent 4a6a3c5673
commit 727b497eca
10 changed files with 1199 additions and 0 deletions

195
src/R_modb_groups.c Normal file
View File

@@ -0,0 +1,195 @@
#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));
}

17
src/R_modb_groups.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef H__R_MODB_GROUPS__
#define H__R_MODB_GROUPS__
#include <Rinternals.h>
#include "modb_groups.h"
SEXP groupToR(struct group_t *group, int with_members);
SEXP rmodb_groupId(SEXP r_conn_ref, SEXP r_name);
SEXP rmodb_groups(SEXP r_conn_ref, SEXP r_with_members, SEXP r_with_deleted);
SEXP rmodb_group(SEXP r_conn_ref, SEXP r_id, SEXP r_with_members);
SEXP rmodb_createGroup(SEXP r_conn_ref, SEXP r_id, SEXP r_name);
SEXP rmodb_deleteGroup(SEXP r_conn_ref, SEXP r_id);
#endif // H__R_MODB_GROUPS__

542
src/R_modb_metaobjects.c Normal file
View File

@@ -0,0 +1,542 @@
#include <string.h>
#include <Rversion.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_metaobjects.h"
#include "R_modb_groups.h"
#include "R_modb_users.h"
#include "R_memory-object.h"
#include "R_magic.h"
SEXP metadataToR(struct metadata_t *metadata)
{
SEXP r_metadata;
SEXP r_title;
SEXP r_groups = R_NilValue;
SEXP r_attrib_names;
SEXP r_class;
int n_protect = 0, with_ext = 0, with_obj = 0;
size_t idx;
if (metadata->object) {
with_obj = 1;
}
if (metadata->ext) {
with_ext = 1;
}
r_title = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_title, 0, PROTECT(Rf_mkChar(metadata->title)));
n_protect += 2;
r_groups = PROTECT(Rf_allocVector(VECSXP, (int)metadata->n_groups));
for (idx = 0; idx < metadata->n_groups; idx++) {
SET_VECTOR_ELT(r_groups, (int)idx, PROTECT(groupToR(*(metadata->groups + idx), 0)));
}
n_protect += 1 + (int)metadata->n_groups;
r_metadata = PROTECT(Rf_allocVector(VECSXP, 7 + with_ext + with_obj));
SET_VECTOR_ELT(r_metadata, 0, PROTECT(Rf_ScalarInteger((int)metadata->id)));
SET_VECTOR_ELT(r_metadata, 1, r_title);
SET_VECTOR_ELT(r_metadata, 2, PROTECT(userToR(metadata->owner, 0)));
SET_VECTOR_ELT(r_metadata, 3, r_groups);
SET_VECTOR_ELT(r_metadata, 4, PROTECT(R_Timestamp(metadata->created_on)));
SET_VECTOR_ELT(r_metadata, 5, PROTECT(R_Timestamp(metadata->updated_on)));
SET_VECTOR_ELT(r_metadata, 6, PROTECT(R_Timestamp(metadata->deleted_on)));
n_protect += 1 + 5;
if (with_ext) {
SET_VECTOR_ELT(r_metadata, 7, PROTECT(metadataExtToR(metadata->ext)));
n_protect++;
}
if (with_obj) {
SET_VECTOR_ELT(r_metadata, 7 + with_ext, PROTECT(objectToR(metadata->object)));
n_protect++;
}
r_attrib_names = PROTECT(Rf_allocVector(STRSXP, 7 + with_ext + with_obj));
SET_STRING_ELT(r_attrib_names, 0, PROTECT(Rf_mkChar("id")));
SET_STRING_ELT(r_attrib_names, 1, PROTECT(Rf_mkChar("title")));
SET_STRING_ELT(r_attrib_names, 2, PROTECT(Rf_mkChar("owner")));
SET_STRING_ELT(r_attrib_names, 3, PROTECT(Rf_mkChar("groups")));
SET_STRING_ELT(r_attrib_names, 4, PROTECT(Rf_mkChar("created_on")));
SET_STRING_ELT(r_attrib_names, 5, PROTECT(Rf_mkChar("updated_on")));
SET_STRING_ELT(r_attrib_names, 6, PROTECT(Rf_mkChar("deleted_on")));
n_protect += 1 + 7;
if (with_ext) {
SET_STRING_ELT(r_attrib_names, 7, PROTECT(Rf_mkChar("ext")));
n_protect++;
}
if (with_obj) {
SET_STRING_ELT(r_attrib_names, 7 + with_ext, PROTECT(Rf_mkChar("object")));
n_protect++;
}
Rf_setAttrib(r_metadata, 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_metaObject")));
Rf_setAttrib(r_metadata, R_ClassSymbol, r_class);
n_protect += 1 + 2;
UNPROTECT(n_protect);
return r_metadata;
}
SEXP objectToR(struct object_t *object)
{
struct r_memoryobject_t mo;
if (object->data_c == 0) {
object->data_c = object->data;
}
mo.buf = (char *)object->data_c;
mo.buf_size = object->data_len;
if (R_VERSION >= R_Version(3,0,0)) {
mo.magic = R_MAGIC_XDR_V3;
} else {
mo.magic = R_MAGIC_XDR_V2;
}
return memoryToRObject(mo);
}
SEXP metadataExtToR(struct meta_ext_t *ext)
{
SEXP r_ext;
SEXP r_tmp = R_NilValue;
SEXP r_attrib_names;
int n_protect = 0;
size_t idx;
struct meta_ext_value_t *ext_value;
r_ext = PROTECT(Rf_allocVector(VECSXP, 1 + (int)ext->n_values));
n_protect++;
r_attrib_names = PROTECT(Rf_allocVector(STRSXP, 1 + (int)ext->n_values));
n_protect++;
for (idx = 0; idx < ext->n_values; idx++) {
ext_value = *(ext->values + idx);
switch(ext_value->type) {
case VTYPE_RAW:
r_tmp = PROTECT(objectToR(ext_value->value.raw));
break;
case VTYPE_BOOL:
r_tmp = PROTECT(Rf_ScalarLogical(ext_value->value.bool));
break;
case VTYPE_INT32:
r_tmp = PROTECT(Rf_ScalarInteger(ext_value->value.int32));
break;
case VTYPE_DOUBLE:
r_tmp = PROTECT(Rf_ScalarReal(ext_value->value.dbl));
break;
case VTYPE_STRING:
r_tmp = PROTECT(Rf_allocVector(STRSXP, 1));
n_protect++;
SET_STRING_ELT(r_tmp, 0, PROTECT(Rf_mkChar(ext_value->value.str)));
break;
case VTYPE_TIMESTAMP:
r_tmp = PROTECT(R_Timestamp(ext_value->value.ts));
break;
case VTYPE_ID:
r_tmp = PROTECT(Rf_ScalarInteger((int)ext_value->value.id));
break;
}
SET_VECTOR_ELT(r_ext, 1 + (int)idx, r_tmp);
SET_STRING_ELT(r_attrib_names, 1 + (int)idx, PROTECT(Rf_mkChar(ext_value->key_c)));
n_protect += 2;
}
Rf_setAttrib(r_ext, R_NamesSymbol, r_attrib_names);
UNPROTECT(n_protect);
return r_ext;
}
SEXP rmodb_metaobjectId(SEXP r_conn_ref, SEXP r_query)
{
return R_NilValue;
}
SEXP rmodb_metaobject(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int mo_id;
struct metadata_t *metadata;
SEXP r_metadata;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
mo_id = (unsigned int)Rf_asInteger(r_id);
if (modbMetadataById(sconn, &modb, mo_id, &metadata) <= 0) {
return R_NilValue;
}
if (modbFetchMetadataOwner(sconn, &modb, metadata) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
if (modbFetchMetadataGroups(sconn, &modb, metadata, 0) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
if (modbFetchMetadataExtended(sconn, &modb, metadata) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
if (modbFetchMetadataObject(sconn, &modb, metadata) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
r_metadata = metadataToR(metadata);
freeMetadata(&metadata);
return r_metadata;
}
SEXP rmodb_metadata(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int mo_id;
struct metadata_t *metadata;
SEXP r_metadata;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
mo_id = (unsigned int)Rf_asInteger(r_id);
if (modbMetadataById(sconn, &modb, mo_id, &metadata) <= 0) {
return R_NilValue;
}
if (modbFetchMetadataOwner(sconn, &modb, metadata) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
if (modbFetchMetadataGroups(sconn, &modb, metadata, 0) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
if (modbFetchMetadataExtended(sconn, &modb, metadata) <= 0) {
freeMetadata(&metadata);
return R_NilValue;
}
r_metadata = metadataToR(metadata);
freeMetadata(&metadata);
return r_metadata;
}
SEXP rmodb_object(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int mo_id;
struct object_t *object;
SEXP r_object;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
mo_id = (unsigned int)Rf_asInteger(r_id);
if (modbObjectById(sconn, &modb, mo_id, &object) <= 0) {
return R_NilValue;
}
r_object = objectToR(object);
freeObject(&object);
return r_object;
}
SEXP rmodb_metaobjects(SEXP r_conn_ref, SEXP r_with_deleted)
{
stored_conn *sconn;
modb_ref modb;
int with_deleted = 0;
struct metadata_t **metadata_list = 0, *metadata;
size_t n_metadatas = 0;
size_t idx;
SEXP r_metadatas;
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);
if (modbMetadataList(sconn, &modb, with_deleted, &metadata_list, &n_metadatas) <= 0) {
return R_NilValue;
}
r_metadatas = PROTECT(Rf_allocVector(VECSXP, (int)n_metadatas));
for (idx = 0; idx < n_metadatas; idx++) {
metadata = *(metadata_list + idx);
if (modbFetchMetadataOwner(sconn, &modb, metadata) < 0) {
freeMetadata(&metadata);
UNPROTECT(1 + (int)idx);
printf("FAILED");
return R_NilValue;
}
if (modbFetchMetadataGroups(sconn, &modb, metadata, 0) < 0) {
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
if (modbFetchMetadataExtended(sconn, &modb, metadata) < 0) {
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
if (modbFetchMetadataObject(sconn, &modb, metadata) < 0) {
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
SET_VECTOR_ELT(r_metadatas, (int)idx, PROTECT(metadataToR(metadata)));
}
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)n_metadatas);
return r_metadatas;
}
SEXP rmodb_metadatas(SEXP r_conn_ref, SEXP r_with_deleted)
{
stored_conn *sconn;
modb_ref modb;
int with_deleted = 0;
struct metadata_t **metadata_list = 0, *metadata;
size_t n_metadatas = 0;
size_t idx;
SEXP r_metadatas;
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);
if (modbMetadataList(sconn, &modb, with_deleted, &metadata_list, &n_metadatas) <= 0) {
return R_NilValue;
}
r_metadatas = PROTECT(Rf_allocVector(VECSXP, (int)n_metadatas));
for (idx = 0; idx < n_metadatas; idx++) {
metadata = *(metadata_list + idx);
if (modbFetchMetadataOwner(sconn, &modb, metadata) < 0) {
freeMetadata(&metadata);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
if (modbFetchMetadataGroups(sconn, &modb, metadata, 0) < 0) {
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
if (modbFetchMetadataExtended(sconn, &modb, metadata) < 0) {
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT(1 + (int)idx);
return R_NilValue;
}
SET_VECTOR_ELT(r_metadatas, (int)idx, PROTECT(metadataToR(metadata)));
}
freeMetadataList(&metadata_list, n_metadatas);
UNPROTECT((int)(1 + n_metadatas));
return r_metadatas;
}
SEXP rmodb_createMetaobject(SEXP r_conn_ref, SEXP r_id,
SEXP r_metadata, SEXP r_object, SEXP r_extendedMeta)
{
stored_conn *sconn;
modb_ref modb;
struct metadata_t metadata;
struct object_t object;
struct meta_ext_t *metadata_ext;
struct meta_ext_value_t *ext_value;
struct r_memoryobject_t *memObj;
SEXP r_tmp, r_names;
int i;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
memset(&metadata, 0, sizeof(struct metadata_t));
metadata.id = (unsigned int)Rf_asInteger(r_id);
metadata.title_c = Rf_translateCharUTF8(STRING_ELT(R_listItem(r_metadata, "title"), 0));
metadata.owner_id = (unsigned int)Rf_asInteger(R_listItem(r_metadata, "owner_id"));
if ((metadata.id = modbMetadataCreate(sconn, &modb, &metadata)) <= 0) {
return Rf_ScalarLogical(FALSE);
}
r_tmp = R_listItem(r_metadata, "group_ids");
if (r_tmp != R_NilValue) {
if (LENGTH(r_tmp) == 1) {
if (modbLink_Metadata_Group(
sconn, &modb, metadata.id,
(unsigned int)Rf_asInteger(r_tmp)) <= 0) {
modbMetadataDestroy(sconn, &modb, metadata.id);
return Rf_ScalarLogical(FALSE);
}
} else {
for (i = 0; i < LENGTH(r_tmp); i++) {
if (modbLink_Metadata_Group(
sconn, &modb, metadata.id,
(unsigned int)Rf_asInteger(VECTOR_ELT(r_tmp, i))) <= 0) {
modbMetadataDestroy(sconn, &modb, metadata.id);
modbSyncMetadataGroups(sconn, &modb, metadata.id, 0, 0);
return Rf_ScalarLogical(FALSE);
}
}
}
}
memObj = robjectToMemory(r_object, R_MAGIC_XDR_V3);
object.id = metadata.id;
object.data_c = memObj->buf;
object.data_len = memObj->buf_size;
if (modbObjectCreate(sconn, &modb, &object) <= 0) {
free(memObj->buf);
free(memObj);
modbSyncMetadataGroups(sconn, &modb, metadata.id, 0, 0);
modbMetadataDestroy(sconn, &modb, metadata.id);
return Rf_ScalarLogical(FALSE);
}
free(memObj->buf);
free(memObj);
if (LENGTH(r_extendedMeta) > 0) {
if ((metadata_ext = allocMetaExt()) == 0) {
modbObjectDestroy(sconn, &modb, metadata.id);
modbSyncMetadataGroups(sconn, &modb, metadata.id, 0, 0);
modbMetadataDestroy(sconn, &modb, metadata.id);
return Rf_ScalarLogical(FALSE);
}
metadata_ext->id = metadata.id;
metadata_ext->n_values = (size_t)LENGTH(r_extendedMeta);
metadata_ext->values = allocMetaExtValues(metadata_ext->n_values, 1);
if (metadata_ext->values == 0) {
freeMetaExt(&metadata_ext);
modbObjectDestroy(sconn, &modb, metadata.id);
modbSyncMetadataGroups(sconn, &modb, metadata.id, 0, 0);
modbMetadataDestroy(sconn, &modb, metadata.id);
return Rf_ScalarLogical(FALSE);
}
r_names = Rf_getAttrib(r_extendedMeta, R_NamesSymbol);
for (i = 0; i < LENGTH(r_extendedMeta); i++) {
ext_value = *(metadata_ext->values + i);
ext_value->key_c = Rf_translateCharUTF8(STRING_ELT(r_names, i));
r_tmp = VECTOR_ELT(r_extendedMeta, i);
if (Rf_isNull(r_tmp)) {
ext_value->type = VTYPE_RAW;
ext_value->is_null = 1;
} else {
switch(TYPEOF(r_tmp)) {
case LGLSXP:/* logical vectors */
ext_value->type = VTYPE_BOOL;
ext_value->value.bool = Rf_asLogical(r_tmp);
break;
case INTSXP:/* integer vectors */
ext_value->type = VTYPE_INT32;
ext_value->value.int32 = Rf_asInteger(r_tmp);
break;
case REALSXP:/* real variables */
ext_value->type = VTYPE_DOUBLE;
ext_value->value.dbl = Rf_asReal(r_tmp);
break;
case STRSXP:/* string vectors */
ext_value->type = VTYPE_STRING;
ext_value->value.str_c = Rf_translateCharUTF8(STRING_ELT(r_tmp, 0));
ext_value->is_const = 1;
break;
case VECSXP:/* generic vectors */
break;
default:
break;
// Screwed if I know how to handle this...
}
}
}
if (modbMetaExtCreate(sconn, &modb, metadata_ext) <= 0) {
freeMetaExt(&metadata_ext);
modbObjectDestroy(sconn, &modb, metadata.id);
modbSyncMetadataGroups(sconn, &modb, metadata.id, 0, 0);
modbMetadataDestroy(sconn, &modb, metadata.id);
return Rf_ScalarLogical(FALSE);
}
}
return Rf_ScalarReal((double)metadata.id);
}
SEXP rmodb_updateMetaobject(SEXP r_conn_ref, SEXP r_id, SEXP r_metaobject)
{
return R_NilValue;
}
SEXP rmodb_deleteMetaobject(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int mdo_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");
}
mdo_id = (unsigned int)Rf_asInteger(r_id);
return Rf_ScalarLogical(modbMetadataDelete(sconn, &modb, mdo_id));
}

28
src/R_modb_metaobjects.h Normal file
View File

@@ -0,0 +1,28 @@
#ifndef H__R_MODB_METAOBJECT__
#define H__R_MODB_METAOBJECT__
#include <Rinternals.h>
#include "modb_metadata.h"
#include "modb_objects.h"
#include "modb_metadata_ext.h"
SEXP metadataToR(struct metadata_t *metadata);
SEXP objectToR(struct object_t *object);
SEXP metadataExtToR(struct meta_ext_t *ext);
SEXP rmodb_metaobjectId(SEXP r_conn_ref, SEXP r_query);
SEXP rmodb_metaobject(SEXP r_conn_ref, SEXP r_id);
SEXP rmodb_metadata(SEXP r_conn_ref, SEXP r_id);
SEXP rmodb_object(SEXP r_conn_ref, SEXP r_id);
SEXP rmodb_metaobjects(SEXP r_conn_ref, SEXP r_with_deleted);
SEXP rmodb_metadatas(SEXP r_conn_ref, SEXP r_with_deleted);
SEXP rmodb_createMetaobject(SEXP r_conn_ref, SEXP r_id,
SEXP r_metadata, SEXP r_object, SEXP r_extendedMeta);
SEXP rmodb_updateMetaobject(SEXP r_conn_ref, SEXP r_id, SEXP r_metaobject);
SEXP rmodb_deleteMetaobject(SEXP r_conn_ref, SEXP r_id);
#endif // H__R_MODB_METAOBJECT__

54
src/R_modb_user_groups.c Normal file
View File

@@ -0,0 +1,54 @@
#include <stdio.h>
#include <string.h>
#include "modb_database.h"
#include "modb_ref.h"
#include "R_modb_users.h"
#include "R_helpers_p.h"
#include "R_modb_user_groups.h"
SEXP rmodb_userAddGroup(SEXP r_conn_ref, SEXP r_user_id, SEXP r_group_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int user_id, 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");
}
user_id = (unsigned int)Rf_asInteger(r_user_id);
group_id = (unsigned int)Rf_asInteger(r_group_id);
if (modbLink_User_Group(sconn, &modb, user_id, group_id) <= 0) {
return Rf_ScalarLogical(FALSE);
}
return Rf_ScalarLogical(TRUE);
}
SEXP rmodb_userRemoveGroup(SEXP r_conn_ref, SEXP r_user_id, SEXP r_group_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int user_id, 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");
}
user_id = (unsigned int)Rf_asInteger(r_user_id);
group_id = (unsigned int)Rf_asInteger(r_group_id);
if (modbUnlink_User_Group(sconn, &modb, user_id, group_id) <= 0) {
return Rf_ScalarLogical(FALSE);
}
return Rf_ScalarLogical(TRUE);
}

9
src/R_modb_user_groups.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef H__R_MODB_USER_GROUPS__
#define H__R_MODB_USER_GROUPS__
#include <Rinternals.h>
SEXP rmodb_userAddGroup(SEXP r_conn_ref, SEXP r_user_id, SEXP r_group_id);
SEXP rmodb_userRemoveGroup(SEXP r_conn_ref, SEXP r_user_id, SEXP r_group_id);
#endif // H__R_MODB_USER_GROUPS__

209
src/R_modb_users.c Normal file
View File

@@ -0,0 +1,209 @@
#include <string.h>
#include "R_helpers_p.h"
#include "R_list_item.h"
#include "R_timestamp.h"
#include "modb_database.h"
#include "modb_ref.h"
#include "R_modb_users.h"
#include "R_modb_groups.h"
SEXP userToR(struct user_t *user, int with_groups)
{
SEXP r_user;
SEXP r_username;
SEXP r_email;
SEXP r_groups = R_NilValue;
SEXP r_attrib_names;
SEXP r_class;
int n_protect = 0;
size_t idx;
r_username = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_username, 0, PROTECT(Rf_mkChar(user->username_c)));
n_protect += 2;
r_email = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_email, 0, PROTECT(Rf_mkChar(user->email_c)));
n_protect += 2;
r_user = PROTECT(Rf_allocVector(VECSXP, 6 + (with_groups ? 1 : 0)));
SET_VECTOR_ELT(r_user, 0, PROTECT(Rf_ScalarInteger((int)user->id)));
SET_VECTOR_ELT(r_user, 1, r_username);
SET_VECTOR_ELT(r_user, 2, r_email);
SET_VECTOR_ELT(r_user, 3, PROTECT(R_Timestamp(user->created_on)));
SET_VECTOR_ELT(r_user, 4, PROTECT(R_Timestamp(user->updated_on)));
SET_VECTOR_ELT(r_user, 5, PROTECT(R_Timestamp(user->deleted_on)));
n_protect += 1 + 4;
r_attrib_names = PROTECT(Rf_allocVector(STRSXP, 6 + (with_groups ? 1 : 0)));
SET_STRING_ELT(r_attrib_names, 0, PROTECT(Rf_mkChar("id")));
SET_STRING_ELT(r_attrib_names, 1, PROTECT(Rf_mkChar("username")));
SET_STRING_ELT(r_attrib_names, 2, PROTECT(Rf_mkChar("email")));
SET_STRING_ELT(r_attrib_names, 3, PROTECT(Rf_mkChar("created_on")));
SET_STRING_ELT(r_attrib_names, 4, PROTECT(Rf_mkChar("updated_on")));
SET_STRING_ELT(r_attrib_names, 5, PROTECT(Rf_mkChar("deleted_on")));
n_protect += 1 + 6;
if (with_groups) {
r_groups = PROTECT(Rf_allocVector(VECSXP, (int)user->n_groups));
for (idx = 0; idx < user->n_groups; idx++) {
SET_VECTOR_ELT(r_groups, (int)idx, PROTECT(groupToR(*(user->groups + idx), 0)));
}
SET_VECTOR_ELT(r_user, 6, r_groups);
n_protect += 1 + (int)user->n_groups;
SET_STRING_ELT(r_attrib_names, 6, PROTECT(Rf_mkChar("groups")));
n_protect++;
}
Rf_setAttrib(r_user, 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_user")));
Rf_setAttrib(r_user, R_ClassSymbol, r_class);
n_protect += 1 + 2;
UNPROTECT(n_protect);
return r_user;
}
SEXP rmodb_userId(SEXP r_conn_ref, SEXP r_name_or_email)
{
stored_conn *sconn;
modb_ref modb;
const char *search = 0;
int is_email = 0;
size_t idx = 0;
struct user_t *user = 0;
SEXP r_user_id;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
search = Rf_translateCharUTF8(STRING_ELT(r_name_or_email, 0));
for (idx = 0; idx < strlen(search); idx++) {
if (*(search + idx) == '@') {
is_email = 1;
}
}
if (!is_email && modbUserByName(sconn, &modb, search, 0, &user) <= 0) {
return Rf_ScalarInteger(-1);
}
if (is_email && modbUserByEmail(sconn, &modb, search, 0, &user) <= 0) {
return Rf_ScalarInteger(-1);
}
r_user_id = PROTECT(Rf_ScalarInteger((int)user->id));
freeUser(&user);
UNPROTECT(1);
return r_user_id;
}
SEXP rmodb_users(SEXP r_conn_ref, SEXP r_with_groups, SEXP r_with_deleted)
{
stored_conn *sconn;
modb_ref modb;
int with_deleted = 0, with_groups = 0;
struct user_t **users = 0;
size_t n_users = 0;
size_t idx;
SEXP r_users;
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_groups = Rf_asLogical(r_with_groups);
if (modbUserList(sconn, &modb, with_deleted, with_groups, &users, &n_users) <= 0) {
return R_NilValue;
}
r_users = PROTECT(Rf_allocVector(VECSXP, (int)n_users));
for (idx = 0; idx < n_users; idx++) {
SET_VECTOR_ELT(r_users, (int)idx, PROTECT(userToR(*(users + idx), with_groups)));
}
freeUsers(&users, n_users);
UNPROTECT((int)(1 + n_users));
return r_users;
}
SEXP rmodb_user(SEXP r_conn_ref, SEXP r_id, SEXP r_with_groups)
{
stored_conn *sconn;
modb_ref modb;
unsigned int user_id = 0;
int with_groups = 0;
struct user_t *user = 0;
SEXP r_user;
if ((sconn = getConnectionByRef(r_conn_ref)) == 0) {
Rf_error("invalid connection reference\n");
}
if (!modbFindUse(sconn, &modb)) {
Rf_error("invalid modb reference\n");
}
user_id = (unsigned int)Rf_asInteger(r_id);
with_groups = Rf_asLogical(r_with_groups);
if (modbUserById(sconn, &modb, user_id, with_groups, &user) <= 0) {
return R_NilValue;
}
r_user = PROTECT(userToR(user, with_groups));
freeUser(&user);
UNPROTECT(1);
return r_user;
}
SEXP rmodb_createUser(SEXP r_conn_ref, SEXP r_id, SEXP r_name, SEXP r_email)
{
stored_conn *sconn;
modb_ref modb;
struct user_t user;
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(&user, sizeof(struct user_t));
user.id = (unsigned int)Rf_asInteger(r_id);
user.username_c = Rf_translateCharUTF8(STRING_ELT(r_name, 0));
user.email_c = Rf_translateCharUTF8(STRING_ELT(r_email, 0));
res = modbUserCreate(sconn, &modb, &user);
return Rf_ScalarReal((double)res);
}
SEXP rmodb_deleteUser(SEXP r_conn_ref, SEXP r_id)
{
stored_conn *sconn;
modb_ref modb;
unsigned int user_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");
}
user_id = (unsigned int)Rf_asInteger(r_id);
return Rf_ScalarLogical(modbUserDelete(sconn, &modb, user_id));
}

17
src/R_modb_users.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef H__R_MODB_USERS__
#define H__R_MODB_USERS__
#include <Rinternals.h>
#include "modb_users.h"
SEXP userToR(struct user_t *user, int with_groups);
SEXP rmodb_userId(SEXP r_conn_ref, SEXP r_name_or_email);
SEXP rmodb_users(SEXP r_conn_ref, SEXP r_with_groups, SEXP r_with_deleted);
SEXP rmodb_user(SEXP r_conn_ref, SEXP r_id, SEXP r_with_groups);
SEXP rmodb_createUser(SEXP r_conn_ref, SEXP r_id, SEXP r_name, SEXP r_email);
SEXP rmodb_deleteUser(SEXP r_conn_ref, SEXP r_id);
#endif // H__R_MODB_USERS__

115
src/R_timestamp.c Normal file
View File

@@ -0,0 +1,115 @@
#define __USE_MISC
#include <time.h>
#include "R_timestamp.h"
SEXP R_Timestamp(int64_t ts)
{
SEXP r_ts;
SEXP r_class;
SEXP r_tzone;
if (ts == 0) {
return(Rf_ScalarReal(R_NaReal));
}
r_ts = PROTECT(Rf_ScalarReal((double)ts));
r_class = PROTECT(Rf_allocVector(STRSXP, 2));
SET_STRING_ELT(r_class, 0, PROTECT(Rf_mkChar("POSIXct")));
SET_STRING_ELT(r_class, 1, PROTECT(Rf_mkChar("POSIXt")));
r_tzone = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_tzone, 0, PROTECT(Rf_mkChar("")));
Rf_setAttrib(r_ts, R_ClassSymbol, r_class);
Rf_setAttrib(r_ts, Rf_install("tzone"), r_tzone);
UNPROTECT(1 + 3 + 2);
return r_ts;
}
SEXP R_TimestampExt(int64_t ts)
{
SEXP r_ts;
SEXP r_names;
SEXP r_zone;
SEXP r_class;
SEXP r_tzone;
struct tm *tmval;
tmval = localtime((time_t *)&ts);
r_zone = PROTECT(Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(r_zone, 0, PROTECT(Rf_mkChar(tmval->tm_zone)));
r_ts = PROTECT(Rf_allocVector(VECSXP, 11));
SET_VECTOR_ELT(r_ts, 0, PROTECT(Rf_ScalarInteger(tmval->tm_sec)));
SET_VECTOR_ELT(r_ts, 1, PROTECT(Rf_ScalarInteger(tmval->tm_min)));
SET_VECTOR_ELT(r_ts, 2, PROTECT(Rf_ScalarInteger(tmval->tm_hour)));
SET_VECTOR_ELT(r_ts, 3, PROTECT(Rf_ScalarInteger(tmval->tm_mday)));
SET_VECTOR_ELT(r_ts, 4, PROTECT(Rf_ScalarInteger(tmval->tm_mon)));
SET_VECTOR_ELT(r_ts, 5, PROTECT(Rf_ScalarInteger(tmval->tm_year)));
SET_VECTOR_ELT(r_ts, 6, PROTECT(Rf_ScalarInteger(tmval->tm_wday)));
SET_VECTOR_ELT(r_ts, 7, PROTECT(Rf_ScalarInteger(tmval->tm_yday)));
SET_VECTOR_ELT(r_ts, 8, PROTECT(Rf_ScalarInteger(tmval->tm_isdst)));
SET_VECTOR_ELT(r_ts, 9, r_zone);
SET_VECTOR_ELT(r_ts, 10, PROTECT(Rf_ScalarInteger((int)tmval->tm_gmtoff)));
r_names = PROTECT(Rf_allocVector(STRSXP, 11));
SET_STRING_ELT(r_names, 0, PROTECT(Rf_mkChar("sec")));
SET_STRING_ELT(r_names, 1, PROTECT(Rf_mkChar("min")));
SET_STRING_ELT(r_names, 2, PROTECT(Rf_mkChar("hour")));
SET_STRING_ELT(r_names, 3, PROTECT(Rf_mkChar("mday")));
SET_STRING_ELT(r_names, 4, PROTECT(Rf_mkChar("mon")));
SET_STRING_ELT(r_names, 5, PROTECT(Rf_mkChar("year")));
SET_STRING_ELT(r_names, 6, PROTECT(Rf_mkChar("wday")));
SET_STRING_ELT(r_names, 7, PROTECT(Rf_mkChar("yday")));
SET_STRING_ELT(r_names, 8, PROTECT(Rf_mkChar("isdst")));
SET_STRING_ELT(r_names, 9, PROTECT(Rf_mkChar("zone")));
SET_STRING_ELT(r_names, 10, PROTECT(Rf_mkChar("gmtoff")));
r_class = PROTECT(Rf_allocVector(STRSXP, 2));
SET_STRING_ELT(r_class, 0, PROTECT(Rf_mkChar("POSIXlt")));
SET_STRING_ELT(r_class, 1, PROTECT(Rf_mkChar("POSIXt")));
r_tzone = PROTECT(Rf_allocVector(STRSXP, 2));
SET_STRING_ELT(r_tzone, 0, PROTECT(Rf_mkChar("")));
SET_STRING_ELT(r_tzone, 1, PROTECT(Rf_mkChar(tmval->tm_zone)));
Rf_setAttrib(r_ts, R_NamesSymbol, r_names);
Rf_setAttrib(r_ts, R_ClassSymbol, r_class);
Rf_setAttrib(r_ts, Rf_install("tzone"), r_tzone);
UNPROTECT(2 + 11 + 12 + 3 + 3);
return r_ts;
}
int64_t R_TimestampUnix(SEXP r_ts)
{
return (int64_t)(Rf_asReal(VECTOR_ELT(r_ts, 0)) / 1);
}
int64_t R_TimestampExtUnix(SEXP r_ts)
{
time_t tunix;
struct tm tmval;
tmval.tm_sec = Rf_asInteger(VECTOR_ELT(r_ts, 0));
tmval.tm_min = Rf_asInteger(VECTOR_ELT(r_ts, 1));
tmval.tm_hour = Rf_asInteger(VECTOR_ELT(r_ts, 2));
tmval.tm_mday = Rf_asInteger(VECTOR_ELT(r_ts, 3));
tmval.tm_mon = Rf_asInteger(VECTOR_ELT(r_ts, 4));
tmval.tm_year = Rf_asInteger(VECTOR_ELT(r_ts, 5));
tmval.tm_wday = Rf_asInteger(VECTOR_ELT(r_ts, 6));
tmval.tm_yday = Rf_asInteger(VECTOR_ELT(r_ts, 7));
tmval.tm_isdst = Rf_asInteger(VECTOR_ELT(r_ts, 8));
tmval.tm_zone = Rf_translateCharUTF8(STRING_ELT(VECTOR_ELT(r_ts, 9), 0));
tmval.tm_gmtoff = Rf_asInteger(VECTOR_ELT(r_ts, 10));
tunix = mktime(&tmval);
return tunix;
}

13
src/R_timestamp.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef H__R_TIMESTAMP__
#define H__R_TIMESTAMP__
#include <Rinternals.h>
#include <stdint.h>
SEXP R_Timestamp(int64_t ts);
SEXP R_TimestampExt(int64_t ts);
int64_t R_TimestampUnix(SEXP r_ts);
int64_t R_TimestampExtUnix(SEXP r_ts);
#endif // H__R_TIMESTAMP__