Browse Source

Merge branch 'sql-absurd-sql-further' of ssh://173.199.124.46:222/trent_larson/crowd-funder-for-time-pwa into sql-absurd-sql-further

pull/134/head
Matthew Raymer 1 week ago
parent
commit
688a5be76e
  1. 2
      src/db-sql/migration.ts
  2. 68
      src/db/databaseUtil.ts
  3. 8
      src/services/AbsurdSqlDatabaseService.ts
  4. 4
      src/utils/logger.ts
  5. 24
      src/views/LogView.vue

2
src/db-sql/migration.ts

@ -107,7 +107,7 @@ const MIGRATIONS = [
CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name); CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(name);
CREATE TABLE IF NOT EXISTS logs ( CREATE TABLE IF NOT EXISTS logs (
date TEXT PRIMARY KEY, date TEXT NOT NULL,
message TEXT NOT NULL message TEXT NOT NULL
); );

68
src/db/databaseUtil.ts

@ -123,6 +123,8 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
} }
} }
let lastCleanupDate: string | null = null;
/** /**
* Logs a message to the database with proper handling of concurrent writes * Logs a message to the database with proper handling of concurrent writes
* @param message - The message to log * @param message - The message to log
@ -131,69 +133,35 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
export async function logToDb(message: string): Promise<void> { export async function logToDb(message: string): Promise<void> {
const platform = PlatformServiceFactory.getInstance(); const platform = PlatformServiceFactory.getInstance();
const todayKey = new Date().toDateString(); const todayKey = new Date().toDateString();
const fullMessage = `${new Date().toISOString()} ${message}`; const nowKey = new Date().toISOString();
try { try {
// Try to insert first, if it fails due to UNIQUE constraint, update instead // Try to insert first, if it fails due to UNIQUE constraint, update instead
try { await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [ nowKey,
todayKey, message,
fullMessage, ]);
]);
} catch (error) {
// If insert fails due to UNIQUE constraint, update instead
if (
error instanceof Error &&
error.message.includes("UNIQUE constraint failed")
) {
const result = await platform.dbQuery(
"SELECT message FROM logs WHERE date = ?",
[todayKey],
);
if (result && result.values.length > 0) {
const prevMessages = result.values[0][0] as string;
const updatedMessage = `${prevMessages}\n${fullMessage}`;
await platform.dbExec("UPDATE logs SET message = ? WHERE date = ?", [
updatedMessage,
todayKey,
]);
}
} else {
// If it's a different error, rethrow it
throw error;
}
}
// Clean up old logs (keep only last 7 days) - do this less frequently // Clean up old logs (keep only last 7 days) - do this less frequently
// Only clean up if the date is different from the last cleanup // Only clean up if the date is different from the last cleanup
const lastCleanupKey = "last_log_cleanup"; if (!lastCleanupDate || lastCleanupDate !== todayKey) {
const result = await platform.dbQuery( const sevenDaysAgo = new Date(
"SELECT value FROM settings WHERE key = ?", new Date().getTime() - 7 * 24 * 60 * 60 * 1000,
[lastCleanupKey], );
);
const lastCleanup = result?.values[0]?.[0] as string;
if (!lastCleanup || lastCleanup !== todayKey) {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
await platform.dbExec("DELETE FROM logs WHERE date < ?", [ await platform.dbExec("DELETE FROM logs WHERE date < ?", [
sevenDaysAgo.toDateString(), sevenDaysAgo.toDateString(),
]); ]);
lastCleanupDate = todayKey;
// Update last cleanup date
await platform.dbExec(
"INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)",
[lastCleanupKey, todayKey],
);
} }
} catch (error) { } catch (error) {
// Log to console as fallback // Log to console as fallback
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error("Failed to log to database:", error); console.error(
// eslint-disable-next-line no-console "Error logging to database:",
console.error("Original message:", message); error,
" ... for original message:",
message,
);
} }
} }

8
src/services/AbsurdSqlDatabaseService.ts

@ -143,6 +143,14 @@ class AbsurdSqlDatabaseService implements DatabaseService {
} }
operation.resolve(result); operation.resolve(result);
} catch (error) { } catch (error) {
logger.error(
"Error while processing SQL queue:",
error,
" ... for sql:",
operation.sql,
" ... with params:",
operation.params,
);
operation.reject(error); operation.reject(error);
} }
} }

4
src/utils/logger.ts

@ -24,8 +24,8 @@ export const logger = {
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.debug(message, ...args); console.debug(message, ...args);
const argsString = args.length > 0 ? " - " + safeStringify(args) : ""; // const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDb(message + argsString); // logToDb(message + argsString);
} }
}, },
log: (message: string, ...args: unknown[]) => { log: (message: string, ...args: unknown[]) => {

24
src/views/LogView.vue

@ -35,11 +35,10 @@
No logs found. No logs found.
</div> </div>
<div v-else> <div v-else>
<div v-for="(log, index) in logs" :key="index" class="mb-8"> <div v-for="(log, index) in logs" :key="index" class="mb-2">
<h2 class="text-lg font-semibold mb-2">{{ log.date }}</h2>
<pre <pre
class="bg-slate-100 p-4 rounded-md overflow-x-auto whitespace-pre-wrap" class="bg-slate-100 p-4 rounded-md overflow-x-auto whitespace-pre-wrap"
>{{ log.message }}</pre >{{ log.date }} {{ log.message }}</pre
> >
</div> </div>
</div> </div>
@ -82,21 +81,22 @@ export default class LogView extends Vue {
let allLogs: Log[] = []; let allLogs: Log[] = [];
const platformService = PlatformServiceFactory.getInstance(); const platformService = PlatformServiceFactory.getInstance();
const queryResult = await platformService.dbQuery("SELECT * FROM logs"); const queryResult = await platformService.dbQuery(
allLogs = databaseUtil.mapQueryResultToValues( "SELECT * FROM logs ORDER BY date DESC",
);
this.logs = databaseUtil.mapQueryResultToValues(
queryResult, queryResult,
) as unknown as Log[]; ) as unknown as Log[];
if (USE_DEXIE_DB) { if (USE_DEXIE_DB) {
await db.open(); await db.open();
allLogs = await db.logs.toArray(); allLogs = await db.logs.toArray();
// Sort by date in reverse chronological order
this.logs = allLogs.sort((a, b) => {
const dateA = new Date(a.date);
const dateB = new Date(b.date);
return dateB.getTime() - dateA.getTime();
});
} }
// Sort by date in reverse chronological order
this.logs = allLogs.sort((a, b) => {
const dateA = new Date(a.date);
const dateB = new Date(b.date);
return dateB.getTime() - dateA.getTime();
});
} catch (error) { } catch (error) {
logger.error("Error loading logs:", error); logger.error("Error loading logs:", error);
this.error = this.error =

Loading…
Cancel
Save