Browse Source

refactor: add strict typing to core database methods in PlatformServiceMixin

- Replace all `any` types in $db, $exec, $one, $query, $first, and $contacts with proper interfaces:
  - Use QueryExecResult and DatabaseExecResult for raw database operations
  - Use Contact[] for contact queries
  - Add generics for mapped query results
- Update PlatformService and database interfaces to match new types
- Remove unused type imports and fix linter errors
- Reduces risk of runtime errors and improves type safety for all database access
pull/142/head
Matthew Raymer 3 days ago
parent
commit
829edaf7d7
  1. 20
      src/interfaces/database.ts
  2. 7
      src/services/PlatformService.ts
  3. 60
      src/utils/PlatformServiceMixin.ts

20
src/interfaces/database.ts

@ -5,11 +5,23 @@ export interface QueryExecResult {
values: Array<Array<SqlValue>>; values: Array<Array<SqlValue>>;
} }
export interface DatabaseExecResult {
changes: number;
lastId?: number;
}
export interface DatabaseService { export interface DatabaseService {
initialize(): Promise<void>; initialize(): Promise<void>;
query(sql: string, params?: unknown[]): Promise<QueryExecResult[]>; query(sql: string, params?: unknown[]): Promise<QueryExecResult[]>;
run( run(sql: string, params?: unknown[]): Promise<DatabaseExecResult>;
sql: string,
params?: unknown[],
): Promise<{ changes: number; lastId?: number }>;
} }
/**
* Generic database result type for mapped query results
*/
export type DatabaseResult<T = Record<string, unknown>> = T;
/**
* Database query result that can be either a single result or an array
*/
export type DatabaseQueryResult<T = Record<string, unknown>> = T | T[] | null;

7
src/services/PlatformService.ts

@ -1,4 +1,4 @@
import { QueryExecResult } from "@/interfaces/database"; import { QueryExecResult, DatabaseExecResult } from "@/interfaces/database";
/** /**
* Represents the result of an image capture or selection operation. * Represents the result of an image capture or selection operation.
@ -145,10 +145,7 @@ export interface PlatformService {
* @param params - The parameters to pass to the statement * @param params - The parameters to pass to the statement
* @returns Promise resolving to the result of the statement * @returns Promise resolving to the result of the statement
*/ */
dbExec( dbExec(sql: string, params?: unknown[]): Promise<DatabaseExecResult>;
sql: string,
params?: unknown[],
): Promise<{ changes: number; lastId?: number }>;
/** /**
* Executes a SQL query and returns the first row as an array. * Executes a SQL query and returns the first row as an array.

60
src/utils/PlatformServiceMixin.ts

@ -40,6 +40,8 @@ import { mapColumnsToValues, parseJsonField } from "@/db/databaseUtil";
import { MASTER_SETTINGS_KEY, type Settings } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY, type Settings } from "@/db/tables/settings";
import * as databaseUtil from "@/db/databaseUtil"; import * as databaseUtil from "@/db/databaseUtil";
import { logger } from "@/utils/logger"; import { logger } from "@/utils/logger";
import { Contact } from "@/db/tables/contacts";
import { QueryExecResult, DatabaseExecResult } from "@/interfaces/database";
// ================================================= // =================================================
// CACHING INFRASTRUCTURE // CACHING INFRASTRUCTURE
@ -385,7 +387,10 @@ export const PlatformServiceMixin = {
* @param sql SQL query string * @param sql SQL query string
* @param params Query parameters * @param params Query parameters
*/ */
async $db(sql: string, params: unknown[] = []): Promise<any> { async $db(
sql: string,
params: unknown[] = [],
): Promise<QueryExecResult | undefined> {
return await (this as any).platformService.dbQuery(sql, params); return await (this as any).platformService.dbQuery(sql, params);
}, },
@ -394,7 +399,10 @@ export const PlatformServiceMixin = {
* @param sql SQL statement string * @param sql SQL statement string
* @param params Statement parameters * @param params Statement parameters
*/ */
async $exec(sql: string, params: unknown[] = []): Promise<any> { async $exec(
sql: string,
params: unknown[] = [],
): Promise<DatabaseExecResult> {
return await (this as any).platformService.dbExec(sql, params); return await (this as any).platformService.dbExec(sql, params);
}, },
@ -403,7 +411,10 @@ export const PlatformServiceMixin = {
* @param sql SQL query string * @param sql SQL query string
* @param params Query parameters * @param params Query parameters
*/ */
async $one(sql: string, params: unknown[] = []): Promise<any> { async $one(
sql: string,
params: unknown[] = [],
): Promise<unknown[] | undefined> {
return await (this as any).platformService.dbGetOneRow(sql, params); return await (this as any).platformService.dbGetOneRow(sql, params);
}, },
@ -418,12 +429,16 @@ export const PlatformServiceMixin = {
* @param params Query parameters * @param params Query parameters
* @returns Mapped array of results * @returns Mapped array of results
*/ */
async $query(sql: string, params: unknown[] = []): Promise<any[]> { async $query<T = Record<string, unknown>>(
sql: string,
params: unknown[] = [],
): Promise<T[]> {
const result = await (this as any).platformService.dbQuery(sql, params); const result = await (this as any).platformService.dbQuery(sql, params);
if (!result?.columns || !result?.values) { if (!result?.columns || !result?.values) {
return []; return [];
} }
return mapColumnsToValues(result.columns, result.values) || []; const mappedResults = mapColumnsToValues(result.columns, result.values);
return mappedResults as T[];
}, },
/** /**
@ -432,9 +447,12 @@ export const PlatformServiceMixin = {
* @param params Query parameters * @param params Query parameters
* @returns First mapped result or null * @returns First mapped result or null
*/ */
async $first(sql: string, params: unknown[] = []): Promise<any | null> { async $first<T = Record<string, unknown>>(
sql: string,
params: unknown[] = [],
): Promise<T | null> {
const results = await (this as any).$query(sql, params); const results = await (this as any).$query(sql, params);
return results.length > 0 ? results[0] : null; return results.length > 0 ? (results[0] as T) : null;
}, },
// ================================================= // =================================================
@ -446,9 +464,9 @@ export const PlatformServiceMixin = {
* Ultra-concise shortcut with 60s TTL for performance * Ultra-concise shortcut with 60s TTL for performance
* @returns Cached mapped array of all contacts * @returns Cached mapped array of all contacts
*/ */
async $contacts(): Promise<any[]> { async $contacts(): Promise<Contact[]> {
const cacheKey = "contacts_all"; const cacheKey = "contacts_all";
const cached = this._getCached<any[]>(cacheKey); const cached = this._getCached<Contact[]>(cacheKey);
if (cached) { if (cached) {
return cached; return cached;
} }
@ -456,7 +474,11 @@ export const PlatformServiceMixin = {
const contacts = await this.$query( const contacts = await this.$query(
"SELECT * FROM contacts ORDER BY name", "SELECT * FROM contacts ORDER BY name",
); );
return this._setCached(cacheKey, contacts, CACHE_DEFAULTS.contacts); return this._setCached(
cacheKey,
contacts as Contact[],
CACHE_DEFAULTS.contacts,
);
}, },
/** /**
@ -656,13 +678,19 @@ declare module "@vue/runtime-core" {
capabilities: any; capabilities: any;
// Ultra-concise database methods (shortest possible names) // Ultra-concise database methods (shortest possible names)
$db(sql: string, params?: unknown[]): Promise<any>; $db(sql: string, params?: unknown[]): Promise<QueryExecResult | undefined>;
$exec(sql: string, params?: unknown[]): Promise<any>; $exec(sql: string, params?: unknown[]): Promise<DatabaseExecResult>;
$one(sql: string, params?: unknown[]): Promise<any>; $one(sql: string, params?: unknown[]): Promise<unknown[] | undefined>;
// Query + mapping combo methods // Query + mapping combo methods
$query(sql: string, params?: unknown[]): Promise<any[]>; $query<T = Record<string, unknown>>(
$first(sql: string, params?: unknown[]): Promise<any | null>; sql: string,
params?: unknown[],
): Promise<T[]>;
$first<T = Record<string, unknown>>(
sql: string,
params?: unknown[],
): Promise<T | null>;
// Enhanced utility methods // Enhanced utility methods
$dbQuery(sql: string, params?: unknown[]): Promise<any>; $dbQuery(sql: string, params?: unknown[]): Promise<any>;
@ -680,7 +708,7 @@ declare module "@vue/runtime-core" {
$withTransaction<T>(fn: () => Promise<T>): Promise<T>; $withTransaction<T>(fn: () => Promise<T>): Promise<T>;
// Cached specialized shortcuts (massive performance boost) // Cached specialized shortcuts (massive performance boost)
$contacts(): Promise<any[]>; $contacts(): Promise<Contact[]>;
$settings(defaults?: Settings): Promise<Settings>; $settings(defaults?: Settings): Promise<Settings>;
$accountSettings(did?: string, defaults?: Settings): Promise<Settings>; $accountSettings(did?: string, defaults?: Settings): Promise<Settings>;

Loading…
Cancel
Save