Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB-2706] fix: Fix issue with SQLite transactions #5934

Merged
merged 4 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion web/core/local-db/storage.sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,18 @@ export class Storage {

constructor() {
this.db = null;

if (typeof window !== "undefined") {
window.addEventListener("beforeunload", this.closeDBConnection);
}
SatishGandham marked this conversation as resolved.
Show resolved Hide resolved
}

closeDBConnection = async () => {
if (this.db) {
await this.db.close();
}
};

reset = () => {
if (this.db) {
this.db.close();
Expand Down Expand Up @@ -293,7 +303,10 @@ export class Storage {
let issuesRaw: any[] = [];
let count: any[];
try {
[issuesRaw, count] = await Promise.all([runQuery(query), runQuery(countQuery)]);
[issuesRaw, count] = await startSpan(
{ name: "GET_ISSUES" },
async () => await Promise.all([runQuery(query), runQuery(countQuery)])
);
} catch (e) {
logError(e);
const issueService = new IssueService();
Expand Down
2 changes: 1 addition & 1 deletion web/core/local-db/utils/load-issues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const addIssue = async (issue: any) => {

export const addIssuesBulk = async (issues: any, batchSize = 100) => {
if (!rootStore.user.localDBEnabled || !persistence.db) return;

if (!issues.length) return;
const insertStart = performance.now();
await persistence.db.exec("BEGIN;");

Expand Down
4 changes: 2 additions & 2 deletions web/core/local-db/utils/load-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,14 @@ export const loadWorkSpaceData = async (workspaceSlug: string) => {
const [labels, modules, cycles, states, estimates, memebers] = await Promise.all(promises);

const start = performance.now();
await persistence.db.exec("BEGIN TRANSACTION;");
await persistence.db.exec("BEGIN;");
await batchInserts(labels, "labels", labelSchema);
await batchInserts(modules, "modules", moduleSchema);
await batchInserts(cycles, "cycles", cycleSchema);
await batchInserts(states, "states", stateSchema);
await batchInserts(estimates, "estimate_points", estimatePointSchema);
await batchInserts(memebers, "members", memberSchema);
await persistence.db.exec("COMMIT");
await persistence.db.exec("COMMIT;");
const end = performance.now();
log("Time taken to load workspace data", end - start);
};
9 changes: 8 additions & 1 deletion web/core/local-db/worker/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ export class DBClass {
this.sqlite3 = SQLite.Factory(m);
const vfs = await MyVFS.create("plane", m);
this.sqlite3.vfs_register(vfs, true);
const db = await this.sqlite3.open_v2(`${dbName}.sqlite3`);
const db = await this.sqlite3.open_v2(
`${dbName}.sqlite3`,
this.sqlite3.OPEN_READWRITE | this.sqlite3.OPEN_CREATE,
"plane"
);

this.instance.db = db;
this.instance.exec = async (sql: string) => {
const rows: any[] = [];
Expand All @@ -57,6 +62,8 @@ export class DBClass {
}

async exec(props: string | TQueryProps) {
// @todo this will fail if the transaction is started any other way
// eg: BEGIN, OR BEGIN TRANSACTION
Comment on lines +65 to +66
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Transaction syntax limitations could cause failures.

The code only handles "BEGIN;" but not other valid SQLite transaction start commands like "BEGIN TRANSACTION;" or "BEGIN". This limitation could lead to transaction deadlocks or failures, especially when transactions are nested.

Consider updating the condition to handle all valid transaction start syntaxes:

-    if (props === "BEGIN;") {
+    if (typeof props === "string" && 
+        (props === "BEGIN;" || 
+         props === "BEGIN" || 
+         props === "BEGIN TRANSACTION;")) {

Committable suggestion skipped: line range outside the PR's diff.

if (props === "BEGIN;") {
let promiseToAwait;
if (this.tp.length > 0) {
Expand Down
5 changes: 1 addition & 4 deletions web/core/services/issue/issue.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,7 @@ export class IssueService extends APIService {
if (!isEmpty(queries.expand as string) && !queries.group_by)
return await this.getIssuesFromServer(workspaceSlug, projectId, queries, config);

const response = await startSpan({ name: "GET_ISSUES" }, async () => {
const res = await persistence.getIssues(workspaceSlug, projectId, queries, config);
return res;
});
const response = await persistence.getIssues(workspaceSlug, projectId, queries, config);
return response as TIssuesResponse;
}

Expand Down
Loading