ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [14/28] ignite git commit: IGNITE-2442: ODBC projects moved to main cpp solution.
Date Wed, 27 Jan 2016 10:39:47 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/common_types.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/common_types.cpp b/modules/platforms/cpp/odbc/src/common_types.cpp
new file mode 100644
index 0000000..276d9fd
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/common_types.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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/impl/binary/binary_common.h>
+
+#include "ignite/odbc/system/odbc_constants.h"
+#include "ignite/odbc/common_types.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        int SqlResultToReturnCode(SqlResult result)
+        {
+            switch (result)
+            {
+                case SQL_RESULT_SUCCESS: 
+                    return SQL_SUCCESS;
+
+                case SQL_RESULT_SUCCESS_WITH_INFO:
+                    return SQL_SUCCESS_WITH_INFO;
+
+                case SQL_RESULT_NO_DATA:
+                    return SQL_NO_DATA;
+
+                case SQL_RESULT_ERROR:
+                default:
+                    return SQL_ERROR;
+            }
+        }
+
+        DiagnosticField DiagnosticFieldToInternal(int16_t field)
+        {
+            switch (field)
+            {
+                case SQL_DIAG_CURSOR_ROW_COUNT:
+                    return IGNITE_SQL_DIAG_HEADER_CURSOR_ROW_COUNT;
+
+                case SQL_DIAG_DYNAMIC_FUNCTION:
+                    return IGNITE_SQL_DIAG_HEADER_DYNAMIC_FUNCTION;
+
+                case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
+                    return IGNITE_SQL_DIAG_HEADER_DYNAMIC_FUNCTION_CODE;
+
+                case SQL_DIAG_NUMBER:
+                    return IGNITE_SQL_DIAG_HEADER_NUMBER;
+
+                case SQL_DIAG_RETURNCODE:
+                    return IGNITE_SQL_DIAG_HEADER_RETURNCODE;
+
+                case SQL_DIAG_ROW_COUNT:
+                    return IGNITE_SQL_DIAG_HEADER_ROW_COUNT;
+
+                case SQL_DIAG_CLASS_ORIGIN:
+                    return IGNITE_SQL_DIAG_STATUS_CLASS_ORIGIN;
+
+                case SQL_DIAG_COLUMN_NUMBER:
+                    return IGNITE_SQL_DIAG_STATUS_COLUMN_NUMBER;
+
+                case SQL_DIAG_CONNECTION_NAME:
+                    return IGNITE_SQL_DIAG_STATUS_CONNECTION_NAME;
+
+                case SQL_DIAG_MESSAGE_TEXT:
+                    return IGNITE_SQL_DIAG_STATUS_MESSAGE_TEXT;
+
+                case SQL_DIAG_NATIVE:
+                    return IGNITE_SQL_DIAG_STATUS_NATIVE;
+
+                case SQL_DIAG_ROW_NUMBER:
+                    return IGNITE_SQL_DIAG_STATUS_ROW_NUMBER;
+
+                case SQL_DIAG_SERVER_NAME:
+                    return IGNITE_SQL_DIAG_STATUS_SERVER_NAME;
+
+                case SQL_DIAG_SQLSTATE:
+                    return IGNITE_SQL_DIAG_STATUS_SQLSTATE;
+
+                case SQL_DIAG_SUBCLASS_ORIGIN:
+                    return IGNITE_SQL_DIAG_STATUS_SUBCLASS_ORIGIN;
+
+                default:
+                    break;
+            }
+
+            return IGNITE_SQL_DIAG_UNKNOWN;
+        }
+
+        EnvironmentAttribute EnvironmentAttributeToInternal(int32_t attr)
+        {
+            switch (attr)
+            {
+                case SQL_ATTR_ODBC_VERSION:
+                    return IGNITE_SQL_ENV_ATTR_ODBC_VERSION;
+
+                case SQL_ATTR_OUTPUT_NTS:
+                    return IGNITE_SQL_ENV_ATTR_OUTPUT_NTS;
+
+                default:
+                    break;
+            }
+
+            return IGNITE_SQL_ENV_ATTR_UNKNOWN;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/config/configuration.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/configuration.cpp b/modules/platforms/cpp/odbc/src/config/configuration.cpp
new file mode 100644
index 0000000..08ee54b
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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 <string>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/config/configuration.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace config
+        {
+            /** Default values for configuration. */
+            namespace dflt
+            {
+                /** Default value for DSN attribute. */
+                const std::string dsn = "Default Apache Ignite DSN";
+
+                /** Default value for Driver attribute. */
+                const std::string driver = "Apache Ignite";
+
+                /** Default value for host attribute. */
+                const std::string host = "localhost";
+
+                /** Default value for port attribute. */
+                const uint16_t port = 11443;
+
+                /** Default value for cache attribute. */
+                const std::string cache = "Persons";
+            }
+
+            /** Connection attribute keywords. */
+            namespace attrkey
+            {
+                /** Connection attribute keyword for DSN attribute. */
+                const std::string dsn = "dsn";
+            
+                /** Connection attribute keyword for Driver attribute. */
+                const std::string driver = "driver";
+
+                /** Connection attribute keyword for server host attribute. */
+                const std::string host = "server";
+
+                /** Connection attribute keyword for server port attribute. */
+                const std::string port = "port";
+
+                /** Default value for cache attribute. */
+                const std::string cache = "cache";
+            }
+
+            Configuration::Configuration() :
+                dsn(dflt::dsn), driver(dflt::driver),
+                host(dflt::host), port(dflt::port),
+                cache(dflt::cache)
+            {
+                // No-op.
+            }
+
+            Configuration::~Configuration()
+            {
+                // No-op.
+            }
+
+            void Configuration::FillFromConnectString(const char* str, size_t len)
+            {
+                ArgumentMap connect_attributes;
+
+                ParseAttributeList(str, len, ';', connect_attributes);
+
+                ArgumentMap::const_iterator it;
+
+                it = connect_attributes.find(attrkey::dsn);
+                if (it != connect_attributes.end())
+                    dsn = it->second;
+                else
+                    dsn.clear();
+
+                it = connect_attributes.find(attrkey::driver);
+                if (it != connect_attributes.end())
+                    driver = it->second;
+                else
+                    driver = dflt::driver;
+
+                it = connect_attributes.find(attrkey::host);
+                if (it != connect_attributes.end())
+                    host = it->second;
+                else
+                    host = dflt::host;
+
+                it = connect_attributes.find(attrkey::port);
+                if (it != connect_attributes.end())
+                    port = atoi(it->second.c_str());
+                else
+                    port = dflt::port;
+
+                it = connect_attributes.find(attrkey::cache);
+                if (it != connect_attributes.end())
+                    cache = it->second;
+                else
+                    cache = dflt::cache;
+            }
+
+            void Configuration::FillFromConnectString(const std::string& str)
+            {
+                FillFromConnectString(str.data(), str.size());
+            }
+
+            std::string Configuration::ToConnectString() const
+            {
+                std::stringstream connect_string_buffer;
+
+                if (!driver.empty())
+                    connect_string_buffer << attrkey::driver << "={" << driver << "};";
+
+                if (!host.empty())
+                    connect_string_buffer << attrkey::host << '=' << host << ';';
+
+                if (port)
+                    connect_string_buffer << attrkey::port << '=' << port << ';';
+
+                if (!dsn.empty())
+                    connect_string_buffer << attrkey::dsn << '=' << dsn << ';';
+
+                if (!cache.empty())
+                    connect_string_buffer << attrkey::cache << '=' << cache << ';';
+
+                return connect_string_buffer.str();
+            }
+
+            void Configuration::FillFromConfigAttributes(const char * attributes)
+            {
+                ArgumentMap config_attributes;
+
+                size_t len = 0;
+
+                // Getting list length. List is terminated by two '\0'.
+                while (attributes[len] || attributes[len + 1])
+                    ++len;
+
+                ++len;
+
+                ParseAttributeList(attributes, len, '\0', config_attributes);
+
+                ArgumentMap::const_iterator it;
+
+                it = config_attributes.find(attrkey::dsn);
+                if (it != config_attributes.end())
+                    dsn = it->second;
+                else
+                    dsn = dflt::dsn;
+
+                it = config_attributes.find(attrkey::driver);
+                if (it != config_attributes.end())
+                    driver = it->second;
+                else
+                    driver.clear();
+
+                it = config_attributes.find(attrkey::host);
+                if (it != config_attributes.end())
+                    host = it->second;
+                else
+                    host.clear();
+
+                it = config_attributes.find(attrkey::port);
+                if (it != config_attributes.end())
+                    port = atoi(it->second.c_str());
+                else
+                    port = 0;
+
+                it = config_attributes.find(attrkey::cache);
+                if (it != config_attributes.end())
+                    cache = it->second;
+                else
+                    cache.clear();
+            }
+
+            void Configuration::ParseAttributeList(const char * str, size_t len, char delimeter, ArgumentMap & args) const
+            {
+                std::string connect_str(str, len);
+                args.clear();
+
+                while (!connect_str.empty())
+                {
+                    size_t attr_begin = connect_str.rfind(delimeter);
+
+                    if (attr_begin == std::string::npos)
+                        attr_begin = 0;
+                    else
+                        ++attr_begin;
+
+                    size_t attr_eq_pos = connect_str.rfind('=');
+
+                    if (attr_eq_pos == std::string::npos)
+                        attr_eq_pos = 0;
+
+                    if (attr_begin < attr_eq_pos)
+                    {
+                        const char* key_begin = connect_str.data() + attr_begin;
+                        const char* key_end = connect_str.data() + attr_eq_pos;
+
+                        const char* value_begin = connect_str.data() + attr_eq_pos + 1;
+                        const char* value_end = connect_str.data() + connect_str.size();
+
+                        std::string key = utility::RemoveSurroundingSpaces(key_begin, key_end);
+                        std::string value = utility::RemoveSurroundingSpaces(value_begin, value_end);
+
+                        utility::IntoLower(key);
+
+                        if (value.front() == '{' && value.back() == '}')
+                            value = value.substr(1, value.size() - 2);
+
+                        args[key] = value;
+                    }
+
+                    if (!attr_begin)
+                        break;
+
+                    connect_str.erase(attr_begin - 1);
+                }
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/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..0e8e748
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -0,0 +1,419 @@
+/*
+ * 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] = 0;
+#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] = 0;
+#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/e8287063/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..28cd7ca
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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/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
+    {
+        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 DNS.");
+
+                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;
+            }
+
+            if (cache.empty())
+            {
+                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Cache is not specified.");
+
+                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 SQL_RESULT_SUCCESS;
+        }
+
+        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;
+        }
+
+        bool Connection::Send(const int8_t* data, size_t len)
+        {
+            if (!connected)
+                return false;
+
+            size_t sent = 0;
+
+            while (sent != len) 
+            {
+                size_t res = socket.Send(data + sent, len - sent);
+
+                if (res <= 0)
+                    return false;
+
+                sent += res;
+            }
+
+            return true;
+        }
+
+        bool Connection::Receive(std::vector<int8_t>& msg)
+        {
+            if (!connected)
+                return false;
+
+            msg.clear();
+
+            OdbcProtocolHeader hdr;
+
+            int received = socket.Receive(reinterpret_cast<int8_t*>(&hdr), sizeof(hdr));
+            LOG_MSG("Received: %d\n", received);
+
+            if (received != sizeof(hdr))
+                return false;
+
+            size_t remain = hdr.len;
+            size_t receivedAtAll = 0;
+
+            msg.resize(remain);
+
+            while (remain)
+            {
+                received = socket.Receive(&msg[receivedAtAll], remain);
+                LOG_MSG("Received: %d\n", received);
+                LOG_MSG("remain: %d\n", remain);
+
+                if (received <= 0)
+                {
+                    msg.resize(receivedAtAll);
+
+                    return false;
+                }
+
+                remain -= static_cast<size_t>(received);
+            }
+
+            return true;
+        }
+
+        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;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/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..edd1818
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/cursor.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+                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::HasNext() const
+        {
+            return !currentPage.get() || !currentPage->IsLast() ||
+                currentPagePos < currentPage->GetSize();
+        }
+
+        void Cursor::UpdateData(std::auto_ptr<ResultPage>& newPage)
+        {
+            currentPage = newPage;
+
+            currentPagePos = 1;
+
+            currentRow.reset(new Row(currentPage->GetData()));
+        }
+
+        Row* Cursor::GetRow()
+        {
+            return currentRow.get();
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/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..0fa37fb
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/decimal.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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/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;
+
+        int32_t localScale = GetScale();
+        
+        for (int32_t i = 0; i < len; ++i)
+        {
+            res = (res * 256) + magnitude[i];
+
+            while (localScale && res > 10.0)
+            {
+                res /= 10.0;
+
+                --localScale;
+            }
+        }
+
+        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 scale;
+    }
+
+    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/e8287063/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..d6cf4fe
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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)
+            {
+                AddStatusRecord(sqlState, message, 0, 0);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/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/e8287063/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/e8287063/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..ba213ab
--- /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 = reinterpret_cast<int32_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 = reinterpret_cast<int32_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;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
new file mode 100644
index 0000000..114dd03
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
@@ -0,0 +1,275 @@
+/*
+ * 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/meta/column_meta.h"
+#include "ignite/odbc/type_traits.h"
+#include "ignite/odbc/common_types.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace meta
+        {
+
+#ifdef ODBC_DEBUG
+
+#define DBG_STR_CASE(x) case x: return #x
+
+            const char* ColumnMeta::AttrIdToString(uint16_t id)
+            {
+                switch (id)
+                {
+                    DBG_STR_CASE(SQL_DESC_LABEL);
+                    DBG_STR_CASE(SQL_DESC_BASE_COLUMN_NAME);
+                    DBG_STR_CASE(SQL_DESC_NAME);
+                    DBG_STR_CASE(SQL_DESC_TABLE_NAME);
+                    DBG_STR_CASE(SQL_DESC_BASE_TABLE_NAME);
+                    DBG_STR_CASE(SQL_DESC_SCHEMA_NAME);
+                    DBG_STR_CASE(SQL_DESC_CATALOG_NAME);
+                    DBG_STR_CASE(SQL_DESC_LITERAL_PREFIX);
+                    DBG_STR_CASE(SQL_DESC_LITERAL_SUFFIX);
+                    DBG_STR_CASE(SQL_DESC_TYPE_NAME);
+                    DBG_STR_CASE(SQL_DESC_LOCAL_TYPE_NAME);
+                    DBG_STR_CASE(SQL_DESC_FIXED_PREC_SCALE);
+                    DBG_STR_CASE(SQL_DESC_AUTO_UNIQUE_VALUE);
+                    DBG_STR_CASE(SQL_DESC_CASE_SENSITIVE);
+                    DBG_STR_CASE(SQL_DESC_CONCISE_TYPE);
+                    DBG_STR_CASE(SQL_DESC_TYPE);
+                    DBG_STR_CASE(SQL_DESC_DISPLAY_SIZE);
+                    DBG_STR_CASE(SQL_DESC_LENGTH);
+                    DBG_STR_CASE(SQL_DESC_OCTET_LENGTH);
+                    DBG_STR_CASE(SQL_DESC_NULLABLE);
+                    DBG_STR_CASE(SQL_DESC_NUM_PREC_RADIX);
+                    DBG_STR_CASE(SQL_DESC_PRECISION);
+                    DBG_STR_CASE(SQL_DESC_SCALE);
+                    DBG_STR_CASE(SQL_DESC_SEARCHABLE);
+                    DBG_STR_CASE(SQL_DESC_UNNAMED);
+                    DBG_STR_CASE(SQL_DESC_UNSIGNED);
+                    DBG_STR_CASE(SQL_DESC_UPDATABLE);
+                default:
+                    break;
+                }
+                return "<< UNKNOWN ID >>";
+            }
+
+#undef DBG_STR_CASE
+
+#endif
+
+            void ColumnMeta::Read(ignite::impl::binary::BinaryReaderImpl& reader)
+            {
+                utility::ReadString(reader, schemaName);
+                utility::ReadString(reader, tableName);
+                utility::ReadString(reader, columnName);
+                utility::ReadString(reader, typeName);
+
+                dataType = reader.ReadInt8();
+            }
+
+            bool ColumnMeta::GetAttribute(uint16_t fieldId, std::string& value) const 
+            {
+                using namespace ignite::impl::binary;
+
+                switch (fieldId)
+                {
+                    case SQL_DESC_LABEL:
+                    case SQL_DESC_BASE_COLUMN_NAME:
+                    case SQL_DESC_NAME:
+                    {
+                        value = columnName;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_TABLE_NAME:
+                    case SQL_DESC_BASE_TABLE_NAME:
+                    {
+                        value = tableName;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_SCHEMA_NAME:
+                    {
+                        value = schemaName;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_CATALOG_NAME:
+                    {
+                        value.clear();
+
+                        return true;
+                    }
+
+                    case SQL_DESC_LITERAL_PREFIX:
+                    case SQL_DESC_LITERAL_SUFFIX:
+                    {
+                        if (dataType == IGNITE_TYPE_STRING)
+                            value = "'";
+                        else
+                            value.clear();
+
+                        return true;
+                    }
+
+                    case SQL_DESC_TYPE_NAME:
+                    case SQL_DESC_LOCAL_TYPE_NAME:
+                    {
+                        value = type_traits::BinaryTypeToSqlTypeName(dataType);
+
+                        return true;
+                    }
+
+                    default:
+                        return false;
+                }
+            }
+
+            bool ColumnMeta::GetAttribute(uint16_t fieldId, SqlLen& value) const
+            {
+                using namespace ignite::impl::binary;
+
+                switch (fieldId)
+                {
+                    case SQL_DESC_FIXED_PREC_SCALE:
+                    case SQL_DESC_AUTO_UNIQUE_VALUE:
+                    {
+                        value = SQL_FALSE;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_CASE_SENSITIVE:
+                    {
+                        if (dataType == IGNITE_TYPE_STRING)
+                            value = SQL_TRUE;
+                        else
+                            value = SQL_FALSE;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_CONCISE_TYPE:
+                    case SQL_DESC_TYPE:
+                    {
+                        value = type_traits::BinaryToSqlType(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_DISPLAY_SIZE:
+                    {
+                        value = type_traits::BinaryTypeDisplaySize(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_LENGTH:
+                    case SQL_DESC_OCTET_LENGTH:
+                    {
+                        value = type_traits::BinaryTypeTransferLength(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_NULLABLE:
+                    {
+                        value = type_traits::BinaryTypeNullability(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_NUM_PREC_RADIX:
+                    {
+                        value = type_traits::BinaryTypeNumPrecRadix(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_PRECISION:
+                    {
+                        value = type_traits::BinaryTypeColumnSize(dataType);
+
+                        return true;
+                    }
+
+                    case SQL_DESC_SCALE:
+                    {
+                        value = type_traits::BinaryTypeDecimalDigits(dataType);
+
+                        if (value < 0)
+                            value = 0;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_SEARCHABLE:
+                    {
+                        value = SQL_PRED_BASIC;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_UNNAMED:
+                    {
+                        value = columnName.empty() ? SQL_UNNAMED : SQL_NAMED;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_UNSIGNED:
+                    {
+                        value = type_traits::BinaryTypeUnsigned(dataType) ? SQL_TRUE : SQL_FALSE;
+
+                        return true;
+                    }
+
+                    case SQL_DESC_UPDATABLE:
+                    {
+                        // We do not support update for now so just set all
+                        // columns to readonly.
+                        value = SQL_ATTR_READONLY;
+
+                        return true;
+                    }
+
+                    default:
+                        return false;
+                }
+            }
+
+            void ReadColumnMetaVector(ignite::impl::binary::BinaryReaderImpl& reader, ColumnMetaVector& meta)
+            {
+                int32_t metaNum = reader.ReadInt32();
+
+                meta.clear();
+                meta.reserve(static_cast<size_t>(metaNum));
+
+                for (int32_t i = 0; i < metaNum; ++i)
+                {
+                    meta.push_back(ColumnMeta());
+
+                    meta.back().Read(reader);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/meta/table_meta.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/meta/table_meta.cpp b/modules/platforms/cpp/odbc/src/meta/table_meta.cpp
new file mode 100644
index 0000000..71ced8f
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/meta/table_meta.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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/meta/table_meta.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace meta
+        {
+            void TableMeta::Read(ignite::impl::binary::BinaryReaderImpl & reader)
+            {
+                utility::ReadString(reader, catalogName);
+                utility::ReadString(reader, schemaName);
+                utility::ReadString(reader, tableName);
+                utility::ReadString(reader, tableType);
+            }
+
+            void ReadTableMetaVector(ignite::impl::binary::BinaryReaderImpl& reader, TableMetaVector& meta)
+            {
+                int32_t metaNum = reader.ReadInt32();
+
+                meta.clear();
+                meta.reserve(static_cast<size_t>(metaNum));
+
+                for (int32_t i = 0; i < metaNum; ++i)
+                {
+                    meta.push_back(TableMeta());
+
+                    meta.back().Read(reader);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file


Mime
View raw message