ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [04/34] ignite git commit: IGNITE-1786: Implemented ODBC driver.
Date Thu, 05 May 2016 14:02:37 GMT
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;
+        }
+    }
+}
+


Mime
View raw message