UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature toggles service. It provides different strategies for handling feature toggles.

178 lines • 5.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const anyEventEmitter_1 = require("../util/anyEventEmitter"); const EVENT_COLUMNS = [ 'id', 'type', 'created_by', 'created_at', 'data', 'pre_data', 'tags', 'feature_name', 'project', 'environment', ]; const TABLE = 'events'; class EventStore extends anyEventEmitter_1.AnyEventEmitter { constructor(db, getLogger) { super(); this.db = db; this.logger = getLogger('lib/db/event-store.ts'); } async store(event) { try { const rows = await this.db(TABLE) .insert(this.eventToDbRow(event)) .returning(EVENT_COLUMNS); const savedEvent = this.rowToEvent(rows[0]); process.nextTick(() => this.emit(event.type, savedEvent)); } catch (error) { this.logger.warn(`Failed to store "${event.type}" event: ${error}`); } } async count() { let count = await this.db(TABLE) .count() .first(); if (typeof count.count === 'string') { return parseInt(count.count, 10); } else { return count.count; } } async filteredCount(eventSearch) { let query = this.db(TABLE); if (eventSearch.type) { query = query.andWhere({ type: eventSearch.type }); } if (eventSearch.project) { query = query.andWhere({ project: eventSearch.project }); } if (eventSearch.feature) { query = query.andWhere({ feature_name: eventSearch.feature }); } let count = await query.count().first(); if (typeof count.count === 'string') { return parseInt(count.count, 10); } else { return count.count; } } async batchStore(events) { try { const savedRows = await this.db(TABLE) .insert(events.map(this.eventToDbRow)) .returning(EVENT_COLUMNS); const savedEvents = savedRows.map(this.rowToEvent); process.nextTick(() => savedEvents.forEach((e) => this.emit(e.type, e))); } catch (error) { this.logger.warn(`Failed to store events: ${error}`); } } async delete(key) { await this.db(TABLE).where({ id: key }).del(); } async deleteAll() { await this.db(TABLE).del(); } destroy() { } async exists(key) { const result = await this.db.raw(`SELECT EXISTS (SELECT 1 FROM ${TABLE} WHERE id = ?) AS present`, [key]); const { present } = result.rows[0]; return present; } async get(key) { const row = await this.db(TABLE).where({ id: key }).first(); return this.rowToEvent(row); } async getAll(query) { return this.getEvents(query); } async getEvents(query) { try { let qB = this.db .select(EVENT_COLUMNS) .from(TABLE) .limit(100) .orderBy('created_at', 'desc'); if (query) { qB = qB.where(query); } const rows = await qB; return rows.map(this.rowToEvent); } catch (err) { return []; } } async searchEvents(search = {}) { let query = this.db .select(EVENT_COLUMNS) .from(TABLE) .limit(search.limit ?? 100) .offset(search.offset ?? 0) .orderBy('created_at', 'desc'); if (search.type) { query = query.andWhere({ type: search.type, }); } if (search.project) { query = query.andWhere({ project: search.project, }); } if (search.feature) { query = query.andWhere({ feature_name: search.feature, }); } if (search.query) { query = query.where((where) => where .orWhereRaw('type::text ILIKE ?', `%${search.query}%`) .orWhereRaw('created_by::text ILIKE ?', `%${search.query}%`) .orWhereRaw('data::text ILIKE ?', `%${search.query}%`) .orWhereRaw('pre_data::text ILIKE ?', `%${search.query}%`)); } try { return (await query).map(this.rowToEvent); } catch (err) { return []; } } rowToEvent(row) { return { id: row.id, type: row.type, createdBy: row.created_by, createdAt: row.created_at, data: row.data, preData: row.pre_data, tags: row.tags || [], featureName: row.feature_name, project: row.project, environment: row.environment, }; } eventToDbRow(e) { return { type: e.type, created_by: e.createdBy, data: e.data, pre_data: e.preData, // @ts-expect-error workaround for json-array tags: JSON.stringify(e.tags), feature_name: e.featureName, project: e.project, environment: e.environment, }; } } exports.default = EventStore; //# sourceMappingURL=event-store.js.map