File: transaction.cpp

package info (click to toggle)
futuresql 0.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 288 kB
  • sloc: cpp: 704; makefile: 5; sql: 4
file content (82 lines) | stat: -rw-r--r-- 2,742 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// SPDX-FileCopyrightText: 2022 Jonah BrĂ¼chert <jbb@kaidan.im
//
// SPDX-License-Identifier: BSD-2-Clause

/*
 * This example demonstrates how to use transactions with FutureSQL
 * For explanations of the general concepts, see the hello-world example,
 * which is very similar (except it doesn't use transactions, of course),
 * but it contains more comments.
 */

// Qt
#include <QCoreApplication>
#include <QTimer>

// QCoro
#include <QCoro/QCoroTask>
#include <QCoro/QCoroFuture>

// FutureSQL
#include <ThreadedDatabase>

// STL
#include <tuple>

// Why is this function not part of the library, I hear you ask.
// Currently, FutureSQL should not hard-depend on QCoro,
// even though with Qt5, QCoro is the only way to use it without
// hand-crafting helper functions to deal with QFutures.
template <typename Func>
QCoro::Task<> transaction(std::unique_ptr<ThreadedDatabase> &database, Func queryFunc) {
    co_await database->execute(QStringLiteral("BEGIN TRANSACTION"));
    co_await queryFunc();
    co_await database->execute(QStringLiteral("COMMIT"));
}

struct HelloWorld {
    using ColumnTypes = std::tuple<int, QString>;

    // attributes
    int id;
    QString data;
};

QCoro::Task<> databaseExample() {
    // This object contains the database configuration,
    // in this case just the path to the SQLite file, and the database type (SQLite).
    DatabaseConfiguration config;
    config.setDatabaseName(QStringLiteral("database.sqlite"));
    config.setType(DatabaseType::SQLite);

    // Here we open the database file, and get a handle to the database.
    auto database = ThreadedDatabase::establishConnection(config);

    // Run the following steps in a transaction
    co_await transaction(database, [&database]() -> QCoro::Task<> {
        // Create the table
        co_await database->execute(QStringLiteral("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT)"));

        // Insert some initial data
        co_await database->execute(QStringLiteral("INSERT INTO test (data) VALUES (?)"), QStringLiteral("Hello World"));
    });

    // Retrieve some data from the database.
    // The data is directly returned as our HelloWorld struct.
    auto results = co_await database->getResults<HelloWorld>(QStringLiteral("SELECT * FROM test"));

    // Print out the data in the result list
    for (const auto &result : results) {
        qDebug() << result.id << result.data;
    }

    // Quit the event loop as we are done
    QCoreApplication::instance()->quit();
}

// Just a minimal main function for QCoro, to start the Qt event loop.
int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);
    QTimer::singleShot(0, databaseExample);
    return app.exec();
}