From be8f069fbe1cedd363bdc7d587b11b099359940d Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Thu, 26 Sep 2024 18:55:49 +0530 Subject: [PATCH 1/4] - Handle single quotes in load workspace queries - Add IS null where condition in query utils --- web/core/local-db/utils/load-workspace.ts | 4 ++-- web/core/local-db/utils/query.utils.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/web/core/local-db/utils/load-workspace.ts b/web/core/local-db/utils/load-workspace.ts index 36d2aabce95..87231161c6f 100644 --- a/web/core/local-db/utils/load-workspace.ts +++ b/web/core/local-db/utils/load-workspace.ts @@ -27,10 +27,10 @@ const stageInserts = (table: string, schema: Schema, data: any) => { return ""; } if (typeof value === "object") { - return `'${JSON.stringify(value)}'`; + return `'${JSON.stringify(value).replace(/'/g, "''")}'`; } if (typeof value === "string") { - return `'${value}'`; + return `'${value.replace(/'/g, "''")}'`; } return value; }) diff --git a/web/core/local-db/utils/query.utils.ts b/web/core/local-db/utils/query.utils.ts index e95174bc7fa..eaaf11a1c87 100644 --- a/web/core/local-db/utils/query.utils.ts +++ b/web/core/local-db/utils/query.utils.ts @@ -238,7 +238,10 @@ export const singleFilterConstructor = (queries: any) => { keys.forEach((key) => { const value = filters[key] ? filters[key].split(",") : ""; - if (!value) return; + if (!value) { + sql += ` AND ${key} IS NULL`; + return; + } if (!ARRAY_FIELDS.includes(key)) { sql += ` AND ${key} in ('${value.join("','")}') `; From 215889c9dfd96ced873b65f134a21ea64543ef79 Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Thu, 26 Sep 2024 19:09:43 +0530 Subject: [PATCH 2/4] Fix description_html being lost --- web/core/local-db/utils/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/web/core/local-db/utils/utils.ts b/web/core/local-db/utils/utils.ts index 619ec9af8d5..f1e05274e82 100644 --- a/web/core/local-db/utils/utils.ts +++ b/web/core/local-db/utils/utils.ts @@ -47,6 +47,7 @@ export const updatePersistentLayer = async (issueIds: string | string[]) => { "label_ids", "module_ids", "type_id", + "description_html", ]); updateIssue({ ...issuePartial, is_local_update: 1 }); } From 00c48c385d8b5aca34d54776f8e9c31c70b7e40c Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Fri, 27 Sep 2024 08:16:24 +0530 Subject: [PATCH 3/4] Change secondary order to sequence_id --- web/core/local-db/utils/indexes.ts | 1 + web/core/local-db/utils/query.utils.ts | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/web/core/local-db/utils/indexes.ts b/web/core/local-db/utils/indexes.ts index aeff6992e9a..214bacb44f5 100644 --- a/web/core/local-db/utils/indexes.ts +++ b/web/core/local-db/utils/indexes.ts @@ -10,6 +10,7 @@ export const createIssueIndexes = async () => { "project_id", "created_by", "cycle_id", + "sequence_id", ]; const promises: Promise[] = []; diff --git a/web/core/local-db/utils/query.utils.ts b/web/core/local-db/utils/query.utils.ts index eaaf11a1c87..ad012a30a90 100644 --- a/web/core/local-db/utils/query.utils.ts +++ b/web/core/local-db/utils/query.utils.ts @@ -47,9 +47,9 @@ export const getOrderByFragment = (order_by: string, table = "") => { if (!order_by) return orderByString; if (order_by.startsWith("-")) { - orderByString += ` ORDER BY ${wrapDateTime(order_by.slice(1))} DESC NULLS LAST, datetime(${table}created_at) DESC`; + orderByString += ` ORDER BY ${wrapDateTime(order_by.slice(1))} DESC NULLS LAST, ${table}sequence_id DESC`; } else { - orderByString += ` ORDER BY ${wrapDateTime(order_by)} ASC NULLS LAST, datetime(${table}created_at) DESC`; + orderByString += ` ORDER BY ${wrapDateTime(order_by)} ASC NULLS LAST, ${table}sequence_id DESC`; } return orderByString; }; @@ -130,7 +130,7 @@ export const getFilteredRowsForGrouping = (projectId: string, queries: any) => { let sql = ""; if (!joinsRequired) { - sql = `WITH fi as (SELECT i.id,i.created_at ${issueTableFilterFields}`; + sql = `WITH fi as (SELECT i.id,i.created_at, i.sequence_id ${issueTableFilterFields}`; if (group_by) { if (group_by === "target_date") { sql += `, date(i.${group_by}) as group_id`; @@ -153,7 +153,7 @@ export const getFilteredRowsForGrouping = (projectId: string, queries: any) => { } sql = `WITH fi AS (`; - sql += `SELECT i.id,i.created_at ${issueTableFilterFields} `; + sql += `SELECT i.id,i.created_at,i.sequence_id ${issueTableFilterFields} `; if (group_by) { if (ARRAY_FIELDS.includes(group_by)) { sql += `, ${group_by}.value as group_id @@ -252,10 +252,6 @@ export const singleFilterConstructor = (queries: any) => { return sql; }; -// let q = '2_months;after;fromnow,1_months;after;fromnow,2024-09-01;after,2024-10-06;after,2_weeks;after;fromnow' - -// ["2_months;after;fromnow", "1_months;after;fromnow", "2024-09-01;after", "2024-10-06;before", "2_weeks;after;fromnow"]; - const createDateFilter = (key: string, q: string) => { let sql = " "; // get todays date in YYYY-MM-DD format From 5cece0f37dce74828a0990d24a970d3d1ef2a83c Mon Sep 17 00:00:00 2001 From: Satish Gandham Date: Fri, 27 Sep 2024 08:58:40 +0530 Subject: [PATCH 4/4] Fix update persistence layer --- web/core/local-db/utils/utils.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web/core/local-db/utils/utils.ts b/web/core/local-db/utils/utils.ts index f1e05274e82..368a19e7fa2 100644 --- a/web/core/local-db/utils/utils.ts +++ b/web/core/local-db/utils/utils.ts @@ -1,6 +1,7 @@ import pick from "lodash/pick"; import { TIssue } from "@plane/types"; import { rootStore } from "@/lib/store-context"; +import { persistence } from "../storage.sqlite"; import { updateIssue } from "./load-issues"; export const log = (...args: any) => { @@ -15,11 +16,13 @@ export const updatePersistentLayer = async (issueIds: string | string[]) => { if (typeof issueIds === "string") { issueIds = [issueIds]; } - issueIds.forEach((issueId) => { + issueIds.forEach(async (issueId) => { + const dbIssue = await persistence.getIssue(issueId); const issue = rootStore.issue.issues.getIssueById(issueId); if (issue) { - const issuePartial = pick(JSON.parse(JSON.stringify(issue)), [ + // JSON.parse(JSON.stringify(issue)) is used to remove the mobx observables + const issuePartial = pick({ ...dbIssue, ...JSON.parse(JSON.stringify(issue)) }, [ "id", "name", "state_id",