Repository: ignite
Updated Branches:
  refs/heads/master 1288531ed -> c10be5780


http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp 
b/modules/platforms/cpp/odbc/src/statement.cpp
index ae19ed6..697f5b4 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -16,6 +16,7 @@
  */
 
 #include "ignite/odbc/system/odbc_constants.h"
+#include "ignite/odbc/query/batch_query.h"
 #include "ignite/odbc/query/data_query.h"
 #include "ignite/odbc/query/column_metadata_query.h"
 #include "ignite/odbc/query/table_metadata_query.h"
@@ -39,9 +40,8 @@ namespace ignite
             currentQuery(),
             rowsFetched(0),
             rowStatuses(0),
-            paramBindOffset(0),
             columnBindOffset(0),
-            currentParamIdx(0)
+            parameters()
         {
             // No-op.
         }
@@ -58,19 +58,19 @@ namespace ignite
 
         SqlResult::Type Statement::InternalBindColumn(uint16_t columnIdx, 
int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* 
strLengthOrIndicator)
         {
-            using namespace odbc::type_traits;
+            using namespace type_traits;
             OdbcNativeType::Type driverType = ToDriverType(targetType);
 
             if (driverType == OdbcNativeType::AI_UNSUPPORTED)
             {
-                
AddStatusRecord(odbc::SqlState::SHY003_INVALID_APPLICATION_BUFFER_TYPE, "The 
argument TargetType was not a valid data type.");
+                
AddStatusRecord(SqlState::SHY003_INVALID_APPLICATION_BUFFER_TYPE, "The argument 
TargetType was not a valid data type.");
 
                 return SqlResult::AI_ERROR;
             }
 
             if (bufferLength < 0)
             {
-                
AddStatusRecord(odbc::SqlState::SHY090_INVALID_STRING_OR_BUFFER_LENGTH,
+                
AddStatusRecord(SqlState::SHY090_INVALID_STRING_OR_BUFFER_LENGTH,
                     "The value specified for the argument BufferLength was 
less than 0.");
 
                 return SqlResult::AI_ERROR;
@@ -91,8 +91,6 @@ namespace ignite
         void Statement::SafeBindColumn(uint16_t columnIdx, const 
app::ApplicationDataBuffer& buffer)
         {
             columnBindings[columnIdx] = buffer;
-
-            columnBindings[columnIdx].SetPtrToOffsetPtr(&columnBindOffset);
         }
 
         void Statement::SafeUnbindColumn(uint16_t columnIdx)
@@ -149,32 +147,36 @@ namespace ignite
         SqlResult::Type Statement::InternalBindParameter(uint16_t paramIdx, 
int16_t ioType, int16_t bufferType, int16_t paramSqlType,
                                                    SqlUlen columnSize, int16_t 
decDigits, void* buffer, SqlLen bufferLen, SqlLen* resLen)
         {
-            using namespace odbc::type_traits;
-            using odbc::Statement;
-            using odbc::app::ApplicationDataBuffer;
-            using odbc::app::Parameter;
-            using odbc::type_traits::IsSqlTypeSupported;
+            using namespace type_traits;
+            using app::ApplicationDataBuffer;
+            using app::Parameter;
 
             if (paramIdx == 0)
             {
-                AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
-                    "The value specified for the argument ParameterNumber was 
less than 1.");
+                std::stringstream builder;
+                builder << "The value specified for the argument 
ParameterNumber was less than 1. [ParameterNumber=" << paramIdx << ']';
+
+                AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE, 
builder.str());
 
                 return SqlResult::AI_ERROR;
             }
 
             if (ioType != SQL_PARAM_INPUT)
             {
-                AddStatusRecord(SqlState::SHY105_INVALID_PARAMETER_TYPE,
-                    "The value specified for the argument InputOutputType was 
not SQL_PARAM_INPUT.");
+                std::stringstream builder;
+                builder << "The value specified for the argument 
InputOutputType was not SQL_PARAM_INPUT. [ioType=" << ioType << ']';
+
+                AddStatusRecord(SqlState::SHY105_INVALID_PARAMETER_TYPE, 
builder.str());
 
                 return SqlResult::AI_ERROR;
             }
 
             if (!IsSqlTypeSupported(paramSqlType))
             {
-                
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
-                    "Data type is not supported.");
+                std::stringstream builder;
+                builder << "Data type is not supported. [typeId=" << 
paramSqlType << ']';
+
+                
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, 
builder.str());
 
                 return SqlResult::AI_ERROR;
             }
@@ -183,8 +185,10 @@ namespace ignite
 
             if (driverType == OdbcNativeType::AI_UNSUPPORTED)
             {
-                
AddStatusRecord(odbc::SqlState::SHY003_INVALID_APPLICATION_BUFFER_TYPE,
-                    "The argument TargetType was not a valid data type.");
+                std::stringstream builder;
+                builder << "The argument TargetType was not a valid data type. 
[TargetType=" << bufferType << ']';
+
+                
AddStatusRecord(SqlState::SHY003_INVALID_APPLICATION_BUFFER_TYPE, 
builder.str());
 
                 return SqlResult::AI_ERROR;
             }
@@ -195,31 +199,14 @@ namespace ignite
 
                 Parameter param(dataBuffer, paramSqlType, columnSize, 
decDigits);
 
-                SafeBindParameter(paramIdx, param);
+                parameters.BindParameter(paramIdx, param);
             }
             else
-                SafeUnbindParameter(paramIdx);
+                parameters.UnbindParameter(paramIdx);
 
             return SqlResult::AI_SUCCESS;
         }
 
-        void Statement::SafeBindParameter(uint16_t paramIdx, const 
app::Parameter& param)
-        {
-            paramBindings[paramIdx] = param;
-
-            
paramBindings[paramIdx].GetBuffer().SetPtrToOffsetPtr(&paramBindOffset);
-        }
-
-        void Statement::SafeUnbindParameter(uint16_t paramIdx)
-        {
-            paramBindings.erase(paramIdx);
-        }
-
-        void Statement::SafeUnbindAllParameters()
-        {
-            paramBindings.clear();
-        }
-
         void Statement::SetAttribute(int attr, void* value, SQLINTEGER 
valueLen)
         {
             IGNITE_ODBC_API_CALL(InternalSetAttribute(attr, value, valueLen));
@@ -231,7 +218,7 @@ namespace ignite
             {
                 case SQL_ATTR_ROW_ARRAY_SIZE:
                 {
-                    SQLULEN val = reinterpret_cast<SQLULEN>(value);
+                    SqlUlen val = reinterpret_cast<SqlUlen>(value);
 
                     LOG_MSG("SQL_ATTR_ROW_ARRAY_SIZE: " << val);
 
@@ -274,6 +261,20 @@ namespace ignite
                     break;
                 }
 
+                case SQL_ATTR_PARAMSET_SIZE:
+                {
+                    
parameters.SetParamSetSize(reinterpret_cast<SqlUlen>(value));
+
+                    break;
+                }
+
+                case SQL_ATTR_PARAMS_PROCESSED_PTR:
+                {
+                    
parameters.SetParamsProcessedPtr(reinterpret_cast<SqlUlen*>(value));
+
+                    break;
+                }
+
                 default:
                 {
                     
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
@@ -311,6 +312,9 @@ namespace ignite
 
                     *val = static_cast<SQLPOINTER>(this);
 
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
+
                     break;
                 }
 
@@ -320,14 +324,20 @@ namespace ignite
 
                     *val = static_cast<SQLINTEGER>(1);
 
+                    if (valueLen)
+                        *valueLen = SQL_IS_INTEGER;
+
                     break;
                 }
 
                 case SQL_ATTR_ROWS_FETCHED_PTR:
                 {
-                    SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
+                    SqlUlen** val = reinterpret_cast<SqlUlen**>(buf);
+
+                    *val = reinterpret_cast<SqlUlen*>(GetRowsFetchedPtr());
 
-                    *val = reinterpret_cast<SQLULEN*>(GetRowsFetchedPtr());
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
 
                     break;
                 }
@@ -338,6 +348,9 @@ namespace ignite
 
                     *val = 
reinterpret_cast<SQLUSMALLINT*>(GetRowStatusesPtr());
 
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
+
                     break;
                 }
 
@@ -345,16 +358,46 @@ namespace ignite
                 {
                     SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
 
-                    *val = reinterpret_cast<SQLULEN*>(GetParamBindOffsetPtr());
+                    *val = 
reinterpret_cast<SQLULEN*>(parameters.GetParamBindOffsetPtr());
+
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
 
                     break;
                 }
 
                 case SQL_ATTR_ROW_BIND_OFFSET_PTR:
                 {
-                    SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
+                    SqlUlen** val = reinterpret_cast<SqlUlen**>(buf);
+
+                    *val = 
reinterpret_cast<SqlUlen*>(GetColumnBindOffsetPtr());
+
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
+
+                    break;
+                }
+
+                case SQL_ATTR_PARAMSET_SIZE:
+                {
+                    SqlUlen* val = reinterpret_cast<SqlUlen*>(buf);
 
-                    *val = 
reinterpret_cast<SQLULEN*>(GetColumnBindOffsetPtr());
+                    *val = static_cast<SqlUlen>(parameters.GetParamSetSize());
+
+                    if (valueLen)
+                        *valueLen = SQL_IS_UINTEGER;
+
+                    break;
+                }
+
+                case SQL_ATTR_PARAMS_PROCESSED_PTR:
+                {
+                    SqlUlen** val = reinterpret_cast<SqlUlen**>(buf);
+
+                    *val = parameters.GetParamsProcessedPtr();
+
+                    if (valueLen)
+                        *valueLen = SQL_IS_POINTER;
 
                     break;
                 }
@@ -392,7 +435,7 @@ namespace ignite
                 return SqlResult::AI_SUCCESS;
             }
 
-            if (paramTypes.empty())
+            if (!parameters.IsMetadataSet())
             {
                 SqlResult::Type res = UpdateParamsMeta();
 
@@ -400,7 +443,7 @@ namespace ignite
                     return res;
             }
 
-            paramNum = static_cast<uint16_t>(paramTypes.size());
+            paramNum = parameters.GetExpectedParamNum();
 
             return SqlResult::AI_SUCCESS;
         }
@@ -409,12 +452,7 @@ namespace ignite
         {
             IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;
 
-            paramBindOffset = ptr;
-        }
-
-        int* Statement::GetParamBindOffsetPtr()
-        {
-            return paramBindOffset;
+            parameters.SetParamBindOffsetPtr(ptr);
         }
 
         void Statement::GetColumnData(uint16_t columnIdx, 
app::ApplicationDataBuffer& buffer)
@@ -448,10 +486,10 @@ namespace ignite
             if (currentQuery.get())
                 currentQuery->Close();
 
-            currentQuery.reset(new query::DataQuery(*this, connection, query, 
paramBindings));
-
             // Resetting parameters types as we are changing the query.
-            paramTypes.clear();
+            parameters.Prepare();
+
+            currentQuery.reset(new query::DataQuery(*this, connection, query, 
parameters));
 
             return SqlResult::AI_SUCCESS;
         }
@@ -485,20 +523,31 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            bool paramDataReady = true;
-
-            app::ParameterBindingMap::iterator it;
-            for (it = paramBindings.begin(); it != paramBindings.end(); ++it)
+            if (parameters.GetParamSetSize() > 1 && currentQuery->GetType() == 
query::QueryType::DATA)
             {
-                app::Parameter& param = it->second;
+                query::DataQuery& qry = 
static_cast<query::DataQuery&>(*currentQuery);
 
-                param.ResetStoredData();
+                currentQuery.reset(new query::BatchQuery(*this, connection, 
qry.GetSql(), parameters));
+            }
+            else if (parameters.GetParamSetSize() == 1 && 
currentQuery->GetType() == query::QueryType::BATCH)
+            {
+                query::BatchQuery& qry = 
static_cast<query::BatchQuery&>(*currentQuery);
 
-                paramDataReady &= param.IsDataReady();
+                currentQuery.reset(new query::DataQuery(*this, connection, 
qry.GetSql(), parameters));
             }
 
-            if (!paramDataReady)
+            if (parameters.IsDataAtExecNeeded())
+            {
+                if (currentQuery->GetType() == query::QueryType::BATCH)
+                {
+                    
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+                        "Data-at-execution is not supported together with 
batching.");
+
+                    return SqlResult::AI_ERROR;
+                }
+
                 return SqlResult::AI_NEED_DATA;
+            }
 
             return currentQuery->Execute();
         }
@@ -624,8 +673,10 @@ namespace ignite
         {
             if (!type_traits::IsSqlTypeSupported(sqlType))
             {
-                
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
-                    "Data type is not supported.");
+                std::stringstream builder;
+                builder << "Data type is not supported. [typeId=" << sqlType 
<< ']';
+
+                
AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED, 
builder.str());
 
                 return SqlResult::AI_ERROR;
             }
@@ -668,7 +719,7 @@ namespace ignite
 
                 case SQL_RESET_PARAMS:
                 {
-                    SafeUnbindAllParameters();
+                    parameters.UnbindAll();
 
                     break;
                 }
@@ -736,6 +787,12 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
+            if (columnBindOffset)
+            {
+                for (app::ColumnBindingMap::iterator it = 
columnBindings.begin(); it != columnBindings.end(); ++it)
+                    it->second.SetByteOffset(*columnBindOffset);
+            }
+            
             SqlResult::Type res = currentQuery->FetchNextRow(columnBindings);
 
             if (res == SqlResult::AI_SUCCESS)
@@ -904,35 +961,24 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            app::ParameterBindingMap::iterator it;
+            app::Parameter *selected = parameters.GetSelectedParameter();
 
-            if (currentParamIdx)
+            if (selected && !selected->IsDataReady())
             {
-                it = paramBindings.find(currentParamIdx);
+                AddStatusRecord(SqlState::S22026_DATA_LENGTH_MISMATCH,
+                    "Less data was sent for a parameter than was specified 
with "
+                    "the StrLen_or_IndPtr argument in SQLBindParameter.");
 
-                if (it != paramBindings.end() && !it->second.IsDataReady())
-                {
-                    AddStatusRecord(SqlState::S22026_DATA_LENGTH_MISMATCH,
-                        "Less data was sent for a parameter than was specified 
with "
-                        "the StrLen_or_IndPtr argument in SQLBindParameter.");
-
-                    return SqlResult::AI_ERROR;
-                }
+                return SqlResult::AI_ERROR;
             }
 
-            for (it = paramBindings.begin(); it != paramBindings.end(); ++it)
-            {
-                uint16_t paramIdx = it->first;
-                app::Parameter& param = it->second;
-
-                if (!param.IsDataReady())
-                {
-                    *paramPtr = param.GetBuffer().GetData();
+            selected = parameters.SelectNextParameter();
 
-                    currentParamIdx = paramIdx;
+            if (selected)
+            {
+                *paramPtr = selected->GetBuffer().GetData();
 
-                    return SqlResult::AI_NEED_DATA;
-                }
+                return SqlResult::AI_NEED_DATA;
             }
 
             SqlResult::Type res = currentQuery->Execute();
@@ -959,7 +1005,7 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            if (currentParamIdx == 0)
+            if (!parameters.IsParameterSelected())
             {
                 AddStatusRecord(SqlState::SHY010_SEQUENCE_ERROR,
                     "Parameter is not selected with the SQLParamData.");
@@ -967,9 +1013,9 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            app::ParameterBindingMap::iterator it = 
paramBindings.find(currentParamIdx);
+            app::Parameter* param = parameters.GetSelectedParameter();
 
-            if (it == paramBindings.end())
+            if (!param)
             {
                 AddStatusRecord(SqlState::SHY000_GENERAL_ERROR,
                     "Selected parameter has been unbound.");
@@ -977,9 +1023,7 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            app::Parameter& param = it->second;
-
-            param.PutData(data, len);
+            param->PutData(data, len);
 
             return SqlResult::AI_SUCCESS;
         }
@@ -1009,10 +1053,7 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            int8_t type = 0;
-
-            if (paramNum > 0 && static_cast<size_t>(paramNum) <= 
paramTypes.size())
-                type = paramTypes[paramNum - 1];
+            int8_t type = parameters.GetParamType(paramNum, 0);
 
             LOG_MSG("Type: " << type);
 
@@ -1023,10 +1064,7 @@ namespace ignite
                 if (res != SqlResult::AI_SUCCESS)
                     return res;
 
-                if (paramNum < 1 || static_cast<size_t>(paramNum) > 
paramTypes.size())
-                    type = impl::binary::IGNITE_HDR_NULL;
-                else
-                    type = paramTypes[paramNum - 1];
+                type = parameters.GetParamType(paramNum, 
impl::binary::IGNITE_HDR_NULL);
             }
 
             if (dataType)
@@ -1079,11 +1117,11 @@ namespace ignite
                 return SqlResult::AI_ERROR;
             }
 
-            paramTypes = rsp.GetTypeIds();
+            parameters.UpdateParamsTypes(rsp.GetTypeIds());
 
-            for (size_t i = 0; i < paramTypes.size(); ++i)
+            for (size_t i = 0; i < rsp.GetTypeIds().size(); ++i)
             {
-                LOG_MSG("[" << i << "] Parameter type: " << paramTypes[i]);
+                LOG_MSG("[" << i << "] Parameter type: " << 
rsp.GetTypeIds()[i]);
             }
 
             return SqlResult::AI_SUCCESS;

Reply via email to