Skip to content

Commit

Permalink
Added test cases for SODA bulk insert and PL/SQL execution row counts.
Browse files Browse the repository at this point in the history
  • Loading branch information
anthony-tuininga committed Apr 25, 2019
1 parent edfa9bd commit e5d8944
Show file tree
Hide file tree
Showing 2 changed files with 321 additions and 0 deletions.
212 changes: 212 additions & 0 deletions test/TestSodaColl.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,80 @@ int dpiTest__insertDoc(dpiTestCase *testCase, dpiSodaDb *db,
}


//-----------------------------------------------------------------------------
// dpiTest__insertManyDocs()
// Create a set of documents and insert it into the collection using
// dpiSodaColl_insertMany(). Verifies the content if required.
//-----------------------------------------------------------------------------
int dpiTest__insertManyDocs(dpiTestCase *testCase, dpiSodaDb *db,
dpiSodaColl *coll, uint32_t numDocs, const char **content,
dpiSodaDoc **insertedDocs)
{
uint64_t origDocCount, docCount;
dpiSodaOperOptions options;
dpiContext *context;
dpiSodaDoc **docs;
uint32_t i;

// get original document count
if (dpiSodaColl_getDocCount(coll, NULL, DPI_SODA_FLAGS_DEFAULT,
&origDocCount) < 0)
return dpiTestCase_setFailedFromError(testCase);

// create documents for each of the contents provided
docs = malloc(numDocs * sizeof(dpiSodaDoc*));
if (!docs)
return dpiTestCase_setFailed(testCase, "Out of memory!");
for (i = 0; i < numDocs; i++) {
if (dpiSodaDb_createDocument(db, NULL, 0, content[i],
strlen(content[i]), NULL, 0, DPI_SODA_FLAGS_DEFAULT,
&docs[i]) < 0)
return dpiTestCase_setFailedFromError(testCase);
}

// perform bulk insert
if (dpiSodaColl_insertMany(coll, numDocs, docs,
DPI_SODA_FLAGS_ATOMIC_COMMIT, insertedDocs) < 0)
return dpiTestCase_setFailedFromError(testCase);

// clean up created documents
for (i = 0; i < numDocs; i++)
dpiSodaDoc_release(docs[i]);
free(docs);

// get document count and verify it matches expectations
if (dpiSodaColl_getDocCount(coll, NULL, DPI_SODA_FLAGS_DEFAULT,
&docCount) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiTestCase_expectUintEqual(testCase, docCount,
origDocCount + numDocs) < 0)
return DPI_FAILURE;

// if result documents are returned, verify that the contents stored match
// what was inserted
if (insertedDocs) {

// initialize operation options
dpiTestSuite_getContext(&context);
if (dpiContext_initSodaOperOptions(context, &options) < 0)
return dpiTestCase_setFailedFromError(testCase);

// verify content for each result document returned
for (i = 0; i < numDocs; i++) {
if (dpiSodaDoc_getKey(insertedDocs[i], &options.key,
&options.keyLength) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiTest__verifyContent(testCase, coll, &options,
content[i]) < 0)
return DPI_FAILURE;
}

}

return DPI_SUCCESS;
}


//-----------------------------------------------------------------------------
// dpiTest_2600_nullHandle()
// Call all public collection functions with NULL handle and verify that the
Expand Down Expand Up @@ -145,6 +219,9 @@ int dpiTest_2600_nullHandle(dpiTestCase *testCase, dpiTestParams *params)
if (dpiTestCase_expectError(testCase, expectedError) < 0)
return DPI_FAILURE;
dpiSodaColl_insertOne(NULL, NULL, DPI_SODA_FLAGS_DEFAULT, NULL);
if (dpiTestCase_expectError(testCase, expectedError) < 0)
return DPI_FAILURE;
dpiSodaColl_insertMany(NULL, 0, NULL, DPI_SODA_FLAGS_DEFAULT, NULL);
if (dpiTestCase_expectError(testCase, expectedError) < 0)
return DPI_FAILURE;
dpiSodaColl_release(NULL);
Expand Down Expand Up @@ -976,6 +1053,137 @@ int dpiTest_2613_verifyDocsWithLargeBytes(dpiTestCase *testCase,
}


//-----------------------------------------------------------------------------
// dpiTest_2614_verifyInsertManyWorksAsExpected()
// Verify dpiSodaColl_insertMany() works as expected. Insert a set of docs
// and perform counts to verify the right number of documents is being
// returned.
//-----------------------------------------------------------------------------
int dpiTest_2614_verifyInsertManyWorksAsExpected(dpiTestCase *testCase,
dpiTestParams *params)
{
const char *contents[4] = {
"{\"test1\" : \"2614 content1\"}",
"{\"test2\" : \"2614 content2\"}",
"{\"test3\" : \"2614 content3\"}",
"{\"test4\" : \"2614 content4\"}"
};
const char *collName = "ODPIC_COLL_2614";
dpiSodaDoc **insertedDocs;
uint32_t numDocs = 4;
uint64_t docCount;
dpiSodaColl *coll;
dpiSodaDb *db;

// get SODA database (Oracle Client 18.5 required for bulk insert)
if (dpiTestCase_setSkippedIfVersionTooOld(testCase, 0, 18, 5) < 0)
return DPI_FAILURE;
if (dpiTestCase_getSodaDb(testCase, &db) < 0)
return DPI_FAILURE;

// create SODA collection
if (dpiSodaDb_createCollection(db, collName, strlen(collName), NULL, 0,
DPI_SODA_FLAGS_DEFAULT, &coll) < 0)
return dpiTestCase_setFailedFromError(testCase);

// remove any documents that may already exist due to previous failures
if (dpiSodaColl_remove(coll, NULL, DPI_SODA_FLAGS_ATOMIC_COMMIT,
&docCount) < 0)
return dpiTestCase_setFailedFromError(testCase);

// insert documents and verify contents
insertedDocs = malloc(numDocs * sizeof(dpiSodaDoc*));
if (!insertedDocs)
return dpiTestCase_setFailed(testCase, "Out of memory!");
if (dpiTest__insertManyDocs(testCase, db, coll, numDocs, contents,
insertedDocs) < 0)
return DPI_FAILURE;
free(insertedDocs);

// insert documents a second time without verifying contents
if (dpiTest__insertManyDocs(testCase, db, coll, numDocs, contents,
NULL) < 0)
return DPI_FAILURE;

// cleanup
if (dpiTestCase_cleanupSodaColl(testCase, coll) < 0)
return DPI_FAILURE;
if (dpiSodaDb_release(db) < 0)
return dpiTestCase_setFailedFromError(testCase);

return DPI_SUCCESS;
}


//-----------------------------------------------------------------------------
// dpiTest_2615_testInsertManyWithInvalidJson()
// Try to insert invalid JSON values into a SODA collection using
// dpiSodaColl_insertMany() and verify that it throws an error.
//-----------------------------------------------------------------------------
int dpiTest_2615_testInsertManyWithInvalidJson(dpiTestCase *testCase,
dpiTestParams *params)
{
const char *contents[5] = {
"{\"test1\" : \"2615 content1\"}",
"{\"test2\" : \"2615 content2\"}",
"{\"test3\" : \"2615 content3\"}",
"{\"test4 : 2615 content4\"}",
"{\"test5\" : \"2615 content5\"}",
};
const char *collName = "ODPIC_COLL_2615";
uint32_t i, numDocs = 5;
dpiErrorInfo errorInfo;
dpiSodaColl *coll;
dpiSodaDoc **docs;
dpiSodaDb *db;

// get SODA database (Oracle Client 18.5 required for bulk insert)
// get SODA database
if (dpiTestCase_setSkippedIfVersionTooOld(testCase, 0, 18, 5) < 0)
return DPI_FAILURE;
if (dpiTestCase_getSodaDb(testCase, &db) < 0)
return DPI_FAILURE;

// create SODA collection
if (dpiSodaDb_createCollection(db, collName, strlen(collName), NULL, 0,
DPI_SODA_FLAGS_DEFAULT, &coll) < 0)
return dpiTestCase_setFailedFromError(testCase);

// insert SODA documents and verify it fails
docs = malloc(numDocs * sizeof(dpiSodaDoc*));
if (!docs)
return dpiTestCase_setFailed(testCase, "Out of memory!");
for (i = 0; i < numDocs; i++) {
if (dpiSodaDb_createDocument(db, NULL, 0, contents[i],
strlen(contents[i]), NULL, 0, DPI_SODA_FLAGS_DEFAULT,
&docs[i]) < 0)
return dpiTestCase_setFailedFromError(testCase);
}
dpiSodaColl_insertMany(coll, numDocs, docs, DPI_SODA_FLAGS_ATOMIC_COMMIT,
NULL);
if (dpiTestCase_expectError(testCase, "ORA-02290:") < 0)
return DPI_FAILURE;

// verify offset is accurate
dpiTestSuite_getErrorInfo(&errorInfo);
if (dpiTestCase_expectIntEqual(testCase, errorInfo.offset, 3) < 0)
return DPI_FAILURE;

// cleanup
for (i = 0; i < numDocs; i++) {
if (dpiSodaDoc_release(docs[i]) < 0)
return dpiTestCase_setFailedFromError(testCase);
}
free(docs);
if (dpiTestCase_cleanupSodaColl(testCase, coll) < 0)
return DPI_FAILURE;
if (dpiSodaDb_release(db) < 0)
return dpiTestCase_setFailedFromError(testCase);

return DPI_SUCCESS;
}


//-----------------------------------------------------------------------------
// main()
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1010,5 +1218,9 @@ int main(int argc, char **argv)
"dpiSodaColl_find() with skip and limit");
dpiTestSuite_addCase(dpiTest_2613_verifyDocsWithLargeBytes,
"verify documents with large data");
dpiTestSuite_addCase(dpiTest_2614_verifyInsertManyWorksAsExpected,
"dpiSodaColl_insertMany() with valid parameters");
dpiTestSuite_addCase(dpiTest_2615_testInsertManyWithInvalidJson,
"dpiSodaColl_insertMany() with invalid JSON");
return dpiTestSuite_run();
}
109 changes: 109 additions & 0 deletions test/TestStatements.c
Original file line number Diff line number Diff line change
Expand Up @@ -1660,6 +1660,113 @@ int dpiTest_1134_bindStmtToItselfAndVerify(dpiTestCase *testCase,
}


//-----------------------------------------------------------------------------
// dpiTest_1135_verifyRowCountWithPlSqlStmt()
// Prepare any PL/SQL statement; call dpiStmt_executeMany() with an array of
// data; call dpiStmt_getRowCount() and verify that the row count returned
// matches expectations (no error).
//-----------------------------------------------------------------------------
int dpiTest_1135_verifyRowCountWithPlSqlStmt(dpiTestCase *testCase,
dpiTestParams *params)
{
const char *deleteSql =
"begin delete from TestTempTable where IntCol < :1; end;";
const char *insertSql =
"begin insert into TestTempTable values (:1, :2); end;";
const char *truncateSql = "truncate table TestTempTable";
dpiData *intData, *strData;
uint32_t numRows = 5, i;
dpiVar *intVar, *strVar;
uint64_t rowCount;
char buffer[100];
dpiConn *conn;
dpiStmt *stmt;

// truncate table
if (dpiTestCase_getConnection(testCase, &conn) < 0)
return DPI_FAILURE;
if (dpiConn_prepareStmt(conn, 0, truncateSql, strlen(truncateSql), NULL, 0,
&stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_execute(stmt, DPI_MODE_EXEC_DEFAULT, NULL) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_release(stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);

// prepare and bind insert statement
if (dpiConn_prepareStmt(conn, 0, insertSql, strlen(insertSql), NULL, 0,
&stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiConn_newVar(conn, DPI_ORACLE_TYPE_NUMBER, DPI_NATIVE_TYPE_INT64,
numRows, 0, 0, 0, NULL, &intVar, &intData) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_bindByPos(stmt, 1, intVar) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiConn_newVar(conn, DPI_ORACLE_TYPE_VARCHAR, DPI_NATIVE_TYPE_BYTES,
numRows, 100, 1, 0, NULL, &strVar, &strData) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_bindByPos(stmt, 2, strVar) < 0)
return dpiTestCase_setFailedFromError(testCase);

// populate some dummy data
for (i = 0; i < numRows; i++) {
dpiData_setInt64(&intData[i], i + 1);
sprintf(buffer, "Dummy data %d", i + 1);
if (dpiVar_setFromBytes(strVar, i, buffer, strlen(buffer)) < 0)
return dpiTestCase_setFailedFromError(testCase);
}

// perform insert and verify row count
if (dpiStmt_executeMany(stmt, DPI_MODE_EXEC_DEFAULT, numRows) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_getRowCount(stmt, &rowCount) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiTestCase_expectUintEqual(testCase, rowCount, numRows) < 0)
return DPI_FAILURE;

// cleanup
if (dpiStmt_release(stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiVar_release(intVar) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiVar_release(strVar) < 0)
return dpiTestCase_setFailedFromError(testCase);

// prepare and bind delete statement
numRows = 2;
if (dpiConn_prepareStmt(conn, 0, deleteSql, strlen(deleteSql), NULL, 0,
&stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiConn_newVar(conn, DPI_ORACLE_TYPE_NUMBER, DPI_NATIVE_TYPE_INT64,
numRows, 0, 0, 0, NULL, &intVar, &intData) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_bindByPos(stmt, 1, intVar) < 0)
return dpiTestCase_setFailedFromError(testCase);

// set up bind data
dpiData_setInt64(&intData[0], 2);
dpiData_setInt64(&intData[1], 5);

// perform delete and verify row count is as expected; note that the number
// of rows actually deleted by the PL/SQL statement is 4, but the row count
// returned by PL/SQL will always match the number of iterations executed
if (dpiStmt_executeMany(stmt, DPI_MODE_EXEC_DEFAULT, numRows) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_getRowCount(stmt, &rowCount) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiTestCase_expectUintEqual(testCase, rowCount, numRows) < 0)
return DPI_FAILURE;

// clean up
if (dpiStmt_release(stmt) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiVar_release(intVar) < 0)
return dpiTestCase_setFailedFromError(testCase);

return DPI_SUCCESS;
}


//-----------------------------------------------------------------------------
// main()
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1736,5 +1843,7 @@ int main(int argc, char **argv)
"verify getQueryInfo returns no metadata if mode is parse only");
dpiTestSuite_addCase(dpiTest_1134_bindStmtToItselfAndVerify,
"bind a stmt to itself and verify it throws an appropriate error");
dpiTestSuite_addCase(dpiTest_1135_verifyRowCountWithPlSqlStmt,
"dpiStmt_executeMany() with PL/SQL statement row count");
return dpiTestSuite_run();
}

0 comments on commit e5d8944

Please sign in to comment.