ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject [02/31] ignite git commit: IGNITE-1786: Implemented ODBC driver.
Date Thu, 05 May 2016 13:46:39 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp b/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
new file mode 100644
index 0000000..ad8aea6
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/query/special_columns_query.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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/type_traits.h"
+#include "ignite/odbc/query/special_columns_query.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace query
+        {
+            SpecialColumnsQuery::SpecialColumnsQuery(diagnostic::Diagnosable& diag,
+                int16_t type, const std::string& catalog, const std::string& schema,
+                const std::string& table, int16_t scope, int16_t nullable) :
+                Query(diag),
+                type(type),
+                catalog(catalog),
+                schema(schema),
+                table(table),
+                scope(scope),
+                nullable(nullable),
+                executed(false),
+                columnsMeta()
+            {
+                using namespace ignite::impl::binary;
+                using namespace ignite::odbc::type_traits;
+
+                using meta::ColumnMeta;
+
+                columnsMeta.reserve(8);
+
+                const std::string sch("");
+                const std::string tbl("");
+
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "SCOPE",          IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "COLUMN_NAME",    IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "DATA_TYPE",      IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TYPE_NAME",      IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "COLUMN_SIZE",    IGNITE_TYPE_INT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "BUFFER_LENGTH",  IGNITE_TYPE_INT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "DECIMAL_DIGITS", IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "PSEUDO_COLUMN",  IGNITE_TYPE_SHORT));
+            }
+
+            SpecialColumnsQuery::~SpecialColumnsQuery()
+            {
+                // No-op.
+            }
+
+            SqlResult SpecialColumnsQuery::Execute()
+            {
+                executed = true;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            const meta::ColumnMetaVector& SpecialColumnsQuery::GetMeta() const
+            {
+                return columnsMeta;
+            }
+
+            SqlResult SpecialColumnsQuery::FetchNextRow(app::ColumnBindingMap & columnBindings)
+            {
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                return SQL_RESULT_NO_DATA;
+            }
+
+            SqlResult SpecialColumnsQuery::GetColumn(uint16_t columnIdx, app::ApplicationDataBuffer& buffer)
+            {
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                return SQL_RESULT_NO_DATA;
+            }
+
+            SqlResult SpecialColumnsQuery::Close()
+            {
+                executed = false;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            bool SpecialColumnsQuery::DataAvailable() const
+            {
+                return false;
+            }
+
+            int64_t SpecialColumnsQuery::AffectedRows() const
+            {
+                return 0;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
new file mode 100644
index 0000000..53aebe4
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -0,0 +1,244 @@
+/*
+ * 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/type_traits.h"
+#include "ignite/odbc/connection.h"
+#include "ignite/odbc/message.h"
+#include "ignite/odbc/query/table_metadata_query.h"
+
+namespace
+{
+    enum ResultColumn
+    {
+        /** Catalog name. NULL if not applicable to the data source. */
+        TABLE_CAT = 1,
+
+        /** Schema name. NULL if not applicable to the data source. */
+        TABLE_SCHEM,
+
+        /** Table name. */
+        TABLE_NAME,
+
+        /** Table type. */
+        TABLE_TYPE,
+
+        /** A description of the column. */
+        REMARKS
+    };
+}
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace query
+        {
+            TableMetadataQuery::TableMetadataQuery(diagnostic::Diagnosable& diag,
+                Connection& connection, const std::string& catalog,const std::string& schema,
+                const std::string& table, const std::string& tableType) :
+                Query(diag),
+                connection(connection),
+                catalog(catalog),
+                schema(schema),
+                table(table),
+                tableType(tableType),
+                executed(false),
+                meta(),
+                columnsMeta()
+            {
+                using namespace ignite::impl::binary;
+                using namespace ignite::odbc::type_traits;
+
+                using meta::ColumnMeta;
+
+                columnsMeta.reserve(5);
+
+                const std::string sch("");
+                const std::string tbl("");
+
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TABLE_CAT",   IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TABLE_SCHEM", IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TABLE_NAME",  IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TABLE_TYPE",  IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "REMARKS",     IGNITE_TYPE_STRING));
+            }
+
+            TableMetadataQuery::~TableMetadataQuery()
+            {
+                // No-op.
+            }
+
+            SqlResult TableMetadataQuery::Execute()
+            {
+                if (executed)
+                    Close();
+
+                SqlResult result = MakeRequestGetTablesMeta();
+
+                if (result == SQL_RESULT_SUCCESS)
+                {
+                    executed = true;
+
+                    cursor = meta.begin();
+                }
+
+                return result;
+            }
+
+            const meta::ColumnMetaVector& TableMetadataQuery::GetMeta() const
+            {
+                return columnsMeta;
+            }
+
+            SqlResult TableMetadataQuery::FetchNextRow(app::ColumnBindingMap& columnBindings)
+            {
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                if (cursor == meta.end())
+                    return SQL_RESULT_NO_DATA;
+
+                app::ColumnBindingMap::iterator it;
+
+                for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
+                    GetColumn(it->first, it->second);
+
+                ++cursor;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            SqlResult TableMetadataQuery::GetColumn(uint16_t columnIdx, app::ApplicationDataBuffer & buffer)
+            {
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                if (cursor == meta.end())
+                    return SQL_RESULT_NO_DATA;
+
+                const meta::TableMeta& currentColumn = *cursor;
+
+                switch (columnIdx)
+                {
+                    case TABLE_CAT:
+                    {
+                        buffer.PutString(currentColumn.GetCatalogName());
+                        break;
+                    }
+
+                    case TABLE_SCHEM:
+                    {
+                        buffer.PutString(currentColumn.GetSchemaName());
+                        break;
+                    }
+
+                    case TABLE_NAME:
+                    {
+                        buffer.PutString(currentColumn.GetTableName());
+                        break;
+                    }
+
+                    case TABLE_TYPE:
+                    {
+                        buffer.PutString(currentColumn.GetTableType());
+                        break;
+                    }
+
+                    case REMARKS:
+                    {
+                        buffer.PutNull();
+                        break;
+                    }
+
+                    default:
+                        break;
+                }
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            SqlResult TableMetadataQuery::Close()
+            {
+                meta.clear();
+
+                executed = false;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            bool TableMetadataQuery::DataAvailable() const
+            {
+                return cursor != meta.end();
+            }
+
+            int64_t TableMetadataQuery::AffectedRows() const
+            {
+                return 0;
+            }
+
+            SqlResult TableMetadataQuery::MakeRequestGetTablesMeta()
+            {
+                QueryGetTablesMetaRequest req(catalog, schema, table, tableType);
+                QueryGetTablesMetaResponse rsp;
+
+                try
+                {
+                    connection.SyncMessage(req, rsp);
+                }
+                catch (const IgniteError& err)
+                {
+                    diag.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());
+
+                    diag.AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, rsp.GetError());
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                meta = rsp.GetMeta();
+
+                for (size_t i = 0; i < meta.size(); ++i)
+                {
+                    LOG_MSG("[%d] CatalogName: %s\n", i, meta[i].GetCatalogName().c_str());
+                    LOG_MSG("[%d] SchemaName:  %s\n", i, meta[i].GetSchemaName().c_str());
+                    LOG_MSG("[%d] TableName:   %s\n", i, meta[i].GetTableName().c_str());
+                    LOG_MSG("[%d] TableType:   %s\n", i, meta[i].GetTableType().c_str());
+                    LOG_MSG("\n");
+                }
+
+                return SQL_RESULT_SUCCESS;
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
new file mode 100644
index 0000000..96bed3a
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -0,0 +1,394 @@
+/*
+ * 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 <cassert>
+
+#include <ignite/impl/binary/binary_common.h>
+
+#include "ignite/odbc/system/odbc_constants.h"
+#include "ignite/odbc/type_traits.h"
+#include "ignite/odbc/query/type_info_query.h"
+
+namespace
+{
+    enum ResultColumn
+    {
+        /** Data source�dependent data-type name. */
+        TYPE_NAME = 1,
+
+        /** SQL data type. */
+        DATA_TYPE,
+
+        /** The maximum column size that the server supports for this data type. */
+        COLUMN_SIZE,
+
+        /** Character or characters used to prefix a literal. */
+        LITERAL_PREFIX,
+
+        /** Character or characters used to terminate a literal. */
+        LITERAL_SUFFIX,
+
+        /**
+         * A list of keywords, separated by commas, corresponding to each
+         * parameter that the application may specify in parentheses when using
+         * the name that is returned in the TYPE_NAME field.
+         */
+        CREATE_PARAMS,
+
+        /** Whether the data type accepts a NULL value. */
+        NULLABLE,
+
+        /**
+         * Whether a character data type is case-sensitive in collations and
+         * comparisons.
+         */
+        CASE_SENSITIVE,
+
+        /** How the data type is used in a WHERE clause. */
+        SEARCHABLE,
+
+        /** Whether the data type is unsigned. */
+        UNSIGNED_ATTRIBUTE,
+
+        /** Whether the data type has predefined fixed precision and scale. */
+        FIXED_PREC_SCALE,
+
+        /** Whether the data type is autoincrementing. */
+        AUTO_UNIQUE_VALUE,
+
+        /**
+         * Localized version of the data source�dependent name of the data
+         * type.
+         */
+        LOCAL_TYPE_NAME,
+
+        /** The minimum scale of the data type on the data source. */
+        MINIMUM_SCALE,
+
+        /** The maximum scale of the data type on the data source. */
+        MAXIMUM_SCALE,
+
+        /**
+         * The value of the SQL data type as it appears in the SQL_DESC_TYPE
+         * field of the descriptor.
+         */
+        SQL_DATA_TYPE,
+
+        /**
+         * When the value of SQL_DATA_TYPE is SQL_DATETIME or SQL_INTERVAL,
+         * this column contains the datetime/interval subcode.
+         */
+        SQL_DATETIME_SUB,
+
+        /**
+         * If the data type is an approximate numeric type, this column
+         * contains the value 2 to indicate that COLUMN_SIZE specifies a number
+         * of bits.
+         */
+        NUM_PREC_RADIX,
+
+        /**
+         * If the data type is an interval data type, then this column contains
+         * the value of the interval leading precision.
+         */
+        INTERVAL_PRECISION
+    };
+}
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace query
+        {
+            TypeInfoQuery::TypeInfoQuery(diagnostic::Diagnosable& diag, int16_t sqlType) :
+                Query(diag),
+                columnsMeta(),
+                executed(false),
+                types(),
+                cursor(types.end())
+            {
+                using namespace ignite::impl::binary;
+                using namespace ignite::odbc::type_traits;
+
+                using meta::ColumnMeta;
+
+                columnsMeta.reserve(19);
+
+                const std::string sch("");
+                const std::string tbl("");
+
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "TYPE_NAME",          IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "DATA_TYPE",          IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "COLUMN_SIZE",        IGNITE_TYPE_INT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "LITERAL_PREFIX",     IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "LITERAL_SUFFIX",     IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "CREATE_PARAMS",      IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "NULLABLE",           IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "CASE_SENSITIVE",     IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "SEARCHABLE",         IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "UNSIGNED_ATTRIBUTE", IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "FIXED_PREC_SCALE",   IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "AUTO_UNIQUE_VALUE",  IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "LOCAL_TYPE_NAME",    IGNITE_TYPE_STRING));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "MINIMUM_SCALE",      IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "MAXIMUM_SCALE",      IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "SQL_DATA_TYPE",      IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "SQL_DATETIME_SUB",   IGNITE_TYPE_SHORT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "NUM_PREC_RADIX",     IGNITE_TYPE_INT));
+                columnsMeta.push_back(ColumnMeta(sch, tbl, "INTERVAL_PRECISION", IGNITE_TYPE_SHORT));
+
+                assert(IsSqlTypeSupported(sqlType));
+
+                if (sqlType == SQL_ALL_TYPES)
+                {
+                    types.push_back(IGNITE_TYPE_STRING);
+                    types.push_back(IGNITE_TYPE_SHORT);
+                    types.push_back(IGNITE_TYPE_INT);
+                    types.push_back(IGNITE_TYPE_DECIMAL);
+                    types.push_back(IGNITE_TYPE_FLOAT);
+                    types.push_back(IGNITE_TYPE_DOUBLE);
+                    types.push_back(IGNITE_TYPE_BOOL);
+                    types.push_back(IGNITE_TYPE_BYTE);
+                    types.push_back(IGNITE_TYPE_LONG);
+                    types.push_back(IGNITE_TYPE_UUID);
+                    types.push_back(IGNITE_TYPE_BINARY);
+                }
+                else
+                    types.push_back(SqlTypeToBinary(sqlType));
+            }
+
+            TypeInfoQuery::~TypeInfoQuery()
+            {
+                // No-op.
+            }
+
+            SqlResult TypeInfoQuery::Execute()
+            {
+                cursor = types.begin();
+
+                executed = true;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            const meta::ColumnMetaVector & TypeInfoQuery::GetMeta() const
+            {
+                return columnsMeta;
+            }
+
+            SqlResult TypeInfoQuery::FetchNextRow(app::ColumnBindingMap & columnBindings)
+            {
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                if (cursor == types.end())
+                    return SQL_RESULT_NO_DATA;
+
+                app::ColumnBindingMap::iterator it;
+
+                for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
+                    GetColumn(it->first, it->second);
+
+                ++cursor;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            SqlResult TypeInfoQuery::GetColumn(uint16_t columnIdx, app::ApplicationDataBuffer & buffer)
+            {
+                using namespace ignite::impl::binary;
+
+                if (!executed)
+                {
+                    diag.AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query was not executed.");
+
+                    return SQL_RESULT_ERROR;
+                }
+
+                if (cursor == types.end())
+                    return SQL_RESULT_NO_DATA;
+
+                int8_t currentType = *cursor;
+
+                switch (columnIdx)
+                {
+                    case TYPE_NAME:
+                    {
+                        buffer.PutString(type_traits::BinaryTypeToSqlTypeName(currentType));
+
+                        break;
+                    }
+
+                    case DATA_TYPE:
+                    case SQL_DATA_TYPE:
+                    {
+                        buffer.PutInt16(type_traits::BinaryToSqlType(currentType));
+
+                        break;
+                    }
+
+                    case COLUMN_SIZE:
+                    {
+                        buffer.PutInt32(type_traits::BinaryTypeColumnSize(currentType));
+
+                        break;
+                    }
+
+                    case LITERAL_PREFIX:
+                    {
+                        if (currentType == IGNITE_TYPE_STRING)
+                            buffer.PutString("'");
+                        else if (currentType == IGNITE_TYPE_BINARY)
+                            buffer.PutString("0x");
+                        else
+                            buffer.PutNull();
+
+                        break;
+                    }
+
+                    case LITERAL_SUFFIX:
+                    {
+                        if (currentType == IGNITE_TYPE_STRING)
+                            buffer.PutString("'");
+                        else
+                            buffer.PutNull();
+
+                        break;
+                    }
+
+                    case CREATE_PARAMS:
+                    {
+                        buffer.PutNull();
+
+                        break;
+                    }
+
+                    case NULLABLE:
+                    {
+                        buffer.PutInt32(type_traits::BinaryTypeNullability(currentType));
+
+                        break;
+                    }
+
+                    case CASE_SENSITIVE:
+                    {
+                        if (currentType == IGNITE_TYPE_STRING)
+                            buffer.PutInt16(SQL_TRUE);
+                        else
+                            buffer.PutInt16(SQL_FALSE);
+
+                        break;
+                    }
+
+                    case SEARCHABLE:
+                    {
+                        buffer.PutInt16(SQL_SEARCHABLE);
+
+                        break;
+                    }
+
+                    case UNSIGNED_ATTRIBUTE:
+                    {
+                        buffer.PutInt16(type_traits::BinaryTypeUnsigned(currentType));
+
+                        break;
+                    }
+
+                    case FIXED_PREC_SCALE:
+                    {
+                        buffer.PutInt16(SQL_FALSE);
+
+                        break;
+                    }
+
+                    case AUTO_UNIQUE_VALUE:
+                    {
+                        buffer.PutInt16(SQL_FALSE);
+
+                        break;
+                    }
+
+                    case LOCAL_TYPE_NAME:
+                    {
+                        buffer.PutNull();
+
+                        break;
+                    }
+
+                    case MINIMUM_SCALE:
+                    case MAXIMUM_SCALE:
+                    {
+                        buffer.PutInt16(type_traits::BinaryTypeDecimalDigits(currentType));
+
+                        break;
+                    }
+
+                    case SQL_DATETIME_SUB:
+                    {
+                        buffer.PutNull();
+
+                        break;
+                    }
+
+                    case NUM_PREC_RADIX:
+                    {
+                        buffer.PutInt32(type_traits::BinaryTypeNumPrecRadix(currentType));
+
+                        break;
+                    }
+
+                    case INTERVAL_PRECISION:
+                    {
+                        buffer.PutNull();
+
+                        break;
+                    }
+
+                    default:
+                        break;
+                }
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            SqlResult TypeInfoQuery::Close()
+            {
+                cursor = types.end();
+
+                executed = false;
+
+                return SQL_RESULT_SUCCESS;
+            }
+
+            bool TypeInfoQuery::DataAvailable() const
+            {
+                return cursor != types.end();;
+            }
+
+            int64_t TypeInfoQuery::AffectedRows() const
+            {
+                return 0;
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/result_page.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/result_page.cpp b/modules/platforms/cpp/odbc/src/result_page.cpp
new file mode 100644
index 0000000..4464481
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/result_page.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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/interop/interop_input_stream.h>
+
+#include "ignite/odbc/result_page.h"
+#include "ignite/odbc/utility.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        ResultPage::ResultPage() :
+            last(false), size(0), data(DEFAULT_ALLOCATED_MEMORY)
+        {
+            //No-op.
+        }
+
+        ResultPage::~ResultPage()
+        {
+            //No-op.
+        }
+
+        void ResultPage::Read(ignite::impl::binary::BinaryReaderImpl& reader)
+        {
+            last = reader.ReadBool();
+            size = reader.ReadInt32();
+
+            ignite::impl::interop::InteropInputStream& stream = *reader.GetStream();
+
+            int32_t dataToRead = stream.Remaining();
+
+            data.Length(dataToRead);
+
+            if (dataToRead)
+            {
+                data.Reallocate(dataToRead);
+
+                reader.GetStream()->ReadInt8Array(data.Data(), dataToRead);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/row.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/row.cpp b/modules/platforms/cpp/odbc/src/row.cpp
new file mode 100644
index 0000000..5e5a00e
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/row.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/interop/interop_stream_position_guard.h>
+
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/row.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        Row::Row(ignite::impl::interop::InteropUnpooledMemory& pageData) :
+            rowBeginPos(0), pos(rowBeginPos), size(0), pageData(pageData),
+            stream(&pageData), reader(&stream), columns()
+        {
+            if (pageData.Length() >= 4)
+            {
+                Reinit();
+            }
+        }
+
+        Row::~Row()
+        {
+            // No-op.
+        }
+
+        bool Row::EnsureColumnDiscovered(uint16_t columnIdx)
+        {
+            if (columns.size() >= columnIdx)
+                return true;
+
+            if (columnIdx > GetSize() || columnIdx < 1)
+                return false;
+
+            if (columns.empty())
+            {
+                Column newColumn(reader);
+
+                if (!newColumn.IsValid())
+                    return false;
+
+                columns.push_back(newColumn);
+            }
+
+            while (columns.size() < columnIdx)
+            {
+                Column& column = columns.back();
+
+                stream.Position(column.GetEndPosition());
+
+                Column newColumn(reader);
+
+                if (!newColumn.IsValid())
+                    return false;
+
+                columns.push_back(newColumn);
+            }
+
+            return true;
+        }
+
+        SqlResult Row::ReadColumnToBuffer(uint16_t columnIdx, app::ApplicationDataBuffer& dataBuf)
+        {
+            using namespace ignite::impl::binary;
+            using namespace ignite::impl::interop;
+
+            if (!EnsureColumnDiscovered(columnIdx))
+                return SQL_RESULT_ERROR;
+
+            Column& column = GetColumn(columnIdx);
+
+            return column.ReadToBuffer(reader, dataBuf);
+        }
+
+        bool Row::MoveToNext()
+        {
+            int32_t lastColumnIdx = GetSize();
+
+            if (!EnsureColumnDiscovered(lastColumnIdx))
+                return false;
+
+            Column& lastColumn = GetColumn(lastColumnIdx);
+
+            stream.Position(lastColumn.GetEndPosition());
+
+            Reinit();
+
+            return true;
+        }
+
+        void Row::Reinit()
+        {
+            size = stream.ReadInt32();
+
+            rowBeginPos = stream.Position();
+
+            columns.clear();
+
+            columns.reserve(size);
+
+            pos = 0;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
new file mode 100644
index 0000000..96a6327
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -0,0 +1,524 @@
+/*
+ * 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/query/data_query.h"
+#include "ignite/odbc/query/column_metadata_query.h"
+#include "ignite/odbc/query/table_metadata_query.h"
+#include "ignite/odbc/query/foreign_keys_query.h"
+#include "ignite/odbc/query/primary_keys_query.h"
+#include "ignite/odbc/query/type_info_query.h"
+#include "ignite/odbc/query/special_columns_query.h"
+#include "ignite/odbc/connection.h"
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/message.h"
+#include "ignite/odbc/statement.h"
+
+namespace ignite
+{
+    namespace odbc
+    {
+        Statement::Statement(Connection& parent) :
+            connection(parent), columnBindings(), currentQuery(),
+            rowsFetched(0), rowStatuses(0), paramBindOffset(0), columnBindOffset(0)
+        {
+            // No-op.
+        }
+
+        Statement::~Statement()
+        {
+            // No-op.
+        }
+
+        void Statement::BindColumn(uint16_t columnIdx, const app::ApplicationDataBuffer& buffer)
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            columnBindings[columnIdx] = buffer;
+
+            columnBindings[columnIdx].SetPtrToOffsetPtr(&columnBindOffset);
+        }
+
+        void Statement::UnbindColumn(uint16_t columnIdx)
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            columnBindings.erase(columnIdx);
+        }
+
+        void Statement::UnbindAllColumns()
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            columnBindings.clear();
+        }
+
+        void Statement::SetColumnBindOffsetPtr(size_t * ptr)
+        {
+            columnBindOffset = ptr;
+        }
+
+        size_t * Statement::GetColumnBindOffsetPtr()
+        {
+            return columnBindOffset;
+        }
+
+        int32_t Statement::GetColumnNumber()
+        {
+            int32_t res;
+
+            IGNITE_ODBC_API_CALL(InternalGetColumnNumber(res));
+
+            return res;
+        }
+
+        SqlResult Statement::InternalGetColumnNumber(int32_t &res)
+        {
+            const meta::ColumnMetaVector* meta = GetMeta();
+
+            if (!meta)
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not executed.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            res = static_cast<int32_t>(meta->size());
+
+            return SQL_RESULT_SUCCESS;
+        }
+
+        void Statement::BindParameter(uint16_t paramIdx, const app::Parameter& param)
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            paramBindings[paramIdx] = param;
+
+            paramBindings[paramIdx].GetBuffer().SetPtrToOffsetPtr(&paramBindOffset);
+        }
+
+        void Statement::UnbindParameter(uint16_t paramIdx)
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            paramBindings.erase(paramIdx);
+        }
+
+        void Statement::UnbindAllParameters()
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            paramBindings.clear();
+        }
+
+        uint16_t Statement::GetParametersNumber()
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            return static_cast<uint16_t>(paramBindings.size());
+        }
+
+        void Statement::SetParamBindOffsetPtr(size_t* ptr)
+        {
+            IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
+
+            paramBindOffset = ptr;
+        }
+
+        size_t * Statement::GetParamBindOffsetPtr()
+        {
+            return paramBindOffset;
+        }
+
+        void Statement::GetColumnData(uint16_t columnIdx, app::ApplicationDataBuffer& buffer)
+        {
+            IGNITE_ODBC_API_CALL(InternalGetColumnData(columnIdx, buffer));
+        }
+
+        SqlResult Statement::InternalGetColumnData(uint16_t columnIdx, app::ApplicationDataBuffer& buffer)
+        {
+            if (!currentQuery.get())
+            {
+                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE, "Cursor is not in the open state.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            SqlResult res = currentQuery->GetColumn(columnIdx, buffer);
+
+            return res;
+        }
+
+        void Statement::PrepareSqlQuery(const std::string& query)
+        {
+            return PrepareSqlQuery(query.data(), query.size());
+        }
+
+        void Statement::PrepareSqlQuery(const char* query, size_t len)
+        {
+            IGNITE_ODBC_API_CALL(InternalPrepareSqlQuery(query, len));
+        }
+
+        SqlResult Statement::InternalPrepareSqlQuery(const char* query, size_t len)
+        {
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            std::string sql(query, len);
+
+            currentQuery.reset(new query::DataQuery(*this, connection, sql, paramBindings));
+
+            return SQL_RESULT_SUCCESS;
+        }
+
+        void Statement::ExecuteSqlQuery(const std::string& query)
+        {
+            ExecuteSqlQuery(query.data(), query.size());
+        }
+
+        void Statement::ExecuteSqlQuery(const char* query, size_t len)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteSqlQuery(query, len));
+        }
+
+        SqlResult Statement::InternalExecuteSqlQuery(const char* query, size_t len)
+        {
+            SqlResult result = InternalPrepareSqlQuery(query, len);
+
+            if (result != SQL_RESULT_SUCCESS)
+                return result;
+
+            return InternalExecuteSqlQuery();
+        }
+
+        void Statement::ExecuteSqlQuery()
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteSqlQuery());
+        }
+
+        SqlResult Statement::InternalExecuteSqlQuery()
+        {
+            if (!currentQuery.get())
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not prepared.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteGetColumnsMetaQuery(const std::string& schema,
+            const std::string& table, const std::string& column)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteGetColumnsMetaQuery(schema, table, column));
+        }
+
+        SqlResult Statement::InternalExecuteGetColumnsMetaQuery(const std::string& schema,
+            const std::string& table, const std::string& column)
+        {
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            std::string cache(schema);
+
+            if (cache.empty())
+                cache = connection.GetCache();
+
+            currentQuery.reset(new query::ColumnMetadataQuery(*this, connection, cache, table, column));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteGetTablesMetaQuery(const std::string& catalog,
+            const std::string& schema, const std::string& table, const std::string& tableType)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteGetTablesMetaQuery(catalog, schema, table, tableType));
+        }
+
+        SqlResult Statement::InternalExecuteGetTablesMetaQuery(const std::string& catalog,
+            const std::string& schema, const std::string& table, const std::string& tableType)
+        {
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            currentQuery.reset(new query::TableMetadataQuery(*this, connection, catalog, schema, table, tableType));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteGetForeignKeysQuery(const std::string& primaryCatalog,
+            const std::string& primarySchema, const std::string& primaryTable,
+            const std::string& foreignCatalog, const std::string& foreignSchema,
+            const std::string& foreignTable)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteGetForeignKeysQuery(primaryCatalog,
+                primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable));
+        }
+
+        SqlResult Statement::InternalExecuteGetForeignKeysQuery(const std::string& primaryCatalog,
+            const std::string& primarySchema, const std::string& primaryTable,
+            const std::string& foreignCatalog, const std::string& foreignSchema,
+            const std::string& foreignTable)
+        {
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            currentQuery.reset(new query::ForeignKeysQuery(*this, connection, primaryCatalog, primarySchema,
+                primaryTable, foreignCatalog, foreignSchema, foreignTable));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteGetPrimaryKeysQuery(const std::string& catalog, const std::string& schema,
+            const std::string& table)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteGetPrimaryKeysQuery(catalog, schema, table));
+        }
+
+        SqlResult Statement::InternalExecuteGetPrimaryKeysQuery(const std::string& catalog, const std::string& schema,
+            const std::string& table)
+        {
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            currentQuery.reset(new query::PrimaryKeysQuery(*this, connection, catalog, schema, table));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteSpecialColumnsQuery(int16_t type,
+            const std::string& catalog, const std::string& schema,
+            const std::string& table, int16_t scope, int16_t nullable)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteSpecialColumnsQuery(type,
+                catalog, schema, table, scope, nullable));
+        }
+
+        SqlResult Statement::InternalExecuteSpecialColumnsQuery(int16_t type,
+            const std::string& catalog, const std::string& schema,
+            const std::string& table, int16_t scope, int16_t nullable)
+        {
+            if (type != SQL_BEST_ROWID && type != SQL_ROWVER)
+            {
+                AddStatusRecord(SQL_STATE_HY097_COLUMN_TYPE_OUT_OF_RANGE,
+                    "An invalid IdentifierType value was specified.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            currentQuery.reset(new query::SpecialColumnsQuery(*this, type,
+                catalog, schema, table, scope, nullable));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::ExecuteGetTypeInfoQuery(int16_t sqlType)
+        {
+            IGNITE_ODBC_API_CALL(InternalExecuteGetTypeInfoQuery(sqlType));
+        }
+
+        SqlResult Statement::InternalExecuteGetTypeInfoQuery(int16_t sqlType)
+        {
+            if (!type_traits::IsSqlTypeSupported(sqlType))
+            {
+                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, "Data type is not supported.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            if (currentQuery.get())
+                currentQuery->Close();
+
+            currentQuery.reset(new query::TypeInfoQuery(*this, sqlType));
+
+            return currentQuery->Execute();
+        }
+
+        void Statement::Close()
+        {
+            IGNITE_ODBC_API_CALL(InternalClose());
+        }
+
+        SqlResult Statement::InternalClose()
+        {
+            if (!currentQuery.get())
+            {
+                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE, "Cursor is not in the open state.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            SqlResult result = currentQuery->Close();
+
+            if (result == SQL_RESULT_SUCCESS)
+                currentQuery.reset();
+
+            return result;
+        }
+
+        void Statement::FetchRow()
+        {
+            IGNITE_ODBC_API_CALL(InternalFetchRow());
+        }
+
+        SqlResult Statement::InternalFetchRow()
+        {
+            if (rowsFetched)
+                *rowsFetched = 0;
+
+            if (!currentQuery.get())
+            {
+                AddStatusRecord(SQL_STATE_24000_INVALID_CURSOR_STATE, "Cursor is not in the open state.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            SqlResult res = currentQuery->FetchNextRow(columnBindings);
+
+            if (res == SQL_RESULT_SUCCESS)
+            {
+                if (rowsFetched)
+                    *rowsFetched = 1;
+
+                if (rowStatuses)
+                    rowStatuses[0] = SQL_ROW_SUCCESS;
+            }
+
+            return res;
+        }
+
+        const meta::ColumnMetaVector* Statement::GetMeta() const
+        {
+            if (!currentQuery.get())
+                return 0;
+
+            return &currentQuery->GetMeta();
+        }
+
+        bool Statement::DataAvailable() const
+        {
+            return currentQuery.get() && currentQuery->DataAvailable();
+        }
+
+        void Statement::GetColumnAttribute(uint16_t colIdx, uint16_t attrId,
+            char* strbuf, int16_t buflen, int16_t* reslen, SqlLen* numbuf)
+        {
+            IGNITE_ODBC_API_CALL(InternalGetColumnAttribute(colIdx, attrId,
+                strbuf, buflen, reslen, numbuf));
+        }
+
+        SqlResult Statement::InternalGetColumnAttribute(uint16_t colIdx,
+            uint16_t attrId, char* strbuf, int16_t buflen, int16_t* reslen,
+            SqlLen* numbuf)
+        {
+            const meta::ColumnMetaVector *meta = GetMeta();
+
+            if (!meta)
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not executed.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            if (colIdx > meta->size() + 1 || colIdx < 1)
+            {
+                AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Column index is out of range.", 0, colIdx);
+
+                return SQL_RESULT_ERROR;
+            }
+
+            const meta::ColumnMeta& columnMeta = meta->at(colIdx - 1);
+
+            bool found = false;
+
+            if (numbuf)
+                found = columnMeta.GetAttribute(attrId, *numbuf);
+
+            if (!found)
+            {
+                std::string out;
+
+                found = columnMeta.GetAttribute(attrId, out);
+
+                size_t outSize = out.size();
+
+                if (found && strbuf)
+                    outSize = utility::CopyStringToBuffer(out, strbuf, buflen);
+
+                if (found && strbuf)
+                    *reslen = static_cast<int16_t>(outSize);
+            }
+
+            if (!found)
+            {
+                AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, "Unknown attribute.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            return SQL_RESULT_SUCCESS;
+        }
+
+        int64_t Statement::AffectedRows()
+        {
+            int64_t rowCnt = 0;
+
+            IGNITE_ODBC_API_CALL(InternalAffectedRows(rowCnt));
+
+            return rowCnt;
+        }
+
+        SqlResult Statement::InternalAffectedRows(int64_t& rowCnt)
+        {
+            if (!currentQuery.get())
+            {
+                AddStatusRecord(SQL_STATE_HY010_SEQUENCE_ERROR, "Query is not executed.");
+
+                return SQL_RESULT_ERROR;
+            }
+
+            rowCnt = currentQuery->AffectedRows();
+
+            return SQL_RESULT_SUCCESS;
+        }
+
+        void Statement::SetRowsFetchedPtr(size_t* ptr)
+        {
+            rowsFetched = ptr;
+        }
+
+        size_t* Statement::GetRowsFetchedPtr()
+        {
+            return rowsFetched;
+        }
+
+        void Statement::SetRowStatusesPtr(uint16_t* ptr)
+        {
+            rowStatuses = ptr;
+        }
+
+        uint16_t * Statement::GetRowStatusesPtr()
+        {
+            return rowStatuses;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/type_traits.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/type_traits.cpp b/modules/platforms/cpp/odbc/src/type_traits.cpp
new file mode 100644
index 0000000..fced2e1
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/type_traits.cpp
@@ -0,0 +1,669 @@
+/*
+ * 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/type_traits.h"
+
+namespace
+{
+    /** Default display size. */
+    enum { DEFAULT_DISPLAY_SIZE = 34 };
+
+    /** Default variable size data display size. */
+    enum { DEFAULT_VARDATA_DISPLAY_SIZE = 64 };
+}
+
+namespace ignite
+{
+    namespace odbc
+    {
+        namespace type_traits
+        {
+            const std::string SqlTypeName::VARCHAR("LONG VARCHAR");
+
+            const std::string SqlTypeName::SMALLINT("SMALLINT");
+
+            const std::string SqlTypeName::INTEGER("INTEGER");
+
+            const std::string SqlTypeName::DECIMAL("DECIMAL");
+
+            const std::string SqlTypeName::FLOAT("FLOAT");
+
+            const std::string SqlTypeName::DOUBLE("DOUBLE");
+
+            const std::string SqlTypeName::BIT("BIT");
+
+            const std::string SqlTypeName::TINYINT("TINYINT");
+
+            const std::string SqlTypeName::BIGINT("BIGINT");
+
+            const std::string SqlTypeName::BINARY("LONG VARBINARY");
+
+            const std::string SqlTypeName::DATE("DATE");
+
+            const std::string SqlTypeName::TIMESTAMP("TIMESTAMP");
+
+            const std::string SqlTypeName::GUID("GUID");
+
+#ifdef ODBC_DEBUG
+
+#define DBG_STR_CASE(x) case x: return #x
+
+            const char* StatementAttrIdToString(long id)
+            {
+                switch (id)
+                {
+                    DBG_STR_CASE(SQL_ATTR_APP_PARAM_DESC);
+                    DBG_STR_CASE(SQL_ATTR_APP_ROW_DESC);
+                    DBG_STR_CASE(SQL_ATTR_ASYNC_ENABLE);
+                    DBG_STR_CASE(SQL_ATTR_CONCURRENCY);
+                    DBG_STR_CASE(SQL_ATTR_CURSOR_SCROLLABLE);
+                    DBG_STR_CASE(SQL_ATTR_CURSOR_SENSITIVITY);
+                    DBG_STR_CASE(SQL_ATTR_CURSOR_TYPE);
+                    DBG_STR_CASE(SQL_ATTR_ENABLE_AUTO_IPD);
+                    DBG_STR_CASE(SQL_ATTR_FETCH_BOOKMARK_PTR);
+                    DBG_STR_CASE(SQL_ATTR_IMP_PARAM_DESC);
+                    DBG_STR_CASE(SQL_ATTR_IMP_ROW_DESC);
+                    DBG_STR_CASE(SQL_ATTR_KEYSET_SIZE);
+                    DBG_STR_CASE(SQL_ATTR_MAX_LENGTH);
+                    DBG_STR_CASE(SQL_ATTR_MAX_ROWS);
+                    DBG_STR_CASE(SQL_ATTR_METADATA_ID);
+                    DBG_STR_CASE(SQL_ATTR_NOSCAN);
+                    DBG_STR_CASE(SQL_ATTR_PARAM_BIND_OFFSET_PTR);
+                    DBG_STR_CASE(SQL_ATTR_PARAM_BIND_TYPE);
+                    DBG_STR_CASE(SQL_ATTR_PARAM_OPERATION_PTR);
+                    DBG_STR_CASE(SQL_ATTR_PARAM_STATUS_PTR);
+                    DBG_STR_CASE(SQL_ATTR_PARAMS_PROCESSED_PTR);
+                    DBG_STR_CASE(SQL_ATTR_PARAMSET_SIZE);
+                    DBG_STR_CASE(SQL_ATTR_QUERY_TIMEOUT);
+                    DBG_STR_CASE(SQL_ATTR_RETRIEVE_DATA);
+                    DBG_STR_CASE(SQL_ATTR_ROW_ARRAY_SIZE);
+                    DBG_STR_CASE(SQL_ATTR_ROW_BIND_OFFSET_PTR);
+                    DBG_STR_CASE(SQL_ATTR_ROW_BIND_TYPE);
+                    DBG_STR_CASE(SQL_ATTR_ROW_NUMBER);
+                    DBG_STR_CASE(SQL_ATTR_ROW_OPERATION_PTR);
+                    DBG_STR_CASE(SQL_ATTR_ROW_STATUS_PTR);
+                    DBG_STR_CASE(SQL_ATTR_ROWS_FETCHED_PTR);
+                    DBG_STR_CASE(SQL_ATTR_SIMULATE_CURSOR);
+                    DBG_STR_CASE(SQL_ATTR_USE_BOOKMARKS);
+                default:
+                    break;
+                }
+                return "<< UNKNOWN ID >>";
+            }
+
+#undef DBG_STR_CASE
+#endif
+
+            const std::string& BinaryTypeToSqlTypeName(int8_t binaryType)
+            {
+                using namespace ignite::impl::binary;
+
+                switch (binaryType)
+                {
+                case IGNITE_TYPE_STRING:
+                    return SqlTypeName::VARCHAR;
+
+                case IGNITE_TYPE_SHORT:
+                    return SqlTypeName::SMALLINT;
+
+                case IGNITE_TYPE_INT:
+                    return SqlTypeName::INTEGER;
+
+                case IGNITE_TYPE_DECIMAL:
+                    return SqlTypeName::DECIMAL;
+
+                case IGNITE_TYPE_FLOAT:
+                    return SqlTypeName::FLOAT;
+
+                case IGNITE_TYPE_DOUBLE:
+                    return SqlTypeName::DOUBLE;
+
+                case IGNITE_TYPE_BOOL:
+                    return SqlTypeName::BIT;
+
+                case IGNITE_TYPE_BYTE:
+                case IGNITE_TYPE_CHAR:
+                    return SqlTypeName::TINYINT;
+
+                case IGNITE_TYPE_LONG:
+                    return SqlTypeName::BIGINT;
+
+                case IGNITE_TYPE_UUID:
+                    return SqlTypeName::GUID;
+
+                case IGNITE_TYPE_DATE:
+                    return SqlTypeName::DATE;
+
+                case IGNITE_TYPE_TIMESTAMP:
+                    return SqlTypeName::TIMESTAMP;
+
+                case IGNITE_TYPE_OBJECT:
+                case IGNITE_TYPE_ARRAY_BYTE:
+                case IGNITE_TYPE_ARRAY_SHORT:
+                case IGNITE_TYPE_ARRAY_INT:
+                case IGNITE_TYPE_ARRAY_LONG:
+                case IGNITE_TYPE_ARRAY_FLOAT:
+                case IGNITE_TYPE_ARRAY_DOUBLE:
+                case IGNITE_TYPE_ARRAY_CHAR:
+                case IGNITE_TYPE_ARRAY_BOOL:
+                case IGNITE_TYPE_ARRAY_DECIMAL:
+                case IGNITE_TYPE_ARRAY_STRING:
+                case IGNITE_TYPE_ARRAY_UUID:
+                case IGNITE_TYPE_ARRAY_DATE:
+                case IGNITE_TYPE_ARRAY_TIMESTAMP:
+                case IGNITE_TYPE_ARRAY:
+                case IGNITE_TYPE_COLLECTION:
+                case IGNITE_TYPE_MAP:
+                case IGNITE_TYPE_MAP_ENTRY:
+                case IGNITE_TYPE_BINARY:
+                default:
+                    return SqlTypeName::BINARY;
+                }
+
+                return SqlTypeName::BINARY;
+            }
+
+            bool IsApplicationTypeSupported(int16_t type)
+            {
+                return ToDriverType(type) != IGNITE_ODBC_C_TYPE_UNSUPPORTED;
+            }
+
+            bool IsSqlTypeSupported(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_CHAR:
+                    case SQL_VARCHAR:
+                    case SQL_LONGVARCHAR:
+                    case SQL_SMALLINT:
+                    case SQL_INTEGER:
+                    case SQL_FLOAT:
+                    case SQL_DOUBLE:
+                    case SQL_BIT:
+                    case SQL_TINYINT:
+                    case SQL_BIGINT:
+                    case SQL_BINARY:
+                    case SQL_VARBINARY:
+                    case SQL_LONGVARBINARY:
+                    case SQL_GUID:
+                    case SQL_DECIMAL:
+                    case SQL_TYPE_DATE:
+                    case SQL_TYPE_TIMESTAMP:
+                        return true;
+
+                    case SQL_WCHAR:
+                    case SQL_WVARCHAR:
+                    case SQL_WLONGVARCHAR:
+                    case SQL_REAL:
+                    case SQL_NUMERIC:
+                    case SQL_TYPE_TIME:
+                    case SQL_INTERVAL_MONTH:
+                    case SQL_INTERVAL_YEAR:
+                    case SQL_INTERVAL_YEAR_TO_MONTH:
+                    case SQL_INTERVAL_DAY:
+                    case SQL_INTERVAL_HOUR:
+                    case SQL_INTERVAL_MINUTE:
+                    case SQL_INTERVAL_SECOND:
+                    case SQL_INTERVAL_DAY_TO_HOUR:
+                    case SQL_INTERVAL_DAY_TO_MINUTE:
+                    case SQL_INTERVAL_DAY_TO_SECOND:
+                    case SQL_INTERVAL_HOUR_TO_MINUTE:
+                    case SQL_INTERVAL_HOUR_TO_SECOND:
+                    case SQL_INTERVAL_MINUTE_TO_SECOND:
+                    default:
+                        return false;
+                }
+            }
+
+            int8_t SqlTypeToBinary(int16_t sqlType)
+            {
+                using namespace ignite::impl::binary;
+
+                switch (sqlType)
+                {
+                    case SQL_CHAR:
+                    case SQL_VARCHAR:
+                    case SQL_LONGVARCHAR:
+                        return IGNITE_TYPE_STRING;
+
+                    case SQL_SMALLINT:
+                        return IGNITE_TYPE_SHORT;
+
+                    case SQL_TINYINT:
+                        return IGNITE_TYPE_BYTE;
+
+                    case SQL_INTEGER:
+                        return IGNITE_TYPE_INT;
+
+                    case SQL_BIGINT:
+                        return IGNITE_TYPE_LONG;
+
+                    case SQL_FLOAT:
+                        return IGNITE_TYPE_FLOAT;
+
+                    case SQL_DOUBLE:
+                        return IGNITE_TYPE_DOUBLE;
+
+                    case SQL_BIT:
+                        return IGNITE_TYPE_BOOL;
+
+                    case SQL_BINARY:
+                    case SQL_VARBINARY:
+                    case SQL_LONGVARBINARY:
+                        return IGNITE_TYPE_BINARY;
+
+                    case SQL_DECIMAL:
+                        return IGNITE_TYPE_DECIMAL;
+
+                    case SQL_GUID:
+                        return IGNITE_TYPE_UUID;
+
+                    case SQL_TYPE_DATE:
+                        return IGNITE_TYPE_DATE;
+
+                    case SQL_TYPE_TIMESTAMP:
+                        return IGNITE_TYPE_TIMESTAMP;
+
+                    default:
+                        break;
+                }
+
+                return -1;
+            }
+
+            IgniteSqlType ToDriverType(int16_t type)
+            {
+                switch (type)
+                {
+                case SQL_C_CHAR:
+                    return IGNITE_ODBC_C_TYPE_CHAR;
+
+                case SQL_C_WCHAR:
+                    return IGNITE_ODBC_C_TYPE_WCHAR;
+
+                case SQL_C_SSHORT:
+                    return IGNITE_ODBC_C_TYPE_SIGNED_SHORT;
+
+                case SQL_C_USHORT:
+                    return IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT;
+
+                case SQL_C_SLONG:
+                    return IGNITE_ODBC_C_TYPE_SIGNED_LONG;
+
+                case SQL_C_ULONG:
+                    return IGNITE_ODBC_C_TYPE_UNSIGNED_LONG;
+
+                case SQL_C_FLOAT:
+                    return IGNITE_ODBC_C_TYPE_FLOAT;
+
+                case SQL_C_DOUBLE:
+                    return IGNITE_ODBC_C_TYPE_DOUBLE;
+
+                case SQL_C_BIT:
+                    return IGNITE_ODBC_C_TYPE_BIT;
+
+                case SQL_C_STINYINT:
+                    return IGNITE_ODBC_C_TYPE_SIGNED_TINYINT;
+
+                case SQL_C_UTINYINT:
+                    return IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT;
+
+                case SQL_C_SBIGINT:
+                    return IGNITE_ODBC_C_TYPE_SIGNED_BIGINT;
+
+                case SQL_C_UBIGINT:
+                    return IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT;
+
+                case SQL_C_BINARY:
+                    return IGNITE_ODBC_C_TYPE_BINARY;
+
+                case SQL_C_TYPE_DATE:
+                    return IGNITE_ODBC_C_TYPE_TDATE;
+
+                case SQL_C_TYPE_TIME:
+                    return IGNITE_ODBC_C_TYPE_TTIME;
+
+                case SQL_C_TYPE_TIMESTAMP:
+                    return IGNITE_ODBC_C_TYPE_TTIMESTAMP;
+
+                case SQL_C_NUMERIC:
+                    return IGNITE_ODBC_C_TYPE_NUMERIC;
+
+                case SQL_C_GUID:
+                    return IGNITE_ODBC_C_TYPE_GUID;
+
+                case SQL_C_DEFAULT:
+                    return IGNITE_ODBC_C_TYPE_DEFAULT;
+
+                default:
+                    return IGNITE_ODBC_C_TYPE_UNSUPPORTED;
+                }
+            }
+
+            int16_t BinaryToSqlType(int8_t binaryType)
+            {
+                using namespace ignite::impl::binary;
+                switch (binaryType)
+                {
+                    case IGNITE_TYPE_BYTE:
+                    case IGNITE_TYPE_CHAR:
+                        return SQL_TINYINT;
+
+                    case IGNITE_TYPE_SHORT:
+                        return SQL_SMALLINT;
+
+                    case IGNITE_TYPE_INT:
+                        return SQL_INTEGER;
+
+                    case IGNITE_TYPE_LONG:
+                        return SQL_BIGINT;
+
+                    case IGNITE_TYPE_FLOAT:
+                        return SQL_FLOAT;
+
+                    case IGNITE_TYPE_DOUBLE:
+                        return SQL_DOUBLE;
+
+                    case IGNITE_TYPE_BOOL:
+                        return SQL_BIT;
+
+                    case IGNITE_TYPE_DECIMAL:
+                        return SQL_DECIMAL;
+
+                    case IGNITE_TYPE_STRING:
+                        return SQL_VARCHAR;
+
+                    case IGNITE_TYPE_UUID:
+                        return SQL_GUID;
+
+                    case IGNITE_TYPE_DATE:
+                        return SQL_TYPE_DATE;
+
+                    case IGNITE_TYPE_TIMESTAMP:
+                        return SQL_TYPE_TIMESTAMP;
+
+                    case IGNITE_TYPE_ARRAY_BYTE:
+                    case IGNITE_TYPE_ARRAY_SHORT:
+                    case IGNITE_TYPE_ARRAY_INT:
+                    case IGNITE_TYPE_ARRAY_LONG:
+                    case IGNITE_TYPE_ARRAY_FLOAT:
+                    case IGNITE_TYPE_ARRAY_DOUBLE:
+                    case IGNITE_TYPE_ARRAY_CHAR:
+                    case IGNITE_TYPE_ARRAY_BOOL:
+                    case IGNITE_TYPE_ARRAY_DECIMAL:
+                    case IGNITE_TYPE_ARRAY_STRING:
+                    case IGNITE_TYPE_ARRAY_UUID:
+                    case IGNITE_TYPE_ARRAY_DATE:
+                    case IGNITE_TYPE_ARRAY:
+                    case IGNITE_TYPE_COLLECTION:
+                    case IGNITE_TYPE_MAP:
+                    case IGNITE_TYPE_MAP_ENTRY:
+                    case IGNITE_TYPE_BINARY:
+                    case IGNITE_TYPE_OBJECT:
+                    default:
+                        return SQL_BINARY;
+                }
+            }
+
+            int16_t BinaryTypeNullability(int8_t binaryType)
+            {
+                return SQL_NULLABLE_UNKNOWN;
+            }
+
+            int32_t SqlTypeDisplaySize(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_VARCHAR:
+                    case SQL_CHAR:
+                    case SQL_WCHAR:
+                    case SQL_BINARY:
+                        return DEFAULT_VARDATA_DISPLAY_SIZE;
+
+                    case SQL_BIT:
+                        return 1;
+
+                    case SQL_TINYINT:
+                        return 4;
+
+                    case SQL_SMALLINT:
+                        return 6;
+
+                    case SQL_INTEGER:
+                        return 11;
+
+                    case SQL_BIGINT:
+                        return 20;
+
+                    case SQL_REAL:
+                        return 14;
+
+                    case SQL_FLOAT:
+                    case SQL_DOUBLE:
+                        return 24;
+
+                    case SQL_TYPE_DATE:
+                        return 10;
+
+                    case SQL_TYPE_TIME:
+                        return 8;
+
+                    case SQL_TYPE_TIMESTAMP:
+                        return 19;
+
+                    case SQL_GUID:
+                        return 36;
+
+                    case SQL_DECIMAL:
+                    case SQL_NUMERIC:
+                    default:
+                        return DEFAULT_DISPLAY_SIZE;
+                }
+            }
+
+            int32_t BinaryTypeDisplaySize(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeDisplaySize(sqlType);
+            }
+
+            int32_t SqlTypeColumnSize(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_VARCHAR:
+                    case SQL_CHAR:
+                    case SQL_WCHAR:
+                    case SQL_BINARY:
+                        return DEFAULT_VARDATA_DISPLAY_SIZE;
+
+                    case SQL_BIT:
+                        return 1;
+
+                    case SQL_TINYINT:
+                        return 3;
+
+                    case SQL_SMALLINT:
+                        return 5;
+
+                    case SQL_INTEGER:
+                        return 10;
+
+                    case SQL_BIGINT:
+                        return 19;
+
+                    case SQL_REAL:
+                        return 7;
+
+                    case SQL_FLOAT:
+                    case SQL_DOUBLE:
+                        return 15;
+
+                    case SQL_TYPE_DATE:
+                        return 10;
+
+                    case SQL_TYPE_TIME:
+                        return 8;
+
+                    case SQL_TYPE_TIMESTAMP:
+                        return 19;
+
+                    case SQL_GUID:
+                        return 36;
+
+                    case SQL_DECIMAL:
+                    case SQL_NUMERIC:
+                    default:
+                        return DEFAULT_DISPLAY_SIZE;
+                }
+            }
+
+            int32_t BinaryTypeColumnSize(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeColumnSize(sqlType);
+            }
+
+            int32_t SqlTypeTransferLength(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_VARCHAR:
+                    case SQL_CHAR:
+                    case SQL_WCHAR:
+                    case SQL_BINARY:
+                        return DEFAULT_VARDATA_DISPLAY_SIZE;
+
+                    case SQL_BIT:
+                    case SQL_TINYINT:
+                        return 1;
+
+                    case SQL_SMALLINT:
+                        return 2;
+
+                    case SQL_INTEGER:
+                        return 4;
+
+                    case SQL_BIGINT:
+                        return 8;
+
+                    case SQL_REAL:
+                    case SQL_FLOAT:
+                        return 4;
+
+                    case SQL_DOUBLE:
+                        return 8;
+
+                    case SQL_TYPE_DATE:
+                    case SQL_TYPE_TIME:
+                        return 6;
+
+                    case SQL_TYPE_TIMESTAMP:
+                        return 16;
+
+                    case SQL_GUID:
+                        return 16;
+
+                    case SQL_DECIMAL:
+                    case SQL_NUMERIC:
+                    default:
+                        return DEFAULT_DISPLAY_SIZE;
+                }
+            }
+
+            int32_t BinaryTypeTransferLength(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeTransferLength(sqlType);
+            }
+
+            int32_t SqlTypeNumPrecRadix(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_REAL:
+                    case SQL_FLOAT:
+                    case SQL_DOUBLE:
+                        return 2;
+
+                    case SQL_BIT:
+                    case SQL_TINYINT:
+                    case SQL_SMALLINT:
+                    case SQL_INTEGER:
+                    case SQL_BIGINT:
+                        return 10;
+
+                    default:
+                        return 0;
+                }
+            }
+
+            int32_t BinaryTypeNumPrecRadix(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeNumPrecRadix(sqlType);
+            }
+
+            int32_t SqlTypeDecimalDigits(int16_t type)
+            {
+                // Not implemented for the NUMERIC and DECIMAL data types.
+                return -1;
+            }
+
+            int32_t BinaryTypeDecimalDigits(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeDecimalDigits(sqlType);
+            }
+
+            bool SqlTypeUnsigned(int16_t type)
+            {
+                switch (type)
+                {
+                    case SQL_BIT:
+                    case SQL_TINYINT:
+                    case SQL_SMALLINT:
+                    case SQL_INTEGER:
+                    case SQL_BIGINT:
+                    case SQL_REAL:
+                    case SQL_FLOAT:
+                    case SQL_DOUBLE:
+                        return false;
+
+                    default:
+                        return true;
+                }
+            }
+
+            bool BinaryTypeUnsigned(int8_t type)
+            {
+                int16_t sqlType = BinaryToSqlType(type);
+
+                return SqlTypeUnsigned(sqlType);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/odbc/src/utility.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/utility.cpp b/modules/platforms/cpp/odbc/src/utility.cpp
new file mode 100644
index 0000000..8cdfdb6
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/utility.cpp
@@ -0,0 +1,130 @@
+/*
+ * 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 <cassert>
+
+#include <ignite/impl/binary/binary_utils.h>
+
+#include "ignite/odbc/utility.h"
+#include "ignite/odbc/system/odbc_constants.h"
+
+#ifdef ODBC_DEBUG
+
+FILE* log_file = NULL;
+
+void logInit(const char* path)
+{
+    if (!log_file)
+    {
+        log_file = fopen(path, "w");
+    }
+}
+
+#endif //ODBC_DEBUG
+
+namespace ignite
+{
+    namespace utility
+    {
+        size_t CopyStringToBuffer(const std::string& str, char* buf, size_t buflen)
+        {
+            if (!buf || !buflen)
+                return 0;
+
+            size_t bytesToCopy = std::min(str.size(), static_cast<size_t>(buflen - 1));
+
+            memcpy(buf, str.data(), bytesToCopy);
+            buf[bytesToCopy] = 0;
+
+            return bytesToCopy;
+        }
+
+        void ReadString(ignite::impl::binary::BinaryReaderImpl& reader, std::string& str)
+        {
+            int32_t strLen = reader.ReadString(0, 0);
+            if (!strLen)
+            {
+                str.clear();
+
+                char dummy;
+
+                reader.ReadString(&dummy, sizeof(dummy));
+            }
+            else
+            {
+                str.resize(strLen);
+
+                reader.ReadString(&str[0], static_cast<int32_t>(str.size()));
+            }
+        }
+
+        void WriteString(ignite::impl::binary::BinaryWriterImpl& writer, const std::string & str)
+        {
+            writer.WriteString(str.data(), static_cast<int32_t>(str.size()));
+        }
+
+        void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, Decimal& decimal)
+        {
+            int8_t hdr = reader.ReadInt8();
+
+            assert(hdr == ignite::impl::binary::IGNITE_TYPE_DECIMAL);
+
+            int32_t scale = reader.ReadInt32();
+
+            int32_t len = reader.ReadInt32();
+
+            std::vector<int8_t> mag;
+
+            mag.resize(len);
+
+            impl::binary::BinaryUtils::ReadInt8Array(reader.GetStream(), mag.data(), static_cast<int32_t>(mag.size()));
+
+            Decimal res(scale, mag.data(), static_cast<int32_t>(mag.size()));
+
+            swap(decimal, res);
+        }
+
+        void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const Decimal& decimal)
+        {
+            writer.WriteInt8(ignite::impl::binary::IGNITE_TYPE_DECIMAL);
+
+            writer.WriteInt32(decimal.GetScale() | (decimal.IsNegative() ? 0x80000000 : 0));
+
+            writer.WriteInt32(decimal.GetLength());
+
+            impl::binary::BinaryUtils::WriteInt8Array(writer.GetStream(), decimal.GetMagnitude(), decimal.GetLength());
+        }
+
+        std::string SqlStringToString(const unsigned char* sqlStr, int32_t sqlStrLen)
+        {
+            std::string res;
+
+            const char* sqlStrC = reinterpret_cast<const char*>(sqlStr);
+
+            if (!sqlStr || !sqlStrLen)
+                return res;
+
+            if (sqlStrLen == SQL_NTS)
+                res.assign(sqlStrC);
+            else
+                res.assign(sqlStrC, sqlStrLen);
+
+            return res;
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/project/vs/ignite.sln
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/project/vs/ignite.sln b/modules/platforms/cpp/project/vs/ignite.sln
index 8b561e6..01f12f9 100644
--- a/modules/platforms/cpp/project/vs/ignite.sln
+++ b/modules/platforms/cpp/project/vs/ignite.sln
@@ -1,13 +1,30 @@
 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\common\project\vs\common.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "..\..\core\project\vs\core.vcxproj", "{E2DEA693-F2EA-43C2-A813-053378F6E4DB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960} = {4F15669B-92EB-49F0-B774-8F19BAE0B960}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core-test", "..\..\core-test\project\vs\core-test.vcxproj", "{133A22DB-FD60-44B9-B5E3-6CBB3EA5ABF0}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960} = {4F15669B-92EB-49F0-B774-8F19BAE0B960}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ignite", "..\..\ignite\project\vs\ignite.vcxproj", "{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960} = {4F15669B-92EB-49F0-B774-8F19BAE0B960}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binary", "..\..\binary\project\vs\binary.vcxproj", "{4F15669B-92EB-49F0-B774-8F19BAE0B960}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc", "..\..\odbc\project\vs\odbc.vcxproj", "{12F77E12-38FE-42D3-B1DA-7E5979362961}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc-test", "..\..\odbc-test\project\vs\odbc-test.vcxproj", "{309BEA40-495D-463F-98D5-4657F03F6D8F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\common\project\vs\common.vcxproj", "{B63F2E01-5157-4719-8491-0E1C7CD3B701}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jni", "..\..\jni\project\vs\jni.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -17,14 +34,6 @@ Global
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.ActiveCfg = Debug|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.Build.0 = Debug|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.ActiveCfg = Debug|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.Build.0 = Debug|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.ActiveCfg = Release|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.Build.0 = Release|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.ActiveCfg = Release|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.Build.0 = Release|x64
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|Win32.Build.0 = Debug|Win32
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|x64.ActiveCfg = Debug|x64
@@ -49,6 +58,46 @@ Global
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|Win32.Build.0 = Release|Win32
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|x64.ActiveCfg = Release|x64
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|x64.Build.0 = Release|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.Build.0 = Debug|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.ActiveCfg = Debug|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.Build.0 = Debug|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.ActiveCfg = Release|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.Build.0 = Release|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.ActiveCfg = Release|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.Build.0 = Release|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|Win32.ActiveCfg = Debug|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|Win32.Build.0 = Debug|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|x64.ActiveCfg = Debug|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|x64.Build.0 = Debug|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|Win32.ActiveCfg = Release|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|Win32.Build.0 = Release|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|x64.ActiveCfg = Release|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|x64.Build.0 = Release|x64
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|Win32.Build.0 = Debug|Win32
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|x64.ActiveCfg = Debug|x64
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|x64.Build.0 = Debug|x64
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|Win32.ActiveCfg = Release|Win32
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|Win32.Build.0 = Release|Win32
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|x64.ActiveCfg = Release|x64
+		{309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|x64.Build.0 = Release|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|Win32.Build.0 = Debug|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|x64.ActiveCfg = Debug|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|x64.Build.0 = Debug|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|Win32.ActiveCfg = Release|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|Win32.Build.0 = Release|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|x64.ActiveCfg = Release|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|x64.Build.0 = Release|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.Build.0 = Debug|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.ActiveCfg = Debug|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.Build.0 = Debug|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.ActiveCfg = Release|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.Build.0 = Release|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.ActiveCfg = Release|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

http://git-wip-us.apache.org/repos/asf/ignite/blob/764c97b9/modules/platforms/cpp/project/vs/ignite.slnrel
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/project/vs/ignite.slnrel b/modules/platforms/cpp/project/vs/ignite.slnrel
index 8b7ad35..1d874a8 100644
--- a/modules/platforms/cpp/project/vs/ignite.slnrel
+++ b/modules/platforms/cpp/project/vs/ignite.slnrel
@@ -1,25 +1,26 @@
 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\common\project\vs\common.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "..\..\core\project\vs\core.vcxproj", "{E2DEA693-F2EA-43C2-A813-053378F6E4DB}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ignite", "..\..\ignite\project\vs\ignite.vcxproj", "{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}"
+	ProjectSection(ProjectDependencies) = postProject
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960} = {4F15669B-92EB-49F0-B774-8F19BAE0B960}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binary", "..\..\binary\project\vs\binary.vcxproj", "{4F15669B-92EB-49F0-B774-8F19BAE0B960}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc", "..\..\odbc\project\vs\odbc.vcxproj", "{12F77E12-38FE-42D3-B1DA-7E5979362961}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\common\project\vs\common.vcxproj", "{B63F2E01-5157-4719-8491-0E1C7CD3B701}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jni", "..\..\jni\project\vs\jni.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.ActiveCfg = Debug|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.Build.0 = Debug|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.ActiveCfg = Debug|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.Build.0 = Debug|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.ActiveCfg = Release|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.Build.0 = Release|Win32
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.ActiveCfg = Release|x64
-		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.Build.0 = Release|x64
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|Win32.Build.0 = Debug|Win32
 		{E2DEA693-F2EA-43C2-A813-053378F6E4DB}.Debug|x64.ActiveCfg = Debug|x64
@@ -36,6 +37,34 @@ Global
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|Win32.Build.0 = Release|Win32
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|x64.ActiveCfg = Release|x64
 		{69688B4D-3EE0-43F5-A1C6-29B5D2DDE949}.Release|x64.Build.0 = Release|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.Build.0 = Debug|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.ActiveCfg = Debug|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.Build.0 = Debug|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.ActiveCfg = Release|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.Build.0 = Release|Win32
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.ActiveCfg = Release|x64
+		{4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.Build.0 = Release|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|Win32.ActiveCfg = Debug|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|x64.ActiveCfg = Debug|x64
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|Win32.ActiveCfg = Release|Win32
+		{12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|x64.ActiveCfg = Release|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|Win32.Build.0 = Debug|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|x64.ActiveCfg = Debug|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Debug|x64.Build.0 = Debug|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|Win32.ActiveCfg = Release|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|Win32.Build.0 = Release|Win32
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|x64.ActiveCfg = Release|x64
+		{B63F2E01-5157-4719-8491-0E1C7CD3B701}.Release|x64.Build.0 = Release|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.Build.0 = Debug|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.ActiveCfg = Debug|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.Build.0 = Debug|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.ActiveCfg = Release|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.Build.0 = Release|Win32
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.ActiveCfg = Release|x64
+		{4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE


Mime
View raw message