1#include <knowCore/BigNumber.h>
2#include <knowCore/Array.h>
3#include <knowCore/Vector.h>
6#include <QJsonDocument>
10#include "postgresql_p.h"
12#include "BinaryInterface_traits_p.h"
14namespace kDB::Repository::DatabaseInterface::PostgreSQL::BinaryInterface
16 template<
typename _T_>
19 static inline std::size_t do_calculate_size(
const _T_&)
25 template<
typename _T_>
26 inline std::size_t calculate_size(
const _T_& _v)
31 template<
typename _T_>
32 inline void write(
const _T_& _value,
char* _data)
34 write_details<_T_>::do_write(_value, _data);
37 template<
typename _T_>
38 inline void write(
const _T_& _value, QByteArray* _array)
40 _array->resize(calculate_size<_T_>(_value));
41 write(_value, _array->data());
43 template<
typename _T_>
44 inline QByteArray write(_T_ _value) Q_REQUIRED_RESULT;
45 template<
typename _T_>
46 inline QByteArray write(_T_ _value)
49 write<_T_>(_value, &r);
54 inline void write<qint64>(
const qint64& _value,
char* _data)
56 qint32* h32 = (qint32*)_data;
57 qint32* l32 = (qint32*)(_data+4);
59 *h32 = htonl(_value >> 32);
60 *l32 = htonl(_value & 0xFFFFFFFF);
63 inline void write<quint64>(
const quint64& _value,
char* _data)
65 write<qint64>(_value, _data);
68 inline void write<qint32>(
const qint32& _value,
char* _data)
70 *
reinterpret_cast<qint32*
>(_data) = htonl(_value);
73 inline void write<quint32>(
const quint32& _value,
char* _data)
75 write<qint32>(_value, _data);
78 inline void write<qint16>(
const qint16& _value,
char* _data)
80 *
reinterpret_cast<qint16*
>(_data) = htons(_value);
83 inline void write<quint16>(
const quint16& _value,
char* _data)
85 write<qint16>(_value, _data);
88 inline void write<bool>(
const bool& _value,
char* _data)
90 *_data = _value ? 1 : 0;
94 inline void write<float>(
const float& _fl,
char* data)
96 union {
float f; qint32 i; } swap;
98 write<qint32>(swap.i, data);
101 inline void write<double>(
const double& _fl,
char* data)
103 union {
double f; qint64 i; } swap;
105 write<qint64>(swap.i, data);
111 return calculate_size<qint64>(0);
118 qFatal(
"Unimplemented");
121 inline std::size_t calculate_size<QString>(
const QString& _v)
123 return _v.toUtf8().size();
126 inline void write<QString>(
const QString& _dt,
char* data)
128 QByteArray r = _dt.toUtf8();
129 memcpy(data, r.data(), r.size());
133 inline std::size_t calculate_size<QStringList>(
const QStringList& _v)
135 return calculate_size<QList<QString>>(_v);
138 inline void write<QStringList>(
const QStringList& _dt,
char* data)
140 write<QList<QString>>(_dt, data);
144 inline std::size_t calculate_size<QByteArray>(
const QByteArray& _v)
149 inline void write<QByteArray>(
const QByteArray& _dt,
char* data)
151 std::copy(_dt.begin(), _dt.end(), data);
157 write<quint16>(_number.digits().size(), data); data += 2;
158 write<quint16>(_number.weight(), data); data += 2;
159 quint16 sign = 0xC000;
160 switch(_number.sign())
162 case knowCore::BigNumber::Sign::Negative:
165 case knowCore::BigNumber::Sign::Positive:
168 case knowCore::BigNumber::Sign::NaN:
171 case knowCore::BigNumber::Sign::PositiveInfinite:
174 case knowCore::BigNumber::Sign::NegativeInfinite:
178 write<quint16>(sign, data); data += 2;
179 write<quint16>(_number.dscale(), data); data += 2;
181 for(quint16 d : _number.digits())
183 write<quint16>(d, data);
190 return (4 + _number.digits().size())*
sizeof(quint16);
193 inline char* write_enum(
const char* enum_name,
char* data)
195 const std::size_t s = strlen(enum_name);
196 write<quint32>(s, data); data +=
sizeof(quint32);
197 std::copy(enum_name, enum_name + s, data); data += s;
200 inline char* write_empty(Oid _oid,
char* data)
202 write<Oid>(_oid, data); data +=
sizeof(Oid);
203 write<quint32>(0xFFFFFFFF, data); data +=
sizeof(quint32);
206 template<
typename _T_>
207 inline char* write_value(Oid _oid,
const _T_& _value,
char* data)
209 std::size_t s = calculate_size<_T_>(_value);
210 write<Oid>(_oid, data); data +=
sizeof(Oid);
211 write<quint32>(s, data); data +=
sizeof(quint32);
212 write<_T_>(_value, data); data += s;
216 template<
typename _T_>
219 static inline std::size_t do_calculate_size(
const QList<_T_>& _val)
221 std::size_t s = 4 * 5;
222 for(
const _T_& t : _val)
224 s += 4 + calculate_size<_T_>(t);
228 static inline void do_write(
const QList<_T_>& _value,
char* data)
230 write<quint32>(1, data); data += 4;
232 write<quint32>(0, data); data += 4;
235 write<quint32>(_value.size(), data); data += 4;
236 write<quint32>(0, data); data += 4;
238 for(
int i = 0; i < _value.size(); ++i)
240 const _T_& val = _value[i];
241 std::size_t s = calculate_size<_T_>(val);
242 write<quint32>(s, data); data += 4;
243 write<_T_>(val, data);
248 template<
typename _T_, std::
size_t _dimension>
253 return 4 * 5 + _dimension * (4 + calculate_size<_T_>(_val[0]));
257 write<QList<_T_>>(_value, data);
261 template<
typename _T_, std::
size_t _dimension>
266 std::size_t s = 4 * 7;
269 for(std::size_t j = 0; j < _dimension; ++j)
271 s += 4 + calculate_size<_T_>(t[j]);
278 write<quint32>(2, data); data += 4;
280 write<quint32>(0, data); data += 4;
283 write<quint32>(_value.size(), data); data += 4;
284 write<quint32>(0, data); data += 4;
285 write<quint32>(_dimension, data); data += 4;
286 write<quint32>(0, data); data += 4;
288 for(
int i = 0; i < _value.size(); ++i)
291 for(std::size_t j = 0; j < _dimension; ++j)
293 std::size_t s = calculate_size<_T_>(v[j]);
294 write<quint32>(s, data); data += 4;
295 write<_T_>(v[j], data);
301 template<
typename _T_>
306 std::size_t s = 4 * (3 + 2 * _val.dimensions().size());
307 for(
const _T_& t : _val.data())
309 s += 4 + calculate_size<_T_>(t);
315 write<quint32>(_value.dimensions().size(), data); data += 4;
317 write<quint32>(0, data); data += 4;
320 for(
int d : _value.dimensions())
322 write<quint32>(d, data); data += 4;
323 write<quint32>(0, data); data += 4;
326 for(
const _T_& val : _value.data())
328 std::size_t s = calculate_size<_T_>(val);
329 write<quint32>(s, data); data += 4;
330 write<_T_>(val, data);
338 inline void write<QJsonDocument>(
const QJsonDocument& _document, QByteArray* _array)
340 write(_document.toJson(QJsonDocument::Compact), _array);
343 inline void write<QJsonArray>(
const QJsonArray& _value, QByteArray* _array)
346 doc.setArray(_value);
350 inline void write<QJsonObject>(
const QJsonObject& _value, QByteArray* _array)
353 doc.setObject(_value);
357 inline void write<QJsonValue>(
const QJsonValue& _value, QByteArray* _array)
359 switch(_value.type())
361 case QJsonValue::Null:
362 case QJsonValue::Undefined:
363 *_array = QByteArray();
365 case QJsonValue::Bool:
366 case QJsonValue::Double:
367 case QJsonValue::String:
368 KNOWCORE_LOG_FATAL(
"Invalid type of QJsonValue: {}", _value);
369 case QJsonValue::Array:
370 write(_value.toArray(), _array);
372 case QJsonValue::Object:
373 write(_value.toObject(), _array);
380 template<
int _N_,
typename... T>
383 static int do_calculate_size(
const std::tuple<T...>& data)
387 static void do_write(
const std::tuple<T...>& data,
char *ptr)
389 auto v = std::get<
sizeof...(T) - _N_>(data);
390 std::size_t s = calculate_size(v);
391 write(
traits<
decltype(v)>::oid(), ptr);
400 template<
typename... T>
403 static int do_calculate_size(std::tuple<T...> data)
408 static void do_write(
const std::tuple<T...>& data,
char *ptr)
416 template<
typename... T>
419 struct_writer(Oid oid, T... _t) : m_data(_t...), m_oid(oid) {}
420 int calculate_size()
const
424 void write(
char* ptr)
const
426 BinaryInterface::write<quint32>(
sizeof...(T), ptr); ptr += 4;
434 std::tuple<T...> m_data;
438 template<
typename... T>
443 return _t.calculate_size();
Class that can contains large numeric value.
Definition BigNumber.h:51
Definition Timestamp.h:39
Definition BinaryInterface_write_p.h:382
Definition BinaryInterface_write_p.h:418
Definition BinaryInterface_traits_p.h:4
Definition BinaryInterface_write_p.h:18