From cd4f89c96b1890aef95696ca95d63dbfa0ba40db Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Wed, 30 Oct 2024 16:18:58 +0530 Subject: [PATCH 1/4] - Fix transaction within transaction issue - Close DB handles on reload - Fix GET_ISSUES tracking --- web/core/local-db/storage.sqlite.ts | 14 +++++++++++++- web/core/local-db/utils/load-issues.ts | 2 +- web/core/local-db/utils/load-workspace.ts | 2 +- web/core/services/issue/issue.service.ts | 5 +---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/web/core/local-db/storage.sqlite.ts b/web/core/local-db/storage.sqlite.ts index 224b5013d01..d1cc8dd77ce 100644 --- a/web/core/local-db/storage.sqlite.ts +++ b/web/core/local-db/storage.sqlite.ts @@ -18,6 +18,7 @@ import { issueFilterCountQueryConstructor, issueFilterQueryConstructor } from ". import { runQuery } from "./utils/query-executor"; import { createTables } from "./utils/tables"; import { clearOPFS, getGroupedIssueResults, getSubGroupedIssueResults, log, logError } from "./utils/utils"; +import { th } from "date-fns/locale"; const DB_VERSION = 1; const PAGE_SIZE = 500; @@ -37,8 +38,17 @@ export class Storage { constructor() { this.db = null; + + if (typeof window !== "undefined") { + window.addEventListener("beforeunload", this.closeDBConnection); + } } + closeDBConnection = async () => { + if (this.db) { + await this.db.close(); + } + }; reset = () => { if (this.db) { this.db.close(); @@ -293,7 +303,9 @@ 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 () => { + return await Promise.all([runQuery(query), runQuery(countQuery)]); + }); } catch (e) { logError(e); const issueService = new IssueService(); diff --git a/web/core/local-db/utils/load-issues.ts b/web/core/local-db/utils/load-issues.ts index d374d2184f6..a16f6bd0ca7 100644 --- a/web/core/local-db/utils/load-issues.ts +++ b/web/core/local-db/utils/load-issues.ts @@ -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;"); diff --git a/web/core/local-db/utils/load-workspace.ts b/web/core/local-db/utils/load-workspace.ts index bb8ee1454da..e2ca6ce0fa7 100644 --- a/web/core/local-db/utils/load-workspace.ts +++ b/web/core/local-db/utils/load-workspace.ts @@ -115,7 +115,7 @@ 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); diff --git a/web/core/services/issue/issue.service.ts b/web/core/services/issue/issue.service.ts index 97fef0c16b0..2cef113d80f 100644 --- a/web/core/services/issue/issue.service.ts +++ b/web/core/services/issue/issue.service.ts @@ -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; } From 2cb04459220eb3243ee059be880f68b8051ddb8b Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Wed, 30 Oct 2024 16:25:32 +0530 Subject: [PATCH 2/4] Cleanup stray code --- web/core/local-db/storage.sqlite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/core/local-db/storage.sqlite.ts b/web/core/local-db/storage.sqlite.ts index d1cc8dd77ce..f09a9812787 100644 --- a/web/core/local-db/storage.sqlite.ts +++ b/web/core/local-db/storage.sqlite.ts @@ -18,7 +18,6 @@ import { issueFilterCountQueryConstructor, issueFilterQueryConstructor } from ". import { runQuery } from "./utils/query-executor"; import { createTables } from "./utils/tables"; import { clearOPFS, getGroupedIssueResults, getSubGroupedIssueResults, log, logError } from "./utils/utils"; -import { th } from "date-fns/locale"; const DB_VERSION = 1; const PAGE_SIZE = 500; @@ -49,6 +48,7 @@ export class Storage { await this.db.close(); } }; + reset = () => { if (this.db) { this.db.close(); From 85d711f5e7113f31d357c55c45add03cbf42dace Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Wed, 30 Oct 2024 17:20:06 +0530 Subject: [PATCH 3/4] Fix lint error --- web/core/local-db/storage.sqlite.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/core/local-db/storage.sqlite.ts b/web/core/local-db/storage.sqlite.ts index f09a9812787..00b3a6bb149 100644 --- a/web/core/local-db/storage.sqlite.ts +++ b/web/core/local-db/storage.sqlite.ts @@ -303,9 +303,10 @@ export class Storage { let issuesRaw: any[] = []; let count: any[]; try { - [issuesRaw, count] = await startSpan({ name: "GET_ISSUES" }, async () => { - return 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(); From 51610d1d1b352886ef9619f6d5aba6c0bd9fa3d3 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Mon, 4 Nov 2024 15:04:50 +0530 Subject: [PATCH 4/4] Possible fix for NoModificationAllowedError --- web/core/local-db/utils/load-workspace.ts | 2 +- web/core/local-db/worker/db.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/web/core/local-db/utils/load-workspace.ts b/web/core/local-db/utils/load-workspace.ts index e2ca6ce0fa7..3b715735e97 100644 --- a/web/core/local-db/utils/load-workspace.ts +++ b/web/core/local-db/utils/load-workspace.ts @@ -122,7 +122,7 @@ export const loadWorkSpaceData = async (workspaceSlug: string) => { 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); }; diff --git a/web/core/local-db/worker/db.ts b/web/core/local-db/worker/db.ts index b14347456b7..0fba3b3abf3 100644 --- a/web/core/local-db/worker/db.ts +++ b/web/core/local-db/worker/db.ts @@ -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[] = []; @@ -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 if (props === "BEGIN;") { let promiseToAwait; if (this.tp.length > 0) {