You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2017/01/10 08:11:06 UTC
ignite git commit: IGNITE-4493: ODBC: Added missing diagnostic
records for error cases
Repository: ignite
Updated Branches:
refs/heads/master bf118aad8 -> 9e8e9798d
IGNITE-4493: ODBC: Added missing diagnostic records for error cases
This closes #1396
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9e8e9798
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9e8e9798
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9e8e9798
Branch: refs/heads/master
Commit: 9e8e9798dae8b92cfbf4d940856dec35d3e30f54
Parents: bf118aa
Author: Sergey Kalashnikov <sk...@gridgain.com>
Authored: Tue Jan 10 11:10:56 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Tue Jan 10 11:10:56 2017 +0300
----------------------------------------------------------------------
.../cpp/odbc-test/src/api_robustness_test.cpp | 113 +++++++++++-
.../cpp/odbc/include/ignite/odbc/common_types.h | 29 ++-
.../cpp/odbc/include/ignite/odbc/statement.h | 143 +++++++++++----
modules/platforms/cpp/odbc/src/connection.cpp | 2 +-
.../odbc/src/diagnostic/diagnostic_record.cpp | 38 ++++
modules/platforms/cpp/odbc/src/odbc.cpp | 118 ++++---------
modules/platforms/cpp/odbc/src/statement.cpp | 176 ++++++++++++++++---
7 files changed, 484 insertions(+), 135 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
index 13a5ea6..0b6df93 100644
--- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
@@ -50,7 +50,7 @@ using ignite::impl::binary::BinaryUtils;
/**
* Test setup fixture.
*/
-struct ApiRobustnessTestSuiteFixture
+struct ApiRobustnessTestSuiteFixture
{
void Prepare()
{
@@ -206,6 +206,33 @@ struct ApiRobustnessTestSuiteFixture
// Operation is not supported. However, there should be no crash.
BOOST_CHECK(ret == SQL_ERROR);
+
+ CheckSQLStatementDiagnosticError("HY106");
+ }
+
+ void CheckSQLDiagnosticError(int16_t handleType, SQLHANDLE handle, const std::string& expectSqlState)
+ {
+ SQLCHAR state[ODBC_BUFFER_SIZE];
+ SQLINTEGER nativeError = 0;
+ SQLCHAR message[ODBC_BUFFER_SIZE];
+ SQLSMALLINT messageLen = 0;
+
+ SQLRETURN ret = SQLGetDiagRec(handleType, handle, 1, state, &nativeError, message, sizeof(message), &messageLen);
+
+ const std::string sqlState = reinterpret_cast<char*>(state);
+ BOOST_REQUIRE_EQUAL(ret, SQL_SUCCESS);
+ BOOST_REQUIRE_EQUAL(sqlState, expectSqlState);
+ BOOST_REQUIRE(messageLen > 0);
+ }
+
+ void CheckSQLStatementDiagnosticError(const std::string& expectSqlState)
+ {
+ CheckSQLDiagnosticError(SQL_HANDLE_STMT, stmt, expectSqlState);
+ }
+
+ void CheckSQLConnectionDiagnosticError(const std::string& expectSqlState)
+ {
+ CheckSQLDiagnosticError(SQL_HANDLE_DBC, dbc, expectSqlState);
}
/**
@@ -234,6 +261,43 @@ struct ApiRobustnessTestSuiteFixture
SQLHSTMT stmt;
};
+SQLSMALLINT unsupportedC[] = {
+ SQL_C_INTERVAL_YEAR,
+ SQL_C_INTERVAL_MONTH,
+ SQL_C_INTERVAL_DAY,
+ SQL_C_INTERVAL_HOUR,
+ SQL_C_INTERVAL_MINUTE,
+ SQL_C_INTERVAL_SECOND,
+ SQL_C_INTERVAL_YEAR_TO_MONTH,
+ SQL_C_INTERVAL_DAY_TO_HOUR,
+ SQL_C_INTERVAL_DAY_TO_MINUTE,
+ SQL_C_INTERVAL_DAY_TO_SECOND,
+ SQL_C_INTERVAL_HOUR_TO_MINUTE,
+ SQL_C_INTERVAL_HOUR_TO_SECOND,
+ SQL_C_INTERVAL_MINUTE_TO_SECOND
+ };
+
+SQLSMALLINT unsupportedSql[] = {
+ SQL_WVARCHAR,
+ SQL_WLONGVARCHAR,
+ SQL_REAL,
+ SQL_NUMERIC,
+ SQL_TYPE_TIME,
+ SQL_INTERVAL_MONTH,
+ SQL_INTERVAL_YEAR,
+ SQL_INTERVAL_YEAR_TO_MONTH,
+ SQL_INTERVAL_DAY,
+ SQL_INTERVAL_HOUR,
+ SQL_INTERVAL_MINUTE,
+ SQL_INTERVAL_SECOND,
+ SQL_INTERVAL_DAY_TO_HOUR,
+ SQL_INTERVAL_DAY_TO_MINUTE,
+ SQL_INTERVAL_DAY_TO_SECOND,
+ SQL_INTERVAL_HOUR_TO_MINUTE,
+ SQL_INTERVAL_HOUR_TO_SECOND,
+ SQL_INTERVAL_MINUTE_TO_SECOND
+ };
+
BOOST_FIXTURE_TEST_SUITE(ApiRobustnessTestSuite, ApiRobustnessTestSuiteFixture)
BOOST_AUTO_TEST_CASE(TestSQLDriverConnect)
@@ -516,6 +580,19 @@ BOOST_AUTO_TEST_CASE(TestSQLBindCol)
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+ //Unsupported data types
+ for(int i = 0; i < sizeof(unsupportedC)/sizeof(unsupportedC[0]); ++i)
+ {
+ ret = SQLBindCol(stmt, 1, unsupportedC[i], &ind1, sizeof(ind1), &len1);
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ CheckSQLStatementDiagnosticError("HY003");
+ }
+
+ // Size is negative.
+ ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &ind1, -1, &len1);
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ CheckSQLStatementDiagnosticError("HY090");
+
// Size is null.
SQLBindCol(stmt, 1, SQL_C_SLONG, &ind1, 0, &len1);
@@ -545,6 +622,24 @@ BOOST_AUTO_TEST_CASE(TestSQLBindParameter)
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+ //Unsupported parameter type : output
+ SQLBindParameter(stmt, 2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, sizeof(ind1), &len1);
+ CheckSQLStatementDiagnosticError("HY105");
+
+ //Unsupported parameter type : input/output
+ SQLBindParameter(stmt, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, sizeof(ind1), &len1);
+ CheckSQLStatementDiagnosticError("HY105");
+
+
+ //Unsupported data types
+ for(int i = 0; i < sizeof(unsupportedSql)/sizeof(unsupportedSql[0]); ++i)
+ {
+ ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, unsupportedSql[i], 100, 100, &ind1, sizeof(ind1), &len1);
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ CheckSQLStatementDiagnosticError("HYC00");
+ }
+
+
// Size is null.
SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, 0, &len1);
@@ -1111,4 +1206,20 @@ BOOST_AUTO_TEST_CASE(TestSQLError)
SQLError(0, 0, 0, 0, 0, 0, 0, 0);
}
+BOOST_AUTO_TEST_CASE(TestSQLDiagnosticRecords)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;cache=cache");
+
+ SQLHANDLE hnd;
+ SQLRETURN ret;
+
+ ret = SQLAllocHandle(SQL_HANDLE_DESC, dbc, &hnd);
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ CheckSQLConnectionDiagnosticError("IM001");
+
+ ret = SQLFreeStmt(stmt, 4);
+ BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+ CheckSQLStatementDiagnosticError("HY092");
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
index 517fe4e..5d8901d 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
@@ -113,15 +113,37 @@ namespace ignite
*/
SQL_STATE_HY001_MEMORY_ALLOCATION,
+ /**
+ * The argument TargetType was neither a valid data type
+ * nor SQL_C_DEFAULT
+ */
+ SQL_STATE_HY003_INVALID_APPLICATION_BUFFER_TYPE,
+
/** Invalid use of null pointer. */
SQL_STATE_HY009_INVALID_USE_OF_NULL_POINTER,
/** Function sequence error. */
SQL_STATE_HY010_SEQUENCE_ERROR,
+ /**
+ * Invalid string or buffer length
+ */
+ SQL_STATE_HY090_INVALID_STRING_OR_BUFFER_LENGTH,
+
+ /**
+ * Option type was out of range.
+ */
+ SQL_STATE_HY092_OPTION_TYPE_OUT_OF_RANGE,
+
/** Column type out of range. */
SQL_STATE_HY097_COLUMN_TYPE_OUT_OF_RANGE,
+ /** The value specified for the argument InputOutputType was invalid. */
+ SQL_STATE_HY105_INVALID_PARAMETER_TYPE,
+
+ /** The value specified for the argument FetchOrientation was invalid. */
+ SQL_STATE_HY106_FETCH_TYPE_OUT_OF_RANGE,
+
/**
* The driver does not support the feature of ODBC behavior that
* the application requested.
@@ -132,7 +154,12 @@ namespace ignite
* The connection timeout period expired before the data source
* responded to the request.
*/
- SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT
+ SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT,
+
+ /**
+ * Driver does not support this function.
+ */
+ SQL_STATE_IM001_FUNCTION_NOT_SUPPORTED
};
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
index db56660..596fc66 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
@@ -57,24 +57,15 @@ namespace ignite
~Statement();
/**
- * Bind result column to specified data buffer.
+ * Bind result column to data buffer provided by application
*
* @param columnIdx Column index.
- * @param buffer Buffer to put column data to.
+ * @param targetType Type of target buffer.
+ * @param targetValue Pointer to target buffer.
+ * @param bufferLength Length of target buffer.
+ * @param strLengthOrIndicator Pointer to the length/indicator buffer.
*/
- void BindColumn(uint16_t columnIdx, const app::ApplicationDataBuffer& buffer);
-
- /**
- * Unbind specified column buffer.
- *
- * @param columnIdx Column index.
- */
- void UnbindColumn(uint16_t columnIdx);
-
- /**
- * Unbind all column buffers.
- */
- void UnbindAllColumns();
+ void BindColumn(uint16_t columnIdx, int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* strLengthOrIndicator);
/**
* Set column binding offset pointer.
@@ -101,21 +92,17 @@ namespace ignite
* Bind parameter.
*
* @param paramIdx Parameter index.
- * @param param Parameter.
- */
- void BindParameter(uint16_t paramIdx, const app::Parameter& param);
-
- /**
- * Unbind specified parameter.
- *
- * @param paramIdx Parameter index.
+ * @param ioType Type of the parameter (input/output).
+ * @param bufferType The data type of the parameter.
+ * @param paramSqlType The SQL data type of the parameter.
+ * @param columnSize The size of the column or expression of the corresponding parameter marker.
+ * @param decDigits The decimal digits of the column or expression of the corresponding parameter marker.
+ * @param buffer A pointer to a buffer for the parameter's data.
+ * @param bufferLen Length of the ParameterValuePtr buffer in bytes.
+ * @param resLen A pointer to a buffer for the parameter's length.
*/
- void UnbindParameter(uint16_t paramIdx);
-
- /**
- * Unbind all parameters.
- */
- void UnbindAllParameters();
+ void BindParameter(uint16_t paramIdx, int16_t ioType, int16_t bufferType, int16_t paramSqlType,
+ SqlUlen columnSize, int16_t decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen);
/**
* Set statement attribute.
@@ -171,7 +158,7 @@ namespace ignite
* @param query SQL query.
*/
void PrepareSqlQuery(const std::string& query);
-
+
/**
* Execute SQL query.
*
@@ -254,11 +241,24 @@ namespace ignite
void ExecuteGetTypeInfoQuery(int16_t sqlType);
/**
+ * Free resources
+ * @param option indicates what needs to be freed
+ */
+ void FreeResources(int16_t option);
+
+ /**
* Close statement.
*/
void Close();
/**
+ * Fetch query result row with offset
+ * @param orientation Fetch type
+ * @param offset Fetch offset
+ */
+ void FetchScroll(int16_t orientation, int64_t offset);
+
+ /**
* Fetch query result row.
*/
void FetchRow();
@@ -362,14 +362,75 @@ namespace ignite
private:
IGNITE_NO_COPY_ASSIGNMENT(Statement);
+
+ /**
+ * Bind result column to specified data buffer.
+ *
+ * @param columnIdx Column index.
+ * @param buffer Buffer to put column data to.
+ */
+ void SafeBindColumn(uint16_t columnIdx, const app::ApplicationDataBuffer& buffer);
+
+ /**
+ * Unbind specified column buffer.
+ *
+ * @param columnIdx Column index.
+ */
+ void SafeUnbindColumn(uint16_t columnIdx);
+
+ /**
+ * Unbind all column buffers.
+ */
+ void SafeUnbindAllColumns();
+
+ /**
+ * Bind result column to data buffer provided by application
+ *
+ * @param columnIdx Column index.
+ * @param targetType Type of target buffer.
+ * @param targetValue Pointer to target buffer.
+ * @param bufferLength Length of target buffer.
+ * @param strLengthOrIndicator Pointer to the length/indicator buffer.
+ * @return Operation result.
+ */
+ SqlResult InternalBindColumn(uint16_t columnIdx, int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* strLengthOrIndicator);
+
/**
* Bind parameter.
*
* @param paramIdx Parameter index.
* @param param Parameter.
+ */
+ void SafeBindParameter(uint16_t paramIdx, const app::Parameter& param);
+
+ /**
+ * Unbind specified parameter.
+ *
+ * @param paramIdx Parameter index.
+ */
+ void SafeUnbindParameter(uint16_t paramIdx);
+
+ /**
+ * Unbind all parameters.
+ */
+ void SafeUnbindAllParameters();
+
+ /**
+ * Bind parameter.
+ *
+ * @param paramIdx Parameter index.
+ * @param ioType Type of the parameter (input/output).
+ * @param bufferType The data type of the parameter.
+ * @param paramSqlType The SQL data type of the parameter.
+ * @param columnSize The size of the column or expression of the corresponding parameter marker.
+ * @param decDigits The decimal digits of the column or expression of the corresponding parameter marker.
+ * @param buffer A pointer to a buffer for the parameter's data.
+ * @param bufferLen Length of the ParameterValuePtr buffer in bytes.
+ * @param resLen A pointer to a buffer for the parameter's length.
* @return Operation result.
*/
- SqlResult InternalBindParameter(uint16_t paramIdx, const app::Parameter& param);
+ SqlResult InternalBindParameter(uint16_t paramIdx, int16_t ioType, int16_t bufferType, int16_t paramSqlType,
+ SqlUlen columnSize, int16_t decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen);
/**
* Set statement attribute.
@@ -403,6 +464,14 @@ namespace ignite
*/
SqlResult InternalGetColumnData(uint16_t columnIdx, app::ApplicationDataBuffer& buffer);
+
+ /**
+ * Free resources
+ * @param option indicates what needs to be freed
+ * @return Operation result.
+ */
+ SqlResult InternalFreeResources(int16_t option);
+
/**
* Close statement.
* Internal call.
@@ -418,7 +487,7 @@ namespace ignite
* @return Operation result.
*/
SqlResult InternalPrepareSqlQuery(const std::string& query);
-
+
/**
* Execute SQL query.
*
@@ -435,6 +504,14 @@ namespace ignite
SqlResult InternalExecuteSqlQuery();
/**
+ * Fetch query result row with offset
+ * @param orientation Fetch type
+ * @param offset Fetch offset
+ * @return Operation result.
+ */
+ SqlResult InternalFetchScroll(int16_t orientation, int64_t offset);
+
+ /**
* Fetch query result row.
*
* @return Operation result.
@@ -621,7 +698,7 @@ namespace ignite
/** Offset added to pointers to change binding of parameters. */
int* paramBindOffset;
-
+
/** Offset added to pointers to change binding of column data. */
int* columnBindOffset;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 2afa42d..4a6de5e 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -226,7 +226,7 @@ namespace ignite
OdbcProtocolHeader hdr;
- int64_t received = ReceiveAll(reinterpret_cast<int8_t*>(&hdr), sizeof(hdr));
+ size_t received = ReceiveAll(reinterpret_cast<int8_t*>(&hdr), sizeof(hdr));
if (received != sizeof(hdr))
IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not receive message header");
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
index 215d77f..3c411d2 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
@@ -64,17 +64,35 @@ namespace
/** SQL state HY001 constant. */
const std::string STATE_HY001 = "HY001";
+ /** SQL state HY003 constant. */
+ const std::string STATE_HY003 = "HY003";
+
/** SQL state HY009 constant. */
const std::string STATE_HY009 = "HY009";
/** SQL state HY010 constant. */
const std::string STATE_HY010 = "HY010";
+ /** SQL state HY092 constant. */
+ const std::string STATE_HY092 = "HY092";
+
+ /** SQL state HY105 constant. */
+ const std::string STATE_HY105 = "HY105";
+
+ /** SQL state HY106 constant. */
+ const std::string STATE_HY106 = "HY106";
+
/** SQL state HYC00 constant. */
const std::string STATE_HYC00 = "HYC00";
/** SQL state HYT01 constant. */
const std::string STATE_HYT01 = "HYT01";
+
+ /** SQL state HY090 constant. */
+ const std::string STATE_HY090 = "HY090";
+
+ /** SQL state IM001 constant. */
+ const std::string STATE_IM001 = "IM001";
}
namespace ignite
@@ -130,6 +148,8 @@ namespace ignite
if (odbcSubclasses.empty())
{
+ // This is a fixed list taken from ODBC doc.
+ // Please do not add/remove values here.
odbcSubclasses.insert("01S00");
odbcSubclasses.insert("01S01");
odbcSubclasses.insert("01S02");
@@ -234,18 +254,36 @@ namespace ignite
case SQL_STATE_HY001_MEMORY_ALLOCATION:
return STATE_HY001;
+ case SQL_STATE_HY003_INVALID_APPLICATION_BUFFER_TYPE:
+ return STATE_HY003;
+
case SQL_STATE_HY009_INVALID_USE_OF_NULL_POINTER:
return STATE_HY009;
case SQL_STATE_HY010_SEQUENCE_ERROR:
return STATE_HY010;
+ case SQL_STATE_HY090_INVALID_STRING_OR_BUFFER_LENGTH:
+ return STATE_HY090;
+
+ case SQL_STATE_HY092_OPTION_TYPE_OUT_OF_RANGE:
+ return STATE_HY092;
+
+ case SQL_STATE_HY105_INVALID_PARAMETER_TYPE:
+ return STATE_HY105;
+
+ case SQL_STATE_HY106_FETCH_TYPE_OUT_OF_RANGE:
+ return STATE_HY106;
+
case SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED:
return STATE_HYC00;
case SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT:
return STATE_HYT01;
+ case SQL_STATE_IM001_FUNCTION_NOT_SUPPORTED:
+ return STATE_IM001;
+
default:
break;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index dbec55f..fd69c0d 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -31,6 +31,7 @@
#include "ignite/odbc/dsn_config.h"
#include "ignite/odbc.h"
+
namespace ignite
{
SQLRETURN SQLGetInfo(SQLHDBC conn,
@@ -71,6 +72,23 @@ namespace ignite
return SQLAllocStmt(parent, result);
case SQL_HANDLE_DESC:
+ {
+ using odbc::Connection;
+ Connection *connection = reinterpret_cast<Connection*>(parent);
+
+ if (!connection)
+ return SQL_INVALID_HANDLE;
+
+ if (result)
+ *result = 0;
+
+ connection->GetDiagnosticRecords().Reset();
+ connection->AddStatusRecord(odbc::SQL_STATE_IM001_FUNCTION_NOT_SUPPORTED,
+ "The HandleType argument was SQL_HANDLE_DESC, and "
+ "the driver does not support allocating a descriptor handle");
+
+ return SQL_ERROR;
+ }
default:
break;
}
@@ -199,39 +217,15 @@ namespace ignite
if (!statement)
return SQL_INVALID_HANDLE;
- switch (option)
+ if (option == SQL_DROP)
{
- case SQL_DROP:
- {
- delete statement;
-
- break;
- }
-
- case SQL_CLOSE:
- {
- return SQLCloseCursor(stmt);
- }
-
- case SQL_UNBIND:
- {
- statement->UnbindAllColumns();
-
- break;
- }
-
- case SQL_RESET_PARAMS:
- {
- statement->UnbindAllParameters();
-
- break;
- }
-
- default:
- return SQL_ERROR;
+ delete statement;
+ return SQL_SUCCESS;
}
- return SQL_SUCCESS;
+ statement->FreeResources(option);
+
+ return statement->GetDiagnosticRecords().GetReturnCode();
}
SQLRETURN SQLCloseCursor(SQLHSTMT stmt)
@@ -419,29 +413,14 @@ namespace ignite
using odbc::Statement;
using odbc::app::ApplicationDataBuffer;
- LOG_MSG("SQLBindCol called: index=%d, type=%d\n", colNum, targetType);
+ LOG_MSG("SQLBindCol called: index=%d, type=%d targetValue=%p bufferLength=%d\n", colNum, targetType, targetValue, bufferLength);
Statement *statement = reinterpret_cast<Statement*>(stmt);
if (!statement)
return SQL_INVALID_HANDLE;
- IgniteSqlType driverType = ToDriverType(targetType);
-
- if (driverType == IGNITE_ODBC_C_TYPE_UNSUPPORTED)
- return SQL_ERROR;
-
- if (bufferLength < 0)
- return SQL_ERROR;
-
- if (targetValue || strLengthOrIndicator)
- {
- ApplicationDataBuffer dataBuffer(driverType, targetValue, bufferLength, strLengthOrIndicator);
-
- statement->BindColumn(colNum, dataBuffer);
- }
- else
- statement->UnbindColumn(colNum);
+ statement->BindColumn(colNum, targetType, targetValue, bufferLength, strLengthOrIndicator);
return statement->GetDiagnosticRecords().GetReturnCode();
}
@@ -464,13 +443,19 @@ namespace ignite
SQLRETURN SQLFetchScroll(SQLHSTMT stmt, SQLSMALLINT orientation, SQLLEN offset)
{
+ using odbc::Statement;
+
LOG_MSG("SQLFetchScroll called\n");
LOG_MSG("Orientation: %d, Offset: %d\n", orientation, offset);
- if (orientation != SQL_FETCH_NEXT)
- return SQL_ERROR;
+ Statement *statement = reinterpret_cast<Statement*>(stmt);
+
+ if (!statement)
+ return SQL_INVALID_HANDLE;
+
+ statement->FetchScroll(orientation, offset);
- return SQLFetch(stmt);
+ return statement->GetDiagnosticRecords().GetReturnCode();
}
SQLRETURN SQLExtendedFetch(SQLHSTMT stmt,
@@ -617,12 +602,7 @@ namespace ignite
SQLLEN bufferLen,
SQLLEN* resLen)
{
- using namespace odbc::type_traits;
-
using odbc::Statement;
- using odbc::app::ApplicationDataBuffer;
- using odbc::app::Parameter;
- using odbc::type_traits::IsSqlTypeSupported;
LOG_MSG("SQLBindParameter called: %d, %d, %d\n", paramIdx, bufferType, paramSqlType);
@@ -631,27 +611,7 @@ namespace ignite
if (!statement)
return SQL_INVALID_HANDLE;
- if (ioType != SQL_PARAM_INPUT)
- return SQL_ERROR;
-
- if (!IsSqlTypeSupported(paramSqlType))
- return SQL_ERROR;
-
- IgniteSqlType driverType = ToDriverType(bufferType);
-
- if (driverType == IGNITE_ODBC_C_TYPE_UNSUPPORTED)
- return SQL_ERROR;
-
- if (buffer)
- {
- ApplicationDataBuffer dataBuffer(driverType, buffer, bufferLen, resLen);
-
- Parameter param(dataBuffer, paramSqlType, columnSize, decDigits);
-
- statement->BindParameter(paramIdx, param);
- }
- else
- statement->UnbindParameter(paramIdx);
+ statement->BindParameter(paramIdx, ioType, bufferType, paramSqlType, columnSize, decDigits, buffer, bufferLen, resLen);
return statement->GetDiagnosticRecords().GetReturnCode();
}
@@ -717,13 +677,13 @@ namespace ignite
}
SQLRETURN SQLDescribeCol(SQLHSTMT stmt,
- SQLUSMALLINT columnNum,
+ SQLUSMALLINT columnNum,
SQLCHAR* columnNameBuf,
SQLSMALLINT columnNameBufLen,
SQLSMALLINT* columnNameLen,
- SQLSMALLINT* dataType,
+ SQLSMALLINT* dataType,
SQLULEN* columnSize,
- SQLSMALLINT* decimalDigits,
+ SQLSMALLINT* decimalDigits,
SQLSMALLINT* nullable)
{
using odbc::Statement;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9e8e9798/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
index 02c6dd9..09ad81c 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -50,26 +50,57 @@ namespace ignite
// No-op.
}
- void Statement::BindColumn(uint16_t columnIdx, const app::ApplicationDataBuffer& buffer)
+ void Statement::BindColumn(uint16_t columnIdx, int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* strLengthOrIndicator)
{
- IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+ IGNITE_ODBC_API_CALL(InternalBindColumn(columnIdx, targetType, targetValue, bufferLength, strLengthOrIndicator));
+ }
+
+ SqlResult Statement::InternalBindColumn(uint16_t columnIdx, int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* strLengthOrIndicator)
+ {
+ using namespace odbc::type_traits;
+ IgniteSqlType driverType = ToDriverType(targetType);
+
+ if (driverType == IGNITE_ODBC_C_TYPE_UNSUPPORTED)
+ {
+ AddStatusRecord(odbc::SQL_STATE_HY003_INVALID_APPLICATION_BUFFER_TYPE, "The argument TargetType was not a valid data type.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ if (bufferLength < 0)
+ {
+ AddStatusRecord(odbc::SQL_STATE_HY090_INVALID_STRING_OR_BUFFER_LENGTH,
+ "The value specified for the argument BufferLength was less than 0.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ if (targetValue || strLengthOrIndicator)
+ {
+ app::ApplicationDataBuffer dataBuffer(driverType, targetValue, bufferLength, strLengthOrIndicator);
+ SafeBindColumn(columnIdx, dataBuffer);
+ }
+ else
+ SafeUnbindColumn(columnIdx);
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Statement::SafeBindColumn(uint16_t columnIdx, const app::ApplicationDataBuffer& buffer)
+ {
columnBindings[columnIdx] = buffer;
columnBindings[columnIdx].SetPtrToOffsetPtr(&columnBindOffset);
}
- void Statement::UnbindColumn(uint16_t columnIdx)
+ void Statement::SafeUnbindColumn(uint16_t columnIdx)
{
- IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
-
columnBindings.erase(columnIdx);
}
- void Statement::UnbindAllColumns()
+ void Statement::SafeUnbindAllColumns()
{
- IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
-
columnBindings.clear();
}
@@ -108,14 +139,21 @@ namespace ignite
return SQL_RESULT_SUCCESS;
}
- void Statement::BindParameter(uint16_t paramIdx, const app::Parameter& param)
+ void Statement::BindParameter(uint16_t paramIdx, int16_t ioType, int16_t bufferType, int16_t paramSqlType,
+ SqlUlen columnSize, int16_t decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen)
{
- IGNITE_ODBC_API_CALL(InternalBindParameter(paramIdx, param));
+ IGNITE_ODBC_API_CALL(InternalBindParameter(paramIdx, ioType, bufferType, paramSqlType, columnSize, decDigits, buffer, bufferLen, resLen));
}
-
- SqlResult Statement::InternalBindParameter(uint16_t paramIdx, const app::Parameter& param)
+ SqlResult Statement::InternalBindParameter(uint16_t paramIdx, int16_t ioType, int16_t bufferType, int16_t paramSqlType,
+ SqlUlen columnSize, int16_t decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen)
{
+ using namespace odbc::type_traits;
+ using odbc::Statement;
+ using odbc::app::ApplicationDataBuffer;
+ using odbc::app::Parameter;
+ using odbc::type_traits::IsSqlTypeSupported;
+
if (paramIdx == 0)
{
AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE,
@@ -124,24 +162,60 @@ namespace ignite
return SQL_RESULT_ERROR;
}
- paramBindings[paramIdx] = param;
+ if (ioType != SQL_PARAM_INPUT)
+ {
+ AddStatusRecord(SQL_STATE_HY105_INVALID_PARAMETER_TYPE,
+ "The value specified for the argument InputOutputType was not SQL_PARAM_INPUT.");
- paramBindings[paramIdx].GetBuffer().SetPtrToOffsetPtr(¶mBindOffset);
+ return SQL_RESULT_ERROR;
+ }
+
+ if (!IsSqlTypeSupported(paramSqlType))
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Data type is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ IgniteSqlType driverType = ToDriverType(bufferType);
+
+ if (driverType == IGNITE_ODBC_C_TYPE_UNSUPPORTED)
+ {
+ AddStatusRecord(odbc::SQL_STATE_HY003_INVALID_APPLICATION_BUFFER_TYPE,
+ "The argument TargetType was not a valid data type.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ if (buffer)
+ {
+ ApplicationDataBuffer dataBuffer(driverType, buffer, bufferLen, resLen);
+
+ Parameter param(dataBuffer, paramSqlType, columnSize, decDigits);
+
+ SafeBindParameter(paramIdx, param);
+ }
+ else
+ SafeUnbindParameter(paramIdx);
return SQL_RESULT_SUCCESS;
}
- void Statement::UnbindParameter(uint16_t paramIdx)
+ void Statement::SafeBindParameter(uint16_t paramIdx, const app::Parameter& param)
{
- IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+ paramBindings[paramIdx] = param;
- paramBindings.erase(paramIdx);
+ paramBindings[paramIdx].GetBuffer().SetPtrToOffsetPtr(¶mBindOffset);
}
- void Statement::UnbindAllParameters()
+ void Statement::SafeUnbindParameter(uint16_t paramIdx)
{
- IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+ paramBindings.erase(paramIdx);
+ }
+ void Statement::SafeUnbindAllParameters()
+ {
paramBindings.clear();
}
@@ -536,6 +610,50 @@ namespace ignite
return currentQuery->Execute();
}
+ void Statement::FreeResources(int16_t option)
+ {
+ IGNITE_ODBC_API_CALL(InternalFreeResources(option));
+ }
+
+ SqlResult Statement::InternalFreeResources(int16_t option)
+ {
+ switch (option)
+ {
+ case SQL_DROP:
+ {
+ AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Deprecated, call SQLFreeHandle instead");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ case SQL_CLOSE:
+ {
+ return InternalClose();
+ }
+
+ case SQL_UNBIND:
+ {
+ SafeUnbindAllColumns();
+
+ break;
+ }
+
+ case SQL_RESET_PARAMS:
+ {
+ SafeUnbindAllParameters();
+
+ break;
+ }
+
+ default:
+ {
+ AddStatusRecord(SQL_STATE_HY092_OPTION_TYPE_OUT_OF_RANGE, "The value specified for the argument Option was invalid");
+ return SQL_RESULT_ERROR;
+ }
+ }
+ return SQL_RESULT_SUCCESS;
+ }
+
void Statement::Close()
{
IGNITE_ODBC_API_CALL(InternalClose());
@@ -545,7 +663,7 @@ namespace ignite
{
if (!currentQuery.get())
return SQL_RESULT_SUCCESS;
-
+
SqlResult result = currentQuery->Close();
if (result == SQL_RESULT_SUCCESS)
@@ -554,6 +672,24 @@ namespace ignite
return result;
}
+ void Statement::FetchScroll(int16_t orientation, int64_t offset)
+ {
+ IGNITE_ODBC_API_CALL(InternalFetchScroll(orientation, offset));
+ }
+
+ SqlResult Statement::InternalFetchScroll(int16_t orientation, int64_t offset)
+ {
+ UNREFERENCED_PARAMETER(offset);
+
+ if (orientation != SQL_FETCH_NEXT)
+ {
+ AddStatusRecord(SQL_STATE_HY106_FETCH_TYPE_OUT_OF_RANGE, "The value specified for the argument FetchOrientation was not SQL_FETCH_NEXT.");
+ return SQL_RESULT_ERROR;
+ }
+
+ return InternalFetchRow();
+ }
+
void Statement::FetchRow()
{
IGNITE_ODBC_API_CALL(InternalFetchRow());