mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-23 01:01:27 +00:00
update to sqlite database WIP
This commit is contained in:
parent
00a8157c7c
commit
855c034a35
109
types/sqlite.ts
109
types/sqlite.ts
@ -1,89 +1,24 @@
|
||||
// types/sqlite.ts
|
||||
|
||||
// Database interfaces
|
||||
export interface SQLite {
|
||||
rows: {
|
||||
_array: any[];
|
||||
length: number;
|
||||
item: (idx: number) => any;
|
||||
};
|
||||
rowsAffected: number;
|
||||
insertId?: number;
|
||||
}
|
||||
|
||||
// Transaction interfaces
|
||||
export interface SQLiteCallback {
|
||||
(transaction: SQLTransaction, resultSet: SQLite): void;
|
||||
}
|
||||
|
||||
export interface SQLErrorCallback {
|
||||
(transaction: SQLTransaction, error: Error): boolean;
|
||||
}
|
||||
|
||||
export interface SQLTransaction {
|
||||
executeSql: (
|
||||
sqlStatement: string,
|
||||
args?: (string | number | null)[],
|
||||
callback?: SQLiteCallback,
|
||||
errorCallback?: SQLErrorCallback
|
||||
) => void;
|
||||
}
|
||||
|
||||
// Database error interfaces
|
||||
export interface SQLError extends Error {
|
||||
code?: number;
|
||||
}
|
||||
|
||||
// Database open options
|
||||
export interface SQLiteOpenOptions {
|
||||
enableChangeListener?: boolean;
|
||||
useNewConnection?: boolean;
|
||||
}
|
||||
|
||||
// Result interfaces
|
||||
export interface SQLiteRunResult {
|
||||
insertId: number;
|
||||
rowsAffected: number;
|
||||
}
|
||||
|
||||
export interface SQLiteRow {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface SQLiteResultSet {
|
||||
insertId?: number;
|
||||
rowsAffected: number;
|
||||
rows: {
|
||||
length: number;
|
||||
_array: SQLiteRow[];
|
||||
item: (index: number) => SQLiteRow;
|
||||
};
|
||||
}
|
||||
|
||||
// Transaction callbacks
|
||||
export interface TransactionCallback {
|
||||
(tx: SQLTransaction): void;
|
||||
}
|
||||
|
||||
export interface TransactionErrorCallback {
|
||||
(error: SQLError): void;
|
||||
}
|
||||
|
||||
export interface TransactionSuccessCallback {
|
||||
(): void;
|
||||
}
|
||||
|
||||
// Database static type
|
||||
export interface Database {
|
||||
transaction(
|
||||
callback: TransactionCallback,
|
||||
error?: TransactionErrorCallback,
|
||||
success?: TransactionSuccessCallback
|
||||
): void;
|
||||
readTransaction(
|
||||
callback: TransactionCallback,
|
||||
error?: TransactionErrorCallback,
|
||||
success?: TransactionSuccessCallback
|
||||
): void;
|
||||
closeAsync(): Promise<void>;
|
||||
}
|
||||
export interface SQLiteRow {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface SQLiteResult<T = SQLiteRow> {
|
||||
rows: {
|
||||
_array: T[];
|
||||
length: number;
|
||||
item: (idx: number) => T;
|
||||
};
|
||||
rowsAffected: number;
|
||||
insertId?: number;
|
||||
}
|
||||
|
||||
export interface SQLiteError extends Error {
|
||||
code?: number;
|
||||
}
|
||||
|
||||
export interface SQLiteStatement {
|
||||
executeSync<T>(params?: any[]): T[] | null;
|
||||
finalizeSync(): void;
|
||||
}
|
@ -1,119 +1,105 @@
|
||||
// utils/db/db-service.ts
|
||||
import * as SQLite from 'expo-sqlite';
|
||||
import {
|
||||
SQLite as SQLiteResult,
|
||||
SQLTransaction,
|
||||
SQLiteCallback,
|
||||
SQLErrorCallback,
|
||||
SQLError,
|
||||
TransactionCallback,
|
||||
TransactionErrorCallback,
|
||||
TransactionSuccessCallback
|
||||
openDatabaseSync,
|
||||
SQLiteDatabase
|
||||
} from 'expo-sqlite';
|
||||
import {
|
||||
SQLiteResult,
|
||||
SQLiteError,
|
||||
SQLiteRow
|
||||
} from '@/types/sqlite';
|
||||
|
||||
export class DbService {
|
||||
private db: SQLite.SQLiteDatabase;
|
||||
private db: SQLiteDatabase | null = null;
|
||||
|
||||
constructor(dbName: string) {
|
||||
this.db = SQLite.openDatabaseSync(dbName);
|
||||
try {
|
||||
this.db = openDatabaseSync(dbName);
|
||||
console.log('Database opened:', this.db);
|
||||
} catch (error) {
|
||||
console.error('Error opening database:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async executeSql(sql: string, params: (string | number | null)[] = []): Promise<SQLiteResult> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.withTransactionAsync(async (tx) => {
|
||||
tx.executeSql(
|
||||
sql,
|
||||
params,
|
||||
(_, result) => resolve(result),
|
||||
(_, error) => {
|
||||
console.error('SQL Error:', error);
|
||||
reject(error);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
}).catch(error => {
|
||||
console.error('Transaction Error:', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
async executeSql<T extends SQLiteRow = any>(
|
||||
sql: string,
|
||||
params: (string | number | null)[] = []
|
||||
): Promise<SQLiteResult<T>> {
|
||||
if (!this.db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
|
||||
try {
|
||||
const statement = this.db.prepareSync(sql);
|
||||
const result = statement.executeSync<T>(params);
|
||||
statement.finalizeSync();
|
||||
|
||||
return {
|
||||
rows: {
|
||||
_array: Array.isArray(result) ? result : [],
|
||||
length: Array.isArray(result) ? result.length : 0,
|
||||
item: (idx: number) => (Array.isArray(result) ? result[idx] : null) as T
|
||||
},
|
||||
rowsAffected: Array.isArray(result) ? result.length : 0,
|
||||
insertId: undefined // SQLite doesn't provide this directly
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('SQL Error:', error, sql, params);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async executeWrite(sql: string, params: (string | number | null)[] = []): Promise<SQLiteResult> {
|
||||
return this.executeSql(sql, params);
|
||||
async executeWrite<T extends SQLiteRow = any>(
|
||||
sql: string,
|
||||
params: (string | number | null)[] = []
|
||||
): Promise<SQLiteResult<T>> {
|
||||
return this.executeSql<T>(sql, params);
|
||||
}
|
||||
|
||||
async executeWriteMany(queries: { sql: string; args?: (string | number | null)[] }[]): Promise<SQLiteResult[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const results: SQLiteResult[] = [];
|
||||
|
||||
this.db.withTransactionAsync(async (tx) => {
|
||||
try {
|
||||
for (const query of queries) {
|
||||
await new Promise<void>((resolveQuery, rejectQuery) => {
|
||||
tx.executeSql(
|
||||
query.sql,
|
||||
query.args || [],
|
||||
(_, result) => {
|
||||
results.push(result);
|
||||
resolveQuery();
|
||||
},
|
||||
(_, error) => {
|
||||
console.error('SQL Error:', error);
|
||||
rejectQuery(error);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
resolve(results);
|
||||
} catch (error) {
|
||||
console.error('Transaction Error:', error);
|
||||
reject(error);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Transaction Error:', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
async executeWriteMany<T extends SQLiteRow = any>(
|
||||
queries: Array<{
|
||||
sql: string;
|
||||
args?: (string | number | null)[]
|
||||
}>
|
||||
): Promise<SQLiteResult<T>[]> {
|
||||
if (!this.db) {
|
||||
throw new Error('Database not initialized');
|
||||
}
|
||||
|
||||
async withTransaction<T>(
|
||||
callback: (tx: SQLTransaction) => Promise<T>
|
||||
): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.withTransactionAsync(async (tx) => {
|
||||
try {
|
||||
const result = await callback(tx);
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
console.error('Transaction Error:', error);
|
||||
reject(error);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('Transaction Error:', error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
const results: SQLiteResult<T>[] = [];
|
||||
|
||||
for (const query of queries) {
|
||||
try {
|
||||
const result = await this.executeSql<T>(query.sql, query.args || []);
|
||||
results.push(result);
|
||||
} catch (error) {
|
||||
console.error('Error executing query:', query, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async tableExists(tableName: string): Promise<boolean> {
|
||||
try {
|
||||
const result = await this.executeSql(
|
||||
const result = await this.executeSql<{ name: string }>(
|
||||
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
||||
[tableName]
|
||||
);
|
||||
return result.rows.length > 0;
|
||||
return result.rows._array.length > 0;
|
||||
} catch (error) {
|
||||
console.error('Error checking table existence:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
async initialize(): Promise<void> {
|
||||
try {
|
||||
await this.db.closeAsync();
|
||||
await this.executeSql('PRAGMA foreign_keys = ON;');
|
||||
} catch (error) {
|
||||
console.error('Error closing database:', error);
|
||||
console.error('Error initializing database:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
@ -203,10 +203,19 @@ class Schema {
|
||||
}
|
||||
|
||||
private async setVersion(version: number): Promise<void> {
|
||||
await this.db.executeSql(
|
||||
'INSERT INTO schema_version (version, updated_at) VALUES (?, ?)',
|
||||
[version, Date.now()]
|
||||
);
|
||||
try {
|
||||
await this.db.executeSql(
|
||||
'DELETE FROM schema_version WHERE version = ?',
|
||||
[version]
|
||||
);
|
||||
await this.db.executeSql(
|
||||
'INSERT INTO schema_version (version, updated_at) VALUES (?, ?)',
|
||||
[version, Date.now()]
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error setting schema version:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user