Skip to content

Commit

Permalink
[AD 551] Adapt Primary Keys (#76)
Browse files Browse the repository at this point in the history
* SQLPrimaryKey using JNI

* odbc test failure fix

* add tests

* fix test failure

* using boost::optional<std::string> to replace std::string

* disable cppcheck

* test refine

* fix linux build failure

* rework based on comments

* fix a typo
  • Loading branch information
Bruce Irschick authored May 27, 2022
1 parent 052f01e commit e391f42
Show file tree
Hide file tree
Showing 19 changed files with 754 additions and 131 deletions.
1 change: 1 addition & 0 deletions src/odbc-test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ set(SOURCES
../odbc/src/message.cpp
../odbc/src/meta/column_meta.cpp
../odbc/src/meta/foreign_key_meta.cpp
../odbc/src/meta/primary_key_meta.cpp
../odbc/src/meta/table_meta.cpp
../odbc/src/nested_tx_mode.cpp
../odbc/src/protocol_version.cpp
Expand Down
87 changes: 35 additions & 52 deletions src/odbc-test/src/api_robustness_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,6 @@ SQLSMALLINT unsupportedSql[] = {SQL_WVARCHAR,

BOOST_FIXTURE_TEST_SUITE(ApiRobustnessTestSuite, ApiRobustnessTestSuiteFixture)

BOOST_AUTO_TEST_CASE(TestSQLPrimaryKeysEmpty) {
std::string dsnConnectionString;
CreateDsnConnectionStringForLocalServer(dsnConnectionString);

Connect(dsnConnectionString);

SQLCHAR empty[] = "";
SQLCHAR schema[] = "odbc-test";
SQLCHAR tableName[] = "api_robustness_test_001";

SQLRETURN ret;
ret = SQLPrimaryKeys(stmt, empty, sizeof(empty), schema, sizeof(schema),
tableName, sizeof(tableName));
if (!SQL_SUCCEEDED(ret)) {
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
ret = SQLFetch(stmt);
BOOST_CHECK_EQUAL(SQL_NO_DATA, ret);
}

BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttrGetStmtAttr) {
// check that statement array size is set correctly

Expand Down Expand Up @@ -473,6 +453,41 @@ BOOST_AUTO_TEST_CASE(TestSQLColumns, *disabled()) {
SQLColumns(dbc, 0, 0, 0, 0, 0, 0, 0, 0);
}

BOOST_AUTO_TEST_CASE(TestSQLPrimaryKeys) {
std::string dsnConnectionString;
CreateDsnConnectionStringForLocalServer(dsnConnectionString);

Connect(dsnConnectionString);

SQLCHAR catalogName[] = "";
SQLCHAR schemaName[] = "odbc-test";
SQLCHAR tableName[] = "jni_test_001";

// Everything is ok.
SQLRETURN ret =
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), tableName, sizeof(tableName));

ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);

ret = SQLFetch(stmt);
BOOST_CHECK_EQUAL(SQL_SUCCESS, ret);

SQLPrimaryKeys(stmt, 0, sizeof(catalogName), schemaName, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, 0, schemaName, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), 0, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName, 0,
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), 0, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), tableName, 0);
SQLPrimaryKeys(stmt, 0, 0, 0, 0, 0, 0);
}

BOOST_AUTO_TEST_CASE(TestSQLBindCol, *disabled()) {
// There are no checks because we do not really care what is the result of
// these calls as long as they do not cause segmentation fault.
Expand Down Expand Up @@ -859,38 +874,6 @@ BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttr, *disabled()) {
SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, 0, 0);
}

BOOST_AUTO_TEST_CASE(TestSQLPrimaryKeys, *disabled()) {
// There are no checks because we do not really care what is the result of
// these calls as long as they do not cause segmentation fault.

Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");

SQLCHAR catalogName[] = "";
SQLCHAR schemaName[] = "cache";
SQLCHAR tableName[] = "TestType";

// Everything is ok.
SQLRETURN ret =
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), tableName, sizeof(tableName));

ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);

SQLPrimaryKeys(stmt, 0, sizeof(catalogName), schemaName, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, 0, schemaName, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), 0, sizeof(schemaName),
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName, 0,
tableName, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), 0, sizeof(tableName));
SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName,
sizeof(schemaName), tableName, 0);
SQLPrimaryKeys(stmt, 0, 0, 0, 0, 0, 0);
}

BOOST_AUTO_TEST_CASE(TestSQLNumParams, *disabled()) {
// There are no checks because we do not really care what is the result of
// these calls as long as they do not cause segmentation fault.
Expand Down
173 changes: 173 additions & 0 deletions src/odbc-test/src/java_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,178 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) {
}
}

BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetPrimaryKeys) {
PrepareContext();
BOOST_REQUIRE(_ctx.Get() != nullptr);

JniErrorInfo errInfo;
SharedPointer< GlobalJObject > connection;
// get connection
JniErrorCode success = _ctx.Get()->DriverManagerGetConnection(
_jdbcConnectionString.c_str(), connection, errInfo);
if (success != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
BOOST_FAIL(errInfo.errMsg);
}
BOOST_REQUIRE(connection.Get());
AutoCloseConnection autoCloseConnection(_ctx, connection);

// get databaseMetaData object
SharedPointer< GlobalJObject > databaseMetaData;
if (_ctx.Get()->ConnectionGetMetaData(connection, databaseMetaData, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_REQUIRE(databaseMetaData.Get());

boost::optional< std::string > catalog = boost::none;
boost::optional< std::string > schema = boost::none;
boost::optional< std::string > table(std::string("jni_test_001"));
std::string pkColumn = "jni_test_001__id";
SharedPointer< GlobalJObject > resultSet;
if (_ctx.Get()->DatabaseMetaDataGetPrimaryKeys(
databaseMetaData, catalog, schema, table, resultSet, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_REQUIRE(resultSet.Get());
AutoCloseResultSet autoCloseResultSet(_ctx, resultSet);

// Get first
bool hasNext;
if (_ctx.Get()->ResultSetNext(resultSet, hasNext, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_REQUIRE(hasNext);

int i = 0;
while (hasNext) {
boost::optional< std::string > value;
// TABLE_CAT (i.e., catalog - always NULL in our case)
if (_ctx.Get()->ResultSetGetString(resultSet, 1, value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
// grab string from first column
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(!value);

// TABLE_CAT (i.e., catalog - always NULL in our case)
if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_CAT", value,
errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { // grab string from first
// column by name
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(!value);

// TABLE_SCHEM (i.e., database)
if (_ctx.Get()->ResultSetGetString(resultSet, 2, value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(DATABASE_NAME, *value);

// TABLE_SCHEM (i.e., database)
if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value,
errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(DATABASE_NAME, *value);

// TABLE_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, 3, value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(table, *value);

// TABLE_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_NAME", value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(table, *value);

// COLUMN_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, 4, value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(pkColumn, *value);

// COLUMN_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, "COLUMN_NAME", value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(value);
BOOST_CHECK_EQUAL(pkColumn, *value);

// KEY_SEQ
boost::optional< int > intVal;
if (_ctx.Get()->ResultSetGetInt(resultSet, 5, intVal, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(intVal);
BOOST_CHECK_EQUAL(1, *intVal);

// KEY_SEQ
if (_ctx.Get()->ResultSetGetInt(resultSet, "KEY_SEQ", intVal, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(intVal);
BOOST_CHECK_EQUAL(1, *intVal);

// PK_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, 6, value, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(!value);

// PK_NAME
if (_ctx.Get()->ResultSetGetString(resultSet, "PK_NAME", value,
errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}
BOOST_CHECK(!value);

// Get next
if (_ctx.Get()->ResultSetNext(resultSet, hasNext, errInfo)
!= JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}

i++;
}
BOOST_CHECK_EQUAL(1, i);
}

BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) {
PrepareContext();
BOOST_REQUIRE(_ctx.Get() != nullptr);
Expand Down Expand Up @@ -843,6 +1015,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) {
std::string errMsg = errInfo.errMsg;
BOOST_FAIL(errMsg);
}

BOOST_REQUIRE(value);
BOOST_REQUIRE(value->size() > 0);
BOOST_CHECK_EQUAL(fkColumn, *value);
Expand Down
Loading

0 comments on commit e391f42

Please sign in to comment.