#include "dpiImpl.h"
static int dpiSodaColl__populateOperOptions(dpiSodaColl *coll,
const dpiSodaOperOptions *options, void *handle, dpiError *error);
int dpiSodaColl__allocate(dpiSodaDb *db, void *handle, dpiSodaColl **coll,
dpiError *error)
{
uint8_t sqlType, contentType;
dpiSodaColl *tempColl;
if (dpiOci__attrGet(handle, DPI_OCI_HTYPE_SODA_COLLECTION,
(void*) &sqlType, 0, DPI_OCI_ATTR_SODA_CTNT_SQL_TYPE,
"get content sql type", error) < 0)
return DPI_FAILURE;
if (dpiGen__allocate(DPI_HTYPE_SODA_COLL, db->env, (void**) &tempColl,
error) < 0)
return DPI_FAILURE;
dpiGen__setRefCount(db, error, 1);
tempColl->db = db;
tempColl->handle = handle;
if (sqlType == DPI_SQLT_BLOB) {
tempColl->binaryContent = 1;
contentType = 0;
dpiOci__attrGet(handle, DPI_OCI_HTYPE_SODA_COLLECTION,
(void*) &contentType, 0, DPI_OCI_ATTR_SODA_CTNT_FORMAT,
NULL, error);
if (contentType == DPI_OCI_JSON_FORMAT_OSON)
tempColl->binaryContent = 0;
}
*coll = tempColl;
return DPI_SUCCESS;
}
static int dpiSodaColl__check(dpiSodaColl *coll, const char *fnName,
dpiError *error)
{
if (dpiGen__startPublicFn(coll, DPI_HTYPE_SODA_COLL, fnName, error) < 0)
return DPI_FAILURE;
if (!coll->db->conn->handle || coll->db->conn->closing)
return dpiError__set(error, "check connection", DPI_ERR_NOT_CONNECTED);
return DPI_SUCCESS;
}
static int dpiSodaColl__createOperOptions(dpiSodaColl *coll,
const dpiSodaOperOptions *options, void **handle, dpiError *error)
{
dpiSodaOperOptions localOptions;
if (!options) {
dpiContext__initSodaOperOptions(&localOptions);
options = &localOptions;
}
if (dpiOci__handleAlloc(coll->env->handle, handle,
DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
"allocate SODA operation options handle", error) < 0)
return DPI_FAILURE;
if (dpiSodaColl__populateOperOptions(coll, options, *handle, error) < 0) {
dpiOci__handleFree(*handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
return DPI_FAILURE;
}
return DPI_SUCCESS;
}
static int dpiSodaColl__find(dpiSodaColl *coll,
const dpiSodaOperOptions *options, uint32_t flags,
dpiSodaDocCursor **cursor, dpiSodaDoc **doc, dpiError *error)
{
uint32_t ociMode, returnHandleType, ociFlags;
void *optionsHandle, *ociReturnHandle;
int status;
ociMode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
ociMode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
error) < 0)
return DPI_FAILURE;
if (coll->binaryContent || coll->env->context->sodaUseJsonDesc) {
ociFlags = DPI_OCI_SODA_AS_STORED;
} else {
ociFlags = DPI_OCI_SODA_AS_AL32UTF8;
}
if (cursor) {
*cursor = NULL;
status = dpiOci__sodaFind(coll, optionsHandle, ociFlags, ociMode,
&ociReturnHandle, error);
} else {
*doc = NULL;
status = dpiOci__sodaFindOne(coll, optionsHandle, ociFlags, ociMode,
&ociReturnHandle, error);
}
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
if (status < 0)
return DPI_FAILURE;
if (cursor) {
status = dpiSodaDocCursor__allocate(coll, ociReturnHandle, cursor,
error);
returnHandleType = DPI_OCI_HTYPE_SODA_DOC_CURSOR;
} else if (ociReturnHandle) {
status = dpiSodaDoc__allocate(coll->db, ociReturnHandle, doc, error);
returnHandleType = DPI_OCI_HTYPE_SODA_DOCUMENT;
}
if (status < 0)
dpiOci__handleFree(ociReturnHandle, returnHandleType);
return status;
}
void dpiSodaColl__free(dpiSodaColl *coll, dpiError *error)
{
if (coll->handle) {
dpiOci__handleFree(coll->handle, DPI_OCI_HTYPE_SODA_COLLECTION);
coll->handle = NULL;
}
if (coll->db) {
dpiGen__setRefCount(coll->db, error, -1);
coll->db = NULL;
}
dpiUtils__freeMemory(coll);
}
static int dpiSodaColl__getDocCount(dpiSodaColl *coll,
const dpiSodaOperOptions *options, uint32_t flags, uint64_t *count,
dpiError *error)
{
void *optionsHandle;
uint32_t ociMode;
int status;
ociMode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
ociMode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
error) < 0)
return DPI_FAILURE;
status = dpiOci__sodaDocCount(coll, optionsHandle, ociMode, count, error);
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
return status;
}
static int dpiSodaColl__insertMany(dpiSodaColl *coll, uint32_t numDocs,
void **docHandles, uint32_t flags, dpiSodaDoc **insertedDocs,
void *operOptionsHandle, dpiError *error)
{
void *outputOptionsHandle;
uint32_t i, j, mode;
uint64_t docCount;
int status;
if (dpiOci__handleAlloc(coll->env->handle, &outputOptionsHandle,
DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS,
"allocate SODA output options handle", error) < 0)
return DPI_FAILURE;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (operOptionsHandle) {
status = dpiOci__sodaBulkInsertAndGetWithOpts(coll, docHandles,
numDocs, operOptionsHandle, outputOptionsHandle, mode, error);
dpiOci__handleFree(operOptionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
} else if (insertedDocs) {
status = dpiOci__sodaBulkInsertAndGet(coll, docHandles, numDocs,
outputOptionsHandle, mode, error);
} else {
status = dpiOci__sodaBulkInsert(coll, docHandles, numDocs,
outputOptionsHandle, mode, error);
}
if (status < 0) {
dpiOci__attrGet(outputOptionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS,
(void*) &docCount, 0, DPI_OCI_ATTR_SODA_DOC_COUNT,
NULL, error);
error->buffer->offset = (uint32_t) docCount;
}
dpiOci__handleFree(outputOptionsHandle, DPI_OCI_HTYPE_SODA_OUTPUT_OPTIONS);
if (insertedDocs && status < 0) {
for (i = 0; i < numDocs; i++) {
if (docHandles[i]) {
dpiOci__handleFree(docHandles[i], DPI_OCI_HTYPE_SODA_DOCUMENT);
docHandles[i] = NULL;
}
}
}
if (status < 0)
return DPI_FAILURE;
if (insertedDocs) {
for (i = 0; i < numDocs; i++) {
if (dpiSodaDoc__allocate(coll->db, docHandles[i], &insertedDocs[i],
error) < 0) {
for (j = 0; j < i; j++) {
dpiSodaDoc__free(insertedDocs[j], error);
insertedDocs[j] = NULL;
}
for (j = i; j < numDocs; j++) {
dpiOci__handleFree(docHandles[i],
DPI_OCI_HTYPE_SODA_DOCUMENT);
}
return DPI_FAILURE;
}
}
}
return DPI_SUCCESS;
}
int dpiSodaColl__listIndexes(dpiSodaColl *coll, uint32_t flags,
dpiStringList *list, dpiError *error)
{
uint32_t ptrLen, numAllocatedStrings = 0;
void *listHandle = NULL;
void **elem, *elemInd;
int32_t i, listLen;
int exists, status;
char *ptr;
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 13,
21, 3, error) < 0)
return DPI_FAILURE;
if (dpiOci__sodaIndexList(coll, flags, &listHandle, error) < 0)
return DPI_FAILURE;
status = dpiOci__collSize(coll->db->conn, listHandle, &listLen, error);
for (i = 0; i < listLen && status == DPI_SUCCESS; i++) {
status = dpiOci__collGetElem(coll->db->conn, listHandle, i, &exists,
(void**) &elem, &elemInd, error);
if (status < 0)
break;
status = dpiOci__stringPtr(coll->env->handle, *elem, &ptr);
if (status < 0)
break;
status = dpiOci__stringSize(coll->env->handle, *elem, &ptrLen);
if (status < 0)
break;
status = dpiStringList__addElement(list, ptr, ptrLen,
&numAllocatedStrings, error);
}
if (listHandle)
dpiOci__objectFree(coll->env->handle, listHandle, 0, error);
return status;
}
static int dpiSodaColl__populateOperOptions(dpiSodaColl *coll,
const dpiSodaOperOptions *options, void *handle, dpiError *error)
{
if (options->numKeys > 0) {
if (dpiOci__sodaOperKeysSet(options, handle, error) < 0)
return DPI_FAILURE;
}
if (options->keyLength > 0) {
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) options->key, options->keyLength,
DPI_OCI_ATTR_SODA_KEY, "set key", error) < 0)
return DPI_FAILURE;
}
if (options->versionLength > 0) {
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) options->version, options->versionLength,
DPI_OCI_ATTR_SODA_VERSION, "set version", error) < 0)
return DPI_FAILURE;
}
if (options->filterLength > 0) {
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) options->filter, options->filterLength,
DPI_OCI_ATTR_SODA_FILTER, "set filter", error) < 0)
return DPI_FAILURE;
}
if (options->skip > 0) {
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) &options->skip, 0, DPI_OCI_ATTR_SODA_SKIP,
"set skip count", error) < 0)
return DPI_FAILURE;
}
if (options->limit > 0) {
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) &options->limit, 0, DPI_OCI_ATTR_SODA_LIMIT,
"set limit", error) < 0)
return DPI_FAILURE;
}
if (options->fetchArraySize > 0) {
if (dpiUtils__checkClientVersion(coll->env->versionInfo, 19, 5,
error) < 0)
return DPI_FAILURE;
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) &options->fetchArraySize, 0,
DPI_OCI_ATTR_SODA_FETCH_ARRAY_SIZE, "set fetch array size",
error) < 0)
return DPI_FAILURE;
}
if (options->hintLength > 0) {
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 11,
21, 3, error) < 0)
return DPI_FAILURE;
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) options->hint, options->hintLength,
DPI_OCI_ATTR_SODA_HINT, "set hint", error) < 0)
return DPI_FAILURE;
}
if (options->lock) {
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 11,
21, 3, error) < 0)
return DPI_FAILURE;
if (dpiOci__attrSet(handle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS,
(void*) &options->lock, 0, DPI_OCI_ATTR_SODA_LOCK, "set lock",
error) < 0)
return DPI_FAILURE;
}
return DPI_SUCCESS;
}
static int dpiSodaColl__remove(dpiSodaColl *coll,
const dpiSodaOperOptions *options, uint32_t flags, uint64_t *count,
dpiError *error)
{
void *optionsHandle;
uint32_t mode;
int status;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
error) < 0)
return DPI_FAILURE;
status = dpiOci__sodaRemove(coll, optionsHandle, mode, count, error);
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
return status;
}
static int dpiSodaColl__replace(dpiSodaColl *coll,
const dpiSodaOperOptions *options, dpiSodaDoc *doc, uint32_t flags,
int *replaced, dpiSodaDoc **replacedDoc, dpiError *error)
{
void *docHandle, *optionsHandle;
int status, dummyIsReplaced;
uint32_t mode;
if (!replaced)
replaced = &dummyIsReplaced;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
error) < 0)
return DPI_FAILURE;
docHandle = doc->handle;
if (!replacedDoc) {
status = dpiOci__sodaReplOne(coll, optionsHandle, docHandle, mode,
replaced, error);
} else {
*replacedDoc = NULL;
status = dpiOci__sodaReplOneAndGet(coll, optionsHandle, &docHandle,
mode, replaced, error);
if (status == 0 && docHandle) {
status = dpiSodaDoc__allocate(coll->db, docHandle, replacedDoc,
error);
if (status < 0)
dpiOci__handleFree(docHandle, DPI_OCI_HTYPE_SODA_DOCUMENT);
}
}
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
return status;
}
static int dpiSodaColl__save(dpiSodaColl *coll, dpiSodaDoc *doc,
uint32_t flags, dpiSodaDoc **savedDoc, void *optionsHandle,
dpiError *error)
{
void *docHandle;
uint32_t mode;
int status;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
docHandle = doc->handle;
if (!savedDoc) {
status = dpiOci__sodaSave(coll, docHandle, mode, error);
} else {
*savedDoc = NULL;
if (optionsHandle) {
status = dpiOci__sodaSaveAndGetWithOpts(coll, &docHandle,
optionsHandle, mode, error);
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
} else {
status = dpiOci__sodaSaveAndGet(coll, &docHandle, mode, error);
}
if (status == 0 && docHandle) {
status = dpiSodaDoc__allocate(coll->db, docHandle, savedDoc,
error);
if (status < 0)
dpiOci__handleFree(docHandle, DPI_OCI_HTYPE_SODA_DOCUMENT);
}
}
return status;
}
int dpiSodaColl_addRef(dpiSodaColl *coll)
{
return dpiGen__addRef(coll, DPI_HTYPE_SODA_COLL, __func__);
}
int dpiSodaColl_createIndex(dpiSodaColl *coll, const char *indexSpec,
uint32_t indexSpecLength, uint32_t flags)
{
dpiError error;
uint32_t mode;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(coll, indexSpec)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
status = dpiOci__sodaIndexCreate(coll, indexSpec, indexSpecLength, mode,
&error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_drop(dpiSodaColl *coll, uint32_t flags, int *isDropped)
{
int status, dummyIsDropped;
dpiError error;
uint32_t mode;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (!isDropped)
isDropped = &dummyIsDropped;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
status = dpiOci__sodaCollDrop(coll, isDropped, mode, &error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_dropIndex(dpiSodaColl *coll, const char *name,
uint32_t nameLength, uint32_t flags, int *isDropped)
{
int status, dummyIsDropped;
dpiError error;
uint32_t mode;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_AND_LENGTH(coll, name)
if (!isDropped)
isDropped = &dummyIsDropped;
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (flags & DPI_SODA_FLAGS_INDEX_DROP_FORCE)
mode |= DPI_OCI_SODA_INDEX_DROP_FORCE;
status = dpiOci__sodaIndexDrop(coll, name, nameLength, mode, isDropped,
&error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_find(dpiSodaColl *coll, const dpiSodaOperOptions *options,
uint32_t flags, dpiSodaDocCursor **cursor)
{
dpiError error;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, cursor)
if (dpiSodaColl__find(coll, options, flags, cursor, NULL, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
return dpiGen__endPublicFn(coll, DPI_SUCCESS, &error);
}
int dpiSodaColl_findOne(dpiSodaColl *coll, const dpiSodaOperOptions *options,
uint32_t flags, dpiSodaDoc **doc)
{
dpiError error;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, doc)
if (dpiSodaColl__find(coll, options, flags, NULL, doc, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
return dpiGen__endPublicFn(coll, DPI_SUCCESS, &error);
}
int dpiSodaColl_getDataGuide(dpiSodaColl *coll, uint32_t flags,
dpiSodaDoc **doc)
{
void *docHandle;
dpiError error;
uint32_t mode;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, doc)
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
if (dpiOci__sodaDataGuideGet(coll, &docHandle, mode, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (!docHandle) {
*doc = NULL;
} else if (dpiSodaDoc__allocate(coll->db, docHandle, doc, &error) < 0) {
dpiOci__handleFree(docHandle, DPI_OCI_HTYPE_SODA_DOCUMENT);
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
return dpiGen__endPublicFn(coll, DPI_SUCCESS, &error);
}
int dpiSodaColl_getDocCount(dpiSodaColl *coll,
const dpiSodaOperOptions *options, uint32_t flags, uint64_t *count)
{
dpiError error;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, count)
if (dpiSodaColl__getDocCount(coll, options, flags, count, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
return dpiGen__endPublicFn(coll, DPI_SUCCESS, &error);
}
int dpiSodaColl_getMetadata(dpiSodaColl *coll, const char **value,
uint32_t *valueLength)
{
dpiError error;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, value)
DPI_CHECK_PTR_NOT_NULL(coll, valueLength)
status = dpiOci__attrGet(coll->handle, DPI_OCI_HTYPE_SODA_COLLECTION,
(void*) value, valueLength, DPI_OCI_ATTR_SODA_COLL_DESCRIPTOR,
"get value", &error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_getName(dpiSodaColl *coll, const char **value,
uint32_t *valueLength)
{
dpiError error;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, value)
DPI_CHECK_PTR_NOT_NULL(coll, valueLength)
status = dpiOci__attrGet(coll->handle, DPI_OCI_HTYPE_SODA_COLLECTION,
(void*) value, valueLength, DPI_OCI_ATTR_SODA_COLL_NAME,
"get value", &error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_insertMany(dpiSodaColl *coll, uint32_t numDocs,
dpiSodaDoc **docs, uint32_t flags, dpiSodaDoc **insertedDocs)
{
return dpiSodaColl_insertManyWithOptions(coll, numDocs, docs, NULL, flags,
insertedDocs);
}
int dpiSodaColl_insertManyWithOptions(dpiSodaColl *coll, uint32_t numDocs,
dpiSodaDoc **docs, dpiSodaOperOptions *options, uint32_t flags,
dpiSodaDoc **insertedDocs)
{
void **docHandles, *optionsHandle = NULL;
dpiError error;
uint32_t i;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, docs)
if (numDocs == 0) {
dpiError__set(&error, "check num documents", DPI_ERR_ARRAY_SIZE_ZERO);
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
for (i = 0; i < numDocs; i++) {
if (dpiGen__checkHandle(docs[i], DPI_HTYPE_SODA_DOC, "check document",
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
if (dpiUtils__checkClientVersion(coll->env->versionInfo, 18, 5,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (insertedDocs && options) {
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 11,
21, 3, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
if (dpiUtils__allocateMemory(numDocs, sizeof(void*), 1,
"allocate document handles", (void**) &docHandles, &error) < 0) {
if (optionsHandle)
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
for (i = 0; i < numDocs; i++)
docHandles[i] = docs[i]->handle;
status = dpiSodaColl__insertMany(coll, numDocs, docHandles, flags,
insertedDocs, optionsHandle, &error);
dpiUtils__freeMemory(docHandles);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_insertOne(dpiSodaColl *coll, dpiSodaDoc *doc, uint32_t flags,
dpiSodaDoc **insertedDoc)
{
return dpiSodaColl_insertOneWithOptions(coll, doc, NULL, flags,
insertedDoc);
}
int dpiSodaColl_insertOneWithOptions(dpiSodaColl *coll, dpiSodaDoc *doc,
dpiSodaOperOptions *options, uint32_t flags, dpiSodaDoc **insertedDoc)
{
void *docHandle, *optionsHandle = NULL;
dpiError error;
uint32_t mode;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiGen__checkHandle(doc, DPI_HTYPE_SODA_DOC, "check document",
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (insertedDoc && options) {
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 11,
21, 3, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
docHandle = doc->handle;
if (!insertedDoc)
status = dpiOci__sodaInsert(coll, docHandle, mode, &error);
else {
if (options) {
status = dpiOci__sodaInsertAndGetWithOpts(coll, &docHandle,
optionsHandle, mode, &error);
dpiOci__handleFree(optionsHandle, DPI_OCI_HTYPE_SODA_OPER_OPTIONS);
} else {
status = dpiOci__sodaInsertAndGet(coll, &docHandle, mode, &error);
}
if (status == 0) {
status = dpiSodaDoc__allocate(coll->db, docHandle, insertedDoc,
&error);
if (status < 0)
dpiOci__handleFree(docHandle, DPI_OCI_HTYPE_SODA_DOCUMENT);
}
}
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_listIndexes(dpiSodaColl *coll, uint32_t flags,
dpiStringList *list)
{
dpiError error;
uint32_t mode;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, list)
memset(list, 0, sizeof(dpiStringList));
mode = DPI_OCI_DEFAULT;
if (flags & DPI_SODA_FLAGS_ATOMIC_COMMIT)
mode |= DPI_OCI_SODA_ATOMIC_COMMIT;
status = dpiSodaColl__listIndexes(coll, mode, list, &error);
if (status < 0)
dpiStringList__free(list);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_release(dpiSodaColl *coll)
{
return dpiGen__release(coll, DPI_HTYPE_SODA_COLL, __func__);
}
int dpiSodaColl_remove(dpiSodaColl *coll, const dpiSodaOperOptions *options,
uint32_t flags, uint64_t *count)
{
dpiError error;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
DPI_CHECK_PTR_NOT_NULL(coll, count)
if (dpiSodaColl__remove(coll, options, flags, count, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
return dpiGen__endPublicFn(coll, DPI_SUCCESS, &error);
}
int dpiSodaColl_replaceOne(dpiSodaColl *coll,
const dpiSodaOperOptions *options, dpiSodaDoc *doc, uint32_t flags,
int *replaced, dpiSodaDoc **replacedDoc)
{
dpiError error;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiGen__checkHandle(doc, DPI_HTYPE_SODA_DOC, "check document",
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
status = dpiSodaColl__replace(coll, options, doc, flags, replaced,
replacedDoc, &error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_save(dpiSodaColl *coll, dpiSodaDoc *doc, uint32_t flags,
dpiSodaDoc **savedDoc)
{
return dpiSodaColl_saveWithOptions(coll, doc, NULL, flags, savedDoc);
}
int dpiSodaColl_saveWithOptions(dpiSodaColl *coll, dpiSodaDoc *doc,
dpiSodaOperOptions *options, uint32_t flags, dpiSodaDoc **savedDoc)
{
void *optionsHandle = NULL;
dpiError error;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiGen__checkHandle(doc, DPI_HTYPE_SODA_DOC, "check document",
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiUtils__checkClientVersion(coll->env->versionInfo, 19, 9,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (savedDoc && options) {
if (dpiUtils__checkClientVersionMulti(coll->env->versionInfo, 19, 11,
21, 3, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiSodaColl__createOperOptions(coll, options, &optionsHandle,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
}
status = dpiSodaColl__save(coll, doc, flags, savedDoc, optionsHandle,
&error);
return dpiGen__endPublicFn(coll, status, &error);
}
int dpiSodaColl_truncate(dpiSodaColl *coll)
{
dpiError error;
int status;
if (dpiSodaColl__check(coll, __func__, &error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
if (dpiUtils__checkClientVersion(coll->env->versionInfo, 20, 1,
&error) < 0)
return dpiGen__endPublicFn(coll, DPI_FAILURE, &error);
status = dpiOci__sodaCollTruncate(coll, &error);
return dpiGen__endPublicFn(coll, status, &error);
}