Skip to content

Commit

Permalink
added sqlitebusy handling logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Umed Khudoiberdiev authored and imnotjames committed Aug 19, 2020
1 parent c96ab43 commit a9d8b0b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
13 changes: 12 additions & 1 deletion src/driver/sqlite/SqliteConnectionOptions.ts
Expand Up @@ -20,4 +20,15 @@ export interface SqliteConnectionOptions extends BaseConnectionOptions {
*/
readonly key?: string;

}
/**
* In your SQLite application when you perform parallel writes its common to face SQLITE_BUSY error.
* This error indicates that SQLite failed to write to the database file since someone else already writes into it.
* Since SQLite cannot handle parallel saves this error cannot be avoided.
*
* To simplify life's of those who have this error this particular option sets a timeout within which ORM will try
* to perform requested write operation again and again until it recieves SQLITE_BUSY error.
*
* Time in milliseconds.
*/
readonly busyErrorRetry?: number;
}
34 changes: 25 additions & 9 deletions src/driver/sqlite/SqliteQueryRunner.ts
@@ -1,6 +1,7 @@
import {QueryRunnerAlreadyReleasedError} from "../../error/QueryRunnerAlreadyReleasedError";
import {QueryFailedError} from "../../error/QueryFailedError";
import {AbstractSqliteQueryRunner} from "../sqlite-abstract/AbstractSqliteQueryRunner";
import {SqliteConnectionOptions} from "./SqliteConnectionOptions";
import {SqliteDriver} from "./SqliteDriver";
import {Broadcaster} from "../../subscriber/Broadcaster";

Expand Down Expand Up @@ -36,11 +37,34 @@ export class SqliteQueryRunner extends AbstractSqliteQueryRunner {
throw new QueryRunnerAlreadyReleasedError();

const connection = this.driver.connection;
const options = connection.options as SqliteConnectionOptions;

return new Promise<any[]>(async (ok, fail) => {

const databaseConnection = await this.connect();
this.driver.connection.logger.logQuery(query, parameters, this);
const queryStartTime = +new Date();
const isInsertQuery = query.substr(0, 11) === "INSERT INTO";

const execute = async () => {
if (isInsertQuery) {
databaseConnection.run(query, parameters, handler);
} else {
databaseConnection.all(query, parameters, handler);
}
};

const handler = function (err: any, result: any) {

if (err) {
if (err.toString().indexOf("SQLITE_BUSY:") !== -1 &&
typeof options.busyErrorRetry === "number" &&
options.busyErrorRetry) {
setTimeout(execute, options.busyErrorRetry);
return;
}
}

// log slow queries if maxQueryExecution time is set
const maxQueryExecutionTime = connection.options.maxQueryExecutionTime;
const queryEndTime = +new Date();
Expand All @@ -56,15 +80,7 @@ export class SqliteQueryRunner extends AbstractSqliteQueryRunner {
}
};

const databaseConnection = await this.connect();
this.driver.connection.logger.logQuery(query, parameters, this);
const queryStartTime = +new Date();
const isInsertQuery = query.substr(0, 11) === "INSERT INTO";
if (isInsertQuery) {
databaseConnection.run(query, parameters, handler);
} else {
databaseConnection.all(query, parameters, handler);
}
await execute();
});
}
}

0 comments on commit a9d8b0b

Please sign in to comment.