Skip to content

Commit

Permalink
SQLPrimaryKey using JNI
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyZhang2022 committed May 19, 2022
1 parent dc215fd commit ba4b68f
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 46 deletions.
1 change: 1 addition & 0 deletions src/odbc-test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ set(SOURCES
../odbc/src/log.cpp
../odbc/src/message.cpp
../odbc/src/meta/column_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
1 change: 1 addition & 0 deletions src/odbc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ set(SOURCES src/app/application_data_buffer.cpp
src/jni/result_set.cpp
src/environment.cpp
src/meta/column_meta.cpp
src/meta/primary_key_meta.cpp
src/meta/table_meta.cpp
src/odbc.cpp
src/entry_points.cpp
Expand Down
10 changes: 10 additions & 0 deletions src/odbc/include/ignite/odbc/jni/database_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ class DatabaseMetaData {
const std::string& columnNamePattern,
JniErrorInfo& errInfo);

/**
* Query the primary keys in the database according to the given
* search critera in catalog (not supported), schema, and
* table.
*/
SharedPointer< ResultSet > GetPrimaryKeys(const std::string& catalog,
const std::string& schema,
const std::string& table,
JniErrorInfo& errInfo);

private:
/**
* Constructs an instance of the DatabaseMetaData class.
Expand Down
7 changes: 7 additions & 0 deletions src/odbc/include/ignite/odbc/jni/java.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ struct JniMembers {
jclass c_DatabaseMetaData;
jmethodID m_DatabaseMetaDataGetTables;
jmethodID m_DatabaseMetaDataGetColumns;
jmethodID m_DatabaseMetaDataGetPrimaryKeys;

jclass c_List;
jmethodID m_ListSize;
Expand Down Expand Up @@ -529,6 +530,12 @@ class IGNITE_IMPORT_EXPORT JniContext {
const std::string& tableNamePattern, const std::string& columnNamePattern,
SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo);

JniErrorCode DatabaseMetaDataGetPrimaryKeys(
const SharedPointer< GlobalJObject >& databaseMetaData,
const std::string& catalog, const std::string& schema,
const std::string& table, SharedPointer< GlobalJObject >& resultSet,
JniErrorInfo& errInfo);

JniErrorCode ResultSetClose(const SharedPointer< GlobalJObject >& resultSet,
JniErrorInfo& errInfo);
JniErrorCode ResultSetNext(const SharedPointer< GlobalJObject >& resultSet,
Expand Down
24 changes: 24 additions & 0 deletions src/odbc/include/ignite/odbc/jni/result_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,30 @@ class ResultSet {
JniErrorCode GetInt(const std::string& columnName,
boost::optional< int >& value, JniErrorInfo& errInfo);

/**
* Gets a value on the current row of the result set for the
* given columnIndex (1-indexed). If a value exists, the value
* is set. If the value is null, the wasNull will be set to
* true, false, otherwise.
*
* @return a JniErrorCode indicating success or failure.
*/
JniErrorCode GetSmallInt(const int columnIndex,
boost::optional< int16_t >& value,
JniErrorInfo& errInfo);

/**
* Gets a value on the current row of the result set for the
* given columnName. If a value exists, the value
* is set. If the value is null, the wasNull will be set to
* true, false, otherwise.
*
* @return a JniErrorCode indicating success or failure.
*/
JniErrorCode GetSmallInt(const std::string& columnName,
boost::optional< int16_t >& value,
JniErrorInfo& errInfo);

private:
/**
* Constructs a new instancee of ResultSet.
Expand Down
43 changes: 31 additions & 12 deletions src/odbc/include/ignite/odbc/meta/primary_key_meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
#include <string>

#include "ignite/odbc/impl/binary/binary_reader_impl.h"
#include "ignite/odbc/jni/result_set.h"
#include "ignite/odbc/log.h"
#include "ignite/odbc/utility.h"

using ignite::odbc::jni::ResultSet;

namespace ignite {
namespace odbc {
namespace meta {
Expand Down Expand Up @@ -96,76 +100,91 @@ class PrimaryKeyMeta {
return *this;
}

/**
* Read resultset item.
* @param resultSet SharedPointer< ResultSet >.
* @paran errInfo JniErrorInfo.
*/
void Read(SharedPointer< ResultSet >& resultSet, JniErrorInfo& errInfo);

/**
* Get catalog name.
* @return Catalog name.
*/
const std::string& GetCatalogName() const {
const boost::optional< std::string >& GetCatalogName() const {
return catalog;
}

/**
* Get schema name.
* @return Schema name.
*/
const std::string& GetSchemaName() const {
const boost::optional< std::string >& GetSchemaName() const {
return schema;
}

/**
* Get table name.
* @return Table name.
*/
const std::string& GetTableName() const {
const boost::optional< std::string >& GetTableName() const {
return table;
}

/**
* Get column name.
* @return Column name.
*/
const std::string& GetColumnName() const {
const boost::optional< std::string >& GetColumnName() const {
return table;
}

/**
* Get column sequence number in key.
* @return Sequence number in key.
*/
int16_t GetKeySeq() const {
boost::optional< int16_t > GetKeySeq() const {
return keySeq;
}

/**
* Get key name.
* @return Key name.
*/
const std::string& GetKeyName() const {
const boost::optional< std::string >& GetKeyName() const {
return keyName;
}

private:
/** Catalog name. */
std::string catalog;
boost::optional< std::string > catalog;

/** Schema name. */
std::string schema;
boost::optional< std::string > schema;

/** Table name. */
std::string table;
boost::optional< std::string > table;

/** Collumn name. */
std::string column;
boost::optional< std::string > column;

/** Column sequence number in key. */
int16_t keySeq;
boost::optional< int16_t > keySeq;

/** Key name. */
std::string keyName;
boost::optional< std::string > keyName;
};

/** Table metadata vector alias. */
typedef std::vector< PrimaryKeyMeta > PrimaryKeyMetaVector;

/**
* Read primary keys metadata collection.
* @param resultSet SharedPointer< ResultSet >.
* @param meta Collection.
*/
void ReadPrimaryKeysColumnMetaVector(SharedPointer< ResultSet >& resultSet,
PrimaryKeyMetaVector& meta);
} // namespace meta
} // namespace odbc
} // namespace ignite
Expand Down
12 changes: 12 additions & 0 deletions src/odbc/include/ignite/odbc/query/primary_keys_query.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ class PrimaryKeysQuery : public Query {
private:
IGNITE_NO_COPY_ASSIGNMENT(PrimaryKeysQuery);

/**
* Make get primary keys metadata requets and use response to set internal
* state.
*
* @return Operation result.
*/
virtual SqlResult::Type MakeRequestGetPrimaryKeysMeta();


/** Connection associated with the statement. */
Connection& connection;

Expand All @@ -125,6 +134,9 @@ class PrimaryKeysQuery : public Query {
/** Query executed. */
bool executed;

/** Fetched flag. */
bool fetched;

/** Columns metadata. */
meta::ColumnMetaVector columnsMeta;

Expand Down
13 changes: 13 additions & 0 deletions src/odbc/src/jni/database_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ SharedPointer< ResultSet > DatabaseMetaData::GetColumns(
}
return new ResultSet(_jniContext, resultSet);
}

SharedPointer< ResultSet > DatabaseMetaData::GetPrimaryKeys(
const std::string& catalog, const std::string& schema,
const std::string& table, JniErrorInfo& errInfo) {
SharedPointer< GlobalJObject > resultSet;
const std::vector< std::string > types;
JniErrorCode success = _jniContext.Get()->DatabaseMetaDataGetPrimaryKeys(
_databaseMetaData, catalog, schema, table, resultSet, errInfo);
if (success != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
return nullptr;
}
return new ResultSet(_jniContext, resultSet);
}
} // namespace jni
} // namespace odbc
} // namespace ignite
55 changes: 54 additions & 1 deletion src/odbc/src/jni/java.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,11 @@ JniMethod const M_DATABASE_META_DATA_GET_COLUMNS =
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
"String;Ljava/lang/String;)Ljava/sql/ResultSet;",
false);

JniMethod const M_DATABASE_META_DATA_GET_PRIMARY_KEYS =
JniMethod("getPrimaryKeys",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
"String;)Ljava/sql/ResultSet;",
false);
const char* const C_DOCUMENTDB_CONNECTION =
"software/amazon/documentdb/jdbc/DocumentDbConnection";
JniMethod const M_DOCUMENTDB_CONNECTION_GET_SSH_LOCAL_PORT =
Expand Down Expand Up @@ -660,6 +664,8 @@ void JniMembers::Initialize(JNIEnv* env) {
FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_TABLES);
m_DatabaseMetaDataGetColumns =
FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_COLUMNS);
m_DatabaseMetaDataGetPrimaryKeys =
FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_PRIMARY_KEYS);

c_Connection = FindClass(env, C_JAVA_SQL_CONNECTION);
m_ConnectionClose =
Expand Down Expand Up @@ -1414,6 +1420,53 @@ JniErrorCode JniContext::DatabaseMetaDataGetColumns(
return errInfo.code;
}

JniErrorCode JniContext::DatabaseMetaDataGetPrimaryKeys(
const SharedPointer< GlobalJObject >& databaseMetaData,
const std::string& catalog, const std::string& schema,
const std::string& table, SharedPointer< GlobalJObject >& resultSet,
JniErrorInfo& errInfo) {
LOG_DEBUG_MSG("DatabaseMetaDataGetPrimaryKeys is called");

if (databaseMetaData.Get() == nullptr) {
errInfo.code = JniErrorCode::IGNITE_JNI_ERR_GENERIC;
errInfo.errMsg = "DatabaseMetaData object must be set.";

LOG_ERROR_MSG("DatabaseMetaDataGetPrimaryKeys exiting with error msg: "
<< errInfo.errMsg);

return errInfo.code;
}

JNIEnv* env = Attach();
jstring jCatalog = env->NewStringUTF(catalog.c_str());
jstring jSchema = env->NewStringUTF(schema.c_str());
jstring jTableName = env->NewStringUTF(table.c_str());

jobject result = env->CallObjectMethod(
databaseMetaData.Get()->GetRef(),
jvm->GetMembers().m_DatabaseMetaDataGetPrimaryKeys, jCatalog, jSchema,
jTableName);
ExceptionCheck(env, &errInfo);

env->DeleteLocalRef(jCatalog);
env->DeleteLocalRef(jSchema);
env->DeleteLocalRef(jTableName);

if (!result || errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) {
resultSet = nullptr;
LOG_ERROR_MSG(
"DatabaseMetaDataGetPrimaryKeys exiting with error. resultSet will be "
"null");
return errInfo.code;
}

resultSet = new GlobalJObject(env, env->NewGlobalRef(result));

LOG_DEBUG_MSG("DatabaseMetaDataGetPrimaryKeys exiting");

return errInfo.code;
}

JniErrorCode JniContext::ResultSetClose(
const SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo) {
LOG_DEBUG_MSG("ResultSetClose is called");
Expand Down
22 changes: 22 additions & 0 deletions src/odbc/src/jni/result_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,28 @@ JniErrorCode ResultSet::GetInt(const std::string& columnName,
return _jniContext.Get()->ResultSetGetInt(_resultSet, columnName, value,
errInfo);
}

JniErrorCode ResultSet::GetSmallInt(const int columnIndex,
boost::optional< int16_t >& value,
JniErrorInfo& errInfo) {
boost::optional< int > val;
JniErrorCode err =
_jniContext.Get()->ResultSetGetInt(_resultSet, columnIndex, val, errInfo);
if (val)
value = static_cast< int16_t >(*val);
return err;
}

JniErrorCode ResultSet::GetSmallInt(const std::string& columnName,
boost::optional< int16_t >& value,
JniErrorInfo& errInfo) {
boost::optional< int > val;
JniErrorCode err =
_jniContext.Get()->ResultSetGetInt(_resultSet, columnName, val, errInfo);
if (val)
value = static_cast< int16_t >(*val);
return err;
}
} // namespace jni
} // namespace odbc
} // namespace ignite
Loading

0 comments on commit ba4b68f

Please sign in to comment.