File indexing completed on 2024-12-08 12:44:36
0001 // SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im 0002 // 0003 // SPDX-License-Identifier: BSD-2-Clause 0004 0005 /* 0006 * This example demonstrates how to use transactions with FutureSQL 0007 * For explanations of the general concepts, see the hello-world example, 0008 * which is very similar (except it doesn't use transactions, of course), 0009 * but it contains more comments. 0010 */ 0011 0012 // Qt 0013 #include <QCoreApplication> 0014 #include <QTimer> 0015 0016 // QCoro 0017 #include <QCoro/QCoroTask> 0018 #include <QCoro/QCoroFuture> 0019 0020 // FutureSQL 0021 #include <ThreadedDatabase> 0022 0023 // STL 0024 #include <tuple> 0025 0026 // Why is this function not part of the library, I hear you ask. 0027 // Currently, FutureSQL should not hard-depend on QCoro, 0028 // even though with Qt5, QCoro is the only way to use it without 0029 // hand-crafting helper functions to deal with QFutures. 0030 template <typename Func> 0031 QCoro::Task<> transaction(std::unique_ptr<ThreadedDatabase> &database, Func queryFunc) { 0032 co_await database->execute(QStringLiteral("BEGIN TRANSACTION")); 0033 co_await queryFunc(); 0034 co_await database->execute(QStringLiteral("COMMIT")); 0035 } 0036 0037 struct HelloWorld { 0038 using ColumnTypes = std::tuple<int, QString>; 0039 0040 // attributes 0041 int id; 0042 QString data; 0043 }; 0044 0045 QCoro::Task<> databaseExample() { 0046 // This object contains the database configuration, 0047 // in this case just the path to the SQLite file, and the database type (SQLite). 0048 DatabaseConfiguration config; 0049 config.setDatabaseName(QStringLiteral("database.sqlite")); 0050 config.setType(DatabaseType::SQLite); 0051 0052 // Here we open the database file, and get a handle to the database. 0053 auto database = ThreadedDatabase::establishConnection(config); 0054 0055 // Run the following steps in a transaction 0056 co_await transaction(database, [&database]() -> QCoro::Task<> { 0057 // Create the table 0058 co_await database->execute(QStringLiteral("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT)")); 0059 0060 // Insert some initial data 0061 co_await database->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("Hello World")); 0062 }); 0063 0064 // Retrieve some data from the database. 0065 // The data is directly returned as our HelloWorld struct. 0066 auto results = co_await database->getResults<HelloWorld>(QStringLiteral("SELECT * FROM test")); 0067 0068 // Print out the data in the result list 0069 for (const auto &result : results) { 0070 qDebug() << result.id << result.data; 0071 } 0072 0073 // Quit the event loop as we are done 0074 QCoreApplication::instance()->quit(); 0075 } 0076 0077 // Just a minimal main function for QCoro, to start the Qt event loop. 0078 int main(int argc, char *argv[]) { 0079 QCoreApplication app(argc, argv); 0080 QTimer::singleShot(0, databaseExample); 0081 return app.exec(); 0082 }