http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/message.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h index 85d5b36..1a1cac2 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h @@ -24,11 +24,11 @@ #include "ignite/impl/binary/binary_writer_impl.h" #include "ignite/impl/binary/binary_reader_impl.h" -#include "ignite/odbc/utility.h" #include "ignite/odbc/result_page.h" +#include "ignite/odbc/protocol_version.h" #include "ignite/odbc/meta/column_meta.h" #include "ignite/odbc/meta/table_meta.h" -#include "ignite/odbc/app/parameter.h" +#include "ignite/odbc/app/parameter_set.h" namespace ignite { @@ -58,7 +58,9 @@ namespace ignite GET_TABLES_METADATA = 6, - GET_PARAMS_METADATA = 7 + GET_PARAMS_METADATA = 7, + + EXECUTE_SQL_QUERY_BATCH = 8 }; }; @@ -85,39 +87,18 @@ namespace ignite * @param distributedJoins Distributed joins flag. * @param enforceJoinOrder Enforce join order flag. */ - HandshakeRequest(const ProtocolVersion& version, bool distributedJoins, bool enforceJoinOrder) : - version(version), - distributedJoins(distributedJoins), - enforceJoinOrder(enforceJoinOrder) - { - // No-op. - } + HandshakeRequest(const ProtocolVersion& version, bool distributedJoins, bool enforceJoinOrder); /** * Destructor. */ - ~HandshakeRequest() - { - // No-op. - } + ~HandshakeRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::HANDSHAKE); - - writer.WriteInt16(version.GetMajor()); - writer.WriteInt16(version.GetMinor()); - writer.WriteInt16(version.GetMaintenance()); - - writer.WriteInt8(ClientType::ODBC); - - writer.WriteBool(distributedJoins); - writer.WriteBool(enforceJoinOrder); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Protocol version. */ @@ -143,51 +124,58 @@ namespace ignite * @param sql SQL query. * @param params Query arguments. */ - QueryExecuteRequest(const std::string& schema, const std::string& sql, - const app::ParameterBindingMap& params) : - schema(schema), - sql(sql), - params(params) - { - // No-op. - } + QueryExecuteRequest(const std::string& schema, const std::string& sql, const app::ParameterSet& params); /** * Destructor. */ - ~QueryExecuteRequest() - { - // No-op. - } + ~QueryExecuteRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::EXECUTE_SQL_QUERY); - utility::WriteString(writer, schema); - utility::WriteString(writer, sql); + void Write(impl::binary::BinaryWriterImpl& writer) const; - writer.WriteInt32(static_cast<int32_t>(params.size())); + private: + /** Schema name. */ + std::string schema; - app::ParameterBindingMap::const_iterator i; - uint16_t prev = 0; + /** SQL query. */ + std::string sql; - for (i = params.begin(); i != params.end(); ++i) { - uint16_t current = i->first; + /** Parameters bindings. */ + const app::ParameterSet& params; + }; - while ((current - prev) > 1) { - writer.WriteNull(); - ++prev; - } + /** + * Query execute batch request. + */ + class QueryExecuteBatchtRequest + { + public: + /** + * Constructor. + * + * @param schema Schema. + * @param sql SQL query. + * @param params Query arguments. + * @param begin Beginng of the interval. + * @param end End of the interval. + */ + QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql, + const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last); - i->second.Write(writer); + /** + * Destructor. + */ + ~QueryExecuteBatchtRequest(); - prev = current; - } - } + /** + * Write request using provided writer. + * @param writer Writer. + */ + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Schema name. */ @@ -197,9 +185,17 @@ namespace ignite std::string sql; /** Parameters bindings. */ - const app::ParameterBindingMap& params; - }; + const app::ParameterSet& params; + + /** Beginng of the interval. */ + SqlUlen begin; + /** End of the interval. */ + SqlUlen end; + + /** Last page flag. */ + bool last; + }; /** * Query close request. @@ -212,28 +208,18 @@ namespace ignite * * @param queryId Query ID. */ - QueryCloseRequest(int64_t queryId) : queryId(queryId) - { - // No-op. - } + QueryCloseRequest(int64_t queryId); /** * Destructor. */ - ~QueryCloseRequest() - { - // No-op. - } + ~QueryCloseRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(ignite::impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::CLOSE_SQL_QUERY); - writer.WriteInt64(queryId); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Query ID. */ @@ -252,31 +238,18 @@ namespace ignite * @param queryId Query ID. * @param pageSize Required page size. */ - QueryFetchRequest(int64_t queryId, int32_t pageSize) : - queryId(queryId), - pageSize(pageSize) - { - // No-op. - } + QueryFetchRequest(int64_t queryId, int32_t pageSize); /** * Destructor. */ - ~QueryFetchRequest() - { - // No-op. - } + ~QueryFetchRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(ignite::impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::FETCH_SQL_QUERY); - writer.WriteInt64(queryId); - writer.WriteInt32(pageSize); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Query ID. */ @@ -299,34 +272,18 @@ namespace ignite * @param table Table name. * @param column Column name. */ - QueryGetColumnsMetaRequest(const std::string& schema, const std::string& table, const std::string& column) : - schema(schema), - table(table), - column(column) - { - // No-op. - } + QueryGetColumnsMetaRequest(const std::string& schema, const std::string& table, const std::string& column); /** * Destructor. */ - ~QueryGetColumnsMetaRequest() - { - // No-op. - } + ~QueryGetColumnsMetaRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(ignite::impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::GET_COLUMNS_METADATA); - - utility::WriteString(writer, schema); - utility::WriteString(writer, table); - utility::WriteString(writer, column); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Schema search pattern. */ @@ -354,36 +311,18 @@ namespace ignite * @param tableTypes Table types search pattern. */ QueryGetTablesMetaRequest(const std::string& catalog, const std::string& schema, - const std::string& table, const std::string& tableTypes) : - catalog(catalog), - schema(schema), - table(table), - tableTypes(tableTypes) - { - // No-op. - } + const std::string& table, const std::string& tableTypes); /** * Destructor. */ - ~QueryGetTablesMetaRequest() - { - // No-op. - } + ~QueryGetTablesMetaRequest(); /** * Write request using provided writer. * @param writer Writer. */ - void Write(ignite::impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::GET_TABLES_METADATA); - - utility::WriteString(writer, catalog); - utility::WriteString(writer, schema); - utility::WriteString(writer, table); - utility::WriteString(writer, tableTypes); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Column search pattern. */ @@ -430,13 +369,7 @@ namespace ignite * Write request using provided writer. * @param writer Writer. */ - void Write(impl::binary::BinaryWriterImpl& writer) const - { - writer.WriteInt8(RequestType::GET_PARAMS_METADATA); - - utility::WriteString(writer, schema); - utility::WriteString(writer, sqlQuery); - } + void Write(impl::binary::BinaryWriterImpl& writer) const; private: /** Schema. */ @@ -455,33 +388,19 @@ namespace ignite /** * Constructor. */ - Response() : status(ResponseStatus::FAILED), error() - { - // No-op. - } + Response(); /** * Destructor. */ - virtual ~Response() - { - // No-op. - } + virtual ~Response(); /** * Read response using provided reader. * @param reader Reader. */ - void Read(ignite::impl::binary::BinaryReaderImpl& reader) - { - status = reader.ReadInt8(); + void Read(impl::binary::BinaryReaderImpl& reader); - if (status == ResponseStatus::SUCCESS) - ReadOnSuccess(reader); - else - utility::ReadString(reader, error);; - } - /** * Get request processing status. * @return Status. @@ -504,10 +423,7 @@ namespace ignite /** * Read data if response status is ResponseStatus::SUCCESS. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl&) - { - // No-op. - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl&); private: /** Request processing status. */ @@ -526,21 +442,12 @@ namespace ignite /** * Constructor. */ - HandshakeResponse() : - accepted(false), - currentVer(), - error() - { - // No-op. - } + HandshakeResponse(); /** * Destructor. */ - ~HandshakeResponse() - { - // No-op. - } + ~HandshakeResponse(); /** * Check if the handshake has been accepted. @@ -573,21 +480,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - void Read(ignite::impl::binary::BinaryReaderImpl& reader) - { - accepted = reader.ReadBool(); - - if (!accepted) - { - int16_t major = reader.ReadInt16(); - int16_t minor = reader.ReadInt16(); - int16_t maintenance = reader.ReadInt16(); - - currentVer = ProtocolVersion(major, minor, maintenance); - - utility::ReadString(reader, error); - } - } + void Read(impl::binary::BinaryReaderImpl& reader); private: /** Handshake accepted. */ @@ -609,18 +502,12 @@ namespace ignite /** * Constructor. */ - QueryCloseResponse() : queryId(0) - { - // No-op. - } + QueryCloseResponse(); /** * Destructor. */ - ~QueryCloseResponse() - { - // No-op. - } + virtual ~QueryCloseResponse(); /** * Get query ID. @@ -636,10 +523,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - queryId = reader.ReadInt64(); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Query ID. */ int64_t queryId; @@ -654,18 +538,12 @@ namespace ignite /** * Constructor. */ - QueryExecuteResponse() : queryId(0), meta() - { - // No-op. - } + QueryExecuteResponse(); /** * Destructor. */ - ~QueryExecuteResponse() - { - // No-op. - } + virtual ~QueryExecuteResponse(); /** * Get query ID. @@ -690,12 +568,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - queryId = reader.ReadInt64(); - - meta::ReadColumnMetaVector(reader, meta); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Query ID. */ int64_t queryId; @@ -705,28 +578,82 @@ namespace ignite }; /** - * Query fetch response. + * Query execute batch start response. */ - class QueryFetchResponse : public Response + class QueryExecuteBatchResponse : public Response { public: /** * Constructor. - * @param resultPage Result page. */ - QueryFetchResponse(ResultPage& resultPage) : queryId(0), resultPage(resultPage) + QueryExecuteBatchResponse(); + + /** + * Destructor. + */ + virtual ~QueryExecuteBatchResponse(); + + /** + * Affected rows. + * @return Affected rows. + */ + int64_t GetAffectedRows() const { - // No-op. + return affectedRows; } /** - * Destructor. + * Get index of the set which caused an error. + * @return Index of the set which caused an error. */ - ~QueryFetchResponse() + int64_t GetErrorSetIdx() const { - // No-op. + return affectedRows; + } + + /** + * Get error message. + * @return Error message. + */ + const std::string& GetErrorMessage() const + { + return errorMessage; } + private: + /** + * Read response using provided reader. + * @param reader Reader. + */ + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); + + /** Affected rows. */ + int64_t affectedRows; + + /** Index of the set which caused an error. */ + int64_t errorSetIdx; + + /** Error message. */ + std::string errorMessage; + }; + + /** + * Query fetch response. + */ + class QueryFetchResponse : public Response + { + public: + /** + * Constructor. + * @param resultPage Result page. + */ + QueryFetchResponse(ResultPage& resultPage); + + /** + * Destructor. + */ + virtual ~QueryFetchResponse(); + /** * Get query ID. * @return Query ID. @@ -741,12 +668,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - queryId = reader.ReadInt64(); - - resultPage.Read(reader); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Query ID. */ int64_t queryId; @@ -764,18 +686,12 @@ namespace ignite /** * Constructor. */ - QueryGetColumnsMetaResponse() - { - // No-op. - } + QueryGetColumnsMetaResponse(); /** * Destructor. */ - ~QueryGetColumnsMetaResponse() - { - // No-op. - } + virtual ~QueryGetColumnsMetaResponse(); /** * Get column metadata. @@ -791,10 +707,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - meta::ReadColumnMetaVector(reader, meta); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Columns metadata. */ meta::ColumnMetaVector meta; @@ -809,18 +722,12 @@ namespace ignite /** * Constructor. */ - QueryGetTablesMetaResponse() - { - // No-op. - } + QueryGetTablesMetaResponse(); /** * Destructor. */ - ~QueryGetTablesMetaResponse() - { - // No-op. - } + virtual ~QueryGetTablesMetaResponse(); /** * Get column metadata. @@ -836,10 +743,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - meta::ReadTableMetaVector(reader, meta); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Columns metadata. */ meta::TableMetaVector meta; @@ -854,18 +758,12 @@ namespace ignite /** * Constructor. */ - QueryGetParamsMetaResponse() - { - // No-op. - } + QueryGetParamsMetaResponse(); /** * Destructor. */ - ~QueryGetParamsMetaResponse() - { - // No-op. - } + virtual ~QueryGetParamsMetaResponse(); /** * Get parameter type IDs. @@ -881,10 +779,7 @@ namespace ignite * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(ignite::impl::binary::BinaryReaderImpl& reader) - { - utility::ReadByteArray(reader, typeIds); - } + virtual void ReadOnSuccess(impl::binary::BinaryReaderImpl& reader); /** Columns metadata. */ std::vector<int8_t> typeIds;
http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/query/batch_query.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/batch_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/batch_query.h new file mode 100644 index 0000000..5e741ed --- /dev/null +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/batch_query.h @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#ifndef _IGNITE_ODBC_QUERY_BATCH_QUERY +#define _IGNITE_ODBC_QUERY_BATCH_QUERY + +#include "ignite/odbc/query/query.h" +#include "ignite/odbc/app/parameter_set.h" +#include "ignite/odbc/cursor.h" + +namespace ignite +{ + namespace odbc + { + /** Connection forward-declaration. */ + class Connection; + + namespace query + { + /** + * Query. + */ + class BatchQuery : public Query + { + public: + /** + * Constructor. + * + * @param diag Diagnostics collector. + * @param connection Associated connection. + * @param sql SQL query string. + * @param params SQL params. + */ + BatchQuery(diagnostic::Diagnosable& diag, Connection& connection, + const std::string& sql, const app::ParameterSet& params); + + /** + * Destructor. + */ + virtual ~BatchQuery(); + + /** + * Execute query. + * + * @return True on success. + */ + virtual SqlResult::Type Execute(); + + /** + * Get column metadata. + * + * @return Column metadata. + */ + virtual const meta::ColumnMetaVector& GetMeta() const; + + /** + * Fetch next result row to application buffers. + * + * @param columnBindings Application buffers to put data to. + * @return Operation result. + */ + virtual SqlResult::Type FetchNextRow(app::ColumnBindingMap& columnBindings); + + /** + * Get data of the specified column in the result set. + * + * @param columnIdx Column index. + * @param buffer Buffer to put column data to. + * @return Operation result. + */ + virtual SqlResult::Type GetColumn(uint16_t columnIdx, app::ApplicationDataBuffer& buffer); + + /** + * Close query. + * + * @return Result. + */ + virtual SqlResult::Type Close(); + + /** + * Check if data is available. + * + * @return True if data is available. + */ + virtual bool DataAvailable() const; + + /** + * Get number of rows affected by the statement. + * + * @return Number of rows affected by the statement. + */ + virtual int64_t AffectedRows() const; + + /** + * Get SQL query string. + * + * @return SQL query string. + */ + const std::string& GetSql() const + { + return sql; + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(BatchQuery); + + /** + * Make query execute request and use response to set internal + * state. + * + * @param begin Paramset interval beginning. + * @param end Paramset interval end. + * @param last Last page flag. + * @return Result. + */ + SqlResult::Type MakeRequestExecuteBatch(SqlUlen begin, SqlUlen end, bool last); + + /** Connection associated with the statement. */ + Connection& connection; + + /** SQL Query. */ + std::string sql; + + /** Parameter bindings. */ + const app::ParameterSet& params; + + /** Columns metadata. */ + meta::ColumnMetaVector resultMeta; + + /** Number of rows affected. */ + int64_t rowsAffected; + + /** Number of parameter sets successfully processed. */ + int64_t setsProcessed; + + /** Query executed. */ + bool executed; + + /** Data retrieved. */ + bool dataRetrieved; + }; + } + } +} + +#endif //_IGNITE_ODBC_QUERY_BATCH_QUERY http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h index ade8fb0..b2edbdd 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/data_query.h @@ -19,7 +19,7 @@ #define _IGNITE_ODBC_QUERY_DATA_QUERY #include "ignite/odbc/query/query.h" -#include "ignite/odbc/app/parameter.h" +#include "ignite/odbc/app/parameter_set.h" #include "ignite/odbc/cursor.h" namespace ignite @@ -46,7 +46,7 @@ namespace ignite * @param params SQL params. */ DataQuery(diagnostic::Diagnosable& diag, Connection& connection, - const std::string& sql, const app::ParameterBindingMap& params); + const std::string& sql, const app::ParameterSet& params); /** * Destructor. @@ -122,21 +122,21 @@ namespace ignite * Make query execute request and use response to set internal * state. * - * @return True on success. + * @return Result. */ SqlResult::Type MakeRequestExecute(); /** * Make query close request. * - * @return True on success. + * @return Result. */ SqlResult::Type MakeRequestClose(); /** * Make data fetch request and use response to set internal state. * - * @return True on success. + * @return Result. */ SqlResult::Type MakeRequestFetch(); @@ -154,7 +154,7 @@ namespace ignite std::string sql; /** Parameter bindings. */ - const app::ParameterBindingMap& params; + const app::ParameterSet& params; /** Columns metadata. */ meta::ColumnMetaVector resultMeta; http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h index 4959eaf..701f5c8 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/query.h @@ -44,6 +44,9 @@ namespace ignite /** Data query type. */ DATA, + /** Batch query type. */ + BATCH, + /** Foreign keys query type. */ FOREIGN_KEYS, http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h index 22b291a..a7cee92 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h @@ -95,7 +95,7 @@ namespace ignite * @return Number of rows affected by the statement. */ virtual int64_t AffectedRows() const; - + private: IGNITE_NO_COPY_ASSIGNMENT(TypeInfoQuery); http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h index 703b4c6..27e883d 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h @@ -23,19 +23,12 @@ #include <map> #include <memory> -#include <ignite/impl/interop/interop_output_stream.h> -#include <ignite/impl/interop/interop_input_stream.h> -#include <ignite/impl/binary/binary_writer_impl.h> - #include "ignite/odbc/meta/column_meta.h" -#include "ignite/odbc/meta/table_meta.h" #include "ignite/odbc/query/query.h" #include "ignite/odbc/app/application_data_buffer.h" -#include "ignite/odbc/app/parameter.h" +#include "ignite/odbc/app/parameter_set.h" #include "ignite/odbc/diagnostic/diagnosable_adapter.h" #include "ignite/odbc/common_types.h" -#include "ignite/odbc/cursor.h" -#include "ignite/odbc/utility.h" namespace ignite { @@ -138,13 +131,6 @@ namespace ignite void SetParamBindOffsetPtr(int* ptr); /** - * Get parameter binding offset pointer. - * - * @return Parameter binding offset pointer. - */ - int* GetParamBindOffsetPtr(); - - /** * Get value of the column in the result set. * * @param columnIdx Column index. @@ -394,27 +380,7 @@ namespace ignite * @return Operation result. */ SqlResult::Type InternalBindColumn(uint16_t columnIdx, int16_t targetType, void* targetValue, SqlLen bufferLength, SqlLen* strLengthOrIndicator); - - /** - * Bind parameter. - * - * @param paramIdx Parameter index. - * @param param Parameter. - */ - void SafeBindParameter(uint16_t paramIdx, const app::Parameter& param); - - /** - * Unbind specified parameter. - * - * @param paramIdx Parameter index. - */ - void SafeUnbindParameter(uint16_t paramIdx); - - /** - * Unbind all parameters. - */ - void SafeUnbindAllParameters(); - + /** * Bind parameter. * @@ -688,12 +654,6 @@ namespace ignite /** Column bindings. */ app::ColumnBindingMap columnBindings; - /** Parameter bindings. */ - app::ParameterBindingMap paramBindings; - - /** Parameter meta. */ - std::vector<int8_t> paramTypes; - /** Underlying query. */ std::auto_ptr<query::Query> currentQuery; @@ -703,14 +663,10 @@ namespace ignite /** Array to store statuses of rows fetched by the last fetch. */ uint16_t* rowStatuses; - /** Offset added to pointers to change binding of parameters. */ - int* paramBindOffset; - /** Offset added to pointers to change binding of column data. */ int* columnBindOffset; - /** Index of the parameter, which is currently being set. */ - uint16_t currentParamIdx; + app::ParameterSet parameters; }; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj index b00e432..e47f618 100644 --- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj @@ -160,6 +160,7 @@ <ClCompile Include="..\..\os\win\src\system\ui\window.cpp" /> <ClCompile Include="..\..\src\app\application_data_buffer.cpp" /> <ClCompile Include="..\..\src\app\parameter.cpp" /> + <ClCompile Include="..\..\src\app\parameter_set.cpp" /> <ClCompile Include="..\..\src\column.cpp" /> <ClCompile Include="..\..\src\common_types.cpp" /> <ClCompile Include="..\..\src\config\configuration.cpp" /> @@ -172,10 +173,12 @@ <ClCompile Include="..\..\src\dsn_config.cpp" /> <ClCompile Include="..\..\src\entry_points.cpp" /> <ClCompile Include="..\..\src\environment.cpp" /> + <ClCompile Include="..\..\src\message.cpp" /> <ClCompile Include="..\..\src\meta\column_meta.cpp" /> <ClCompile Include="..\..\src\meta\table_meta.cpp" /> <ClCompile Include="..\..\src\odbc.cpp" /> <ClCompile Include="..\..\src\protocol_version.cpp" /> + <ClCompile Include="..\..\src\query\batch_query.cpp" /> <ClCompile Include="..\..\src\query\data_query.cpp" /> <ClCompile Include="..\..\src\query\column_metadata_query.cpp" /> <ClCompile Include="..\..\src\query\foreign_keys_query.cpp" /> @@ -197,6 +200,7 @@ <ClInclude Include="..\..\include\ignite\odbc.h" /> <ClInclude Include="..\..\include\ignite\odbc\app\application_data_buffer.h" /> <ClInclude Include="..\..\include\ignite\odbc\app\parameter.h" /> + <ClInclude Include="..\..\include\ignite\odbc\app\parameter_set.h" /> <ClInclude Include="..\..\include\ignite\odbc\column.h" /> <ClInclude Include="..\..\include\ignite\odbc\common_types.h" /> <ClInclude Include="..\..\include\ignite\odbc\config\configuration.h" /> @@ -215,6 +219,7 @@ <ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" /> <ClInclude Include="..\..\include\ignite\odbc\parser.h" /> <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\batch_query.h" /> <ClInclude Include="..\..\include\ignite\odbc\query\data_query.h" /> <ClInclude Include="..\..\include\ignite\odbc\query\column_metadata_query.h" /> <ClInclude Include="..\..\include\ignite\odbc\query\foreign_keys_query.h" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters index 1828be1..e252d5d 100644 --- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters @@ -139,6 +139,15 @@ <ClCompile Include="..\..\src\protocol_version.cpp"> <Filter>Code</Filter> </ClCompile> + <ClCompile Include="..\..\src\app\parameter_set.cpp"> + <Filter>Code\app</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\batch_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\message.cpp"> + <Filter>Code</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <None Include="module.def"> @@ -266,5 +275,11 @@ <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h"> <Filter>Code</Filter> </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\app\parameter_set.h"> + <Filter>Code\app</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\batch_query.h"> + <Filter>Code\query</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp index ced8c01..ec3b11d 100644 --- a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp +++ b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp @@ -33,35 +33,38 @@ namespace ignite { namespace app { - using ignite::impl::binary::BinaryUtils; + using impl::binary::BinaryUtils; ApplicationDataBuffer::ApplicationDataBuffer() : type(type_traits::OdbcNativeType::AI_UNSUPPORTED), buffer(0), buflen(0), reslen(0), - offset(0) + byteOffset(0), + elementOffset(0) { // No-op. } ApplicationDataBuffer::ApplicationDataBuffer(type_traits::OdbcNativeType::Type type, - void* buffer, SqlLen buflen, SqlLen* reslen, int** offset) : + void* buffer, SqlLen buflen, SqlLen* reslen) : type(type), buffer(buffer), buflen(buflen), reslen(reslen), - offset(offset) + byteOffset(0), + elementOffset(0) { // No-op. } - ApplicationDataBuffer::ApplicationDataBuffer(const ApplicationDataBuffer & other) : + ApplicationDataBuffer::ApplicationDataBuffer(const ApplicationDataBuffer& other) : type(other.type), buffer(other.buffer), buflen(other.buflen), reslen(other.reslen), - offset(other.offset) + byteOffset(other.byteOffset), + elementOffset(other.elementOffset) { // No-op. } @@ -77,7 +80,8 @@ namespace ignite buffer = other.buffer; buflen = other.buflen; reslen = other.reslen; - offset = other.offset; + byteOffset = other.byteOffset; + elementOffset = other.elementOffset; return *this; } @@ -1228,22 +1232,22 @@ namespace ignite const void* ApplicationDataBuffer::GetData() const { - return ApplyOffset(buffer); + return ApplyOffset(buffer, GetElementSize()); } const SqlLen* ApplicationDataBuffer::GetResLen() const { - return ApplyOffset(reslen); + return ApplyOffset(reslen, sizeof(*reslen)); } void* ApplicationDataBuffer::GetData() { - return ApplyOffset(buffer); + return ApplyOffset(buffer, GetElementSize()); } SqlLen* ApplicationDataBuffer::GetResLen() { - return ApplyOffset(reslen); + return ApplyOffset(reslen, sizeof(*reslen)); } template<typename T> @@ -1645,12 +1649,12 @@ namespace ignite } template<typename T> - T* ApplicationDataBuffer::ApplyOffset(T* ptr) const + T* ApplicationDataBuffer::ApplyOffset(T* ptr, size_t elemSize) const { - if (!ptr || !offset || !*offset) + if (!ptr) return ptr; - return utility::GetPointerWithOffset(ptr, **offset); + return utility::GetPointerWithOffset(ptr, byteOffset + elemSize * elementOffset); } bool ApplicationDataBuffer::IsDataAtExec() const @@ -1740,6 +1744,64 @@ namespace ignite return 0; } + SqlLen ApplicationDataBuffer::GetElementSize() const + { + using namespace type_traits; + + switch (type) + { + case OdbcNativeType::AI_WCHAR: + case OdbcNativeType::AI_CHAR: + case OdbcNativeType::AI_BINARY: + return buflen; + + case OdbcNativeType::AI_SIGNED_SHORT: + case OdbcNativeType::AI_UNSIGNED_SHORT: + return static_cast<SqlLen>(sizeof(short)); + + case OdbcNativeType::AI_SIGNED_LONG: + case OdbcNativeType::AI_UNSIGNED_LONG: + return static_cast<SqlLen>(sizeof(long)); + + case OdbcNativeType::AI_FLOAT: + return static_cast<SqlLen>(sizeof(float)); + + case OdbcNativeType::AI_DOUBLE: + return static_cast<SqlLen>(sizeof(double)); + + case OdbcNativeType::AI_BIT: + case OdbcNativeType::AI_SIGNED_TINYINT: + case OdbcNativeType::AI_UNSIGNED_TINYINT: + return static_cast<SqlLen>(sizeof(char)); + + case OdbcNativeType::AI_SIGNED_BIGINT: + case OdbcNativeType::AI_UNSIGNED_BIGINT: + return static_cast<SqlLen>(sizeof(SQLBIGINT)); + + case OdbcNativeType::AI_TDATE: + return static_cast<SqlLen>(sizeof(SQL_DATE_STRUCT)); + + case OdbcNativeType::AI_TTIME: + return static_cast<SqlLen>(sizeof(SQL_TIME_STRUCT)); + + case OdbcNativeType::AI_TTIMESTAMP: + return static_cast<SqlLen>(sizeof(SQL_TIMESTAMP_STRUCT)); + + case OdbcNativeType::AI_NUMERIC: + return static_cast<SqlLen>(sizeof(SQL_NUMERIC_STRUCT)); + + case OdbcNativeType::AI_GUID: + return static_cast<SqlLen>(sizeof(SQLGUID)); + + case OdbcNativeType::AI_DEFAULT: + case OdbcNativeType::AI_UNSUPPORTED: + default: + break; + } + + return 0; + } + SqlLen ApplicationDataBuffer::GetInputSize() const { if (!IsDataAtExec()) http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/app/parameter.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/app/parameter.cpp b/modules/platforms/cpp/odbc/src/app/parameter.cpp index 13136f0..96e5503 100644 --- a/modules/platforms/cpp/odbc/src/app/parameter.cpp +++ b/modules/platforms/cpp/odbc/src/app/parameter.cpp @@ -16,8 +16,6 @@ */ #include <algorithm> -#include <string> -#include <sstream> #include "ignite/odbc/system/odbc_constants.h" #include "ignite/odbc/app/parameter.h" @@ -78,7 +76,7 @@ namespace ignite return *this; } - void Parameter::Write(ignite::impl::binary::BinaryWriterImpl& writer) const + void Parameter::Write(impl::binary::BinaryWriterImpl& writer, int offset, SqlUlen idx) const { if (buffer.GetInputSize() == SQL_NULL_DATA) { @@ -89,6 +87,8 @@ namespace ignite // Buffer to use to get data. ApplicationDataBuffer buf(buffer); + buf.SetByteOffset(offset); + buf.SetElementOffset(idx); SqlLen storedDataLen = static_cast<SqlLen>(storedData.size()); @@ -216,6 +216,11 @@ namespace ignite return buffer; } + const ApplicationDataBuffer& Parameter::GetBuffer() const + { + return buffer; + } + void Parameter::ResetStoredData() { storedData.clear(); http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/app/parameter_set.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/app/parameter_set.cpp b/modules/platforms/cpp/odbc/src/app/parameter_set.cpp new file mode 100644 index 0000000..c110d05 --- /dev/null +++ b/modules/platforms/cpp/odbc/src/app/parameter_set.cpp @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/app/parameter_set.h" + +namespace ignite +{ + namespace odbc + { + namespace app + { + ParameterSet::ParameterSet(): + parameters(), + paramTypes(), + paramBindOffset(0), + processedParamRows(0), + paramSetSize(1), + paramSetPos(0), + currentParamIdx(0), + typesSet(false) + { + // No-op. + } + + void ParameterSet::SetParamSetSize(SqlUlen size) + { + paramSetSize = size; + } + + void ParameterSet::BindParameter(uint16_t paramIdx, const Parameter& param) + { + parameters[paramIdx] = param; + } + + void ParameterSet::UnbindParameter(uint16_t paramIdx) + { + parameters.erase(paramIdx); + } + + void ParameterSet::UnbindAll() + { + parameters.clear(); + } + + uint16_t ParameterSet::GetParametersNumber() const + { + return static_cast<uint16_t>(parameters.size()); + } + + void ParameterSet::SetParamBindOffsetPtr(int* ptr) + { + paramBindOffset = ptr; + } + + int* ParameterSet::GetParamBindOffsetPtr() + { + return paramBindOffset; + } + + void ParameterSet::Prepare() + { + paramTypes.clear(); + + typesSet = false; + + paramSetPos = 0; + + for (ParameterBindingMap::iterator it = parameters.begin(); it != parameters.end(); ++it) + it->second.ResetStoredData(); + } + + bool ParameterSet::IsDataAtExecNeeded() const + { + for (ParameterBindingMap::const_iterator it = parameters.begin(); it != parameters.end(); ++it) + { + if (!it->second.IsDataReady()) + return true; + } + + return false; + } + + void ParameterSet::SetParamsProcessedPtr(SqlUlen* ptr) + { + processedParamRows = ptr; + } + + SqlUlen* ParameterSet::GetParamsProcessedPtr() + { + return processedParamRows; + } + + void ParameterSet::SetParamsProcessed(SqlUlen processed) const + { + if (processedParamRows) + *processedParamRows = processed; + } + + void ParameterSet::UpdateParamsTypes(const ParameterTypeVector& meta) + { + paramTypes = meta; + + typesSet = true; + } + + int8_t ParameterSet::GetParamType(int16_t idx, int8_t dflt) + { + if (idx > 0 && static_cast<size_t>(idx) <= paramTypes.size()) + return paramTypes[idx - 1]; + + return dflt; + } + + uint16_t ParameterSet::GetExpectedParamNum() + { + return static_cast<uint16_t>(paramTypes.size()); + } + + bool ParameterSet::IsMetadataSet() const + { + return typesSet; + } + + bool ParameterSet::IsParameterSelected() const + { + return currentParamIdx != 0; + } + + Parameter* ParameterSet::GetParameter(uint16_t idx) + { + ParameterBindingMap::iterator it = parameters.find(currentParamIdx); + + if (it != parameters.end()) + return &it->second; + + return 0; + } + + Parameter* ParameterSet::GetSelectedParameter() + { + return GetParameter(currentParamIdx); + } + + Parameter* ParameterSet::SelectNextParameter() + { + for (ParameterBindingMap::iterator it = parameters.begin(); it != parameters.end(); ++it) + { + uint16_t paramIdx = it->first; + Parameter& param = it->second; + + if (!param.IsDataReady()) + { + currentParamIdx = paramIdx; + + return ¶m; + } + } + + return 0; + } + + void ParameterSet::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt32(CalculateRowLen()); + + WriteRow(writer, 0); + } + + void ParameterSet::Write(impl::binary::BinaryWriterImpl& writer, SqlUlen begin, SqlUlen end, bool last) const + { + int32_t rowLen = CalculateRowLen(); + + writer.WriteInt32(rowLen); + + SqlUlen intervalEnd = std::min(paramSetSize, end); + + assert(begin < intervalEnd); + + int32_t intervalLen = static_cast<int32_t>(intervalEnd - begin); + + writer.WriteInt32(intervalLen); + writer.WriteBool(last); + + if (rowLen) + { + for (SqlUlen i = begin; i < intervalEnd; ++i) + WriteRow(writer, i); + } + } + + void ParameterSet::WriteRow(impl::binary::BinaryWriterImpl& writer, SqlUlen idx) const + { + uint16_t prev = 0; + + int appOffset = paramBindOffset ? *paramBindOffset : 0; + + for (ParameterBindingMap::const_iterator it = parameters.begin(); it != parameters.end(); ++it) + { + uint16_t paramIdx = it->first; + const Parameter& param = it->second; + + while ((paramIdx - prev) > 1) + { + writer.WriteNull(); + ++prev; + } + + param.Write(writer, appOffset, idx); + + prev = paramIdx; + } + } + + int32_t ParameterSet::CalculateRowLen() const + { + if (!parameters.empty()) + return static_cast<int32_t>(parameters.rbegin()->first); + + return 0; + } + + int32_t ParameterSet::GetParamSetSize() const + { + return static_cast<int32_t>(paramSetSize); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/column.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/column.cpp b/modules/platforms/cpp/odbc/src/column.cpp index a9783a9..bd2abda 100644 --- a/modules/platforms/cpp/odbc/src/column.cpp +++ b/modules/platforms/cpp/odbc/src/column.cpp @@ -314,7 +314,6 @@ namespace ignite default: { // This is a fail case. - std::cout << (int)hdr << std::endl; assert(false); return; } http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/config/connection_info.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp index b642a39..4e7cc3c 100644 --- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp +++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp @@ -118,6 +118,8 @@ namespace ignite DBG_STR_CASE(SQL_CONVERT_WLONGVARCHAR); DBG_STR_CASE(SQL_CONVERT_WVARCHAR); DBG_STR_CASE(SQL_CONVERT_GUID); + DBG_STR_CASE(SQL_PARAM_ARRAY_ROW_COUNTS); + DBG_STR_CASE(SQL_PARAM_ARRAY_SELECTS); default: break; } @@ -585,6 +587,40 @@ namespace ignite SQL_CVT_TIME | SQL_CVT_TIMESTAMP | SQL_CVT_GUID; #endif //SQL_CONVERT_LONGVARBINARY +#ifdef SQL_PARAM_ARRAY_ROW_COUNTS + // Enumerating the driver's properties regarding the availability of row counts in a parameterized + // execution. Has the following values: + // + // SQL_PARC_BATCH = Individual row counts are available for each set of parameters. This is conceptually + // equivalent to the driver generating a batch of SQL statements, one for each parameter set in the + // array. Extended error information can be retrieved by using the SQL_PARAM_STATUS_PTR descriptor + // field. + // + // SQL_PARC_NO_BATCH = There is only one row count available, which is the cumulative row count + // resulting from the execution of the statement for the entire array of parameters. This is + // conceptually equivalent to treating the statement together with the complete parameter array as + // one atomic unit. Errors are handled the same as if one statement were executed. + intParams[SQL_PARAM_ARRAY_ROW_COUNTS] = SQL_PARC_NO_BATCH; +#endif //SQL_PARAM_ARRAY_ROW_COUNTS + +#ifdef SQL_PARAM_ARRAY_SELECTS + // Enumerating the driver's properties regarding the availability of result sets in a parameterized + // execution. Has the following values: + // + // SQL_PAS_BATCH = There is one result set available per set of parameters. This is conceptually + // equivalent to the driver generating a batch of SQL statements, one for each parameter set in + // the array. + // + // SQL_PAS_NO_BATCH = There is only one result set available, which represents the cumulative result set + // resulting from the execution of the statement for the complete array of parameters. This is + // conceptually equivalent to treating the statement together with the complete parameter array as + // one atomic unit. + // + // SQL_PAS_NO_SELECT = A driver does not allow a result - set generating statement to be executed with + // an array of parameters. + intParams[SQL_PARAM_ARRAY_SELECTS] = SQL_PAS_NO_SELECT; +#endif //SQL_PARAM_ARRAY_SELECTS + #ifdef SQL_CONVERT_GUID // Bitmask indicates the conversions supported by the CONVERT scalar function for target type GUID intParams[SQL_CONVERT_GUID] = SQL_CVT_CHAR | SQL_CVT_VARCHAR | SQL_CVT_LONGVARCHAR | http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/message.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/message.cpp b/modules/platforms/cpp/odbc/src/message.cpp new file mode 100644 index 0000000..c0fddbe --- /dev/null +++ b/modules/platforms/cpp/odbc/src/message.cpp @@ -0,0 +1,373 @@ +/* + * 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/message.h" +#include "ignite/odbc/utility.h" + +namespace ignite +{ + namespace odbc + { + HandshakeRequest::HandshakeRequest(const ProtocolVersion& version, bool distributedJoins, bool enforceJoinOrder): + version(version), + distributedJoins(distributedJoins), + enforceJoinOrder(enforceJoinOrder) + { + // No-op. + } + + HandshakeRequest::~HandshakeRequest() + { + // No-op. + } + + void HandshakeRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::HANDSHAKE); + + writer.WriteInt16(version.GetMajor()); + writer.WriteInt16(version.GetMinor()); + writer.WriteInt16(version.GetMaintenance()); + + writer.WriteInt8(ClientType::ODBC); + + writer.WriteBool(distributedJoins); + writer.WriteBool(enforceJoinOrder); + } + + QueryExecuteRequest::QueryExecuteRequest(const std::string& schema, const std::string& sql, const app::ParameterSet& params): + schema(schema), + sql(sql), + params(params) + { + // No-op. + } + + QueryExecuteRequest::~QueryExecuteRequest() + { + // No-op. + } + + void QueryExecuteRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::EXECUTE_SQL_QUERY); + + if (schema.empty()) + writer.WriteNull(); + else + writer.WriteObject<std::string>(schema); + + writer.WriteObject<std::string>(sql); + + params.Write(writer); + } + + QueryExecuteBatchtRequest::QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql, + const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last): + schema(schema), + sql(sql), + params(params), + begin(begin), + end(end), + last(last) + { + // No-op. + } + + QueryExecuteBatchtRequest::~QueryExecuteBatchtRequest() + { + // No-op. + } + + void QueryExecuteBatchtRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::EXECUTE_SQL_QUERY_BATCH); + + if (schema.empty()) + writer.WriteNull(); + else + writer.WriteObject<std::string>(schema); + + writer.WriteObject<std::string>(sql); + + params.Write(writer, begin, end, last); + } + + QueryCloseRequest::QueryCloseRequest(int64_t queryId): queryId(queryId) + { + // No-op. + } + + QueryCloseRequest::~QueryCloseRequest() + { + // No-op. + } + + void QueryCloseRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::CLOSE_SQL_QUERY); + writer.WriteInt64(queryId); + } + + QueryFetchRequest::QueryFetchRequest(int64_t queryId, int32_t pageSize): + queryId(queryId), + pageSize(pageSize) + { + // No-op. + } + + QueryFetchRequest::~QueryFetchRequest() + { + // No-op. + } + + void QueryFetchRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::FETCH_SQL_QUERY); + writer.WriteInt64(queryId); + writer.WriteInt32(pageSize); + } + + QueryGetColumnsMetaRequest::QueryGetColumnsMetaRequest(const std::string& schema, const std::string& table, const std::string& column): + schema(schema), + table(table), + column(column) + { + // No-op. + } + + QueryGetColumnsMetaRequest::~QueryGetColumnsMetaRequest() + { + // No-op. + } + + void QueryGetColumnsMetaRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::GET_COLUMNS_METADATA); + + writer.WriteObject<std::string>(schema); + writer.WriteObject<std::string>(table); + writer.WriteObject<std::string>(column); + } + + QueryGetTablesMetaRequest::QueryGetTablesMetaRequest(const std::string& catalog, const std::string& schema, const std::string& table, const std::string& tableTypes): + catalog(catalog), + schema(schema), + table(table), + tableTypes(tableTypes) + { + // No-op. + } + + QueryGetTablesMetaRequest::~QueryGetTablesMetaRequest() + { + // No-op. + } + + void QueryGetTablesMetaRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::GET_TABLES_METADATA); + + writer.WriteObject<std::string>(catalog); + writer.WriteObject<std::string>(schema); + writer.WriteObject<std::string>(table); + writer.WriteObject<std::string>(tableTypes); + } + + void QueryGetParamsMetaRequest::Write(impl::binary::BinaryWriterImpl& writer) const + { + writer.WriteInt8(RequestType::GET_PARAMS_METADATA); + + writer.WriteObject<std::string>(schema); + writer.WriteObject<std::string>(sqlQuery); + } + + Response::Response(): status(ResponseStatus::FAILED), error() + { + // No-op. + } + + Response::~Response() + { + // No-op. + } + + void Response::Read(impl::binary::BinaryReaderImpl& reader) + { + status = reader.ReadInt8(); + + if (status == ResponseStatus::SUCCESS) + ReadOnSuccess(reader); + else + utility::ReadString(reader, error);; + } + + void Response::ReadOnSuccess(impl::binary::BinaryReaderImpl&) + { + // No-op. + } + + HandshakeResponse::HandshakeResponse(): + accepted(false), + currentVer(), + error() + { + // No-op. + } + + HandshakeResponse::~HandshakeResponse() + { + // No-op. + } + + void HandshakeResponse::Read(impl::binary::BinaryReaderImpl& reader) + { + accepted = reader.ReadBool(); + + if (!accepted) + { + int16_t major = reader.ReadInt16(); + int16_t minor = reader.ReadInt16(); + int16_t maintenance = reader.ReadInt16(); + + currentVer = ProtocolVersion(major, minor, maintenance); + + utility::ReadString(reader, error); + } + } + + QueryCloseResponse::QueryCloseResponse(): queryId(0) + { + // No-op. + } + + QueryCloseResponse::~QueryCloseResponse() + { + // No-op. + } + + void QueryCloseResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + queryId = reader.ReadInt64(); + } + + QueryExecuteResponse::QueryExecuteResponse(): queryId(0), meta() + { + // No-op. + } + + QueryExecuteResponse::~QueryExecuteResponse() + { + // No-op. + } + + void QueryExecuteResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + queryId = reader.ReadInt64(); + + meta::ReadColumnMetaVector(reader, meta); + } + + QueryExecuteBatchResponse::QueryExecuteBatchResponse(): + affectedRows(0), + errorSetIdx(-1), + errorMessage() + { + // No-op. + } + + QueryExecuteBatchResponse::~QueryExecuteBatchResponse() + { + // No-op. + } + + void QueryExecuteBatchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + bool success = reader.ReadBool(); + affectedRows = reader.ReadInt64(); + + if (!success) + { + errorSetIdx = reader.ReadInt64(); + errorMessage = reader.ReadObject<std::string>(); + } + } + + QueryFetchResponse::QueryFetchResponse(ResultPage& resultPage): queryId(0), resultPage(resultPage) + { + // No-op. + } + + QueryFetchResponse::~QueryFetchResponse() + { + // No-op. + } + + void QueryFetchResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + queryId = reader.ReadInt64(); + + resultPage.Read(reader); + } + + QueryGetColumnsMetaResponse::QueryGetColumnsMetaResponse() + { + // No-op. + } + + QueryGetColumnsMetaResponse::~QueryGetColumnsMetaResponse() + { + // No-op. + } + + void QueryGetColumnsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + meta::ReadColumnMetaVector(reader, meta); + } + + QueryGetTablesMetaResponse::QueryGetTablesMetaResponse() + { + // No-op. + } + + QueryGetTablesMetaResponse::~QueryGetTablesMetaResponse() + { + // No-op. + } + + void QueryGetTablesMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + meta::ReadTableMetaVector(reader, meta); + } + + QueryGetParamsMetaResponse::QueryGetParamsMetaResponse() + { + // No-op. + } + + QueryGetParamsMetaResponse::~QueryGetParamsMetaResponse() + { + // No-op. + } + + void QueryGetParamsMetaResponse::ReadOnSuccess(impl::binary::BinaryReaderImpl& reader) + { + utility::ReadByteArray(reader, typeIds); + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/query/batch_query.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp new file mode 100644 index 0000000..df9fb05 --- /dev/null +++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/connection.h" +#include "ignite/odbc/message.h" +#include "ignite/odbc/log.h" +#include "ignite/odbc/query/batch_query.h" + +namespace ignite +{ + namespace odbc + { + namespace query + { + BatchQuery::BatchQuery(diagnostic::Diagnosable& diag, Connection& connection, + const std::string& sql, const app::ParameterSet& params) : + Query(diag, QueryType::BATCH), + connection(connection), + sql(sql), + params(params), + resultMeta(), + rowsAffected(0), + setsProcessed(0), + executed(false), + dataRetrieved(false) + { + // No-op. + } + + BatchQuery::~BatchQuery() + { + // No-op. + } + + SqlResult::Type BatchQuery::Execute() + { + if (executed) + { + diag.AddStatusRecord(SqlState::SHY010_SEQUENCE_ERROR, "Query cursor is in open state already."); + + return SqlResult::AI_ERROR; + } + + int32_t maxPageSize = connection.GetConfiguration().GetPageSize(); + int32_t rowNum = params.GetParamSetSize(); + SqlResult::Type res; + + int32_t processed = 0; + + do { + int32_t currentPageSize = std::min(maxPageSize, rowNum - processed); + bool lastPage = currentPageSize == rowNum - processed; + + res = MakeRequestExecuteBatch(processed, processed + currentPageSize, lastPage); + + processed += currentPageSize; + } while (res == SqlResult::AI_SUCCESS && processed < rowNum); + + params.SetParamsProcessed(static_cast<SqlUlen>(setsProcessed)); + + return res; + } + + const meta::ColumnMetaVector& BatchQuery::GetMeta() const + { + return resultMeta; + } + + SqlResult::Type BatchQuery::FetchNextRow(app::ColumnBindingMap& columnBindings) + { + if (!executed) + { + diag.AddStatusRecord(SqlState::SHY010_SEQUENCE_ERROR, "Query was not executed."); + + return SqlResult::AI_ERROR; + } + + if (dataRetrieved) + return SqlResult::AI_NO_DATA; + + app::ColumnBindingMap::iterator it = columnBindings.find(1); + + if (it != columnBindings.end()) + it->second.PutInt64(rowsAffected); + + dataRetrieved = true; + + return SqlResult::AI_SUCCESS; + } + + SqlResult::Type BatchQuery::GetColumn(uint16_t columnIdx, app::ApplicationDataBuffer& buffer) + { + if (!executed) + { + diag.AddStatusRecord(SqlState::SHY010_SEQUENCE_ERROR, "Query was not executed."); + + return SqlResult::AI_ERROR; + } + + if (dataRetrieved) + return SqlResult::AI_NO_DATA; + + if (columnIdx != 1) + { + std::stringstream builder; + builder << "Column with id " << columnIdx << " is not available in result set."; + + diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, builder.str()); + + return SqlResult::AI_ERROR; + } + + buffer.PutInt64(rowsAffected); + + return SqlResult::AI_SUCCESS; + } + + SqlResult::Type BatchQuery::Close() + { + return SqlResult::AI_SUCCESS; + } + + bool BatchQuery::DataAvailable() const + { + return false; + } + + int64_t BatchQuery::AffectedRows() const + { + return rowsAffected; + } + + SqlResult::Type BatchQuery::MakeRequestExecuteBatch(SqlUlen begin, SqlUlen end, bool last) + { + const std::string& schema = connection.GetSchema(); + + QueryExecuteBatchtRequest req(schema, sql, params, begin, end, last); + QueryExecuteBatchResponse rsp; + + try + { + connection.SyncMessage(req, rsp); + } + catch (const IgniteError& err) + { + diag.AddStatusRecord(SqlState::SHYT01_CONNECTIOIN_TIMEOUT, err.GetText()); + + return SqlResult::AI_ERROR; + } + + if (rsp.GetStatus() != ResponseStatus::SUCCESS) + { + LOG_MSG("Error: " << rsp.GetError()); + + diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetError()); + + return SqlResult::AI_ERROR; + } + + rowsAffected += rsp.GetAffectedRows(); + LOG_MSG("rowsAffected: " << rowsAffected); + + if (!rsp.GetErrorMessage().empty()) + { + LOG_MSG("Error: " << rsp.GetErrorMessage()); + + setsProcessed += rsp.GetErrorSetIdx(); + LOG_MSG("setsProcessed: " << setsProcessed); + + diag.AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, rsp.GetErrorMessage(), + static_cast<int32_t>(setsProcessed), 0); + + return SqlResult::AI_SUCCESS_WITH_INFO; + } + + setsProcessed += end - begin; + LOG_MSG("setsProcessed: " << setsProcessed); + + return SqlResult::AI_SUCCESS; + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/c10be578/modules/platforms/cpp/odbc/src/query/data_query.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp index 2ad679b..3cd3b16 100644 --- a/modules/platforms/cpp/odbc/src/query/data_query.cpp +++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp @@ -19,6 +19,7 @@ #include "ignite/odbc/message.h" #include "ignite/odbc/log.h" #include "ignite/odbc/query/data_query.h" +#include "ignite/odbc/query/batch_query.h" namespace ignite { @@ -26,9 +27,8 @@ namespace ignite { namespace query { - DataQuery::DataQuery(diagnostic::Diagnosable& diag, - Connection& connection, const std::string& sql, - const app::ParameterBindingMap& params) : + DataQuery::DataQuery(diagnostic::Diagnosable& diag, Connection& connection, + const std::string& sql, const app::ParameterSet& params) : Query(diag, QueryType::DATA), connection(connection), sql(sql), @@ -39,7 +39,7 @@ namespace ignite DataQuery::~DataQuery() { - Close(); + InternalClose(); } SqlResult::Type DataQuery::Execute() @@ -141,6 +141,11 @@ namespace ignite SqlResult::Type DataQuery::Close() { + return InternalClose(); + } + + SqlResult::Type DataQuery::InternalClose() + { if (!cursor.get()) return SqlResult::AI_SUCCESS;
