3#include <knowCore/Array.h>
4#include <knowCore/BigNumber.h>
5#include <knowCore/Vector.h>
8#include <QJsonDocument>
12#include "postgresql_p.h"
14#include "BinaryInterface_traits_p.h"
16namespace kDB::Repository::DatabaseInterface::PostgreSQL::BinaryInterface
18 template<
typename _T_>
21 static inline std::size_t do_calculate_size(
const _T_&) {
return sizeof(_T_); }
24 template<
typename _T_>
25 inline std::size_t calculate_size(
const _T_& _v)
30 template<
typename _T_>
31 inline void write(
const _T_& _value,
char* _data)
33 write_details<_T_>::do_write(_value, _data);
36 template<
typename _T_>
37 inline void write(
const _T_& _value, QByteArray* _array)
39 _array->resize(calculate_size<_T_>(_value));
40 write(_value, _array->data());
42 template<
typename _T_>
43 inline QByteArray write(_T_ _value) Q_REQUIRED_RESULT;
44 template<
typename _T_>
45 inline QByteArray write(_T_ _value)
48 write<_T_>(_value, &r);
53 inline void write<qint64>(
const qint64& _value,
char* _data)
55 qint32* h32 = (qint32*)_data;
56 qint32* l32 = (qint32*)(_data + 4);
58 *h32 = htonl(_value >> 32);
59 *l32 = htonl(_value & 0xFFFFFFFF);
62 inline void write<quint64>(
const quint64& _value,
char* _data)
64 write<qint64>(_value, _data);
67 inline void write<qint32>(
const qint32& _value,
char* _data)
69 *
reinterpret_cast<qint32*
>(_data) = htonl(_value);
72 inline void write<quint32>(
const quint32& _value,
char* _data)
74 write<qint32>(_value, _data);
77 inline void write<qint16>(
const qint16& _value,
char* _data)
79 *
reinterpret_cast<qint16*
>(_data) = htons(_value);
82 inline void write<quint16>(
const quint16& _value,
char* _data)
84 write<qint16>(_value, _data);
87 inline void write<bool>(
const bool& _value,
char* _data)
89 *_data = _value ? 1 : 0;
93 inline void write<float>(
const float& _fl,
char* data)
101 write<qint32>(swap.i, data);
104 inline void write<double>(
const double& _fl,
char* data)
112 write<qint64>(swap.i, data);
118 return calculate_size<qint64>(0);
125 qFatal(
"Unimplemented");
128 inline std::size_t calculate_size<QString>(
const QString& _v)
130 return _v.toUtf8().size();
133 inline void write<QString>(
const QString& _dt,
char* data)
135 QByteArray r = _dt.toUtf8();
136 memcpy(data, r.data(), r.size());
140 inline std::size_t calculate_size<QByteArray>(
const QByteArray& _v)
145 inline void write<QByteArray>(
const QByteArray& _dt,
char* data)
147 std::copy(_dt.begin(), _dt.end(), data);
153 write<quint16>(_number.digits().size(), data);
155 write<quint16>(_number.weight(), data);
157 quint16 sign = 0xC000;
158 switch(_number.sign())
160 case knowCore::BigNumber::Sign::Negative:
163 case knowCore::BigNumber::Sign::Positive:
166 case knowCore::BigNumber::Sign::NaN:
169 case knowCore::BigNumber::Sign::PositiveInfinite:
172 case knowCore::BigNumber::Sign::NegativeInfinite:
176 write<quint16>(sign, data);
178 write<quint16>(_number.dscale(), data);
181 for(quint16 d : _number.digits())
183 write<quint16>(d, data);
190 return (4 + _number.digits().size()) *
sizeof(quint16);
194 inline char* write_enum(
const char* enum_name,
char* data)
196 const std::size_t s = strlen(enum_name);
197 write<quint32>(s, data);
198 data +=
sizeof(quint32);
199 std::copy(enum_name, enum_name + s, data);
203 inline char* write_empty(Oid _oid,
char* data)
205 write<Oid>(_oid, data);
207 write<quint32>(0xFFFFFFFF, data);
208 data +=
sizeof(quint32);
211 template<
typename _T_>
212 inline char* write_value(Oid _oid,
const _T_& _value,
char* data)
214 std::size_t s = calculate_size<_T_>(_value);
215 write<Oid>(_oid, data);
217 write<quint32>(s, data);
218 data +=
sizeof(quint32);
219 write<_T_>(_value, data);
224 template<
typename _T_>
227 static inline std::size_t do_calculate_size(
const QList<_T_>& _val)
229 std::size_t s = 4 * 5;
230 for(
const _T_& t : _val)
232 s += 4 + calculate_size<_T_>(t);
236 static inline void do_write(
const QList<_T_>& _value,
char* data)
238 write<quint32>(1, data);
241 write<quint32>(0, data);
246 write<quint32>(_value.size(), data);
248 write<quint32>(0, data);
251 for(
int i = 0; i < _value.size(); ++i)
253 const _T_& val = _value[i];
254 std::size_t s = calculate_size<_T_>(val);
255 write<quint32>(s, data);
257 write<_T_>(val, data);
262 template<
typename _T_, std::
size_t _dimension>
267 return 4 * 5 + _dimension * (4 + calculate_size<_T_>(_val[0]));
271 write<QList<_T_>>(_value, data);
275 template<
typename _T_, std::
size_t _dimension>
278 static inline std::size_t
281 std::size_t s = 4 * 7;
284 for(std::size_t j = 0; j < _dimension; ++j)
286 s += 4 + calculate_size<_T_>(t[j]);
293 write<quint32>(2, data);
296 write<quint32>(0, data);
301 write<quint32>(_value.size(), data);
303 write<quint32>(0, data);
305 write<quint32>(_dimension, data);
307 write<quint32>(0, data);
310 for(
int i = 0; i < _value.size(); ++i)
313 for(std::size_t j = 0; j < _dimension; ++j)
315 std::size_t s = calculate_size<_T_>(v[j]);
316 write<quint32>(s, data);
318 write<_T_>(v[j], data);
324 template<
typename _T_>
329 std::size_t s = 4 * (3 + 2 * _val.dimensions().size());
330 for(
const _T_& t : _val.data())
332 s += 4 + calculate_size<_T_>(t);
338 write<quint32>(_value.dimensions().size(), data);
341 write<quint32>(0, data);
346 for(
int d : _value.dimensions())
348 write<quint32>(d, data);
350 write<quint32>(0, data);
354 for(
const _T_& val : _value.data())
356 std::size_t s = calculate_size<_T_>(val);
357 write<quint32>(s, data);
359 write<_T_>(val, data);
367 inline void write<QJsonDocument>(
const QJsonDocument& _document, QByteArray* _array)
369 write(_document.toJson(QJsonDocument::Compact), _array);
372 inline void write<QJsonArray>(
const QJsonArray& _value, QByteArray* _array)
375 doc.setArray(_value);
379 inline void write<QJsonObject>(
const QJsonObject& _value, QByteArray* _array)
382 doc.setObject(_value);
386 inline void write<QJsonValue>(
const QJsonValue& _value, QByteArray* _array)
388 switch(_value.type())
390 case QJsonValue::Null:
391 case QJsonValue::Undefined:
392 *_array = QByteArray();
394 case QJsonValue::Bool:
395 case QJsonValue::Double:
396 case QJsonValue::String:
397 clog_fatal(
"Invalid type of QJsonValue: {}", _value);
398 case QJsonValue::Array:
399 write(_value.toArray(), _array);
401 case QJsonValue::Object:
402 write(_value.toObject(), _array);
409 template<
int _N_,
typename... T>
412 static int do_calculate_size(
const std::tuple<T...>& data)
415 + calculate_size(std::get<
sizeof...(T) - _N_>(data)) + 4 + 4 ;
417 static void do_write(
const std::tuple<T...>& data,
char* ptr)
419 auto v = std::get<
sizeof...(T) - _N_>(data);
420 std::size_t s = calculate_size(v);
421 write(
traits<
decltype(v)>::oid(), ptr);
430 template<
typename... T>
433 static int do_calculate_size(std::tuple<T...> data)
438 static void do_write(
const std::tuple<T...>& data,
char* ptr)
446 template<
typename... T>
449 struct_writer(Oid oid, T... _t) : m_data(_t...), m_oid(oid) {}
450 int calculate_size()
const
454 void write(
char* ptr)
const
456 BinaryInterface::write<quint32>(
sizeof...(T), ptr);
460 Oid oid()
const {
return m_oid; }
462 std::tuple<T...> m_data;
466 template<
typename... T>
471 return _t.calculate_size();
Class that can contains large numeric value.
Definition BigNumber.h:51
Definition Timestamp.h:39
Definition BinaryInterface_write_p.h:411
Definition BinaryInterface_write_p.h:448
Definition BinaryInterface_traits_p.h:4
Definition BinaryInterface_write_p.h:20