All files / src/lib/db tag-store.ts

78.72% Statements 37/47
50% Branches 1/2
76.92% Functions 10/13
78.72% Lines 37/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126    69x 69x   69x       69x 69x             69x               87x 87x 87x 57x                           14x 14x 14x 14x       20x 20x       20x 20x 13x       7x       3x 3x       3x 3x 3x       15x 15x 15x       2x 2x 2x       3x 3x 3x       2x                                                 8x           69x  
import { Knex } from 'knex';
import { EventEmitter } from 'events';
import { DB_TIME } from '../metric-events';
import metricsHelper from '../util/metrics-helper';
import { LogProvider, Logger } from '../logger';
import NotFoundError from '../error/notfound-error';
import { ITag } from '../types/model';
import { ITagStore } from '../types/stores/tag-store';
 
const COLUMNS = ['type', 'value'];
const TABLE = 'tags';
 
interface ITagTable {
    type: string;
    value: string;
}
 
export default class TagStore implements ITagStore {
    private db: Knex;
 
    private logger: Logger;
 
    private readonly timer: Function;
 
    constructor(db: Knex, eventBus: EventEmitter, getLogger: LogProvider) {
        this.db = db;
        this.logger = getLogger('tag-store.ts');
        this.timer = (action) =>
            metricsHelper.wrapTimer(eventBus, DB_TIME, {
                store: 'tag',
                action,
            });
    }
 
    async getTagsByType(type: string): Promise<ITag[]> {
        const stopTimer = this.timer('getTagByType');
        const rows = await this.db.select(COLUMNS).from(TABLE).where({ type });
        stopTimer();
        return rows.map(this.rowToTag);
    }
 
    async getAll(): Promise<ITag[]> {
        const stopTimer = this.timer('getAll');
        const rows = await this.db.select(COLUMNS).from(TABLE);
        stopTimer();
        return rows.map(this.rowToTag);
    }
 
    async getTag(type: string, value: string): Promise<ITag> {
        const stopTimer = this.timer('getTag');
        const tag = await this.db
            .first(COLUMNS)
            .from(TABLE)
            .where({ type, value });
        stopTimer();
        if (!tag) {
            throw new NotFoundError(
                `No tag with type: [${type}] and value [${value}]`,
            );
        }
        return tag;
    }
 
    async exists(tag: ITag): Promise<boolean> {
        const stopTimer = this.timer('exists');
        const result = await this.db.raw(
            `SELECT EXISTS (SELECT 1 FROM ${TABLE} WHERE type = ? AND value = ?) AS present`,
            [tag.type, tag.value],
        );
        const { present } = result.rows[0];
        stopTimer();
        return present;
    }
 
    async createTag(tag: ITag): Promise<void> {
        const stopTimer = this.timer('createTag');
        await this.db(TABLE).insert(tag);
        stopTimer();
    }
 
    async delete(tag: ITag): Promise<void> {
        const stopTimer = this.timer('deleteTag');
        await this.db(TABLE).where(tag).del();
        stopTimer();
    }
 
    async deleteAll(): Promise<void> {
        const stopTimer = this.timer('deleteAll');
        await this.db(TABLE).del();
        stopTimer();
    }
 
    async bulkImport(tags: ITag[]): Promise<ITag[]> {
        return this.db(TABLE)
            .insert(tags)
            .returning(COLUMNS)
            .onConflict(['type', 'value'])
            .ignore();
    }
 
    destroy(): void {}
 
    async get({ type, value }: ITag): Promise<ITag> {
        const stopTimer = this.timer('getTag');
        const tag = await this.db
            .first(COLUMNS)
            .from(TABLE)
            .where({ type, value });
        stopTimer();
        Iif (!tag) {
            throw new NotFoundError(
                `No tag with type: [${type}] and value [${value}]`,
            );
        }
        return tag;
    }
 
    rowToTag(row: ITagTable): ITag {
        return {
            type: row.type,
            value: row.value,
        };
    }
}
module.exports = TagStore;