5#ifndef QSQL_FIREBIRD_HELPERS_P_H
6#define QSQL_FIREBIRD_HELPERS_P_H
19#include <QtCore/qbytearray.h>
20#include <QtCore/qdatetime.h>
21#include <QtCore/qloggingcategory.h>
22#include <QtCore/qmetatype.h>
23#include <QtCore/qvariant.h>
24#include <QtSql/qtsqlglobal.h>
25#include <QtSql/qsqlerror.h>
28#include <firebird/Interface.h>
34Q_DECLARE_LOGGING_CATEGORY(lcFirebird)
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
54template <
typename T>
static void fbRelease(T *h) { h->release(); }
55template <
typename T>
static void fbDispose(T *h) { h->dispose(); }
61 using FreeFn =
void (*)(T *);
63
64
65
66 Q_NODISCARD_CTOR FbGuard(T *handle, FreeFn freeFn) : m_handle(handle), m_free(freeFn) {}
67 ~FbGuard() {
if (m_handle) m_free(m_handle); }
69
70
71
72 FbGuard(
const FbGuard &) =
delete;
73 FbGuard &operator=(
const FbGuard &) =
delete;
75 T *get()
const {
return m_handle; }
76 T *operator->()
const {
return m_handle; }
77 explicit operator
bool()
const {
return m_handle !=
nullptr; }
80 T *take() { T *h = m_handle; m_handle =
nullptr;
return h; }
81 void dismiss() { m_handle =
nullptr; }
84
85
86
87
88
89 template <
typename CloseFn>
90 void closeWith(CloseFn closeFn,
bool rethrow =
true)
118 QSqlError::ErrorType type);
136 Firebird::ITransaction *&tr,
TxnEnd end);
138 Firebird::ThrowStatusWrapper &st,
145void encodeTextValue(
char *data,
int fbType, qsizetype length,
const QByteArray &bytes);
153
154
155
160 return QString::number(
static_cast<qint64>(val));
163 return QString::number(
static_cast<qint64>(val)) + QString(scale, u'0');
165 const bool negative = val < 0;
166 QString number = QString::number(negative ? -
static_cast<qint64>(val)
167 :
static_cast<qint64>(val));
168 const int absScale = -scale;
169 if (absScale >= number.size())
170 number = QString(absScale - number.size() + 1, u'0') + number;
171 const int sepPos = number.size() - absScale;
172 number = number.left(sepPos) + u'.' + number.mid(sepPos);
174 number = u'-' + number;
184 return QVariant(
static_cast<qint64>(val));
186 case QSql::LowPrecisionInt32:
187 case QSql::LowPrecisionInt64: {
189
190
191 const qint64 iv =
static_cast<qint64>(val);
192 const qint64 scaled = scale < 0 ? iv / pow10i(-scale) : iv * pow10i(scale);
193 return policy == QSql::LowPrecisionInt32 ? QVariant(
static_cast<qint32>(scaled))
196 case QSql::LowPrecisionDouble:
197 return QVariant(
static_cast<
double>(val) *
std::pow(10.0, scale));
198 case QSql::HighPrecision:
199 return QVariant(numberToHighPrecision(val, scale));
201 return QVariant(
static_cast<
double>(val) *
std::pow(10.0, scale));
209
210
211
212
213
214
215
219 const FB_I128 *value,
int scale);
222
223
224
225template <
typename Iface,
typename Raw>
229 iface->toString(&st, value,
sizeof(buf), buf);
230 return QString::fromLatin1(buf);
233template <
typename Iface,
typename Raw>
235 const QByteArray &s, Raw *out)
237 iface->fromString(&st, s.constData(), out);
246 const QDateTime &dt);
248 const QDateTime &dt);
253 const ISC_TIMESTAMP_TZ &tstz);
255 const ISC_TIME_TZ &ttz);
void setError(const QString &msg, QSqlError::ErrorType type, const QString &code={})
QHash< QString, QFirebirdEventSubscription * > eventSubscriptions
Firebird::ITransaction * iTrans
Firebird::IAttachment * iAtt
Firebird::IStatus * iStatus
QList< QFirebirdResultPrivate * > activeResults
bool finishTransaction(TxnEnd end)
bool cacheScrollableResults
void setFbError(const QString &context, QSqlError::ErrorType type=QSqlError::UnknownError)
bool commitTransaction() override
This function is called to commit a transaction.
QSqlResult * createResult() const override
Creates an empty SQL result on the database.
bool cancelQuery() override
bool hasFeature(DriverFeature feature) const override
Returns true if the driver supports feature feature; otherwise returns false.
QString escapeIdentifier(const QString &identifier, IdentifierType type) const override
Returns the identifier escaped according to the database rules.
QSqlRecord record(const QString &tableName) const override
Returns a QSqlRecord populated with the names of the fields in table tableName.
QFirebirdDriver(QObject *parent=nullptr)
bool rollbackTransaction() override
This function is called to rollback a transaction.
QSqlIndex primaryIndex(const QString &tableName) const override
Returns the primary index for table tableName.
int maximumIdentifierLength(IdentifierType type) const override
QVariant handle() const override
Returns the low-level database handle wrapped in a QVariant or an invalid variant if there is no hand...
bool open(const QString &db, const QString &user, const QString &password, const QString &host, int port, const QString &connOpts) override
Derived classes must reimplement this pure virtual function to open a database connection on database...
QStringList subscribedToNotifications() const override
Returns a list of the names of the event notifications that are currently subscribed to.
bool unsubscribeFromNotification(const QString &name) override
This function is called to unsubscribe from event notifications from the database.
QString formatValue(const QSqlField &field, bool trimStrings) const override
Returns a string representation of the field value for the database.
bool beginTransaction() override
This function is called to begin a transaction.
bool subscribeToNotification(const QString &name) override
This function is called to subscribe to event notifications from the database.
~QFirebirdDriver() override
void close() override
Derived classes must reimplement this pure virtual function in order to close the database connection...
void eventCallbackFunction(unsigned length, const unsigned char *data) override
std::atomic< int > counter
QFirebirdEventSubscription(QFirebirdDriver *drv, IAttachment *att, const QString &eventName)
QFirebirdResult(const QFirebirdDriver *driver)
QDateTime decodeFirebirdTimestamp(Firebird::IUtil *util, const ISC_TIMESTAMP &ts)
QString fbErrorLog(const QSqlError &err)
static void decFloatFromString(Iface *iface, Firebird::ThrowStatusWrapper &st, const QByteArray &s, Raw *out)
Firebird::ITransaction * startDefaultTransaction(Firebird::IAttachment *att, Firebird::ThrowStatusWrapper &st, TxnWait wait)
QString fbErrorString(Firebird::IMaster *master, Firebird::IStatus *status)
bool decimalToScaledInt64(const QByteArray &decimal, int scale, qint64 *out)
ISC_TIMESTAMP encodeQDateTime(Firebird::IUtil *util, const QDateTime &dt)
ISC_TIME encodeQTime(Firebird::IUtil *util, const QTime &t)
QDate decodeFirebirdDate(Firebird::IUtil *util, ISC_DATE date)
static QVariant applyScale(T val, int scale, QSql::NumericalPrecisionPolicy policy)
QDateTime decodeFirebirdTimeTz(Firebird::IStatus *iStatus, Firebird::IUtil *util, const ISC_TIME_TZ &ttz)
void encodeTextValue(char *data, int fbType, qsizetype length, const QByteArray &bytes)
void finishAndClear(Firebird::ThrowStatusWrapper &st, Firebird::ITransaction *&tr, TxnEnd end)
QDateTime decodeFirebirdTimestampTz(Firebird::IStatus *iStatus, Firebird::IUtil *util, const ISC_TIMESTAMP_TZ &tstz)
QByteArray numericInputString(const QVariant &val)
QMetaType::Type blrTypeToQt(unsigned char blrType, bool hasScale)
QTime decodeFirebirdTime(Firebird::IUtil *util, ISC_TIME time)
ISC_TIMESTAMP_TZ encodeQDateTimeTz(Firebird::IStatus *iStatus, Firebird::IUtil *util, const QDateTime &dt)
static QString decFloatToString(Iface *iface, Firebird::ThrowStatusWrapper &st, const Raw *value)
ISC_TIME_TZ encodeQTimeTz(Firebird::IStatus *iStatus, Firebird::IUtil *util, const QDateTime &dt)
QString int128ToString(Firebird::IUtil *util, Firebird::ThrowStatusWrapper &st, const FB_I128 *value, int scale)
QSqlError fbError(Firebird::IMaster *master, Firebird::IStatus *status, QSqlError::ErrorType type)
ISC_DATE encodeQDate(Firebird::IUtil *util, const QDate &d)
QMetaType::Type fbTypeToQt(int fbType, int scale)
static QString numberToHighPrecision(T val, int scale)