blob: 603c86765415541063c20630f43c49242c9c4309 [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.
*/
#pragma once
#include "ignite/odbc/common_types.h"
#include "ignite/odbc/type_traits.h"
#include <ignite/common/big_decimal.h>
#include <ignite/common/bytes_view.h>
#include <ignite/common/ignite_date.h>
#include <ignite/common/ignite_date_time.h>
#include <ignite/common/ignite_duration.h>
#include <ignite/common/ignite_period.h>
#include <ignite/common/ignite_time.h>
#include <ignite/common/ignite_timestamp.h>
#include <ignite/common/uuid.h>
#include <cstdint>
#include <map>
namespace ignite {
/**
* Conversion result
*/
enum class conversion_result {
/** Conversion successful. No data lost. */
AI_SUCCESS,
/** Conversion successful, but fractional truncation occurred. */
AI_FRACTIONAL_TRUNCATED,
/** Conversion successful, but right-side variable length data truncation occurred. */
AI_VARLEN_DATA_TRUNCATED,
/** Conversion is not supported. */
AI_UNSUPPORTED_CONVERSION,
/** Indicator buffer needed to complete the operation but it is NULL. */
AI_INDICATOR_NEEDED,
/** No data found. */
AI_NO_DATA,
/** General operation failure. */
AI_FAILURE
};
/**
* User application data buffer.
*/
class application_data_buffer {
public:
// Default
application_data_buffer() = default;
/**
* Constructor.
*
* @param type Underlying data type.
* @param buffer Data buffer pointer.
* @param buf_len Data buffer length.
* @param res_len Resulting data length.
*/
application_data_buffer(odbc_native_type type, void *buffer, SQLLEN buf_len, SQLLEN *res_len);
/**
* Set offset in bytes for all bound pointers.
*
* @param offset Offset.
*/
void set_byte_offset(int offset) { this->m_byte_offset = offset; }
/**
* Set offset in elements for all bound pointers.
*
* @param offset Offset.
*/
void set_element_offset(SQLULEN offset) { this->m_element_offset = offset; }
/**
* Put in buffer value of type int8_t.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_int8(int8_t value);
/**
* Put in buffer value of type int16_t.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_int16(int16_t value);
/**
* Put in buffer value of type int32_t.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_int32(int32_t value);
/**
* Put in buffer value of type int64_t.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_int64(int64_t value);
/**
* Put in buffer value of type float.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_float(float value);
/**
* Put in buffer value of type double.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_double(double value);
/**
* Put in buffer value of type bool.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_bool(bool value);
/**
* Put in buffer value of type string.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_string(const std::optional<std::string> &value) {
return value ? put_string(*value) : put_null();
}
/**
* Put in buffer value of type string.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_string(const char *value) { return put_string(std::string(value)); }
/**
* Put in buffer value of type string.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_string(const std::string &value);
/**
* Put in buffer value of type string.
*
* @param value Value.
* @param written Number of written characters.
* @return Conversion result.
*/
conversion_result put_string(const std::string &value, int32_t &written);
/**
* Put in buffer value of type GUID.
*
* @param value Value.
* @return Conversion result.
*/
conversion_result put_uuid(const uuid &value);
/**
* Put binary data in buffer.
*
* @param data Data pointer.
* @param len Data length.
* @param written Number of written characters.
* @return Conversion result.
*/
conversion_result put_binary_data(void *data, size_t len, std::int32_t &written);
/**
* Put binary data in buffer.
*
* @param data Data.
* @return Conversion result.
*/
conversion_result put_binary_data(bytes_view data) {
std::int32_t dummy;
return put_binary_data((void *) data.data(), data.size(), dummy);
}
/**
* Put NULL.
* @return Conversion result.
*/
conversion_result put_null();
/**
* Put decimal value to buffer.
*
* @param value Value to put.
* @return Conversion result.
*/
conversion_result put_decimal(const big_decimal &value);
/**
* Put date to buffer.
*
* @param value Value to put.
* @return Conversion result.
*/
conversion_result put_date(const ignite_date &value);
/**
* Put timestamp to buffer.
*
* @param value Value to put.
* @return Conversion result.
*/
conversion_result put_timestamp(const ignite_timestamp &value);
/**
* Put time to buffer.
*
* @param value Value to put.
* @return Conversion result.
*/
conversion_result put_time(const ignite_time &value);
/**
* Put datetime to buffer.
*
* @param value Value to put.
* @return Conversion result.
*/
conversion_result put_date_time(const ignite_date_time &value);
/**
* Get string.
*
* @return String value of buffer.
*/
[[nodiscard]] std::string get_string(size_t maxLen) const;
/**
* Get value of type int8_t.
*
* @return Integer value of type int8_t.
*/
[[nodiscard]] int8_t get_int8() const;
/**
* Get value of type int16_t.
*
* @return Integer value of type int16_t.
*/
[[nodiscard]] int16_t get_int16() const;
/**
* Get value of type int32_t.
*
* @return Integer value of type int32_t.
*/
[[nodiscard]] int32_t get_int32() const;
/**
* Get value of type int64_t.
*
* @return Integer value of type int64_t.
*/
[[nodiscard]] int64_t get_int64() const;
/**
* Get value of type float.
*
* @return Integer value of type float.
*/
[[nodiscard]] float get_float() const;
/**
* Get value of type double.
*
* @return Value of type double.
*/
[[nodiscard]] double get_double() const;
/**
* Get value of type GUID.
*
* @return Value of type uuid.
*/
[[nodiscard]] uuid get_uuid() const;
/**
* Get value of type ignite_date.
*
* @return Value of type ignite_date.
*/
[[nodiscard]] ignite_date get_date() const;
/**
* Get value of type ignite_date_time.
*
* @return Value of type ignite_date_time.
*/
[[nodiscard]] ignite_date_time get_date_time() const;
/**
* Get value of type ignite_timestamp.
*
* @return Value of type ignite_timestamp.
*/
[[nodiscard]] ignite_timestamp get_timestamp() const;
/**
* Get value of type ignite_time.
*
* @return Value of type ignite_timestamp.
*/
[[nodiscard]] ignite_time get_time() const;
/**
* Get value of type big_decimal.
*
* @param val Result is placed here.
*/
void get_decimal(big_decimal &val) const;
/**
* Get raw data.
*
* @return Buffer data.
*/
[[nodiscard]] const void *get_data() const;
/**
* Get result data length.
*
* @return Data length pointer.
*/
[[nodiscard]] const SQLLEN *get_result_len() const;
/**
* Get raw data.
*
* @return Buffer data.
*/
void *get_data();
/**
* Get result data length.
*
* @return Data length pointer.
*/
SQLLEN *get_result_len();
/**
* Get buffer size in bytes.
*
* @return Buffer size.
*/
[[nodiscard]] SQLLEN get_size() const { return m_buffer_len; }
/**
* Check if the data is going to be provided at execution.
*
* @return True if the data is going to be provided
* at execution.
*/
[[nodiscard]] bool is_data_at_exec() const;
/**
* Get size of the data that is going to be provided at
* execution.
*
* @return Size of the data that is going to be provided
* at execution.
*/
[[nodiscard]] SQLLEN get_data_at_exec_size() const;
/**
* Get single element size.
*
* @return Size of the single element.
*/
[[nodiscard]] SQLLEN get_element_size() const;
/**
* Get size of the input buffer.
*
* @return Input buffer size, or zero if the data is going
* to be provided at execution.
*/
[[nodiscard]] SQLLEN get_input_size() const;
/**
* Get buffer type.
*
* @return Buffer type.
*/
[[nodiscard]] odbc_native_type get_type() const { return m_type; }
private:
/**
* Put value of numeric type in the buffer.
*
* @param value Numeric value to put.
* @return Conversion result.
*/
template<typename T>
conversion_result put_num(T value);
/**
* Put numeric value to numeric buffer.
*
* @param value Numeric value.
* @return Conversion result.
*/
template<typename TBuf, typename TIn>
conversion_result put_num_to_num_buffer(TIn value);
/**
* Put value to string buffer.
*
* @param value Value that can be converted to string.
* @return Conversion result.
*/
template<typename CharT, typename Tin>
conversion_result put_value_to_string_buffer(const Tin &value);
/**
* Put value to string buffer.
* Specialisation for int8_t.
*
* @param value Value that can be converted to string.
* @return Conversion result.
*/
template<typename CharT>
conversion_result put_value_to_string_buffer(const int8_t &value);
/**
* Put string to string buffer.
*
* @param value String value.
* @param written Number of characters written.
* @return Conversion result.
*/
template<typename OutCharT, typename InCharT>
conversion_result put_string_to_string_buffer(const std::basic_string<InCharT> &value, int32_t &written);
/**
* Put raw data to any buffer.
*
* @param data Data pointer.
* @param len Data length.
* @param written Number of characters written.
* @return Conversion result.
*/
conversion_result put_raw_data_to_buffer(void *data, size_t len, int32_t &written);
/**
* Put data from struct tm to a string buffer.
*
* @param tm_time Time.
* @param val_len Resulting string length.
* @param fmt Format for underlying strftime.
* @return Result.
*/
conversion_result put_tm_to_string(tm &tm_time, SQLLEN val_len, const char *fmt);
/**
* Get int of type T.
*
* @return Integer value of specified type.
*/
template<typename T>
T get_num() const;
/**
* Apply buffer offset to pointer.
* Adds offset to pointer if offset pointer is not null.
*
* @param ptr Pointer.
* @param elemSize Element size.
* @return Pointer with applied offset.
*/
template<typename T>
T *apply_offset(T *ptr, size_t elemSize) const;
/** Underlying data type. */
odbc_native_type m_type{odbc_native_type::AI_UNSUPPORTED};
/** Buffer pointer. */
void *m_buffer{nullptr};
/** Buffer length. */
SQLLEN m_buffer_len{0};
/** Result length. */
SQLLEN *m_result_len{nullptr};
/** Current byte offset */
int m_byte_offset{0};
/** Current element offset. */
SQLULEN m_element_offset{0};
};
/** Column binging map type alias. */
typedef std::map<std::uint16_t, application_data_buffer> column_binding_map;
} // namespace ignite