modules/platforms/cpp/ignite/odbc/app/parameter.cpp (252 lines of code) (raw):
/*
* 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.h"
#include "ignite/odbc/system/odbc_constants.h"
#include "ignite/protocol/utils.h"
#include <algorithm>
namespace ignite {
void parameter::claim(binary_tuple_builder &builder, int offset, SQLULEN idx) const {
if (m_buffer.get_input_size() == SQL_NULL_DATA) {
builder.claim_null(); // Type.
builder.claim_null(); // Scale.
builder.claim_null(); // Value.
return;
}
// Buffer to use to get data.
application_data_buffer buf(m_buffer);
buf.set_byte_offset(offset);
buf.set_element_offset(idx);
auto stored_data_len = static_cast<SQLLEN>(m_stored_data.size());
if (m_buffer.is_data_at_exec()) {
buf = application_data_buffer(
m_buffer.get_type(), const_cast<std::byte *>(&m_stored_data[0]), stored_data_len, &stored_data_len);
}
switch (m_sql_type) {
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR: {
protocol::claim_type_and_scale(builder, ignite_type::STRING);
builder.claim_varlen(buf.get_string(m_column_size));
break;
}
case SQL_TINYINT: {
protocol::claim_type_and_scale(builder, ignite_type::INT8);
builder.claim_int8(buf.get_int8());
break;
}
case SQL_SMALLINT: {
protocol::claim_type_and_scale(builder, ignite_type::INT16);
builder.claim_int16(buf.get_int16());
break;
}
case SQL_INTEGER: {
protocol::claim_type_and_scale(builder, ignite_type::INT32);
builder.claim_int32(buf.get_int32());
break;
}
case SQL_BIGINT: {
protocol::claim_type_and_scale(builder, ignite_type::INT64);
builder.claim_int64(buf.get_int64());
break;
}
case SQL_FLOAT: {
protocol::claim_type_and_scale(builder, ignite_type::FLOAT);
builder.claim_float(buf.get_float());
break;
}
case SQL_DOUBLE: {
protocol::claim_type_and_scale(builder, ignite_type::DOUBLE);
builder.claim_double(buf.get_double());
break;
}
case SQL_BIT: {
protocol::claim_type_and_scale(builder, ignite_type::BOOLEAN);
builder.claim_bool(buf.get_int8() != 0);
break;
}
case SQL_TYPE_DATE:
case SQL_DATE: {
protocol::claim_type_and_scale(builder, ignite_type::DATE);
builder.claim_date(buf.get_date());
break;
}
case SQL_TYPE_TIMESTAMP:
case SQL_TIMESTAMP: {
protocol::claim_type_and_scale(builder, ignite_type::DATETIME);
builder.claim_date_time(buf.get_date_time());
break;
}
case SQL_TYPE_TIME:
case SQL_TIME: {
protocol::claim_type_and_scale(builder, ignite_type::TIME);
builder.claim_time(buf.get_time());
break;
}
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY: {
protocol::claim_type_and_scale(builder, ignite_type::BYTE_ARRAY);
const application_data_buffer &const_buf = buf;
const SQLLEN *res_len_ptr = const_buf.get_result_len();
if (!res_len_ptr)
break;
auto param_len = static_cast<std::size_t>(*res_len_ptr);
builder.claim_varlen({const_buf.get_data(), param_len});
break;
}
case SQL_GUID: {
protocol::claim_type_and_scale(builder, ignite_type::UUID);
builder.claim_uuid(buf.get_uuid());
break;
}
case SQL_DECIMAL: {
big_decimal dec_value;
buf.get_decimal(dec_value);
protocol::claim_type_and_scale(builder, ignite_type::DECIMAL, dec_value.get_scale());
builder.claim_number(dec_value);
break;
}
default:
break;
}
}
void parameter::append(binary_tuple_builder &builder, int offset, SQLULEN idx) const {
if (m_buffer.get_input_size() == SQL_NULL_DATA) {
builder.append_null(); // Type.
builder.append_null(); // Scale.
builder.append_null(); // Value.
return;
}
// Buffer to use to get data.
application_data_buffer buf(m_buffer);
buf.set_byte_offset(offset);
buf.set_element_offset(idx);
auto stored_data_len = static_cast<SQLLEN>(m_stored_data.size());
if (m_buffer.is_data_at_exec()) {
buf = application_data_buffer(
m_buffer.get_type(), const_cast<std::byte *>(&m_stored_data[0]), stored_data_len, &stored_data_len);
}
switch (m_sql_type) {
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR: {
protocol::append_type_and_scale(builder, ignite_type::STRING);
builder.append_varlen(buf.get_string(m_column_size));
break;
}
case SQL_TINYINT: {
protocol::append_type_and_scale(builder, ignite_type::INT8);
builder.append_int8(buf.get_int8());
break;
}
case SQL_SMALLINT: {
protocol::append_type_and_scale(builder, ignite_type::INT16);
builder.append_int16(buf.get_int16());
break;
}
case SQL_INTEGER: {
protocol::append_type_and_scale(builder, ignite_type::INT32);
builder.append_int32(buf.get_int32());
break;
}
case SQL_BIGINT: {
protocol::append_type_and_scale(builder, ignite_type::INT64);
builder.append_int64(buf.get_int64());
break;
}
case SQL_FLOAT: {
protocol::append_type_and_scale(builder, ignite_type::FLOAT);
builder.append_float(buf.get_float());
break;
}
case SQL_DOUBLE: {
protocol::append_type_and_scale(builder, ignite_type::DOUBLE);
builder.append_double(buf.get_double());
break;
}
case SQL_BIT: {
protocol::append_type_and_scale(builder, ignite_type::BOOLEAN);
builder.append_bool(buf.get_int8() != 0);
break;
}
case SQL_TYPE_DATE:
case SQL_DATE: {
protocol::append_type_and_scale(builder, ignite_type::DATE);
builder.append_date(buf.get_date());
break;
}
case SQL_TYPE_TIMESTAMP:
case SQL_TIMESTAMP: {
protocol::append_type_and_scale(builder, ignite_type::DATETIME);
builder.append_date_time(buf.get_date_time());
break;
}
case SQL_TYPE_TIME:
case SQL_TIME: {
protocol::append_type_and_scale(builder, ignite_type::TIME);
builder.append_time(buf.get_time());
break;
}
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY: {
protocol::append_type_and_scale(builder, ignite_type::BYTE_ARRAY);
const application_data_buffer &const_buf = buf;
const SQLLEN *res_len_ptr = const_buf.get_result_len();
if (!res_len_ptr)
break;
auto param_len = static_cast<std::size_t>(*res_len_ptr);
builder.append_varlen({const_buf.get_data(), param_len});
break;
}
case SQL_GUID: {
protocol::append_type_and_scale(builder, ignite_type::UUID);
builder.append_uuid(buf.get_uuid());
break;
}
case SQL_DECIMAL: {
big_decimal dec_value;
buf.get_decimal(dec_value);
protocol::append_type_and_scale(builder, ignite_type::DECIMAL, dec_value.get_scale());
builder.append_number(dec_value);
break;
}
default:
break;
}
}
application_data_buffer ¶meter::get_buffer() {
return m_buffer;
}
const application_data_buffer ¶meter::get_buffer() const {
return m_buffer;
}
void parameter::reset_stored_data() {
m_stored_data.clear();
if (m_buffer.is_data_at_exec())
m_stored_data.reserve(m_buffer.get_data_at_exec_size());
}
bool parameter::is_data_ready() const {
return !m_buffer.is_data_at_exec() || static_cast<SQLLEN>(m_stored_data.size()) == m_buffer.get_data_at_exec_size();
}
void parameter::put_data(void *data, SQLLEN len) {
if (len == SQL_DEFAULT_PARAM)
return;
if (len == SQL_NULL_DATA) {
m_null_data = true;
return;
}
if (m_buffer.get_type() == odbc_native_type::AI_CHAR || m_buffer.get_type() == odbc_native_type::AI_BINARY) {
SQLLEN s_len = len;
if (m_buffer.get_type() == odbc_native_type::AI_CHAR && s_len == SQL_NTSL) {
const char *str = reinterpret_cast<char *>(data);
s_len = SQLLEN(std::strlen(str));
}
if (s_len <= 0)
return;
size_t begin_pos = m_stored_data.size();
m_stored_data.resize(m_stored_data.size() + static_cast<size_t>(s_len));
memcpy(&m_stored_data[begin_pos], data, static_cast<size_t>(s_len));
return;
}
size_t data_size = m_buffer.get_data_at_exec_size();
m_stored_data.resize(data_size);
memcpy(&m_stored_data[0], data, data_size);
}
} // namespace ignite