blob: e7654a49f4622ed6281483b92ce7733e85cc046d [file]
/*
* 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"
#include "ignite/tuple/binary_tuple_builder.h"
#include <algorithm>
namespace ignite {
void parameter_set_impl::set_param_set_size(SQLULEN size) {
m_param_set_size = size;
}
void parameter_set_impl::bind_parameter(std::uint16_t param_idx, const parameter &param) {
m_params[param_idx] = param;
}
void parameter_set_impl::unbind_parameter(std::uint16_t param_idx) {
m_params.erase(param_idx);
}
void parameter_set_impl::unbind_all() {
m_params.clear();
}
std::uint16_t parameter_set_impl::get_parameters_number() const {
return static_cast<std::uint16_t>(m_params.size());
}
void parameter_set_impl::set_param_bind_offset_ptr(int *ptr) {
m_param_bind_offset = ptr;
}
int *parameter_set_impl::get_param_bind_offset_ptr() {
return m_param_bind_offset;
}
void parameter_set_impl::prepare() {
m_param_set_pos = 0;
for (auto &param : m_params)
param.second.reset_stored_data();
}
bool parameter_set_impl::is_data_at_exec_needed() const {
return std::any_of(
m_params.begin(), m_params.end(), [](const auto &param) { return !param.second.is_data_ready(); });
}
void parameter_set_impl::set_params_processed_ptr(SQLULEN *ptr) {
m_processed_param_rows = ptr;
}
SQLULEN *parameter_set_impl::get_params_processed_ptr() const {
return m_processed_param_rows;
}
void parameter_set_impl::set_params_status_ptr(SQLUSMALLINT *value) {
m_params_status = value;
}
SQLUSMALLINT *parameter_set_impl::get_params_status_ptr() const {
return m_params_status;
}
void parameter_set_impl::set_params_status(int64_t idx, SQLUSMALLINT status) const {
if (idx < 0 || !m_params_status || idx >= static_cast<int64_t>(m_param_set_size))
return;
m_params_status[idx] = status;
}
void parameter_set_impl::set_params_processed(SQLULEN processed) {
if (m_processed_param_rows)
*m_processed_param_rows = processed;
}
bool parameter_set_impl::is_parameter_selected() const {
return m_current_param_idx != 0;
}
parameter *parameter_set_impl::get_parameter(std::uint16_t idx) {
auto it = m_params.find(idx);
if (it != m_params.end())
return &it->second;
return nullptr;
}
const parameter *parameter_set_impl::get_parameter(std::uint16_t idx) const {
auto it = m_params.find(idx);
if (it != m_params.end())
return &it->second;
return nullptr;
}
parameter *parameter_set_impl::get_selected_parameter() {
return get_parameter(m_current_param_idx);
}
parameter *parameter_set_impl::select_next_parameter() {
for (auto it = m_params.begin(); it != m_params.end(); ++it) {
std::uint16_t param_idx = it->first;
parameter &param = it->second;
if (!param.is_data_ready()) {
m_current_param_idx = param_idx;
return &param;
}
}
return nullptr;
}
void parameter_set_impl::write(protocol::writer &writer) const {
auto args_num = calculate_row_len();
if (args_num == 0) {
writer.write_nil();
return;
}
writer.write(args_num);
write_row(writer, 0);
}
void parameter_set_impl::write(protocol::writer &writer, SQLULEN begin, SQLULEN end, bool last) const {
std::int32_t row_len = calculate_row_len();
writer.write(row_len);
SQLULEN interval_end = std::min(m_param_set_size, end);
assert(begin < interval_end);
auto interval_len = static_cast<std::int32_t>(interval_end - begin);
writer.write(interval_len);
writer.write_bool(last);
if (row_len) {
for (SQLULEN i = begin; i < interval_end; ++i)
write_row(writer, i);
}
}
void parameter_set_impl::write_row(protocol::writer &writer, SQLULEN idx) const {
auto args_num = calculate_row_len();
binary_tuple_builder row_builder{args_num * 3};
row_builder.start();
std::uint16_t prev = 0;
int app_offset = m_param_bind_offset ? *m_param_bind_offset : 0;
for (const auto &pair : m_params) {
std::uint16_t param_idx = pair.first;
const parameter &param = pair.second;
while ((param_idx - prev) > 1) {
row_builder.claim_null();
++prev;
}
param.claim(row_builder, app_offset, idx);
prev = param_idx;
}
row_builder.layout();
for (const auto &pair : m_params) {
std::uint16_t param_idx = pair.first;
const parameter &param = pair.second;
while ((param_idx - prev) > 1) {
row_builder.append_null();
++prev;
}
param.append(row_builder, app_offset, idx);
prev = param_idx;
}
auto args_data = row_builder.build();
writer.write_binary(args_data);
}
std::int32_t parameter_set_impl::calculate_row_len() const {
if (!m_params.empty())
return static_cast<std::int32_t>(m_params.rbegin()->first);
return 0;
}
std::int32_t parameter_set_impl::get_param_set_size() const {
return static_cast<std::int32_t>(m_param_set_size);
}
} // namespace ignite