From 08ab85ec589f0da56c1be938b4f4cc368a6dfb4f Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 20 Apr 2026 21:16:47 +0800 Subject: [PATCH] feat(db-sync): add user entitlement fields to users table --- deps/db-sync/src/logseq/db_sync/index.cljs | 155 +++++++++++++++++- .../test/logseq/db_sync/index_test.cljs | 35 ++++ .../migrations/0005_add_users_sync_fields.sql | 17 ++ 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 deps/db-sync/worker/migrations/0005_add_users_sync_fields.sql diff --git a/deps/db-sync/src/logseq/db_sync/index.cljs b/deps/db-sync/src/logseq/db_sync/index.cljs index 21d342e3b7..ef151d4862 100644 --- a/deps/db-sync/src/logseq/db_sync/index.cljs +++ b/deps/db-sync/src/logseq/db_sync/index.cljs @@ -52,10 +52,66 @@ [v] (if (false? v) 0 1)) +(defn- user-is-pro-sql->bool + [v] + (cond + (nil? v) false + (or (= 1 v) (= "1" v)) true + (or (= 0 v) (= "0" v)) false + :else (true? v))) + +(defn- user-is-pro-bool->sql + [v] + (if (true? v) 1 0)) + +(defn- parse-user-groups + [value] + (let [parsed (cond + (nil? value) nil + (string? value) (try (js->clj (js/JSON.parse value)) + (catch :default _ nil)) + (array? value) (vec value) + (sequential? value) value + :else nil)] + (->> parsed + (keep (fn [item] + (when (string? item) + item))) + vec))) + +(defn- user-groups->sql-json + [groups] + (js/JSON.stringify (clj->js (parse-user-groups groups)))) + +(defn- parse-int-default + [value default] + (cond + (number? value) value + (string? value) (let [n (js/parseInt value 10)] + (if (js/isNaN n) default n)) + :else default)) + +(defn- clamp-non-negative-int + [value] + (let [n (parse-int-default value 0)] + (if (neg? n) 0 n))) + (def ^:private graph-e2ee-migration-sql "alter table graphs add column graph_e2ee INTEGER DEFAULT 1") (def ^:private graph-ready-for-use-migration-sql "alter table graphs add column graph_ready_for_use integer default 1") +(def ^:private user-expire-time-migration-sql + "alter table users add column expire_time integer") +(def ^:private user-user-groups-migration-sql + "alter table users add column user_groups text default '[]'") +(def ^:private user-is-pro-migration-sql + "alter table users add column is_pro integer not null default 0") +(def ^:private user-graphs-count-migration-sql + "alter table users add column graphs_count integer not null default 0") +(def ^:private user-storage-count-migration-sql + "alter table users add column storage_count integer not null default 0") +(def ^:private user-updated-at-migration-sql + "alter table users add column updated_at integer") (defn- duplicate-column-error? [error column-name] @@ -96,6 +152,40 @@ (p/catch (fn [_] ( (common/ (p/let [result (common/ row (aget "expire_time")) 0) + :user-groups (parse-user-groups (some-> row (aget "user_groups"))) + :is-pro (user-is-pro-sql->bool (some-> row (aget "is_pro"))) + :graphs-count (clamp-non-negative-int (some-> row (aget "graphs_count"))) + :storage-count (clamp-non-negative-int (some-> row (aget "storage_count"))) + :updated-at (parse-int-default (some-> row (aget "updated_at")) 0)}))) + +(defn (aget row "email") string/lower-case) + :user-groups (parse-user-groups (aget row "user_groups")) + :is-pro (user-is-pro-sql->bool (aget row "is_pro")) + :expire-time (parse-int-default (aget row "expire_time") 0) + :graphs-count (clamp-non-negative-int (aget row "graphs_count")) + :storage-count (clamp-non-negative-int (aget row "storage_count"))}) + rows))) + +(defn sql-json user-groups) + (user-is-pro-bool->sql is-pro) + (clamp-non-negative-int graphs-count) + (clamp-non-negative-int storage-count) + (parse-int-default updated-at (common/now-ms)) + user-id))) + +(defn (p/with-redefs [common/