commit caa3746d154386c09a4c171e3a01efa0f04a0aa8
parent 9be97c83006f2a88302d8b5705c4e6755a215170
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 30 Aug 2024 21:56:55 +0000
client: update iclient, add `nostr_note` model
Diffstat:
2 files changed, 144 insertions(+), 18 deletions(-)
diff --git a/client/src/capacitor/sql.ts b/client/src/capacitor/sql.ts
@@ -1,7 +1,7 @@
-import { Capacitor } from '@capacitor/core';
import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection, type DBSQLiteValues, type capSQLiteChanges, type capSQLiteUpgradeOptions, type capSQLiteVersionUpgrade } from '@radroots/capacitor-sqlite';
-import { LocationGcsSchema, location_gcs_sort, models_initial_upgrade, parse_location_gcs_form_field_types, parse_location_gcss, type ILocationGcsGet, type ILocationGcsGetList, type ILocationGcsQueryBindValues, type ILocationGcsQueryBindValuesTuple, type ILocationGcsUpdate, type IModelsQueryBindValueOpt, type IModelsQueryBindValueTuple, type IModelsQueryParam, type LocationGcs, type LocationGcsFields, type LocationGcsFormFields } from "@radroots/models";
-import { err_msg, time_created_on, uuidv4 } from '@radroots/utils';
+import { Capacitor } from '@capacitor/core';
+import { time_created_on, uuidv4, err_msg } from '@radroots/utils';
+import { type IModelsQueryParam, type IModelsQueryBindValue, type IModelsQueryBindValueTuple, type IModelsQueryBindValueOpt, models_initial_upgrade, parse_location_gcs_form_field_types, location_gcs_sort, type ILocationGcsGetList, type ILocationGcsGet, type ILocationGcsUpdate, type ILocationGcsQueryBindValues, type ILocationGcsQueryBindValuesKey, type ILocationGcsQueryBindValuesTuple, parse_location_gcs, parse_location_gcss, type LocationGcs, type LocationGcsFields, type LocationGcsFormFields, LocationGcsSchema, parse_nostr_note_form_field_types, nostr_note_sort, type INostrNoteGetList, type INostrNoteGet, type INostrNoteUpdate, type INostrNoteQueryBindValues, type INostrNoteQueryBindValuesKey, type INostrNoteQueryBindValuesTuple, parse_nostr_note, parse_nostr_notes, type NostrNote, type NostrNoteFields, type NostrNoteFormFields, NostrNoteSchema} from "@radroots/models";
const models_upgrades = [
{
@@ -20,9 +20,10 @@ export type IISQLiteServiceOpenDatabase = {
version: number;
};
-export type IISQLiteServiceMessage =
-
- | "*-location-gcs-geohash-unique" | "*-validate"
+export type IISQLiteServiceMessage =
+ | "*-location-gcs-geohash-unique"
+ | "*-nostr-note-ev-id-unique"
+ | "*-validate"
| "*-result"
| "*-fields"
| "*-open"
@@ -183,6 +184,7 @@ export class CapacitorClientSQLite {
} catch (e) {
const { error } = err_msg(e, "execute");
if (String(e).includes("UNIQUE constraint failed: location_gcs.geohash")) return "*-location-gcs-geohash-unique";
+ else if (String(e).includes("UNIQUE constraint failed: nostr_note.ev_id")) return "*-nostr-note-ev-id-unique";
return this.append_logs("*-exe", bv_o, query, error);
};
};
@@ -237,7 +239,7 @@ export class CapacitorClientSQLite {
};
}
- private location_gcs_add_validate(opts: LocationGcsFormFields): LocationGcsFields | string[] {
+ private location_gcs_add_validate(opts: LocationGcsFormFields): LocationGcsFields | string[] {
const opts_filtered = Object.entries(opts).reduce((acc: Record<string, (string | number)>, [key, value]) => {
if (!!value) {
switch (parse_location_gcs_form_field_types(key)) {
@@ -254,7 +256,7 @@ export class CapacitorClientSQLite {
const location_gcs_v = LocationGcsSchema.safeParse(opts_filtered);
if (!location_gcs_v.success) return location_gcs_v.error.issues.map(i => i.message);
else return {
- ...location_gcs_v.data,
+ ...location_gcs_v.data,
};
};
@@ -263,9 +265,9 @@ export class CapacitorClientSQLite {
if (Array.isArray(optsv)) return optsv;
const fields = Object.entries(optsv);
if (!fields.length) return "*-fields";
- const id = uuidv4();
+ const id = uuidv4();
const bind_values_tup: IModelsQueryBindValueTuple[] = [
- ["id", id],
+ ["id", id],
["created_at", time_created_on()]
];
for (const field of this.filter_bind_value_fields(fields)) bind_values_tup.push(field);
@@ -273,7 +275,7 @@ export class CapacitorClientSQLite {
const query = `INSERT INTO location_gcs (${bind_values_tup.map(([k]) => k).join(", ")}) VALUES (${bind_values_tup.map((_, num) => `$${1 + num}`).join(", ")});`;
try {
const result = await this.execute(query, bind_values);
- if (typeof result !== "string" && typeof result.changes?.changes === "number" && result.changes.changes > 0) return { id };
+ if (typeof result !== "string" && typeof result.changes?.changes === "number" && result.changes.changes > 0) return { id };
else if (typeof result === "string") return result;
return "*-result";
} catch (e) {
@@ -281,12 +283,12 @@ export class CapacitorClientSQLite {
};
};
- private location_gcs_query_bind_values = (opts: ILocationGcsQueryBindValues): ILocationGcsQueryBindValuesTuple => {
+ private location_gcs_query_bind_values = (opts: ILocationGcsQueryBindValues): ILocationGcsQueryBindValuesTuple => {
if ("id" in opts) return ["id", opts.id];
- else return ["geohash", opts.geohash];
+ else return ["geohash", opts.geohash];
};
- private location_gcs_get_query_list = (opts: ILocationGcsGetList): IModelsQueryParam => {
+ private location_gcs_get_query_list = (opts: ILocationGcsGetList): IModelsQueryParam => {
const sort = location_gcs_sort[opts.sort || "newest"];
let query = "";
let bind_values = null;
@@ -300,7 +302,7 @@ export class CapacitorClientSQLite {
};
};
- private location_gcs_get_parse_opts = (opts: ILocationGcsGet): IModelsQueryParam => {
+ private location_gcs_get_parse_opts = (opts: ILocationGcsGet): IModelsQueryParam => {
if ("list" in opts) return this.location_gcs_get_query_list(opts);
else {
const bv_tup = this.location_gcs_query_bind_values(opts);
@@ -311,7 +313,7 @@ export class CapacitorClientSQLite {
};
};
- public async location_gcs_get(opts: ILocationGcsGet): Promise<LocationGcs[] | IISQLiteServiceMessage> {
+ public async location_gcs_get(opts: ILocationGcsGet): Promise<LocationGcs[] | IISQLiteServiceMessage> {
const { query, bind_values } = this.location_gcs_get_parse_opts(opts);
try {
const response = await this.select(query, bind_values);
@@ -326,7 +328,7 @@ export class CapacitorClientSQLite {
};
};
- public async location_gcs_delete(opts: ILocationGcsQueryBindValues): Promise<true | IISQLiteServiceMessage> {
+ public async location_gcs_delete(opts: ILocationGcsQueryBindValues): Promise<true | IISQLiteServiceMessage> {
const bv_tup = this.location_gcs_query_bind_values(opts);
const bind_values = [bv_tup[1]];
const query = `DELETE FROM location_gcs WHERE ${bv_tup[0]} = $1;`;
@@ -340,7 +342,7 @@ export class CapacitorClientSQLite {
};
};
- public async location_gcs_update(opts: ILocationGcsUpdate): Promise<true | string[] | IISQLiteServiceMessage> {
+ public async location_gcs_update(opts: ILocationGcsUpdate): Promise<true | string[] | IISQLiteServiceMessage> {
const optsv = this.location_gcs_add_validate(opts.fields);
if (Array.isArray(optsv)) return optsv;
const fields = this.filter_bind_value_fields(Object.entries(optsv));
@@ -357,4 +359,124 @@ export class CapacitorClientSQLite {
return this.append_logs("*", [], query, ["location_gcs_update", e]);
};
};
+
+ private nostr_note_add_validate(opts: NostrNoteFormFields): NostrNoteFields | string[] {
+ const opts_filtered = Object.entries(opts).reduce((acc: Record<string, (string | number)>, [key, value]) => {
+ if (!!value) {
+ switch (parse_nostr_note_form_field_types(key)) {
+ case "string":
+ acc[key] = value;
+ break;
+ case "number":
+ acc[key] = Number(value);
+ break;
+ }
+ };
+ return acc;
+ }, {});
+ const nostr_note_v = NostrNoteSchema.safeParse(opts_filtered);
+ if (!nostr_note_v.success) return nostr_note_v.error.issues.map(i => i.message);
+ else return {
+ ...nostr_note_v.data,
+ };
+ };
+
+ public async nostr_note_add(opts: NostrNoteFormFields): Promise<{ id: string; } | string[] | IISQLiteServiceMessage> {
+ const optsv = this.nostr_note_add_validate(opts);
+ if (Array.isArray(optsv)) return optsv;
+ const fields = Object.entries(optsv);
+ if (!fields.length) return "*-fields";
+ const id = uuidv4();
+ const bind_values_tup: IModelsQueryBindValueTuple[] = [
+ ["id", id],
+ ["created_at", time_created_on()]
+ ];
+ for (const field of this.filter_bind_value_fields(fields)) bind_values_tup.push(field);
+ const bind_values = bind_values_tup.map(([_, v]) => v);
+ const query = `INSERT INTO nostr_note (${bind_values_tup.map(([k]) => k).join(", ")}) VALUES (${bind_values_tup.map((_, num) => `$${1 + num}`).join(", ")});`;
+ try {
+ const result = await this.execute(query, bind_values);
+ if (typeof result !== "string" && typeof result.changes?.changes === "number" && result.changes.changes > 0) return { id };
+ else if (typeof result === "string") return result;
+ return "*-result";
+ } catch (e) {
+ return this.append_logs("*", bind_values, query, ["nostr_note_add", e]);
+ };
+ };
+
+ private nostr_note_query_bind_values = (opts: INostrNoteQueryBindValues): INostrNoteQueryBindValuesTuple => {
+ return ["id", opts.id];
+ };
+
+ private nostr_note_get_query_list = (opts: INostrNoteGetList): IModelsQueryParam => {
+ const sort = nostr_note_sort[opts.sort || "newest"];
+ let query = "";
+ let bind_values = null;
+ if (opts.list[0] === "all") {
+ query = `SELECT * FROM nostr_note ORDER BY ${sort};`;
+ }
+ if (!query) throw new Error("Error: Missing query (nostr_note_get_query_list)")
+ return {
+ query,
+ bind_values
+ };
+ };
+
+ private nostr_note_get_parse_opts = (opts: INostrNoteGet): IModelsQueryParam => {
+ if ("list" in opts) return this.nostr_note_get_query_list(opts);
+ else {
+ const bv_tup = this.nostr_note_query_bind_values(opts);
+ return {
+ query: `SELECT * FROM nostr_note WHERE ${bv_tup[0]} = $1;`,
+ bind_values: [bv_tup[1]]
+ };
+ };
+ };
+
+ public async nostr_note_get(opts: INostrNoteGet): Promise<NostrNote[] | IISQLiteServiceMessage> {
+ const { query, bind_values } = this.nostr_note_get_parse_opts(opts);
+ try {
+ const response = await this.select(query, bind_values);
+ if (typeof response === "string") return response;
+ else {
+ const result = parse_nostr_notes(response);
+ if (result) return result;
+ }
+ return "*-result";
+ } catch (e) {
+ return this.append_logs("*", opts, query, ["nostr_note_get", e]);
+ };
+ };
+
+ public async nostr_note_delete(opts: INostrNoteQueryBindValues): Promise<true | IISQLiteServiceMessage> {
+ const bv_tup = this.nostr_note_query_bind_values(opts);
+ const bind_values = [bv_tup[1]];
+ const query = `DELETE FROM nostr_note WHERE ${bv_tup[0]} = $1;`;
+ try {
+ const response = await this.execute(query, bind_values);
+ if (typeof response === "string") return response;
+ else if (typeof response.changes?.changes === "number" && response.changes.changes > 0) return true;
+ return "*-result";
+ } catch (e) {
+ return this.append_logs("*", [], query, ["nostr_note_delete", e]);
+ };
+ };
+
+ public async nostr_note_update(opts: INostrNoteUpdate): Promise<true | string[] | IISQLiteServiceMessage> {
+ const optsv = this.nostr_note_add_validate(opts.fields);
+ if (Array.isArray(optsv)) return optsv;
+ const fields = this.filter_bind_value_fields(Object.entries(optsv));
+ if (!fields.length) return "*-fields";
+ const bv_tup = this.nostr_note_query_bind_values(opts.on);
+ const bind_values = [bv_tup[1], ...fields.map(([_, v]) => v)];
+ const query = `UPDATE nostr_note SET ${fields.map(([k], num) => `${k} = $${1 + num}`).join(", ")} WHERE ${bv_tup[0]} = $1;`;
+ try {
+ const response = await this.execute(query, bind_values);
+ if (typeof response === "string") return response;
+ else if (typeof response.changes?.changes === "number" && response.changes.changes > 0) return true;
+ return "*-result";
+ } catch (e) {
+ return this.append_logs("*", [], query, ["nostr_note_update", e]);
+ };
+ };
};
\ No newline at end of file
diff --git a/client/src/types.ts b/client/src/types.ts
@@ -4,6 +4,7 @@ import { type ScanResult } from '@radroots/capacitor-bluetooth-le';
import { IOSSettings, type AndroidSettings } from '@radroots/capacitor-native-settings';
import { type ConnectToWifiResult, type GetCurrentWifiResult, type PermissionStatus, type ScanWifiResult } from '@radroots/capacitor-wifi';
import { type ErrorResponse } from '@radroots/utils';
+import { CapacitorClientSQLite } from './capacitor/sql';
export type IClient = {
nostr: IClientNostr;
@@ -23,6 +24,7 @@ export type IClient = {
window: IClientWindow;
ble: IClientBluetoothLe;
settings: IClientSettings;
+ db: IClientDb;
};
export type IClientNostr = {
@@ -32,6 +34,8 @@ export type IClientNostr = {
export type IClientPlatform = `androiď` | `ios` | `web`;
+export type IClientDb = CapacitorClientSQLite;
+
export type IClientKeystore = {
init: () => Promise<void>;
set(key: string, val: string): Promise<boolean>;