Skip to content

Commit 6ce6399

Browse files
Merge pull request #391 from treefrogframework/preparedstatement
Support prepared statements for PostgreSQL and MySQL
2 parents 7358747 + 30b190f commit 6ce6399

File tree

9 files changed

+326
-72
lines changed

9 files changed

+326
-72
lines changed

src/tsqldatabase.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,11 @@ TSqlDatabase::DbmsType TSqlDatabase::dbmsType() const
8585

8686
void TSqlDatabase::setDriverExtension(TSqlDriverExtension *extension)
8787
{
88-
Q_ASSERT(!_driverExtension);
8988
_driverExtension = extension;
9089
}
9190

9291

93-
const TSqlDatabase &TSqlDatabase::database(const QString &connectionName)
92+
TSqlDatabase &TSqlDatabase::database(const QString &connectionName)
9493
{
9594
static TSqlDatabase defaultDatabase;
9695
auto *dict = dbDict();
@@ -140,3 +139,9 @@ bool TSqlDatabase::isUpsertSupported() const
140139
{
141140
return _driverExtension && _driverExtension->isUpsertSupported();
142141
}
142+
143+
144+
bool TSqlDatabase::isPreparedStatementSupported() const
145+
{
146+
return _driverExtension && _driverExtension->isPreparedStatementSupported();
147+
}

src/tsqldatabase.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,25 @@ class T_CORE_EXPORT TSqlDatabase {
5050
bool isUpsertEnabled() const { return _enableUpsert; }
5151
void setUpsertEnabled(bool enable) { _enableUpsert = enable; }
5252
bool isUpsertSupported() const;
53+
bool isPreparedStatementSupported() const;
5354
const TSqlDriverExtension *driverExtension() const { return _driverExtension; }
54-
void setDriverExtension(TSqlDriverExtension *extension);
5555

5656
static const char *const defaultConnection;
57-
static const TSqlDatabase &database(const QString &connectionName = QLatin1String(defaultConnection));
57+
static TSqlDatabase &database(const QString &connectionName = QLatin1String(defaultConnection));
5858
static TSqlDatabase &addDatabase(const QString &driver, const QString &connectionName = QLatin1String(defaultConnection));
5959
static void removeDatabase(const QString &connectionName = QLatin1String(defaultConnection));
6060
static bool contains(const QString &connectionName = QLatin1String(defaultConnection));
6161

6262
private:
63+
TSqlDriverExtension *driverExtension() { return _driverExtension; }
64+
void setDriverExtension(TSqlDriverExtension *extension);
65+
6366
QSqlDatabase _sqlDatabase;
6467
QStringList _postOpenStatements;
6568
bool _enableUpsert {false};
6669
TSqlDriverExtension *_driverExtension {nullptr};
70+
71+
friend class TSqlDatabasePool;
6772
};
6873

6974

src/tsqldatabasepool.cpp

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ TSqlDatabasePool::~TSqlDatabasePool()
5050
QString name;
5151
while (!cache.isEmpty()) {
5252
name = cache.pop();
53-
QSqlDatabase db = TSqlDatabase::database(name).sqlDatabase();
54-
db.close();
53+
auto &db = TSqlDatabase::database(name);
54+
closeDatabase(db);
5555
TSqlDatabase::removeDatabase(name);
5656
}
5757

@@ -90,7 +90,6 @@ void TSqlDatabasePool::init()
9090

9191
QMutexLocker locker(&_mutex);
9292

93-
9493
cachedDatabase = new QStack<QString>[Tf::app()->sqlDatabaseSettingsCount()];
9594
lastCachedTime = new TAtomic<uint>[Tf::app()->sqlDatabaseSettingsCount()];
9695
availableNames = new QStack<QString>[Tf::app()->sqlDatabaseSettingsCount()];
@@ -129,7 +128,6 @@ void TSqlDatabasePool::init()
129128
QSqlDatabase TSqlDatabasePool::database(int databaseId)
130129
{
131130
QMutexLocker locker(&_mutex);
132-
TSqlDatabase tdb;
133131

134132
if (Q_LIKELY(databaseId >= 0 && databaseId < Tf::app()->sqlDatabaseSettingsCount())) {
135133
auto &cache = cachedDatabase[databaseId];
@@ -139,7 +137,7 @@ QSqlDatabase TSqlDatabasePool::database(int databaseId)
139137
QString name;
140138
if (!cache.isEmpty()) {
141139
name = cache.pop();
142-
tdb = TSqlDatabase::database(name);
140+
const auto &tdb = TSqlDatabase::database(name);
143141
if (Q_LIKELY(tdb.sqlDatabase().isOpen())) {
144142
tSystemDebug("Gets cached database: %s", qUtf8Printable(tdb.connectionName()));
145143
return tdb.sqlDatabase();
@@ -152,8 +150,8 @@ QSqlDatabase TSqlDatabasePool::database(int databaseId)
152150

153151
if (Q_LIKELY(!stack.isEmpty())) {
154152
name = stack.pop();
155-
auto tdb = TSqlDatabase::database(name);
156-
if (Q_UNLIKELY(!tdb.sqlDatabase().open())) {
153+
auto &tdb = TSqlDatabase::database(name);
154+
if (Q_UNLIKELY(!openDatabase(tdb))) {
157155
tError("Database open error. Invalid database settings, or maximum number of SQL connection exceeded.");
158156
tSystemError("SQL database open error: %s", qUtf8Printable(tdb.sqlDatabase().connectionName()));
159157
stack.push(name);
@@ -241,9 +239,6 @@ bool TSqlDatabasePool::setDatabaseSettings(TSqlDatabase &database, int databaseI
241239
tSystemDebug("Database enableUpsert: %d", enableUpsert);
242240
database.setUpsertEnabled(enableUpsert);
243241

244-
auto *extension = TSqlDriverExtensionFactory::create(database.sqlDatabase().driverName(), database.sqlDatabase().driver());
245-
database.setDriverExtension(extension);
246-
247242
return true;
248243
}
249244

@@ -258,7 +253,8 @@ void TSqlDatabasePool::pool(QSqlDatabase &database, bool forceClose)
258253
if (databaseId >= 0 && databaseId < Tf::app()->sqlDatabaseSettingsCount()) {
259254
if (forceClose) {
260255
tSystemWarn("Force close database: %s", qUtf8Printable(database.connectionName()));
261-
closeDatabase(database);
256+
TSqlDatabase &db = TSqlDatabase::database(database.connectionName());
257+
closeDatabase(db);
262258
} else {
263259
if (database.isOpen()) {
264260
// pool
@@ -294,7 +290,7 @@ void TSqlDatabasePool::timerEvent(QTimerEvent *event)
294290
while (lastCachedTime[i].load() < (uint)std::time(nullptr) - 30
295291
&& !cache.isEmpty()) {
296292
name = cache.pop();
297-
QSqlDatabase db = TSqlDatabase::database(name).sqlDatabase();
293+
TSqlDatabase &db = TSqlDatabase::database(name);
298294
closeDatabase(db);
299295
}
300296
}
@@ -304,13 +300,39 @@ void TSqlDatabasePool::timerEvent(QTimerEvent *event)
304300
}
305301

306302

307-
void TSqlDatabasePool::closeDatabase(QSqlDatabase &database)
303+
bool TSqlDatabasePool::openDatabase(TSqlDatabase &database)
304+
{
305+
bool ret = database.sqlDatabase().open();
306+
307+
if (ret) {
308+
TSqlDriverExtension *extension = database.driverExtension();
309+
if (extension) {
310+
TSqlDriverExtensionFactory::destroy(database.sqlDatabase().driverName(), extension);
311+
}
312+
313+
extension = TSqlDriverExtensionFactory::create(database.sqlDatabase().driverName(), database.sqlDatabase().driver());
314+
database.setDriverExtension(extension);
315+
}
316+
317+
return ret;
318+
}
319+
320+
321+
void TSqlDatabasePool::closeDatabase(TSqlDatabase &database)
308322
{
309323
QMutexLocker locker(&_mutex);
310324

311-
int id = getDatabaseId(database);
312-
QString name = database.connectionName();
313-
database.close();
325+
QSqlDatabase db = database.sqlDatabase();
326+
int id = getDatabaseId(db);
327+
QString name = db.connectionName();
328+
db.close();
329+
330+
TSqlDriverExtension *extension = database.driverExtension();
331+
if (extension) {
332+
TSqlDriverExtensionFactory::destroy(database.sqlDatabase().driverName(), extension);
333+
}
334+
database.setDriverExtension(nullptr);
335+
314336
tSystemDebug("Closed database connection, name: %s", qUtf8Printable(name));
315337
availableNames[id].push(name);
316338
}

src/tsqldatabasepool.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class T_CORE_EXPORT TSqlDatabasePool : public QObject {
2626
protected:
2727
void init();
2828
void timerEvent(QTimerEvent *event);
29-
void closeDatabase(QSqlDatabase &database);
3029

3130
private:
31+
bool openDatabase(TSqlDatabase &database);
32+
void closeDatabase(TSqlDatabase &database);
3233
TSqlDatabasePool();
3334

3435
#if QT_VERSION < 0x060000

src/tsqldriverextension.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class T_CORE_EXPORT TSqlDriverExtension {
1212
virtual bool isUpsertSupported() const { return false; }
1313
virtual QString upsertStatement(const QString &tableName, const QSqlRecord &recordToInsert,
1414
const QSqlRecord &recordToUpdate, const QString &pkField, const QString &lockRevisionField) const;
15+
virtual bool isPreparedStatementSupported() const { return false; }
16+
virtual QString prepareStatement(const QString &) const { return QString(); }
17+
virtual QString executeStatement(const QVariantList &) const { return QString(); }
1518
};
1619

1720

0 commit comments

Comments
 (0)