update
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
// packages/backend/src/repositories/notification.repository.ts
|
||||
import { Database } from 'sqlite3';
|
||||
import { getDb } from '../database';
|
||||
// Import new async helpers and the instance getter
|
||||
import { getDbInstance, runDb, getDb as getDbRow, allDb } from '../database/connection';
|
||||
import { NotificationSetting, RawNotificationSetting, NotificationChannelType, NotificationEvent, NotificationChannelConfig } from '../types/notification.types';
|
||||
|
||||
// Helper to parse raw data from DB
|
||||
@@ -11,85 +13,81 @@ const parseRawSetting = (raw: RawNotificationSetting): NotificationSetting => {
|
||||
config: JSON.parse(raw.config || '{}'),
|
||||
enabled_events: JSON.parse(raw.enabled_events || '[]'),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error parsing notification setting ID ${raw.id}:`, error);
|
||||
// Return a default/error state or re-throw, depending on desired handling
|
||||
// For now, return partially parsed with defaults for JSON fields
|
||||
// Cast to satisfy type checker, but this indicates a parsing error.
|
||||
} catch (error: any) { // Add type annotation
|
||||
console.error(`Error parsing notification setting ID ${raw.id}:`, error.message);
|
||||
return {
|
||||
...raw,
|
||||
enabled: Boolean(raw.enabled),
|
||||
config: {} as NotificationChannelConfig, // Config is invalid due to parsing error
|
||||
config: {} as NotificationChannelConfig, // Indicate parsing error
|
||||
enabled_events: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export class NotificationSettingsRepository {
|
||||
private db: Database;
|
||||
|
||||
constructor() {
|
||||
this.db = getDb();
|
||||
}
|
||||
// Remove constructor or leave it empty
|
||||
// constructor() { }
|
||||
|
||||
async getAll(): Promise<NotificationSetting[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.all('SELECT * FROM notification_settings ORDER BY created_at ASC', (err, rows: RawNotificationSetting[]) => {
|
||||
if (err) {
|
||||
return reject(new Error(`Error fetching notification settings: ${err.message}`));
|
||||
}
|
||||
resolve(rows.map(parseRawSetting));
|
||||
});
|
||||
});
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const rows = await allDb<RawNotificationSetting>(db, 'SELECT * FROM notification_settings ORDER BY created_at ASC');
|
||||
return rows.map(parseRawSetting);
|
||||
} catch (err: any) {
|
||||
console.error(`Error fetching notification settings:`, err.message);
|
||||
throw new Error(`Error fetching notification settings: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getById(id: number): Promise<NotificationSetting | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.get('SELECT * FROM notification_settings WHERE id = ?', [id], (err, row: RawNotificationSetting) => {
|
||||
if (err) {
|
||||
return reject(new Error(`Error fetching notification setting by ID ${id}: ${err.message}`));
|
||||
}
|
||||
resolve(row ? parseRawSetting(row) : null);
|
||||
});
|
||||
});
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const row = await getDbRow<RawNotificationSetting>(db, 'SELECT * FROM notification_settings WHERE id = ?', [id]);
|
||||
return row ? parseRawSetting(row) : null;
|
||||
} catch (err: any) {
|
||||
console.error(`Error fetching notification setting by ID ${id}:`, err.message);
|
||||
throw new Error(`Error fetching notification setting by ID ${id}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getEnabledByEvent(event: NotificationEvent): Promise<NotificationSetting[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Note: This query is inefficient as it fetches all enabled settings and filters in code.
|
||||
// For better performance with many settings, consider normalizing enabled_events
|
||||
// or using JSON functions if the SQLite version supports them well.
|
||||
this.db.all('SELECT * FROM notification_settings WHERE enabled = 1', (err, rows: RawNotificationSetting[]) => {
|
||||
if (err) {
|
||||
return reject(new Error(`Error fetching enabled notification settings: ${err.message}`));
|
||||
}
|
||||
const parsedRows = rows.map(parseRawSetting);
|
||||
const filteredRows = parsedRows.filter(setting => setting.enabled_events.includes(event));
|
||||
resolve(filteredRows);
|
||||
});
|
||||
});
|
||||
// Note: Query remains inefficient, consider optimization later if needed.
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const rows = await allDb<RawNotificationSetting>(db, 'SELECT * FROM notification_settings WHERE enabled = 1');
|
||||
const parsedRows = rows.map(parseRawSetting);
|
||||
const filteredRows = parsedRows.filter(setting => setting.enabled_events.includes(event));
|
||||
return filteredRows;
|
||||
} catch (err: any) {
|
||||
console.error(`Error fetching enabled notification settings:`, err.message);
|
||||
throw new Error(`Error fetching enabled notification settings: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async create(setting: Omit<NotificationSetting, 'id' | 'created_at' | 'updated_at'>): Promise<number> {
|
||||
const sql = `
|
||||
INSERT INTO notification_settings (channel_type, name, enabled, config, enabled_events)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`;
|
||||
INSERT INTO notification_settings (channel_type, name, enabled, config, enabled_events, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, strftime('%s', 'now'), strftime('%s', 'now'))
|
||||
`; // Added created_at, updated_at
|
||||
const params = [
|
||||
setting.channel_type,
|
||||
setting.name,
|
||||
setting.name ?? '', // Ensure name is not undefined
|
||||
setting.enabled ? 1 : 0,
|
||||
JSON.stringify(setting.config || {}),
|
||||
JSON.stringify(setting.enabled_events || [])
|
||||
];
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(sql, params, function (err) { // Use function() to access this.lastID
|
||||
if (err) {
|
||||
return reject(new Error(`Error creating notification setting: ${err.message}`));
|
||||
}
|
||||
resolve(this.lastID);
|
||||
});
|
||||
});
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const result = await runDb(db, sql, params);
|
||||
// Ensure lastID is valid before returning
|
||||
if (typeof result.lastID !== 'number' || result.lastID <= 0) {
|
||||
throw new Error('创建通知设置后未能获取有效的 lastID');
|
||||
}
|
||||
return result.lastID;
|
||||
} catch (err: any) {
|
||||
console.error(`Error creating notification setting:`, err.message);
|
||||
throw new Error(`Error creating notification setting: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async update(id: number, setting: Partial<Omit<NotificationSetting, 'id' | 'created_at' | 'updated_at'>>): Promise<boolean> {
|
||||
@@ -97,29 +95,16 @@ export class NotificationSettingsRepository {
|
||||
const fields: string[] = [];
|
||||
const params: (string | number | null)[] = [];
|
||||
|
||||
if (setting.channel_type !== undefined) {
|
||||
fields.push('channel_type = ?');
|
||||
params.push(setting.channel_type);
|
||||
}
|
||||
if (setting.name !== undefined) {
|
||||
fields.push('name = ?');
|
||||
params.push(setting.name);
|
||||
}
|
||||
if (setting.enabled !== undefined) {
|
||||
fields.push('enabled = ?');
|
||||
params.push(setting.enabled ? 1 : 0);
|
||||
}
|
||||
if (setting.config !== undefined) {
|
||||
fields.push('config = ?');
|
||||
params.push(JSON.stringify(setting.config || {}));
|
||||
}
|
||||
if (setting.enabled_events !== undefined) {
|
||||
fields.push('enabled_events = ?');
|
||||
params.push(JSON.stringify(setting.enabled_events || []));
|
||||
}
|
||||
// Dynamically build SET clauses
|
||||
if (setting.channel_type !== undefined) { fields.push('channel_type = ?'); params.push(setting.channel_type); }
|
||||
if (setting.name !== undefined) { fields.push('name = ?'); params.push(setting.name); }
|
||||
if (setting.enabled !== undefined) { fields.push('enabled = ?'); params.push(setting.enabled ? 1 : 0); }
|
||||
if (setting.config !== undefined) { fields.push('config = ?'); params.push(JSON.stringify(setting.config || {})); }
|
||||
if (setting.enabled_events !== undefined) { fields.push('enabled_events = ?'); params.push(JSON.stringify(setting.enabled_events || [])); }
|
||||
|
||||
if (fields.length === 0) {
|
||||
return Promise.resolve(true); // Nothing to update
|
||||
console.warn(`[NotificationRepo] update called for ID ${id} with no fields to update.`);
|
||||
return true; // Or false, depending on desired behavior for no-op update
|
||||
}
|
||||
|
||||
fields.push('updated_at = strftime(\'%s\', \'now\')'); // Always update timestamp
|
||||
@@ -127,25 +112,28 @@ export class NotificationSettingsRepository {
|
||||
const sql = `UPDATE notification_settings SET ${fields.join(', ')} WHERE id = ?`;
|
||||
params.push(id);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(sql, params, function (err) { // Use function() to access this.changes
|
||||
if (err) {
|
||||
return reject(new Error(`Error updating notification setting ID ${id}: ${err.message}`));
|
||||
}
|
||||
resolve(this.changes > 0);
|
||||
});
|
||||
});
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const result = await runDb(db, sql, params);
|
||||
return result.changes > 0;
|
||||
} catch (err: any) {
|
||||
console.error(`Error updating notification setting ID ${id}:`, err.message);
|
||||
throw new Error(`Error updating notification setting ID ${id}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async delete(id: number): Promise<boolean> {
|
||||
const sql = 'DELETE FROM notification_settings WHERE id = ?';
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(sql, [id], function (err) { // Use function() to access this.changes
|
||||
if (err) {
|
||||
return reject(new Error(`Error deleting notification setting ID ${id}: ${err.message}`));
|
||||
}
|
||||
resolve(this.changes > 0);
|
||||
});
|
||||
});
|
||||
try {
|
||||
const db = await getDbInstance();
|
||||
const result = await runDb(db, sql, [id]);
|
||||
return result.changes > 0;
|
||||
} catch (err: any) {
|
||||
console.error(`Error deleting notification setting ID ${id}:`, err.message);
|
||||
throw new Error(`Error deleting notification setting ID ${id}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export the class (Removed redundant export below as class is already exported)
|
||||
// export { NotificationSettingsRepository };
|
||||
|
||||
Reference in New Issue
Block a user