taskeep-app/services/data/sqliteDataService.ts
2025-07-22 14:04:38 +02:00

95 lines
3.4 KiB
TypeScript

import { toast } from '@backpackapp-io/react-native-toast';
import * as SQLite from 'expo-sqlite';
import { IEntity } from '../../models/IEntity';
import { IQuery } from '../../models/IQuery';
import { IDataService } from './IDataService';
export class SQLiteDataService<T extends IEntity> implements IDataService<T> {
private static db: SQLite.SQLiteDatabase | null = null;
private tableName: string;
constructor(queryObj: IQuery) {
this.tableName = queryObj.tableName;
SQLiteDataService.openDatabase(queryObj.tableQuery);
}
static openDatabase(tableQuery: string): SQLite.SQLiteDatabase | null {
try {
if (SQLiteDataService.db == null) {
SQLiteDataService.db = SQLite.openDatabaseSync('mydb2');
}
const response = SQLiteDataService.db.runSync(tableQuery);
}
catch (error) {
console.error('Error opening database or running table query:', error);
toast.error(error);
}
console.log('Database opened and table created if not exists');
return SQLiteDataService.db;
}
async create(item: T): Promise<T> {
const db = await this.getDb();
const id = await this.add(item);
return { ...item, id } as T;
}
async findById(id: number): Promise<T | null> {
const db = await this.getDb();
return await db.getFirstAsync<T>(`SELECT * FROM ${this.tableName} WHERE id = ?`, [id]) || null;
}
async findAll(): Promise<T[]> {
const db = await this.getDb();
return await db.getAllAsync<T>(`SELECT * FROM ${this.tableName}`);
}
private async getDb(): Promise<SQLite.SQLiteDatabase> {
if (!SQLiteDataService.db) {
SQLiteDataService.db = await SQLite.openDatabaseAsync('habitask');
}
return SQLiteDataService.db;
}
async add(item: T): Promise<number> {
const db = await this.getDb();
const keys = Object.keys(item).filter(k => k !== 'id');
const values = keys.map(k => (item as any)[k]);
const placeholders = keys.map(() => '?').join(', ');
const result = await db.runAsync(
`INSERT INTO ${this.tableName} (${keys.join(', ')}) VALUES (${placeholders})`,
...values);
return result.lastInsertRowId;
}
async update(id: number, item: Partial<T>): Promise<T | null> {
const db = await this.getDb();
if (!item.id) {
throw new Error('Item must have an id to update');
}
const keys = Object.keys(item).filter(k => k !== 'id');
const values = keys.map(k => (item as any)[k]);
const setClause = keys.map(k => `${k} = ?`).join(', ');
try {
await db.runAsync(
`UPDATE ${this.tableName} SET ${setClause} WHERE id = ?`,
...values, item.id);
return await this.findById(id);
} catch (error) {
console.error(`Error updating item with id ${item.id}:`, error);
return null;
}
}
async delete(id: number): Promise<boolean> {
const db = await this.getDb();
try {
await db.runAsync(`DELETE FROM ${this.tableName} WHERE id = ?`, [id]);
return true;
} catch (error) {
console.error(`Error deleting item with id ${id}:`, error);
return false;
}
}
}