333
schangxiang@126.com
2025-09-19 18966e02fb573c7e2bb0c6426ed792b38b910940
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var QueryRunnerAlreadyReleasedError_1 = require("../../error/QueryRunnerAlreadyReleasedError");
var QueryFailedError_1 = require("../../error/QueryFailedError");
var AbstractSqliteQueryRunner_1 = require("../sqlite-abstract/AbstractSqliteQueryRunner");
var TransactionAlreadyStartedError_1 = require("../../error/TransactionAlreadyStartedError");
var TransactionNotStartedError_1 = require("../../error/TransactionNotStartedError");
var Broadcaster_1 = require("../../subscriber/Broadcaster");
/**
 * Runs queries on a single sqlite database connection.
 */
var ExpoQueryRunner = /** @class */ (function (_super) {
    tslib_1.__extends(ExpoQueryRunner, _super);
    // -------------------------------------------------------------------------
    // Constructor
    // -------------------------------------------------------------------------
    function ExpoQueryRunner(driver) {
        var _this = _super.call(this) || this;
        _this.driver = driver;
        _this.connection = driver.connection;
        _this.broadcaster = new Broadcaster_1.Broadcaster(_this);
        return _this;
    }
    /**
     * Starts transaction. Within Expo, all database operations happen in a
     * transaction context, so issuing a `BEGIN TRANSACTION` command is
     * redundant and will result in the following error:
     *
     * `Error: Error code 1: cannot start a transaction within a transaction`
     *
     * Instead, we keep track of a `Transaction` object in `this.transaction`
     * and continue using the same object until we wish to commit the
     * transaction.
     */
    ExpoQueryRunner.prototype.startTransaction = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            return tslib_1.__generator(this, function (_a) {
                if (this.isTransactionActive && typeof this.transaction !== "undefined")
                    throw new TransactionAlreadyStartedError_1.TransactionAlreadyStartedError();
                this.isTransactionActive = true;
                return [2 /*return*/];
            });
        });
    };
    /**
     * Commits transaction.
     * Error will be thrown if transaction was not started.
     * Since Expo will automatically commit the transaction once all the
     * callbacks of the transaction object have been completed, "committing" a
     * transaction in this driver's context means that we delete the transaction
     * object and set the stage for the next transaction.
     */
    ExpoQueryRunner.prototype.commitTransaction = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            return tslib_1.__generator(this, function (_a) {
                if (!this.isTransactionActive && typeof this.transaction === "undefined")
                    throw new TransactionNotStartedError_1.TransactionNotStartedError();
                this.isTransactionActive = false;
                this.transaction = undefined;
                return [2 /*return*/];
            });
        });
    };
    /**
     * Rollbacks transaction.
     * Error will be thrown if transaction was not started.
     * This method's functionality is identical to `commitTransaction()` because
     * the transaction lifecycle is handled within the Expo transaction object.
     * Issuing separate statements for `COMMIT` or `ROLLBACK` aren't necessary.
     */
    ExpoQueryRunner.prototype.rollbackTransaction = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            return tslib_1.__generator(this, function (_a) {
                if (!this.isTransactionActive && typeof this.transaction === "undefined")
                    throw new TransactionNotStartedError_1.TransactionNotStartedError();
                this.isTransactionActive = false;
                this.transaction = undefined;
                return [2 /*return*/];
            });
        });
    };
    /**
     * Executes a given SQL query.
     */
    ExpoQueryRunner.prototype.query = function (query, parameters) {
        var _this = this;
        if (this.isReleased)
            throw new QueryRunnerAlreadyReleasedError_1.QueryRunnerAlreadyReleasedError();
        return new Promise(function (ok, fail) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
            var databaseConnection, queryStartTime;
            var _this = this;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.connect()];
                    case 1:
                        databaseConnection = _a.sent();
                        this.driver.connection.logger.logQuery(query, parameters, this);
                        queryStartTime = +new Date();
                        // All Expo SQL queries are executed in a transaction context
                        databaseConnection.transaction(function (transaction) {
                            if (typeof _this.transaction === "undefined") {
                                _this.startTransaction();
                                _this.transaction = transaction;
                            }
                            _this.transaction.executeSql(query, parameters, function (t, result) {
                                // log slow queries if maxQueryExecution time is set
                                var maxQueryExecutionTime = _this.driver.connection.options.maxQueryExecutionTime;
                                var queryEndTime = +new Date();
                                var queryExecutionTime = queryEndTime - queryStartTime;
                                if (maxQueryExecutionTime && queryExecutionTime > maxQueryExecutionTime) {
                                    _this.driver.connection.logger.logQuerySlow(queryExecutionTime, query, parameters, _this);
                                }
                                // return id of inserted row, if query was insert statement.
                                if (query.substr(0, 11) === "INSERT INTO") {
                                    ok(result.insertId);
                                }
                                else {
                                    var resultSet = [];
                                    for (var i = 0; i < result.rows.length; i++) {
                                        resultSet.push(result.rows.item(i));
                                    }
                                    ok(resultSet);
                                }
                            }, function (t, err) {
                                _this.driver.connection.logger.logQueryError(err, query, parameters, _this);
                                fail(new QueryFailedError_1.QueryFailedError(query, parameters, err));
                            });
                        }, function (err) {
                            _this.rollbackTransaction();
                        }, function () {
                            _this.isTransactionActive = false;
                            _this.transaction = undefined;
                        });
                        return [2 /*return*/];
                }
            });
        }); });
    };
    return ExpoQueryRunner;
}(AbstractSqliteQueryRunner_1.AbstractSqliteQueryRunner));
exports.ExpoQueryRunner = ExpoQueryRunner;
 
//# sourceMappingURL=ExpoQueryRunner.js.map