1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00
unleash.unleash/src/lib/db/client-applications-store.ts

185 lines
5.1 KiB
TypeScript
Raw Normal View History

import EventEmitter from 'events';
import { Knex } from 'knex';
import NotFoundError from '../error/notfound-error';
import {
IClientApplication,
IClientApplicationsStore,
} from '../types/stores/client-applications-store';
import { Logger, LogProvider } from '../logger';
import { IApplicationQuery } from '../types/query';
2016-12-06 09:19:15 +01:00
2017-06-28 10:17:14 +02:00
const COLUMNS = [
'app_name',
'created_at',
'created_by',
2017-06-28 10:17:14 +02:00
'updated_at',
'description',
'strategies',
'url',
'color',
'icon',
];
2016-12-06 09:19:15 +01:00
const TABLE = 'client_applications';
const mapRow: (any) => IClientApplication = (row) => ({
2016-12-06 09:19:15 +01:00
appName: row.app_name,
createdAt: row.created_at,
updatedAt: row.updated_at,
description: row.description,
strategies: row.strategies || [],
createdBy: row.created_by,
2016-12-06 09:19:15 +01:00
url: row.url,
color: row.color,
icon: row.icon,
lastSeen: row.last_seen,
announced: row.announced,
2016-12-06 09:19:15 +01:00
});
const remapRow = (input) => {
const temp = {
app_name: input.appName,
updated_at: input.updatedAt || new Date(),
seen_at: input.lastSeen || new Date(),
description: input.description,
created_by: input.createdBy,
announced: input.announced,
url: input.url,
color: input.color,
icon: input.icon,
strategies: JSON.stringify(input.strategies),
};
Object.keys(temp).forEach((k) => {
if (temp[k] === undefined) {
// not using !temp[k] to allow false and null values to get through
delete temp[k];
}
});
return temp;
};
2016-12-06 09:19:15 +01:00
export default class ClientApplicationsStore
implements IClientApplicationsStore
{
private db: Knex;
private logger: Logger;
constructor(db: Knex, eventBus: EventEmitter, getLogger: LogProvider) {
2016-12-06 09:19:15 +01:00
this.db = db;
this.logger = getLogger('client-applications-store.ts');
2016-12-06 09:19:15 +01:00
}
async upsert(details: Partial<IClientApplication>): Promise<void> {
const row = remapRow(details);
await this.db(TABLE).insert(row).onConflict('app_name').merge();
2016-12-06 09:19:15 +01:00
}
async bulkUpsert(apps: Partial<IClientApplication>[]): Promise<void> {
const rows = apps.map(remapRow);
await this.db(TABLE).insert(rows).onConflict('app_name').merge();
2016-12-06 09:19:15 +01:00
}
async exists(appName: string): Promise<boolean> {
const result = await this.db.raw(
`SELECT EXISTS(SELECT 1 FROM ${TABLE} WHERE app_name = ?) AS present`,
[appName],
);
const { present } = result.rows[0];
return present;
2016-12-06 09:19:15 +01:00
}
async getAll(): Promise<IClientApplication[]> {
2020-09-18 09:05:09 +02:00
const rows = await this.db
2017-11-02 09:23:38 +01:00
.select(COLUMNS)
.from(TABLE)
2020-09-18 09:05:09 +02:00
.orderBy('app_name', 'asc');
return rows.map(mapRow);
}
async getApplication(appName: string): Promise<IClientApplication> {
2020-09-18 09:05:09 +02:00
const row = await this.db
2017-06-28 10:17:14 +02:00
.select(COLUMNS)
.where('app_name', appName)
.from(TABLE)
2020-09-18 09:05:09 +02:00
.first();
2021-01-06 13:25:25 +01:00
if (!row) {
throw new NotFoundError(`Could not find appName=${appName}`);
}
2020-09-18 09:05:09 +02:00
return mapRow(row);
}
async deleteApplication(appName: string): Promise<void> {
return this.db(TABLE).where('app_name', appName).del();
2020-09-25 09:39:12 +02:00
}
/**
* Could also be done in SQL:
* (not sure if it is faster though)
*
* SELECT app_name from (
* SELECT app_name, json_array_elements(strategies)::text as strategyName from client_strategies
* ) as foo
* WHERE foo.strategyName = '"other"';
*/
async getAppsForStrategy(
query: IApplicationQuery,
): Promise<IClientApplication[]> {
2020-09-18 09:05:09 +02:00
const rows = await this.db.select(COLUMNS).from(TABLE);
const apps = rows.map(mapRow);
2020-09-18 09:05:09 +02:00
if (query.strategyName) {
return apps.filter((app) =>
app.strategies.includes(query.strategyName),
2017-06-28 10:17:14 +02:00
);
}
return apps;
}
async getUnannounced(): Promise<IClientApplication[]> {
const rows = await this.db(TABLE)
.select(COLUMNS)
.where('announced', false);
return rows.map(mapRow);
}
/** *
* Updates all rows that have announced = false to announced =true and returns the rows altered
* @return {[app]} - Apps that hadn't been announced
*/
async setUnannouncedToAnnounced(): Promise<IClientApplication[]> {
const rows = await this.db(TABLE)
.update({ announced: true })
.where('announced', false)
.whereNotNull('announced')
.returning(COLUMNS);
return rows.map(mapRow);
}
2016-12-06 09:19:15 +01:00
async delete(key: string): Promise<void> {
await this.db(TABLE).where('app_name', key).del();
}
async deleteAll(): Promise<void> {
await this.db(TABLE).del();
}
destroy(): void {}
async get(appName: string): Promise<IClientApplication> {
const row = await this.db
.select(COLUMNS)
.where('app_name', appName)
.from(TABLE)
.first();
if (!row) {
throw new NotFoundError(`Could not find appName=${appName}`);
}
return mapRow(row);
}
}