mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 11:58:41 +00:00
117 lines
2.7 KiB
TypeScript
117 lines
2.7 KiB
TypeScript
import { SqliteConnection } from '@affine/native';
|
|
|
|
import { logger } from '../logger';
|
|
|
|
/**
|
|
* A base class for SQLite DB adapter that provides basic methods around updates & blobs
|
|
*/
|
|
export abstract class BaseSQLiteAdapter {
|
|
db: SqliteConnection | null = null;
|
|
abstract role: string;
|
|
|
|
constructor(public readonly path: string) {}
|
|
|
|
async connectIfNeeded() {
|
|
if (!this.db) {
|
|
this.db = new SqliteConnection(this.path);
|
|
await this.db.connect();
|
|
logger.info(`[SQLiteAdapter:${this.role}]`, 'connected:', this.path);
|
|
}
|
|
return this.db;
|
|
}
|
|
|
|
async destroy() {
|
|
const { db } = this;
|
|
this.db = null;
|
|
// log after close will sometimes crash the app when quitting
|
|
logger.info(`[SQLiteAdapter:${this.role}]`, 'destroyed:', this.path);
|
|
await db?.close();
|
|
}
|
|
|
|
async addBlob(key: string, data: Uint8Array) {
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return;
|
|
}
|
|
await this.db.addBlob(key, data);
|
|
} catch (error) {
|
|
logger.error('addBlob', error);
|
|
}
|
|
}
|
|
|
|
async getBlob(key: string) {
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return;
|
|
}
|
|
const blob = await this.db.getBlob(key);
|
|
return blob?.data;
|
|
} catch (error) {
|
|
logger.error('getBlob', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async deleteBlob(key: string) {
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return;
|
|
}
|
|
await this.db.deleteBlob(key);
|
|
} catch (error) {
|
|
logger.error(`${this.path} delete blob failed`, error);
|
|
}
|
|
}
|
|
|
|
async getBlobKeys() {
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return [];
|
|
}
|
|
return await this.db.getBlobKeys();
|
|
} catch (error) {
|
|
logger.error(`getBlobKeys failed`, error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async getUpdates() {
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return [];
|
|
}
|
|
return await this.db.getUpdates();
|
|
} catch (error) {
|
|
logger.error('getUpdates', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// add a single update to SQLite
|
|
async addUpdateToSQLite(updates: Uint8Array[]) {
|
|
// batch write instead write per key stroke?
|
|
try {
|
|
if (!this.db) {
|
|
logger.warn(`${this.path} is not connected`);
|
|
return;
|
|
}
|
|
const start = performance.now();
|
|
await this.db.insertUpdates(updates);
|
|
logger.debug(
|
|
`[SQLiteAdapter][${this.role}] addUpdateToSQLite`,
|
|
'length:',
|
|
updates.length,
|
|
performance.now() - start,
|
|
'ms'
|
|
);
|
|
} catch (error) {
|
|
logger.error('addUpdateToSQLite', this.path, error);
|
|
}
|
|
}
|
|
}
|