You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/05/05 13:46:41 UTC
[04/31] ignite git commit: IGNITE-1786: Implemented ODBC driver.
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
new file mode 100644
index 0000000..7f0e3bd
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstring>
+#include <algorithm>
+
+#include "ignite/odbc/system/odbc_constants.h"
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/config/connection_info.h"
+
+ // Temporary workaround.
+#ifndef SQL_ASYNC_NOTIFICATION
+#define SQL_ASYNC_NOTIFICATION 10025
+#endif
+
+#ifndef SQL_ASYNC_NOTIFICATION_NOT_CAPABLE
+#define SQL_ASYNC_NOTIFICATION_NOT_CAPABLE 0x00000000L
+#endif
+
+#ifndef SQL_ASYNC_NOTIFICATION_CAPABLE
+#define SQL_ASYNC_NOTIFICATION_CAPABLE 0x00000001L
+#endif
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace config
+ {
+
+#ifdef ODBC_DEBUG
+
+#define DBG_STR_CASE(x) case x: return #x
+
+ const char * ConnectionInfo::InfoTypeToString(InfoType type)
+ {
+ switch (type)
+ {
+ DBG_STR_CASE(SQL_DRIVER_NAME);
+ DBG_STR_CASE(SQL_DBMS_NAME);
+ DBG_STR_CASE(SQL_DRIVER_ODBC_VER);
+ DBG_STR_CASE(SQL_DBMS_VER);
+ DBG_STR_CASE(SQL_DRIVER_VER);
+ DBG_STR_CASE(SQL_COLUMN_ALIAS);
+ DBG_STR_CASE(SQL_IDENTIFIER_QUOTE_CHAR);
+ DBG_STR_CASE(SQL_CATALOG_NAME_SEPARATOR);
+ DBG_STR_CASE(SQL_SPECIAL_CHARACTERS);
+ DBG_STR_CASE(SQL_CATALOG_TERM);
+ DBG_STR_CASE(SQL_TABLE_TERM);
+ DBG_STR_CASE(SQL_SCHEMA_TERM);
+ DBG_STR_CASE(SQL_ASYNC_DBC_FUNCTIONS);
+ DBG_STR_CASE(SQL_ASYNC_NOTIFICATION);
+ DBG_STR_CASE(SQL_GETDATA_EXTENSIONS);
+ DBG_STR_CASE(SQL_ODBC_INTERFACE_CONFORMANCE);
+ DBG_STR_CASE(SQL_SQL_CONFORMANCE);
+ DBG_STR_CASE(SQL_CATALOG_USAGE);
+ DBG_STR_CASE(SQL_SCHEMA_USAGE);
+ DBG_STR_CASE(SQL_MAX_IDENTIFIER_LEN);
+ DBG_STR_CASE(SQL_AGGREGATE_FUNCTIONS);
+ DBG_STR_CASE(SQL_NUMERIC_FUNCTIONS);
+ DBG_STR_CASE(SQL_STRING_FUNCTIONS);
+ DBG_STR_CASE(SQL_TIMEDATE_FUNCTIONS);
+ DBG_STR_CASE(SQL_TIMEDATE_ADD_INTERVALS);
+ DBG_STR_CASE(SQL_TIMEDATE_DIFF_INTERVALS);
+ DBG_STR_CASE(SQL_DATETIME_LITERALS);
+ DBG_STR_CASE(SQL_SYSTEM_FUNCTIONS);
+ DBG_STR_CASE(SQL_CONVERT_FUNCTIONS);
+ DBG_STR_CASE(SQL_OJ_CAPABILITIES);
+ DBG_STR_CASE(SQL_POS_OPERATIONS);
+ DBG_STR_CASE(SQL_MAX_CONCURRENT_ACTIVITIES);
+ DBG_STR_CASE(SQL_CURSOR_COMMIT_BEHAVIOR);
+ DBG_STR_CASE(SQL_CURSOR_ROLLBACK_BEHAVIOR);
+ DBG_STR_CASE(SQL_TXN_CAPABLE);
+ DBG_STR_CASE(SQL_QUOTED_IDENTIFIER_CASE);
+ DBG_STR_CASE(SQL_SQL92_NUMERIC_VALUE_FUNCTIONS);
+ DBG_STR_CASE(SQL_SQL92_STRING_FUNCTIONS);
+ DBG_STR_CASE(SQL_SQL92_DATETIME_FUNCTIONS);
+ DBG_STR_CASE(SQL_SQL92_PREDICATES);
+ DBG_STR_CASE(SQL_SQL92_RELATIONAL_JOIN_OPERATORS);
+ DBG_STR_CASE(SQL_SQL92_VALUE_EXPRESSIONS);
+ default:
+ break;
+ }
+ return "<< UNKNOWN TYPE >>";
+ }
+
+#undef DBG_STR_CASE
+#endif
+
+ ConnectionInfo::ConnectionInfo() : strParams(), intParams(),
+ shortParams()
+ {
+ //========================= String Params =========================
+ // Driver name.
+ strParams[SQL_DRIVER_NAME] = "Apache Ignite";
+ strParams[SQL_DBMS_NAME] = "Apache Ignite";
+
+ // ODBC version.
+ strParams[SQL_DRIVER_ODBC_VER] = "03.00";
+ strParams[SQL_DBMS_VER] = "03.00";
+
+#ifdef SQL_DRIVER_VER
+ // Driver version. At a minimum, the version is of the form
+ // ##.##.####, where the first two digits are the major version,
+ // the next two digits are the minor version, and the last four
+ // digits are the release version.
+ strParams[SQL_DRIVER_VER] = "01.05.0000";
+#endif // SQL_DRIVER_VER
+
+#ifdef SQL_COLUMN_ALIAS
+ // A character string: "Y" if the data source supports column
+ // aliases; otherwise, "N".
+ strParams[SQL_COLUMN_ALIAS] = "N";
+#endif // SQL_COLUMN_ALIAS
+
+#ifdef SQL_IDENTIFIER_QUOTE_CHAR
+ // The character string that is used as the starting and ending
+ // delimiter of a quoted (delimited) identifier in SQL statements.
+ // Identifiers passed as arguments to ODBC functions do not have to
+ // be quoted. If the data source does not support quoted
+ // identifiers, a blank is returned.
+ strParams[SQL_IDENTIFIER_QUOTE_CHAR] = "";
+#endif // SQL_IDENTIFIER_QUOTE_CHAR
+
+#ifdef SQL_CATALOG_NAME_SEPARATOR
+ // A character string: the character or characters that the data
+ // source defines as the separator between a catalog name and the
+ // qualified name element that follows or precedes it.
+ strParams[SQL_CATALOG_NAME_SEPARATOR] = ".";
+#endif // SQL_CATALOG_NAME_SEPARATOR
+
+#ifdef SQL_SPECIAL_CHARACTERS
+ // A character string that contains all special characters (that
+ // is, all characters except a through z, A through Z, 0 through 9,
+ // and underscore) that can be used in an identifier name, such as
+ // a table name, column name, or index name, on the data source.
+ strParams[SQL_SPECIAL_CHARACTERS] = "";
+#endif // SQL_SPECIAL_CHARACTERS
+
+#ifdef SQL_CATALOG_TERM
+ // A character string with the data source vendor's name for
+ // a catalog; for example, "database" or "directory". This string
+ // can be in upper, lower, or mixed case.
+ strParams[SQL_CATALOG_TERM] = "catalog";
+#endif // SQL_CATALOG_TERM
+
+#ifdef SQL_TABLE_TERM
+ // A character string with the data source vendor's name for
+ // a table; for example, "table" or "file".
+ strParams[SQL_TABLE_TERM] = "table";
+#endif // SQL_TABLE_TERM
+
+#ifdef SQL_SCHEMA_TERM
+ // A character string with the data source vendor's name for
+ // a schema; for example, "owner", "Authorization ID", or "Schema".
+ strParams[SQL_SCHEMA_TERM] = "schema";
+#endif // SQL_SCHEMA_TERM
+
+#ifdef SQL_ASYNC_DBC_FUNCTIONS
+ //======================== Integer Params =========================
+ // Indicates if the driver can execute functions asynchronously
+ // on the connection handle.
+ // SQL_ASYNC_DBC_CAPABLE = The driver can execute connection
+ // functions asynchronously.
+ // SQL_ASYNC_DBC_NOT_CAPABLE = The driver can not execute
+ // connection functions asynchronously.
+ intParams[SQL_ASYNC_DBC_FUNCTIONS] = SQL_ASYNC_DBC_NOT_CAPABLE;
+#endif // SQL_ASYNC_DBC_FUNCTIONS
+
+#ifdef SQL_ASYNC_NOTIFICATION
+ // Indicates if the driver supports asynchronous notification.
+ // SQL_ASYNC_NOTIFICATION_CAPABLE = Asynchronous execution
+ // notification is supported by the driver.
+ // SQL_ASYNC_NOTIFICATION_NOT_CAPABLE Asynchronous execution
+ // notification is not supported by the driver.
+ intParams[SQL_ASYNC_NOTIFICATION] = SQL_ASYNC_NOTIFICATION_NOT_CAPABLE;
+#endif // SQL_ASYNC_NOTIFICATION
+
+#ifdef SQL_GETDATA_EXTENSIONS
+ // Bitmask enumerating extensions to SQLGetData.
+ intParams[SQL_GETDATA_EXTENSIONS] = SQL_GD_ANY_COLUMN;
+#endif // SQL_GETDATA_EXTENSIONS
+
+#ifdef SQL_ODBC_INTERFACE_CONFORMANCE
+ // Indicates the level of the ODBC 3.x interface that the driver
+ // complies with.
+ intParams[SQL_ODBC_INTERFACE_CONFORMANCE] = SQL_OIC_CORE;
+#endif // SQL_ODBC_INTERFACE_CONFORMANCE
+
+#ifdef SQL_SQL_CONFORMANCE
+ // Indicates the level of SQL-92 supported by the driver.
+ intParams[SQL_SQL_CONFORMANCE] = 0; // SQL_SC_SQL92_ENTRY;
+#endif // SQL_SQL_CONFORMANCE
+
+#ifdef SQL_CATALOG_USAGE
+ // Bitmask enumerating the statements in which catalogs can be used.
+ intParams[SQL_CATALOG_USAGE] = 0;
+#endif // SQL_CATALOG_USAGE
+
+#ifdef SQL_SCHEMA_USAGE
+ // Bitmask enumerating the statements in which schemas can be used.
+ intParams[SQL_SCHEMA_USAGE] = 0;
+#endif // SQL_SCHEMA_USAGE
+
+#ifdef SQL_MAX_IDENTIFIER_LEN
+ // Indicates the maximum size in characters that the data source
+ // supports for user-defined names.
+ intParams[SQL_MAX_IDENTIFIER_LEN] = 128;
+#endif // SQL_MAX_IDENTIFIER_LEN
+
+#ifdef SQL_AGGREGATE_FUNCTIONS
+ // Bitmask enumerating support for aggregation functions.
+ intParams[SQL_AGGREGATE_FUNCTIONS] = SQL_AF_ALL | SQL_AF_AVG |
+ SQL_AF_COUNT | SQL_AF_DISTINCT | SQL_AF_MAX | SQL_AF_MIN |
+ SQL_AF_SUM;
+#endif // SQL_AGGREGATE_FUNCTIONS
+
+#ifdef SQL_NUMERIC_FUNCTIONS
+ // Bitmask enumerating the scalar numeric functions supported by
+ // the driver and associated data source.
+ intParams[SQL_NUMERIC_FUNCTIONS] = SQL_FN_NUM_ABS;
+#endif // SQL_NUMERIC_FUNCTIONS
+
+#ifdef SQL_STRING_FUNCTIONS
+ // Bitmask enumerating the scalar string functions supported by the
+ // driver and associated data source.
+ intParams[SQL_STRING_FUNCTIONS] = 0;
+#endif // SQL_STRING_FUNCTIONS
+
+#ifdef SQL_TIMEDATE_FUNCTIONS
+ // Bitmask enumerating the scalar date and time functions supported
+ // by the driver and associated data source.
+ intParams[SQL_TIMEDATE_FUNCTIONS] = 0;
+#endif // SQL_TIMEDATE_FUNCTIONS
+
+#ifdef SQL_TIMEDATE_ADD_INTERVALS
+ // Bitmask enumerating timestamp intervals supported by the driver
+ // and associated data source for the TIMESTAMPADD scalar function.
+ intParams[SQL_TIMEDATE_ADD_INTERVALS] = 0;
+#endif // SQL_TIMEDATE_ADD_INTERVALS
+
+#ifdef SQL_TIMEDATE_DIFF_INTERVALS
+ // Bitmask enumerating timestamp intervals supported by the driver
+ // and associated data source for the TIMESTAMPDIFF scalar function.
+ intParams[SQL_TIMEDATE_DIFF_INTERVALS] = 0;
+#endif // SQL_TIMEDATE_DIFF_INTERVALS
+
+#ifdef SQL_DATETIME_LITERALS
+ // Bitmask enumerating the SQL-92 datetime literals supported by
+ // the data source.
+ intParams[SQL_DATETIME_LITERALS] = SQL_DL_SQL92_INTERVAL_HOUR |
+ SQL_DL_SQL92_DATE | SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND |
+ SQL_DL_SQL92_TIME | SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND |
+ SQL_DL_SQL92_TIMESTAMP | SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE |
+ SQL_DL_SQL92_INTERVAL_YEAR | SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND |
+ SQL_DL_SQL92_INTERVAL_MONTH | SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR |
+ SQL_DL_SQL92_INTERVAL_DAY | SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE |
+ SQL_DL_SQL92_INTERVAL_MINUTE | SQL_DL_SQL92_INTERVAL_SECOND |
+ SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH;
+#endif // SQL_DATETIME_LITERALS
+
+#ifdef SQL_SYSTEM_FUNCTIONS
+ // Bitmask enumerating the scalar system functions supported by the
+ // driver and associated data source.
+ intParams[SQL_SYSTEM_FUNCTIONS] = 0;
+#endif // SQL_SYSTEM_FUNCTIONS
+
+#ifdef SQL_CONVERT_FUNCTIONS
+ // Bitmask enumerating the scalar conversion functions supported
+ // by the driver and associated data source.
+ intParams[SQL_CONVERT_FUNCTIONS] = 0;
+#endif // SQL_CONVERT_FUNCTIONS
+
+#ifdef SQL_OJ_CAPABILITIES
+ // Bitmask enumerating the types of outer joins supported by the
+ // driver and data source.
+ intParams[SQL_OJ_CAPABILITIES] = SQL_OJ_LEFT | SQL_OJ_RIGHT |
+ SQL_OJ_FULL | SQL_OJ_NESTED | SQL_OJ_INNER |
+ SQL_OJ_ALL_COMPARISON_OPS;
+#endif // SQL_OJ_CAPABILITIES
+
+#ifdef SQL_POS_OPERATIONS
+ // Bitmask enumerating the support operations in SQLSetPos.
+ intParams[SQL_POS_OPERATIONS] = 0;
+#endif // SQL_POS_OPERATIONS
+
+#ifdef SQL_SQL92_NUMERIC_VALUE_FUNCTIONS
+ // Bitmask enumerating the numeric value scalar functions.
+ intParams[SQL_SQL92_NUMERIC_VALUE_FUNCTIONS] = 0;
+#endif // SQL_SQL92_NUMERIC_VALUE_FUNCTIONS
+
+#ifdef SQL_SQL92_STRING_FUNCTIONS
+ // Bitmask enumerating the string scalar functions.
+ intParams[SQL_SQL92_STRING_FUNCTIONS] = 0;
+#endif // SQL_SQL92_STRING_FUNCTIONS
+
+#ifdef SQL_SQL92_DATETIME_FUNCTIONS
+ // Bitmask enumerating the datetime scalar functions.
+ intParams[SQL_SQL92_DATETIME_FUNCTIONS] = SQL_SDF_CURRENT_DATE |
+ SQL_SDF_CURRENT_TIMESTAMP;
+#endif // SQL_SQL92_DATETIME_FUNCTIONS
+
+#ifdef SQL_SQL92_VALUE_EXPRESSIONS
+ // Bitmask enumerating the value expressions supported,
+ // as defined in SQL-92.
+ intParams[SQL_SQL92_VALUE_EXPRESSIONS] = SQL_SVE_CASE |
+ SQL_SVE_COALESCE | SQL_SVE_NULLIF;
+#endif // SQL_SQL92_VALUE_EXPRESSIONS
+
+#ifdef SQL_SQL92_PREDICATES
+ // Bitmask enumerating the datetime scalar functions.
+ intParams[SQL_SQL92_PREDICATES] = SQL_SP_BETWEEN |
+ SQL_SP_COMPARISON | SQL_SP_EXISTS | SQL_SP_IN |
+ SQL_SP_ISNOTNULL | SQL_SP_ISNULL | SQL_SP_LIKE |
+ SQL_SP_MATCH_FULL | SQL_SP_MATCH_PARTIAL |
+ SQL_SP_MATCH_UNIQUE_FULL | SQL_SP_MATCH_UNIQUE_PARTIAL |
+ SQL_SP_OVERLAPS | SQL_SP_QUANTIFIED_COMPARISON |
+ SQL_SP_UNIQUE;
+#endif // SQL_SQL92_PREDICATES
+
+#ifdef SQL_SQL92_RELATIONAL_JOIN_OPERATORS
+ // Bitmask enumerating the relational join operators supported
+ // in a SELECT statement, as defined in SQL-92.
+ intParams[SQL_SQL92_RELATIONAL_JOIN_OPERATORS] =
+ SQL_SRJO_CORRESPONDING_CLAUSE | SQL_SRJO_CROSS_JOIN |
+ SQL_SRJO_EXCEPT_JOIN | SQL_SRJO_EXCEPT_JOIN |
+ SQL_SRJO_INNER_JOIN | SQL_SRJO_INTERSECT_JOIN |
+ SQL_SRJO_LEFT_OUTER_JOIN | SQL_SRJO_NATURAL_JOIN |
+ SQL_SRJO_RIGHT_OUTER_JOIN | SQL_SRJO_UNION_JOIN;
+#endif // SQL_SQL92_RELATIONAL_JOIN_OPERATORS
+
+ //========================= Short Params ==========================
+#ifdef SQL_MAX_CONCURRENT_ACTIVITIES
+ // The maximum number of active statements that the driver can
+ // support for a connection. Zero mean no limit.
+ shortParams[SQL_MAX_CONCURRENT_ACTIVITIES] = 32;
+#endif // SQL_MAX_CONCURRENT_ACTIVITIES
+
+#ifdef SQL_CURSOR_COMMIT_BEHAVIOR
+ // Indicates how a COMMIT operation affects cursors and prepared
+ // statements in the data source.
+ shortParams[SQL_CURSOR_COMMIT_BEHAVIOR] = SQL_CB_PRESERVE;
+#endif // SQL_CURSOR_COMMIT_BEHAVIOR
+
+#ifdef SQL_CURSOR_ROLLBACK_BEHAVIOR
+ // Indicates how a ROLLBACK operation affects cursors and prepared
+ // statements in the data source.
+ shortParams[SQL_CURSOR_ROLLBACK_BEHAVIOR] = SQL_CB_PRESERVE;
+#endif // SQL_CURSOR_ROLLBACK_BEHAVIOR
+
+#ifdef SQL_TXN_CAPABLE
+ // Describs the transaction support in the driver or data source.
+ shortParams[SQL_TXN_CAPABLE] = SQL_TC_NONE;
+#endif // SQL_TXN_CAPABLE
+
+#ifdef SQL_QUOTED_IDENTIFIER_CASE
+ // Case-sensitiveness of the quoted identifiers in SQL.
+ shortParams[SQL_QUOTED_IDENTIFIER_CASE] = SQL_IC_SENSITIVE;
+#endif // SQL_QUOTED_IDENTIFIER_CASE
+ }
+
+ ConnectionInfo::~ConnectionInfo()
+ {
+ // No-op.
+ }
+
+ SqlResult ConnectionInfo::GetInfo(InfoType type, void* buf,
+ short buflen, short* reslen) const
+ {
+ if (!buf || !buflen)
+ return SQL_RESULT_ERROR;
+
+ StringInfoMap::const_iterator itStr = strParams.find(type);
+
+ if (itStr != strParams.cend())
+ {
+ unsigned short strlen = static_cast<short>(
+ utility::CopyStringToBuffer(itStr->second,
+ reinterpret_cast<char*>(buf), buflen));
+
+ if (reslen)
+ *reslen = strlen;
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ UintInfoMap::const_iterator itInt = intParams.find(type);
+
+ if (itInt != intParams.cend())
+ {
+ unsigned int *res = reinterpret_cast<unsigned int*>(buf);
+
+ *res = itInt->second;
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ UshortInfoMap::const_iterator itShort = shortParams.find(type);
+
+ if (itShort != shortParams.cend())
+ {
+ unsigned short *res = reinterpret_cast<unsigned short*>(buf);
+
+ *res = itShort->second;
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ return SQL_RESULT_ERROR;
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/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
new file mode 100644
index 0000000..59a25f9
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -0,0 +1,347 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstring>
+
+#include <sstream>
+
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/statement.h"
+#include "ignite/odbc/connection.h"
+#include "ignite/odbc/message.h"
+#include "ignite/odbc/config/configuration.h"
+
+// TODO: implement appropriate protocol with de-/serialisation.
+namespace
+{
+#pragma pack(push, 1)
+ struct OdbcProtocolHeader
+ {
+ int32_t len;
+ };
+#pragma pack(pop)
+}
+
+namespace ignite
+{
+ namespace odbc
+ {
+ const std::string Connection::PROTOCOL_VERSION_SINCE = "1.6.0";
+
+ Connection::Connection() : socket(), connected(false), cache(), parser()
+ {
+ // No-op.
+ }
+
+ Connection::~Connection()
+ {
+ // No-op.
+ }
+
+ const config::ConnectionInfo& Connection::GetInfo() const
+ {
+ // Connection info is the same for all connections now.
+ static config::ConnectionInfo info;
+
+ return info;
+ }
+
+ void Connection::GetInfo(config::ConnectionInfo::InfoType type, void* buf, short buflen, short* reslen)
+ {
+ IGNITE_ODBC_API_CALL(InternalGetInfo(type, buf, buflen, reslen));
+ }
+
+ SqlResult Connection::InternalGetInfo(config::ConnectionInfo::InfoType type, void* buf, short buflen, short* reslen)
+ {
+ const config::ConnectionInfo& info = GetInfo();
+
+ SqlResult res = info.GetInfo(type, buf, buflen, reslen);
+
+ if (res != SQL_RESULT_SUCCESS)
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, "Not implemented.");
+
+ return res;
+ }
+
+ void Connection::Establish(const std::string& server)
+ {
+ IGNITE_ODBC_API_CALL(InternalEstablish(server));
+ }
+
+ SqlResult Connection::InternalEstablish(const std::string& server)
+ {
+ config::Configuration config;
+
+ if (server != config.GetDsn())
+ {
+ AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Unknown server.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ return InternalEstablish(config.GetHost(), config.GetPort(), config.GetCache());
+ }
+
+ void Connection::Establish(const std::string& host, uint16_t port, const std::string& cache)
+ {
+ IGNITE_ODBC_API_CALL(InternalEstablish(host, port, cache));
+ }
+
+ SqlResult Connection::InternalEstablish(const std::string & host, uint16_t port, const std::string & cache)
+ {
+ if (connected)
+ {
+ AddStatusRecord(SQL_STATE_08002_ALREADY_CONNECTED, "Already connected.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ this->cache = cache;
+
+ connected = socket.Connect(host.c_str(), port);
+
+ if (!connected)
+ {
+ AddStatusRecord(SQL_STATE_08001_CANNOT_CONNECT, "Failed to establish connection with the host.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ return MakeRequestHandshake();
+ }
+
+ void Connection::Release()
+ {
+ IGNITE_ODBC_API_CALL(InternalRelease());
+ }
+
+ SqlResult Connection::InternalRelease()
+ {
+ if (!connected)
+ {
+ AddStatusRecord(SQL_STATE_08003_NOT_CONNECTED, "Connection is not open.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ socket.Close();
+
+ connected = false;
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ Statement* Connection::CreateStatement()
+ {
+ Statement* statement;
+
+ IGNITE_ODBC_API_CALL(InternalCreateStatement(statement));
+
+ return statement;
+ }
+
+ SqlResult Connection::InternalCreateStatement(Statement*& statement)
+ {
+ statement = new Statement(*this);
+
+ if (!statement)
+ {
+ AddStatusRecord(SQL_STATE_HY001_MEMORY_ALLOCATION, "Not enough memory.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Connection::Send(const int8_t* data, size_t len)
+ {
+ if (!connected)
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_ILLEGAL_STATE, "Connection is not established");
+
+ OdbcProtocolHeader hdr;
+
+ hdr.len = static_cast<int32_t>(len);
+
+ size_t sent = SendAll(reinterpret_cast<int8_t*>(&hdr), sizeof(hdr));
+
+ if (sent != sizeof(hdr))
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not send message header");
+
+ sent = SendAll(data, len);
+
+ if (sent != len)
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not send message body");
+ }
+
+ size_t Connection::SendAll(const int8_t* data, size_t len)
+ {
+ int sent = 0;
+
+ while (sent != len)
+ {
+ int res = socket.Send(data + sent, len - sent);
+
+ LOG_MSG("Sent: %d\n", res);
+
+ if (res <= 0)
+ return sent;
+
+ sent += res;
+ }
+
+ return sent;
+ }
+
+ void Connection::Receive(std::vector<int8_t>& msg)
+ {
+ if (!connected)
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_ILLEGAL_STATE, "Connection is not established");
+
+ msg.clear();
+
+ OdbcProtocolHeader 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");
+
+ if (hdr.len < 0)
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Message lenght is negative");
+
+ if (hdr.len == 0)
+ return;
+
+ msg.resize(hdr.len);
+
+ received = ReceiveAll(&msg[0], hdr.len);
+
+ if (received != hdr.len)
+ {
+ msg.resize(received);
+
+ IGNITE_ERROR_1(IgniteError::IGNITE_ERR_GENERIC, "Can not receive message body");
+ }
+ }
+
+ size_t Connection::ReceiveAll(void* dst, size_t len)
+ {
+ size_t remain = len;
+ int8_t* buffer = reinterpret_cast<int8_t*>(dst);
+
+ while (remain)
+ {
+ size_t received = len - remain;
+
+ int res = socket.Receive(buffer + received, remain);
+ LOG_MSG("Receive res: %d\n", res);
+ LOG_MSG("remain: %d\n", remain);
+
+ if (res <= 0)
+ return received;
+
+ remain -= static_cast<size_t>(res);
+ }
+
+ return len;
+ }
+
+ const std::string& Connection::GetCache() const
+ {
+ return cache;
+ }
+
+ diagnostic::DiagnosticRecord Connection::CreateStatusRecord(SqlState sqlState,
+ const std::string& message, int32_t rowNum, int32_t columnNum) const
+ {
+ return diagnostic::DiagnosticRecord(sqlState, message, "", "", rowNum, columnNum);
+ }
+
+ void Connection::TransactionCommit()
+ {
+ IGNITE_ODBC_API_CALL(InternalTransactionCommit());
+ }
+
+ SqlResult Connection::InternalTransactionCommit()
+ {
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Connection::TransactionRollback()
+ {
+ IGNITE_ODBC_API_CALL(InternalTransactionRollback());
+ }
+
+ SqlResult Connection::InternalTransactionRollback()
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Rollback operation is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ SqlResult Connection::MakeRequestHandshake()
+ {
+ HandshakeRequest req(PROTOCOL_VERSION);
+ HandshakeResponse rsp;
+
+ try
+ {
+ SyncMessage(req, rsp);
+ }
+ catch (const IgniteError& err)
+ {
+ AddStatusRecord(SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT, err.GetText());
+
+ return SQL_RESULT_ERROR;
+ }
+
+ if (rsp.GetStatus() != RESPONSE_STATUS_SUCCESS)
+ {
+ LOG_MSG("Error: %s\n", rsp.GetError().c_str());
+
+ AddStatusRecord(SQL_STATE_08001_CANNOT_CONNECT, rsp.GetError());
+
+ InternalRelease();
+
+ return SQL_RESULT_ERROR;
+ }
+
+ if (!rsp.IsAccepted())
+ {
+ LOG_MSG("Hanshake message has been rejected.\n");
+
+ std::stringstream constructor;
+
+ constructor << "Node rejected handshake message. "
+ << "Current node Apache Ignite version: " << rsp.CurrentVer() << ", "
+ << "node protocol version introduced in version: " << rsp.ProtoVerSince() << ", "
+ << "driver protocol version introduced in version: " << PROTOCOL_VERSION_SINCE << ".";
+
+ AddStatusRecord(SQL_STATE_08001_CANNOT_CONNECT, constructor.str());
+
+ InternalRelease();
+
+ return SQL_RESULT_ERROR;
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/cursor.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/cursor.cpp b/modules/platforms/cpp/odbc/src/cursor.cpp
new file mode 100644
index 0000000..2648278
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/cursor.cpp
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/odbc/cursor.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ Cursor::Cursor(int64_t queryId) : queryId(queryId), currentPage(),
+ currentPagePos(0), currentRow()
+ {
+ // No-op.
+ }
+
+ Cursor::~Cursor()
+ {
+ // No-op.
+ }
+
+ bool Cursor::Increment()
+ {
+ if (currentPage.get() && currentPagePos < currentPage->GetSize())
+ {
+ ++currentPagePos;
+
+ if (currentPagePos == currentPage->GetSize())
+ currentRow.reset();
+ else
+ {
+ Row *row = currentRow.get();
+
+ if (row)
+ row->MoveToNext();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool Cursor::NeedDataUpdate() const
+ {
+ return !currentPage.get() || (!currentPage->IsLast() &&
+ currentPagePos == currentPage->GetSize());
+ }
+
+ bool Cursor::HasData() const
+ {
+ return !currentPage.get() || !currentPage->IsLast() ||
+ currentPagePos < currentPage->GetSize();
+ }
+
+ void Cursor::UpdateData(std::auto_ptr<ResultPage>& newPage)
+ {
+ currentPage = newPage;
+
+ currentPagePos = 0;
+
+ currentRow.reset(new Row(currentPage->GetData()));
+ }
+
+ Row* Cursor::GetRow()
+ {
+ return currentRow.get();
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/decimal.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/decimal.cpp b/modules/platforms/cpp/odbc/src/decimal.cpp
new file mode 100644
index 0000000..c1b2c44
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/decimal.cpp
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstring>
+#include <utility>
+
+#include "ignite/common/utils.h"
+
+#include "ignite/odbc/decimal.h"
+
+namespace ignite
+{
+ Decimal::Decimal() :
+ scale(0), len(0), magnitude(0)
+ {
+ // No-op.
+ }
+
+ Decimal::Decimal(int32_t scale, const int8_t* mag, int32_t len) :
+ scale(scale), len(len), magnitude(0)
+ {
+ magnitude = new int8_t[len];
+
+ memcpy(magnitude, mag, len);
+ }
+
+ Decimal::Decimal(const Decimal& other) :
+ scale(other.scale), len(other.len), magnitude(0)
+ {
+ magnitude = new int8_t[len];
+
+ memcpy(magnitude, other.magnitude, len);
+ }
+
+ Decimal::~Decimal()
+ {
+ if (magnitude)
+ delete[] magnitude;
+ }
+
+ Decimal& Decimal::operator=(const Decimal& other)
+ {
+ Decimal tmp(other);
+
+ swap(tmp, *this);
+
+ return *this;
+ }
+
+ Decimal::operator double() const
+ {
+ double res = 0;
+
+ for (int32_t i = 0; i < len; ++i)
+ res = (res * 256) + static_cast<uint8_t>(magnitude[i]);
+
+ for (int32_t i = 0; i < GetScale(); ++i)
+ res /= 10.0;
+
+ return res * GetSign();
+ }
+
+ int32_t Decimal::GetScale() const
+ {
+ return scale & 0x7FFFFFFF;
+ }
+
+ int32_t Decimal::GetSign() const
+ {
+ return IsNegative() ? -1 : 1;
+ }
+
+ bool Decimal::IsNegative() const
+ {
+ return (scale & 0x80000000) != 0;
+ }
+
+ int32_t Decimal::GetLength() const
+ {
+ return len;
+ }
+
+ int32_t Decimal::BitLength() const
+ {
+ using namespace common;
+
+ if (len == 0)
+ return 0;
+
+ int32_t bitsLen = (len - 1) * 8 +
+ BitLengthForOctet(magnitude[len - 1]);
+
+ if (IsNegative()) {
+
+ // Check if magnitude is a power of two
+ bool pow2 = PowerOfTwo(magnitude[len - 1]);
+ for (int i = 0; i < len - 1 && pow2; ++i)
+ pow2 = (magnitude[i] == 0);
+
+ if (pow2)
+ --bitsLen;
+ }
+
+ return bitsLen;
+ }
+
+ const int8_t* Decimal::GetMagnitude() const
+ {
+ return magnitude;
+ }
+
+ void swap(Decimal& first, Decimal& second)
+ {
+ using std::swap;
+
+ std::swap(first.scale, second.scale);
+ std::swap(first.len, second.len);
+ std::swap(first.magnitude, second.magnitude);
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
new file mode 100644
index 0000000..260e3e4
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/odbc/connection.h"
+#include "ignite/odbc/diagnostic/diagnosable_adapter.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace diagnostic
+ {
+ void DiagnosableAdapter::AddStatusRecord(SqlState sqlState,
+ const std::string& message, int32_t rowNum, int32_t columnNum)
+ {
+ if (connection)
+ {
+ diagnosticRecords.AddStatusRecord(
+ connection->CreateStatusRecord(sqlState, message, rowNum, columnNum));
+ }
+ else
+ {
+ diagnosticRecords.AddStatusRecord(
+ DiagnosticRecord(sqlState, message, "", "", rowNum, columnNum));
+ }
+ }
+
+ void DiagnosableAdapter::AddStatusRecord(SqlState sqlState, const std::string& message)
+ {
+ LOG_MSG("Adding new record: %s\n", message.c_str());
+
+ AddStatusRecord(sqlState, message, 0, 0);
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/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
new file mode 100644
index 0000000..568c125
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <string>
+
+#include "ignite/odbc/diagnostic/diagnostic_record.h"
+
+namespace
+{
+ /** SQLSTATEs defined by Open Group and ISO call-level interface. */
+ const std::string ORIGIN_ISO_9075 = "ISO 9075";
+
+ /** ODBC-specific SQLSTATEs (all those whose SQLSTATE class is "IM"). */
+ const std::string ORIGIN_ODBC_3_0 = "ODBC 3.0";
+
+ /** SQL state unknown constant. */
+ const std::string STATE_UNKNOWN = "";
+
+ /** SQL state 01004 constant. */
+ const std::string STATE_01004 = "01004";
+
+ /** SQL state 01S01 constant. */
+ const std::string STATE_01S01 = "01S01";
+
+ /** SQL state 24000 constant. */
+ const std::string STATE_24000 = "24000";
+
+ /** SQL state 08001 constant. */
+ const std::string STATE_08001 = "08001";
+
+ /** SQL state 08002 constant. */
+ const std::string STATE_08002 = "08002";
+
+ /** SQL state 08003 constant. */
+ const std::string STATE_08003 = "08003";
+
+ /** SQL state HY000 constant. */
+ const std::string STATE_HY000 = "HY000";
+
+ /** SQL state HY001 constant. */
+ const std::string STATE_HY001 = "HY001";
+
+ /** SQL state HY010 constant. */
+ const std::string STATE_HY010 = "HY010";
+
+ /** SQL state HYC00 constant. */
+ const std::string STATE_HYC00 = "HYC00";
+
+ /** SQL state HYT01 constant. */
+ const std::string STATE_HYT01 = "HYT01";
+}
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace diagnostic
+ {
+ DiagnosticRecord::DiagnosticRecord() :
+ sqlState(SQL_STATE_UNKNOWN),
+ message(),
+ connectionName(),
+ serverName(),
+ rowNum(0),
+ columnNum(0)
+ {
+ // No-op.
+ }
+
+ DiagnosticRecord::DiagnosticRecord(SqlState sqlState,
+ const std::string& message, const std::string& connectionName,
+ const std::string& serverName, int32_t rowNum, int32_t columnNum) :
+ sqlState(sqlState),
+ message(message),
+ connectionName(connectionName),
+ serverName(serverName),
+ rowNum(rowNum),
+ columnNum(columnNum)
+ {
+ // No-op.
+ }
+
+ DiagnosticRecord::~DiagnosticRecord()
+ {
+ // No-op.
+ }
+
+ const std::string& DiagnosticRecord::GetClassOrigin() const
+ {
+ const std::string& state = GetSqlState();
+
+ if (state[0] == 'I' && state[1] == 'M')
+ return ORIGIN_ODBC_3_0;
+
+ return ORIGIN_ISO_9075;
+ }
+
+ const std::string& DiagnosticRecord::GetSubclassOrigin() const
+ {
+ static std::set<std::string> odbcSubclasses;
+
+ if (odbcSubclasses.empty())
+ {
+ odbcSubclasses.insert("01S00");
+ odbcSubclasses.insert("01S01");
+ odbcSubclasses.insert("01S02");
+ odbcSubclasses.insert("01S06");
+ odbcSubclasses.insert("01S07");
+ odbcSubclasses.insert("07S01");
+ odbcSubclasses.insert("08S01");
+ odbcSubclasses.insert("21S01");
+ odbcSubclasses.insert("21S02");
+ odbcSubclasses.insert("25S01");
+ odbcSubclasses.insert("25S02");
+ odbcSubclasses.insert("25S03");
+ odbcSubclasses.insert("42S01");
+ odbcSubclasses.insert("42S02");
+ odbcSubclasses.insert("42S11");
+ odbcSubclasses.insert("42S12");
+ odbcSubclasses.insert("42S21");
+ odbcSubclasses.insert("42S22");
+ odbcSubclasses.insert("HY095");
+ odbcSubclasses.insert("HY097");
+ odbcSubclasses.insert("HY098");
+ odbcSubclasses.insert("HY099");
+ odbcSubclasses.insert("HY100");
+ odbcSubclasses.insert("HY101");
+ odbcSubclasses.insert("HY105");
+ odbcSubclasses.insert("HY107");
+ odbcSubclasses.insert("HY109");
+ odbcSubclasses.insert("HY110");
+ odbcSubclasses.insert("HY111");
+ odbcSubclasses.insert("HYT00");
+ odbcSubclasses.insert("HYT01");
+ odbcSubclasses.insert("IM001");
+ odbcSubclasses.insert("IM002");
+ odbcSubclasses.insert("IM003");
+ odbcSubclasses.insert("IM004");
+ odbcSubclasses.insert("IM005");
+ odbcSubclasses.insert("IM006");
+ odbcSubclasses.insert("IM007");
+ odbcSubclasses.insert("IM008");
+ odbcSubclasses.insert("IM010");
+ odbcSubclasses.insert("IM011");
+ odbcSubclasses.insert("IM012");
+ }
+
+ const std::string& state = GetSqlState();
+
+ if (odbcSubclasses.find(state) != odbcSubclasses.end())
+ return ORIGIN_ODBC_3_0;
+
+ return ORIGIN_ISO_9075;
+ }
+
+ const std::string& DiagnosticRecord::GetMessage() const
+ {
+ return message;
+ }
+
+ const std::string& DiagnosticRecord::GetConnectionName() const
+ {
+ return connectionName;
+ }
+
+ const std::string& DiagnosticRecord::GetServerName() const
+ {
+ return serverName;
+ }
+
+ const std::string& DiagnosticRecord::GetSqlState() const
+ {
+ switch (sqlState)
+ {
+ case SQL_STATE_01004_DATA_TRUNCATED:
+ return STATE_01004;
+
+ case SQL_STATE_01S01_ERROR_IN_ROW:
+ return STATE_01S01;
+
+ case SQL_STATE_24000_INVALID_CURSOR_STATE:
+ return STATE_24000;
+
+ case SQL_STATE_08001_CANNOT_CONNECT:
+ return STATE_08001;
+
+ case SQL_STATE_08002_ALREADY_CONNECTED:
+ return STATE_08002;
+
+ case SQL_STATE_08003_NOT_CONNECTED:
+ return STATE_08003;
+
+ case SQL_STATE_HY000_GENERAL_ERROR:
+ return STATE_HY000;
+
+ case SQL_STATE_HY001_MEMORY_ALLOCATION:
+ return STATE_HY001;
+
+ case SQL_STATE_HY010_SEQUENCE_ERROR:
+ return STATE_HY010;
+
+ case SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED:
+ return STATE_HYC00;
+
+ case SQL_STATE_HYT01_CONNECTIOIN_TIMEOUT:
+ return STATE_HYT01;
+
+ default:
+ break;
+ }
+
+ return STATE_UNKNOWN;
+ }
+
+ int32_t DiagnosticRecord::GetRowNumber() const
+ {
+ return rowNum;
+ }
+
+ int32_t DiagnosticRecord::GetColumnNumber() const
+ {
+ return columnNum;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
new file mode 100644
index 0000000..90c0a4f
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record_storage.cpp
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <set>
+#include <string>
+
+#include "ignite/odbc/diagnostic/diagnostic_record_storage.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ namespace diagnostic
+ {
+ DiagnosticRecordStorage::DiagnosticRecordStorage() :
+ rowCount(0),
+ dynamicFunction(),
+ dynamicFunctionCode(0),
+ result(SQL_RESULT_SUCCESS),
+ rowsAffected(0)
+ {
+ // No-op.
+ }
+
+ DiagnosticRecordStorage::~DiagnosticRecordStorage()
+ {
+ // No-op.
+ }
+
+ void DiagnosticRecordStorage::SetHeaderRecord(SqlResult result)
+ {
+ rowCount = 0;
+ dynamicFunction.clear();
+ dynamicFunctionCode = 0;
+ this->result = result;
+ rowsAffected = 0;
+ }
+
+ void DiagnosticRecordStorage::AddStatusRecord(const DiagnosticRecord& record)
+ {
+ statusRecords.push_back(record);
+ }
+
+ void DiagnosticRecordStorage::Reset()
+ {
+ SetHeaderRecord(SQL_RESULT_ERROR);
+
+ statusRecords.clear();
+ }
+
+ SqlResult DiagnosticRecordStorage::GetOperaionResult() const
+ {
+ return result;
+ }
+
+ int DiagnosticRecordStorage::GetReturnCode() const
+ {
+ return SqlResultToReturnCode(result);
+ }
+
+ int64_t DiagnosticRecordStorage::GetRowCount() const
+ {
+ return rowCount;
+ }
+
+ const std::string & DiagnosticRecordStorage::GetDynamicFunction() const
+ {
+ return dynamicFunction;
+ }
+
+ int32_t DiagnosticRecordStorage::GetDynamicFunctionCode() const
+ {
+ return dynamicFunctionCode;
+ }
+
+ int32_t DiagnosticRecordStorage::GetRowsAffected() const
+ {
+ return rowsAffected;
+ }
+
+ int32_t DiagnosticRecordStorage::GetStatusRecordsNumber() const
+ {
+ return static_cast<int32_t>(statusRecords.size());
+ }
+
+ const DiagnosticRecord& DiagnosticRecordStorage::GetStatusRecord(int32_t idx) const
+ {
+ return statusRecords[idx - 1];
+ }
+
+ bool DiagnosticRecordStorage::IsSuccessful() const
+ {
+ return result == SQL_RESULT_SUCCESS ||
+ result == SQL_RESULT_SUCCESS_WITH_INFO;
+ }
+
+ SqlResult DiagnosticRecordStorage::GetField(int32_t recNum, DiagnosticField field, app::ApplicationDataBuffer& buffer) const
+ {
+ // Header record.
+ switch (field)
+ {
+ case IGNITE_SQL_DIAG_HEADER_CURSOR_ROW_COUNT:
+ {
+ buffer.PutInt64(GetRowCount());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_HEADER_DYNAMIC_FUNCTION:
+ {
+ buffer.PutString(GetDynamicFunction());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_HEADER_DYNAMIC_FUNCTION_CODE:
+ {
+ buffer.PutInt32(GetDynamicFunctionCode());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_HEADER_NUMBER:
+ {
+ buffer.PutInt32(GetStatusRecordsNumber());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_HEADER_RETURNCODE:
+ {
+ buffer.PutInt32(GetReturnCode());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_HEADER_ROW_COUNT:
+ {
+ buffer.PutInt64(GetRowsAffected());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ if (recNum < 1 || static_cast<size_t>(recNum) > statusRecords.size())
+ return SQL_RESULT_NO_DATA;
+
+ // Status record.
+ const DiagnosticRecord& record = GetStatusRecord(recNum);
+
+ switch (field)
+ {
+ case IGNITE_SQL_DIAG_STATUS_CLASS_ORIGIN:
+ {
+ buffer.PutString(record.GetClassOrigin());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_COLUMN_NUMBER:
+ {
+ buffer.PutInt32(record.GetColumnNumber());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_CONNECTION_NAME:
+ {
+ buffer.PutString(record.GetConnectionName());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_MESSAGE_TEXT:
+ {
+ buffer.PutString(record.GetMessage());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_NATIVE:
+ {
+ buffer.PutInt32(0);
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_ROW_NUMBER:
+ {
+ buffer.PutInt64(record.GetRowNumber());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_SERVER_NAME:
+ {
+ buffer.PutString(record.GetServerName());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_SQLSTATE:
+ {
+ buffer.PutString(record.GetSqlState());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_DIAG_STATUS_SUBCLASS_ORIGIN:
+ {
+ buffer.PutString(record.GetSubclassOrigin());
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ return SQL_RESULT_ERROR;
+ }
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/entry_points.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/entry_points.cpp b/modules/platforms/cpp/odbc/src/entry_points.cpp
new file mode 100644
index 0000000..c8e78a5
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/entry_points.cpp
@@ -0,0 +1,694 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/odbc.h"
+
+#include "ignite/odbc/utility.h"
+
+BOOL INSTAPI ConfigDSN(HWND hwndParent,
+ WORD req,
+ LPCSTR driver,
+ LPCSTR attributes)
+{
+ return ignite::ConfigDSN(hwndParent, req, driver, attributes);
+}
+
+SQLRETURN SQL_API SQLGetInfo(SQLHDBC conn,
+ SQLUSMALLINT infoType,
+ SQLPOINTER infoValue,
+ SQLSMALLINT infoValueMax,
+ SQLSMALLINT* length)
+{
+ return ignite::SQLGetInfo(conn, infoType, infoValue, infoValueMax, length);
+}
+
+SQLRETURN SQL_API SQLAllocHandle(SQLSMALLINT type, SQLHANDLE parent, SQLHANDLE* result)
+{
+ return ignite::SQLAllocHandle(type, parent, result);
+}
+
+SQLRETURN SQL_API SQLAllocEnv(SQLHENV* env)
+{
+ return ignite::SQLAllocEnv(env);
+}
+
+SQLRETURN SQL_API SQLAllocConnect(SQLHENV env, SQLHDBC* conn)
+{
+ return ignite::SQLAllocConnect(env, conn);
+}
+
+SQLRETURN SQL_API SQLAllocStmt(SQLHDBC conn, SQLHSTMT* stmt)
+{
+ return ignite::SQLAllocStmt(conn, stmt);
+}
+
+SQLRETURN SQL_API SQLFreeHandle(SQLSMALLINT type, SQLHANDLE handle)
+{
+ return ignite::SQLFreeHandle(type, handle);
+}
+
+SQLRETURN SQL_API SQLFreeEnv(SQLHENV env)
+{
+ return ignite::SQLFreeEnv(env);
+}
+
+SQLRETURN SQL_API SQLFreeConnect(SQLHDBC conn)
+{
+ return ignite::SQLFreeConnect(conn);
+}
+
+SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT stmt, SQLUSMALLINT option)
+{
+ return ignite::SQLFreeStmt(stmt, option);
+}
+
+SQLRETURN SQL_API SQLCloseCursor(SQLHSTMT stmt)
+{
+ return ignite::SQLCloseCursor(stmt);
+}
+
+SQLRETURN SQL_API SQLDriverConnect(SQLHDBC conn,
+ SQLHWND windowHandle,
+ SQLCHAR* inConnectionString,
+ SQLSMALLINT inConnectionStringLen,
+ SQLCHAR* outConnectionString,
+ SQLSMALLINT outConnectionStringBufferLen,
+ SQLSMALLINT* outConnectionStringLen,
+ SQLUSMALLINT driverCompletion)
+{
+ return ignite::SQLDriverConnect(conn, windowHandle, inConnectionString,
+ inConnectionStringLen, outConnectionString, outConnectionStringBufferLen,
+ outConnectionStringLen, driverCompletion);
+}
+
+SQLRETURN SQL_API SQLConnect(SQLHDBC conn,
+ SQLCHAR* serverName,
+ SQLSMALLINT serverNameLen,
+ SQLCHAR* userName,
+ SQLSMALLINT userNameLen,
+ SQLCHAR* auth,
+ SQLSMALLINT authLen)
+{
+ return ignite::SQLConnect(conn, serverName, serverNameLen,
+ userName, userNameLen, auth, authLen);
+}
+
+SQLRETURN SQL_API SQLDisconnect(SQLHDBC conn)
+{
+ return ignite::SQLDisconnect(conn);
+}
+
+SQLRETURN SQL_API SQLPrepare(SQLHSTMT stmt, SQLCHAR* query, SQLINTEGER queryLen)
+{
+ return ignite::SQLPrepare(stmt, query, queryLen);
+}
+
+SQLRETURN SQL_API SQLExecute(SQLHSTMT stmt)
+{
+ return ignite::SQLExecute(stmt);
+}
+
+SQLRETURN SQL_API SQLExecDirect(SQLHSTMT stmt, SQLCHAR* query, SQLINTEGER queryLen)
+{
+ return ignite::SQLExecDirect(stmt, query, queryLen);
+}
+
+SQLRETURN SQL_API SQLBindCol(SQLHSTMT stmt,
+ SQLUSMALLINT colNum,
+ SQLSMALLINT targetType,
+ SQLPOINTER targetValue,
+ SQLLEN bufferLength,
+ SQLLEN* strLengthOrIndicator)
+{
+ return ignite::SQLBindCol(stmt, colNum, targetType,
+ targetValue, bufferLength, strLengthOrIndicator);
+}
+
+SQLRETURN SQL_API SQLFetch(SQLHSTMT stmt)
+{
+ return ignite::SQLFetch(stmt);
+}
+
+SQLRETURN SQL_API SQLFetchScroll(SQLHSTMT stmt,
+ SQLSMALLINT orientation,
+ SQLLEN offset)
+{
+ return ignite::SQLFetchScroll(stmt, orientation, offset);
+}
+
+SQLRETURN SQL_API SQLExtendedFetch(SQLHSTMT stmt,
+ SQLUSMALLINT orientation,
+ SQLLEN offset,
+ SQLULEN* rowCount,
+ SQLUSMALLINT* rowStatusArray)
+{
+ return ignite::SQLExtendedFetch(stmt, orientation,
+ offset, rowCount, rowStatusArray);
+}
+
+SQLRETURN SQL_API SQLNumResultCols(SQLHSTMT stmt, SQLSMALLINT *columnNum)
+{
+ return ignite::SQLNumResultCols(stmt, columnNum);
+}
+
+SQLRETURN SQL_API SQLTables(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen,
+ SQLCHAR* tableType,
+ SQLSMALLINT tableTypeLen)
+{
+ return ignite::SQLTables(stmt, catalogName, catalogNameLen,
+ schemaName, schemaNameLen, tableName, tableNameLen,
+ tableType, tableTypeLen);
+}
+
+SQLRETURN SQL_API SQLColumns(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen,
+ SQLCHAR* columnName,
+ SQLSMALLINT columnNameLen)
+{
+ return ignite::SQLColumns(stmt, catalogName, catalogNameLen, schemaName,
+ schemaNameLen, tableName, tableNameLen, columnName, columnNameLen);
+}
+
+SQLRETURN SQL_API SQLMoreResults(SQLHSTMT stmt)
+{
+ return ignite::SQLMoreResults(stmt);
+}
+
+SQLRETURN SQL_API SQLBindParameter(SQLHSTMT stmt,
+ SQLUSMALLINT paramIdx,
+ SQLSMALLINT ioType,
+ SQLSMALLINT bufferType,
+ SQLSMALLINT paramSqlType,
+ SQLULEN columnSize,
+ SQLSMALLINT decDigits,
+ SQLPOINTER buffer,
+ SQLLEN bufferLen,
+ SQLLEN* resLen)
+{
+ return ignite::SQLBindParameter(stmt, paramIdx, ioType,
+ bufferType, paramSqlType, columnSize, decDigits,
+ buffer, bufferLen, resLen);
+}
+
+SQLRETURN SQL_API SQLNativeSql(SQLHDBC conn,
+ SQLCHAR* inQuery,
+ SQLINTEGER inQueryLen,
+ SQLCHAR* outQueryBuffer,
+ SQLINTEGER outQueryBufferLen,
+ SQLINTEGER* outQueryLen)
+{
+ return ignite::SQLNativeSql(conn, inQuery, inQueryLen,
+ outQueryBuffer, outQueryBufferLen, outQueryLen);
+}
+
+SQLRETURN SQL_API SQLColAttribute(SQLHSTMT stmt,
+ SQLUSMALLINT columnNum,
+ SQLUSMALLINT fieldId,
+ SQLPOINTER strAttr,
+ SQLSMALLINT bufferLen,
+ SQLSMALLINT* strAttrLen,
+ SQLLEN* numericAttr)
+{
+ return ignite::SQLColAttribute(stmt, columnNum, fieldId,
+ strAttr, bufferLen, strAttrLen, numericAttr);
+}
+
+SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT stmt,
+ SQLUSMALLINT columnNum,
+ SQLCHAR* columnNameBuf,
+ SQLSMALLINT columnNameBufLen,
+ SQLSMALLINT* columnNameLen,
+ SQLSMALLINT* dataType,
+ SQLULEN* columnSize,
+ SQLSMALLINT* decimalDigits,
+ SQLSMALLINT* nullable)
+{
+ return ignite::SQLDescribeCol(stmt, columnNum, columnNameBuf,
+ columnNameBufLen, columnNameLen, dataType, columnSize,
+ decimalDigits, nullable);
+}
+
+
+SQLRETURN SQL_API SQLRowCount(SQLHSTMT stmt, SQLLEN* rowCnt)
+{
+ return ignite::SQLRowCount(stmt, rowCnt);
+}
+
+SQLRETURN SQL_API SQLForeignKeys(SQLHSTMT stmt,
+ SQLCHAR* primaryCatalogName,
+ SQLSMALLINT primaryCatalogNameLen,
+ SQLCHAR* primarySchemaName,
+ SQLSMALLINT primarySchemaNameLen,
+ SQLCHAR* primaryTableName,
+ SQLSMALLINT primaryTableNameLen,
+ SQLCHAR* foreignCatalogName,
+ SQLSMALLINT foreignCatalogNameLen,
+ SQLCHAR* foreignSchemaName,
+ SQLSMALLINT foreignSchemaNameLen,
+ SQLCHAR* foreignTableName,
+ SQLSMALLINT foreignTableNameLen)
+{
+ return ignite::SQLForeignKeys(stmt, primaryCatalogName,
+ primaryCatalogNameLen, primarySchemaName, primarySchemaNameLen,
+ primaryTableName, primaryTableNameLen, foreignCatalogName,
+ foreignCatalogNameLen, foreignSchemaName, foreignSchemaNameLen,
+ foreignTableName, foreignTableNameLen);
+}
+
+SQLRETURN SQL_API SQLGetStmtAttr(SQLHSTMT stmt,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen)
+{
+ return ignite::SQLGetStmtAttr(stmt, attr, valueBuf, valueBufLen, valueResLen);
+}
+
+SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT stmt,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen)
+{
+ return ignite::SQLSetStmtAttr(stmt, attr, value, valueLen);
+}
+
+SQLRETURN SQL_API SQLPrimaryKeys(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen)
+{
+ return ignite::SQLPrimaryKeys(stmt, catalogName, catalogNameLen,
+ schemaName, schemaNameLen, tableName, tableNameLen);
+}
+
+SQLRETURN SQL_API SQLNumParams(SQLHSTMT stmt, SQLSMALLINT* paramCnt)
+{
+ return ignite::SQLNumParams(stmt, paramCnt);
+}
+
+SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT handleType,
+ SQLHANDLE handle,
+ SQLSMALLINT recNum,
+ SQLSMALLINT diagId,
+ SQLPOINTER buffer,
+ SQLSMALLINT bufferLen,
+ SQLSMALLINT* resLen)
+{
+ return ignite::SQLGetDiagField(handleType, handle,
+ recNum, diagId, buffer, bufferLen, resLen);
+}
+
+SQLRETURN SQL_API SQLGetDiagRec(SQLSMALLINT handleType,
+ SQLHANDLE handle,
+ SQLSMALLINT recNum,
+ SQLCHAR* sqlState,
+ SQLINTEGER* nativeError,
+ SQLCHAR* msgBuffer,
+ SQLSMALLINT msgBufferLen,
+ SQLSMALLINT* msgLen)
+{
+ return ignite::SQLGetDiagRec(handleType, handle, recNum,
+ sqlState, nativeError, msgBuffer, msgBufferLen, msgLen);
+}
+
+SQLRETURN SQL_API SQLGetTypeInfo(SQLHSTMT stmt, SQLSMALLINT type)
+{
+ return ignite::SQLGetTypeInfo(stmt, type);
+}
+
+SQLRETURN SQL_API SQLEndTran(SQLSMALLINT handleType,
+ SQLHANDLE handle,
+ SQLSMALLINT completionType)
+{
+ return ignite::SQLEndTran(handleType, handle, completionType);
+}
+
+SQLRETURN SQL_API SQLGetData(SQLHSTMT stmt,
+ SQLUSMALLINT colNum,
+ SQLSMALLINT targetType,
+ SQLPOINTER targetValue,
+ SQLLEN bufferLength,
+ SQLLEN* strLengthOrIndicator)
+{
+ return ignite::SQLGetData(stmt, colNum, targetType,
+ targetValue, bufferLength, strLengthOrIndicator);
+}
+
+SQLRETURN SQL_API SQLSetEnvAttr(SQLHENV env,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen)
+{
+ return ignite::SQLSetEnvAttr(env, attr, value, valueLen);
+}
+
+SQLRETURN SQL_API SQLGetEnvAttr(SQLHENV env,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen)
+{
+ return ignite::SQLGetEnvAttr(env, attr,
+ valueBuf, valueBufLen, valueResLen);
+}
+
+SQLRETURN SQL_API SQLSpecialColumns(SQLHSTMT stmt,
+ SQLSMALLINT idType,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen,
+ SQLSMALLINT scope,
+ SQLSMALLINT nullable)
+{
+ return ignite::SQLSpecialColumns(stmt, idType, catalogName,
+ catalogNameLen, schemaName, schemaNameLen, tableName,
+ tableNameLen, scope, nullable);
+}
+
+//
+// ==== Not implemented ====
+//
+
+SQLRETURN SQL_API SQLCancel(SQLHSTMT stmt)
+{
+ LOG_MSG("SQLCancel called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLColAttributes(SQLHSTMT stmt,
+ SQLUSMALLINT colNum,
+ SQLUSMALLINT fieldId,
+ SQLPOINTER strAttrBuf,
+ SQLSMALLINT strAttrBufLen,
+ SQLSMALLINT* strAttrResLen,
+ SQLLEN* numAttrBuf)
+{
+ LOG_MSG("SQLColAttributes called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLError(SQLHENV env,
+ SQLHDBC conn,
+ SQLHSTMT stmt,
+ SQLCHAR* state,
+ SQLINTEGER* error,
+ SQLCHAR* msgBuf,
+ SQLSMALLINT msgBufLen,
+ SQLSMALLINT* msgResLen)
+{
+ LOG_MSG("SQLError called\n");
+ return SQL_ERROR;
+}
+
+SQLRETURN SQL_API SQLGetCursorName(SQLHSTMT stmt,
+ SQLCHAR* nameBuf,
+ SQLSMALLINT nameBufLen,
+ SQLSMALLINT* nameResLen)
+{
+ LOG_MSG("SQLGetCursorName called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetCursorName(SQLHSTMT stmt,
+ SQLCHAR* name,
+ SQLSMALLINT nameLen)
+{
+ LOG_MSG("SQLSetCursorName called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLGetConnectOption(SQLHDBC conn,
+ SQLUSMALLINT option,
+ SQLPOINTER value)
+{
+ LOG_MSG("SQLGetConnectOption called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLGetStmtOption(SQLHSTMT stmt,
+ SQLUSMALLINT option,
+ SQLPOINTER value)
+{
+ LOG_MSG("SQLGetStmtOption called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLParamData(SQLHSTMT stmt,
+ SQLPOINTER* value)
+{
+ LOG_MSG("SQLParamData called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLPutData(SQLHSTMT stmt,
+ SQLPOINTER data,
+ SQLLEN strLengthOrIndicator)
+{
+ LOG_MSG("SQLPutData called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC conn,
+ SQLUSMALLINT option,
+ SQLULEN value)
+{
+ LOG_MSG("SQLSetConnectOption called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt,
+ SQLUSMALLINT option,
+ SQLULEN value)
+{
+ LOG_MSG("SQLSetStmtOption called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLStatistics(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen,
+ SQLUSMALLINT unique,
+ SQLUSMALLINT reserved)
+{
+ LOG_MSG("SQLStatistics called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLBrowseConnect(SQLHDBC conn,
+ SQLCHAR* inConnectionStr,
+ SQLSMALLINT inConnectionStrLen,
+ SQLCHAR* outConnectionStrBuf,
+ SQLSMALLINT outConnectionStrBufLen,
+ SQLSMALLINT* outConnectionStrResLen)
+{
+ LOG_MSG("SQLBrowseConnect called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLProcedureColumns(SQLHSTMT stmt,
+ SQLCHAR * catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR * schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR * procName,
+ SQLSMALLINT procNameLen,
+ SQLCHAR * columnName,
+ SQLSMALLINT columnNameLen)
+{
+ LOG_MSG("SQLProcedureColumns called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetPos(SQLHSTMT stmt,
+ SQLSETPOSIROW rowNum,
+ SQLUSMALLINT operation,
+ SQLUSMALLINT lockType)
+{
+ LOG_MSG("SQLSetPos called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetScrollOptions(SQLHSTMT stmt,
+ SQLUSMALLINT concurrency,
+ SQLLEN crowKeyset,
+ SQLUSMALLINT crowRowset)
+{
+ LOG_MSG("SQLSetScrollOptions called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER valueBuf,
+ SQLINTEGER valueBufLen,
+ SQLINTEGER* valueResLen)
+{
+ LOG_MSG("SQLGetConnectAttr called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC conn,
+ SQLINTEGER attr,
+ SQLPOINTER value,
+ SQLINTEGER valueLen)
+{
+ LOG_MSG("SQLSetConnectAttr called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLBulkOperations(SQLHSTMT stmt,
+ SQLUSMALLINT operation)
+{
+ LOG_MSG("SQLBulkOperations called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLTablePrivileges(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen)
+{
+ LOG_MSG("SQLTablePrivileges called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLCopyDesc(SQLHDESC src, SQLHDESC dst)
+{
+ LOG_MSG("SQLCopyDesc called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLGetDescField(SQLHDESC descr,
+ SQLSMALLINT recNum,
+ SQLSMALLINT fieldId,
+ SQLPOINTER buffer,
+ SQLINTEGER bufferLen,
+ SQLINTEGER* resLen)
+{
+ LOG_MSG("SQLGetDescField called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle,
+ SQLSMALLINT RecNumber,
+ SQLCHAR* nameBuffer,
+ SQLSMALLINT nameBufferLen,
+ SQLSMALLINT* strLen,
+ SQLSMALLINT* type,
+ SQLSMALLINT* subType,
+ SQLLEN* len,
+ SQLSMALLINT* precision,
+ SQLSMALLINT* scale,
+ SQLSMALLINT* nullable)
+{
+ LOG_MSG("SQLGetDescRec called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetDescField(SQLHDESC descr,
+ SQLSMALLINT recNum,
+ SQLSMALLINT fieldId,
+ SQLPOINTER buffer,
+ SQLINTEGER bufferLen)
+{
+ LOG_MSG("SQLSetDescField called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLSetDescRec(SQLHDESC descr,
+ SQLSMALLINT recNum,
+ SQLSMALLINT type,
+ SQLSMALLINT subType,
+ SQLLEN len,
+ SQLSMALLINT precision,
+ SQLSMALLINT scale,
+ SQLPOINTER buffer,
+ SQLLEN* resLen,
+ SQLLEN* id)
+{
+ LOG_MSG("SQLSetDescRec called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLColumnPrivileges(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen,
+ SQLCHAR* columnName,
+ SQLSMALLINT columnNameLen)
+{
+ LOG_MSG("SQLColumnPrivileges called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLDescribeParam(SQLHSTMT stmt,
+ SQLUSMALLINT paramNum,
+ SQLSMALLINT* dataType,
+ SQLULEN* paramSize,
+ SQLSMALLINT* decimalDigits,
+ SQLSMALLINT* nullable)
+{
+ LOG_MSG("SQLDescribeParam called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt,
+ SQLULEN paramSetSize,
+ SQLULEN* paramsProcessed)
+{
+ LOG_MSG("SQLParamOptions called\n");
+ return SQL_SUCCESS;
+}
+
+SQLRETURN SQL_API SQLProcedures(SQLHSTMT stmt,
+ SQLCHAR* catalogName,
+ SQLSMALLINT catalogNameLen,
+ SQLCHAR* schemaName,
+ SQLSMALLINT schemaNameLen,
+ SQLCHAR* tableName,
+ SQLSMALLINT tableNameLen)
+{
+ LOG_MSG("SQLProcedures called\n");
+ return SQL_SUCCESS;
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/environment.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/environment.cpp b/modules/platforms/cpp/odbc/src/environment.cpp
new file mode 100644
index 0000000..3928295
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/environment.cpp
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ignite/odbc/system/odbc_constants.h"
+#include "ignite/odbc/connection.h"
+#include "ignite/odbc/environment.h"
+
+namespace ignite
+{
+ namespace odbc
+ {
+ Environment::Environment() :
+ odbcVersion(SQL_OV_ODBC3), odbcNts(SQL_TRUE)
+ {
+ // No-op.
+ }
+
+ Environment::~Environment()
+ {
+ // No-op.
+ }
+
+ Connection* Environment::CreateConnection()
+ {
+ Connection* connection;
+
+ IGNITE_ODBC_API_CALL(InternalCreateConnection(connection));
+
+ return connection;
+ }
+
+ SqlResult Environment::InternalCreateConnection(Connection*& connection)
+ {
+ connection = new Connection;
+
+ if (!connection)
+ {
+ AddStatusRecord(SQL_STATE_HY001_MEMORY_ALLOCATION, "Not enough memory.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Environment::TransactionCommit()
+ {
+ IGNITE_ODBC_API_CALL(InternalTransactionCommit());
+ }
+
+ SqlResult Environment::InternalTransactionCommit()
+ {
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Environment::TransactionRollback()
+ {
+ IGNITE_ODBC_API_CALL(InternalTransactionRollback());
+ }
+
+ SqlResult Environment::InternalTransactionRollback()
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Rollback operation is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ void Environment::SetAttribute(int32_t attr, void* value, int32_t len)
+ {
+ IGNITE_ODBC_API_CALL(InternalSetAttribute(attr, value, len));
+ }
+
+ SqlResult Environment::InternalSetAttribute(int32_t attr, void* value, int32_t len)
+ {
+ EnvironmentAttribute attribute = EnvironmentAttributeToInternal(attr);
+
+ switch (attribute)
+ {
+ case IGNITE_SQL_ENV_ATTR_ODBC_VERSION:
+ {
+ int32_t version = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
+
+ if (version != odbcVersion)
+ {
+ AddStatusRecord(SQL_STATE_01S02_OPTION_VALUE_CHANGED,
+ "ODBC version is not supported.");
+
+ return SQL_RESULT_SUCCESS_WITH_INFO;
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_ENV_ATTR_OUTPUT_NTS:
+ {
+ int32_t nts = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
+
+ if (nts != odbcNts)
+ {
+ AddStatusRecord(SQL_STATE_01S02_OPTION_VALUE_CHANGED,
+ "Only null-termination of strings is supported.");
+
+ return SQL_RESULT_SUCCESS_WITH_INFO;
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_ENV_ATTR_UNKNOWN:
+ default:
+ break;
+ }
+
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Attribute is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ void Environment::GetAttribute(int32_t attr, app::ApplicationDataBuffer& buffer)
+ {
+ IGNITE_ODBC_API_CALL(InternalGetAttribute(attr, buffer));
+ }
+
+ SqlResult Environment::InternalGetAttribute(int32_t attr, app::ApplicationDataBuffer& buffer)
+ {
+ EnvironmentAttribute attribute = EnvironmentAttributeToInternal(attr);
+
+ switch (attribute)
+ {
+ case IGNITE_SQL_ENV_ATTR_ODBC_VERSION:
+ {
+ buffer.PutInt32(odbcVersion);
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_ENV_ATTR_OUTPUT_NTS:
+ {
+ buffer.PutInt32(odbcNts);
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ case IGNITE_SQL_ENV_ATTR_UNKNOWN:
+ default:
+ break;
+ }
+
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Attribute is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+ }
+}
+