#include "dpiImpl.h"
static int dpiSodaDb__checkConnected(dpiSodaDb *db, const char *fnName,
dpiError *error)
{
if (dpiGen__startPublicFn(db, DPI_HTYPE_SODA_DB, fnName, error) < 0)
return DPI_FAILURE;
if (!db->conn->handle || db->conn->closing)
return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED);
return DPI_SUCCESS;
}
static int dpiSodaDb__createDocument(dpiSodaDb *db, const char *key,
uint32_t keyLength, const char *content, uint32_t contentLength,
const char *mediaType, uint32_t mediaTypeLength, dpiSodaDoc **doc,
dpiError *error)
{
dpiSodaDoc *tempDoc;
int detectEncoding;
if (dpiSodaDoc__allocate(db, NULL, &tempDoc, error) < 0)
return DPI_FAILURE;
if (key && keyLength > 0) {
if (dpiOci__attrSet(tempDoc->handle, DPI_OCI_HTYPE_SODA_DOCUMENT,
(void*) key, keyLength, DPI_OCI_ATTR_SODA_KEY, "set key",
error) < 0) {
dpiSodaDoc__free(tempDoc, error);
return DPI_FAILURE;
}
}
if (content && contentLength > 0) {
tempDoc->binaryContent = 1;
detectEncoding = 1;
if (dpiOci__attrSet(tempDoc->handle, DPI_OCI_HTYPE_SODA_DOCUMENT,
(void*) &detectEncoding, 0, DPI_OCI_ATTR_SODA_DETECT_JSON_ENC,
"set detect encoding", error) < 0) {
dpiSodaDoc__free(tempDoc, error);
return DPI_FAILURE;
}
if (dpiOci__attrSet(tempDoc->handle, DPI_OCI_HTYPE_SODA_DOCUMENT,
(void*) content, contentLength, DPI_OCI_ATTR_SODA_CONTENT,
"set content", error) < 0) {
dpiSodaDoc__free(tempDoc, error);
return DPI_FAILURE;
}
}
if (mediaType && mediaTypeLength > 0) {
if (dpiOci__attrSet(tempDoc->handle, DPI_OCI_HTYPE_SODA_DOCUMENT,
(void*) mediaType, mediaTypeLength,
DPI_OCI_ATTR_SODA_MEDIA_TYPE, "set media type", error) < 0) {
dpiSodaDoc__free(tempDoc, error);
return DPI_FAILURE;
}
}
*doc = tempDoc;
return DPI_SUCCESS;
}
static int dpiSodaDb__getCollectionNames(dpiSodaDb *db, void *cursorHandle,
uint32_t limit, dpiStringList *names, dpiError *error)
{
uint32_t numAllocatedStrings = 0, nameLength;
void *collectionHandle;
char *name;
while (names->numStrings < limit || limit == 0) {
if (dpiOci__sodaCollGetNext(db->conn, cursorHandle, &collectionHandle,
error) < 0)
return DPI_FAILURE;
if (!collectionHandle)
break;
if (dpiOci__attrGet(collectionHandle, DPI_OCI_HTYPE_SODA_COLLECTION,
(void*) &name, &nameLength, DPI_OCI_ATTR_SODA_COLL_NAME,
"get collection name", error) < 0) {
dpiOci__handleFree(collectionHandle, DPI_OCI_HTYPE_SODA_COLLECTION);
return DPI_FAILURE;
}
if (dpiStringList__addElement(names, name, nameLength,
&numAllocatedStrings, error) < 0) {
dpiOci__handleFree(collectionHandle, DPI_OCI_HTYPE_SODA_COLLECTION);
return DPI_FAILURE;
}
dpiOci__handleFree(collectionHandle, DPI_OCI_HTYPE_SODA_COLLECTION);
}
return DPI_SUCCESS;
}
void dpiSodaDb__free(dpiSodaDb *db, dpiError *error)
{
if (db->conn) {
dpiGen__setRefCount(db->conn, error, -1);
db->conn = NULL;
}
dpiUtils__freeMemory(db);
}
int dpiSodaDb_addRef(dpiSodaDb *db)
{
return dpiGen__addRef(db, DPI_HTYPE_SODA_DB, __func__);
}
int dpiSodaDb_createCollection(dpiSodaDb *db, const char *name,
uint32_t nameLength, const char *metadata, uint32_t metadataLength,
uint32_t flags, dpiSodaColl **coll)
{
dpiError error;
uint32_t mode;
void *handle;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, name)
DPI_CHECK_PTR_AND_LENGTH(db, metadata)
DPI_CHECK_PTR_NOT_NULL(db, coll)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (flags & DPI_SODA_FLAGS_CREATE_COLL_MAP)
mode |= DPI_OCI_SODA_COLL_CREATE_MAP;
if (dpiOci__sodaCollCreateWithMetadata(db, name, nameLength, metadata,
metadataLength, mode, &handle, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
if (dpiSodaColl__allocate(db, handle, coll, &error) < 0) {
dpiOci__handleFree(handle, DPI_OCI_HTYPE_SODA_COLLECTION);
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
}
return dpiGen__endPublicFn(db, DPI_SUCCESS, &error);
}
int dpiSodaDb_createDocument(dpiSodaDb *db, const char *key,
uint32_t keyLength, const char *content, uint32_t contentLength,
const char *mediaType, uint32_t mediaTypeLength, UNUSED uint32_t flags,
dpiSodaDoc **doc)
{
dpiError error;
int status;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, key)
DPI_CHECK_PTR_AND_LENGTH(db, content)
DPI_CHECK_PTR_AND_LENGTH(db, mediaType)
DPI_CHECK_PTR_NOT_NULL(db, doc)
status = dpiSodaDb__createDocument(db, key, keyLength, content,
contentLength, mediaType, mediaTypeLength, doc, &error);
return dpiGen__endPublicFn(db, status, &error);
}
int dpiSodaDb_createJsonDocument(dpiSodaDb *db, const char *key,
uint32_t keyLength, const dpiJsonNode *content, UNUSED uint32_t flags,
dpiSodaDoc **doc)
{
int status, jsonDesc;
uint32_t tempLength;
dpiSodaDoc *tempDoc;
void *jsonHandle;
dpiError error;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, key)
DPI_CHECK_PTR_NOT_NULL(db, doc)
if (dpiUtils__checkClientVersion(db->env->versionInfo, 23, 4, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
if (dpiSodaDb__createDocument(db, key, keyLength, NULL, 0, NULL, 0,
&tempDoc, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
if (content) {
jsonDesc = 1;
status = dpiOci__attrSet(tempDoc->handle, DPI_OCI_HTYPE_SODA_DOCUMENT,
&jsonDesc, 0, DPI_OCI_ATTR_SODA_JSON_DESC,
"set JSON descriptor flag", &error);
if (status == DPI_SUCCESS) {
status = dpiOci__attrGet(tempDoc->handle,
DPI_OCI_HTYPE_SODA_DOCUMENT, (void*) &jsonHandle,
&tempLength, DPI_OCI_ATTR_SODA_CONTENT,
"get JSON descriptor", &error);
}
if (status == DPI_SUCCESS)
status = dpiJson__allocate(db->conn, jsonHandle, &tempDoc->json,
&error);
if (status == DPI_SUCCESS)
status = dpiJson__setValue(tempDoc->json, content, &error);
if (status != DPI_SUCCESS) {
dpiSodaDoc__free(tempDoc, &error);
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
}
}
*doc = tempDoc;
return dpiGen__endPublicFn(db, DPI_SUCCESS, &error);
}
int dpiSodaDb_freeCollectionNames(dpiSodaDb *db, dpiStringList *names)
{
dpiError error;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(db, names)
dpiStringList__free(names);
return dpiGen__endPublicFn(db, DPI_SUCCESS, &error);
}
int dpiSodaDb_getCollections(dpiSodaDb *db, const char *startName,
uint32_t startNameLength, uint32_t flags, dpiSodaCollCursor **cursor)
{
dpiError error;
uint32_t mode;
void *handle;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, startName)
DPI_CHECK_PTR_NOT_NULL(db, cursor)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiOci__sodaCollList(db, startName, startNameLength, &handle, mode,
&error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
if (dpiSodaCollCursor__allocate(db, handle, cursor, &error) < 0) {
dpiOci__handleFree(handle, DPI_OCI_HTYPE_SODA_COLL_CURSOR);
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
}
return dpiGen__endPublicFn(db, DPI_SUCCESS, &error);
}
int dpiSodaDb_getCollectionNames(dpiSodaDb *db, const char *startName,
uint32_t startNameLength, uint32_t limit, uint32_t flags,
dpiStringList *names)
{
dpiError error;
uint32_t mode;
void *handle;
int status;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, startName)
DPI_CHECK_PTR_NOT_NULL(db, names)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiOci__sodaCollList(db, startName, startNameLength, &handle, mode,
&error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
memset(names, 0, sizeof(dpiStringList));
status = dpiSodaDb__getCollectionNames(db, handle, limit, names, &error);
dpiOci__handleFree(handle, DPI_OCI_HTYPE_SODA_COLL_CURSOR);
if (status < 0)
dpiStringList__free(names);
return dpiGen__endPublicFn(db, status, &error);
}
int dpiSodaDb_openCollection(dpiSodaDb *db, const char *name,
uint32_t nameLength, uint32_t flags, dpiSodaColl **coll)
{
dpiError error;
uint32_t mode;
void *handle;
if (dpiSodaDb__checkConnected(db, __func__, &error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(db, name)
DPI_CHECK_PTR_NOT_NULL(db, coll)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiOci__sodaCollOpen(db, name, nameLength, mode, &handle,
&error) < 0)
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
*coll = NULL;
if (handle) {
if (dpiSodaColl__allocate(db, handle, coll, &error) < 0) {
dpiOci__handleFree(handle, DPI_OCI_HTYPE_SODA_COLLECTION);
return dpiGen__endPublicFn(db, DPI_FAILURE, &error);
}
}
return dpiGen__endPublicFn(db, DPI_SUCCESS, &error);
}
int dpiSodaDb_release(dpiSodaDb *db)
{
return dpiGen__release(db, DPI_HTYPE_SODA_DB, __func__);
}