Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 67f9a8974445785ce28a84b0459025f5070fa151
  • master par défaut protégée
  • dev-deurstann-3
  • dev-deurstann-2
  • dev-kubat
  • dev-deurstann
  • dev-sting
7 résultats

db.js

Blame
  • db.js 7,05 Kio
    const logger = require.main.require('./common/logger.js');
    const config = require.main.require('./common/config.js');
    const MiniSearch = require("minisearch")
    var sqlite3 = require.main.require('sqlite3').verbose();
    
    /* The kara table is defined as follows:
     *
     * <code>
     * CREATE TABLE IF NOT EXISTS kara
     *   ( id          INTEGER PRIMARY KEY AUTOINCREMENT
     *   , song_name   TEXT    NOT NULL
     *   , source_name TEXT    NOT NULL
     *   , category    INTEGER NOT NULL REFERENCES kara_category
     *   , song_type   INTEGER NOT NULL REFERENCES kara_type
     *   , song_number INTEGER NOT NULL CHECK(song_number > 0)
     *   , language    TEXT    REFERENCES language
     *   , file_path   TEXT    NOT NULL UNIQUE
     *   , is_new      INTEGER NOT NULL
     *   , author_name TEXT
     *   , available   INTEGER CHECK(available = 0 OR available = 1) DEFAULT 1 NOT NULL
     *   , string      TEXT GENERATED ALWAYS AS
     *     ( category || ' - ' || language || ' / ' || source_name || ' - ' || song_type ||
     *       song_number || ' - ' || song_name || ' [ ' || author_name || ' ]' ||
     *       CASE WHEN available = 0 THEN ' (U)' ELSE '' END
     *     ) STORED
     *   );
     * </code>
     */
    
    /* The queue table is defined as follows:
     *
     * <code>
     * CREATE TABLE IF NOT EXISTS queue
     *  ( position INTEGER PRIMARY KEY AUTOINCREMENT CHECK(position > 0)
     *  , kara_id  INTEGER REFERENCES kara
     *  , priority INTEGER NOT NULL DEFAULT 1 CHECK(priority > 0 AND priority < 6)
     *  );
     * </code>
     */
    
    class KaraDatabase {
        /* The constructor
         * - karaPath: String
         *
         * Private members
         * - m_karaPath: String
         * - m_db: sqlite3 database */
        constructor() {
            this.m_karaPath = config.content.database.path;
            this.m_db = new sqlite3.Database(this.m_karaPath);
            this.m_db.configure('busyTimeout', 50000);
            this.m_search_engine = new MiniSearch({
                fields: [
                    "id",
                    "cat",
                    "type",
                    "language",
                    "author",
                    "title",
                    "source"
                ], // fields to index for full-text search
                storeFields: [
                    "id",
                    "cat",
                    "type",
                    "language",
                    "author",
                    "title",
                    "source",
    		"available"
                ] // fields to return with search results
              })
            logger.info('db', 'Create database from file ' + config.content.database.path);
        }
    
        /* Call this as a destructor */
        close() {
            this.m_db.close();
            logger.info('db', `Close database ${this.m_karaPath}`);
        }
    
        /* Search for karas with the search engine
         *  - queryString: String
         * => A list of search results [(id: Int, string, cat, type, language, author, title, source)] */
        search(queryString) {
            let searchResult = this.m_search_engine.search(queryString, {
                prefix: term => term.length,
                fuzzy: term => term.length > 3 ? 0.2 : null,
                combineWith: 'AND'
            }).slice(0,200);
            return searchResult;
        }
    
        /* Initiate the search engine with the db
         * => a promize */
        setup_search_engine() {
            var __ret = [];
            var __sqlQuery = `SELECT id,
                                category AS cat,
                                (song_type || song_number) AS type,
                                language, author_name AS author,
                                song_name AS title, source_name AS source, available
                              FROM kara`;
            function __getRecords(db) {
                return new Promise(resolv => {
                    db.all(__sqlQuery, [], (err, rows) => {
                        if (err) {
                            logger.error('db', err);
                            throw err;
                        }
                        rows.forEach(row => {
                            __ret.push(row);
                        });
                        resolv(__ret);
                    });
                });
            }
    
            function __SetupSE(karas, search_engine = db.m_search_engine){
                search_engine.removeAll()
                logger.info("db", karas.length)
                search_engine.addAll(karas)
                logger.info("db", search_engine.documentCount)
            }
    
            return __getRecords(this.m_db).then(__SetupSE);
        }
    
        /* List all the next karas in the queue.
         * => a promize, callback with [(id: Int, string, cat, type, language,
         *    author, title, source, position: Int)] */
        queueAll() {
            var __ret = [];
            let __sqlQuery = `WITH content AS (
                 SELECT kara.id AS id, string,
                        category AS cat,
                        (song_type || song_number) AS type,
                        language, author_name AS author,
                        song_name AS title, source_name AS source,
                        position
                  FROM queue
                  JOIN kara ON kara_id = kara.id
                  GROUP BY position ORDER BY position ASC, priority DESC)
            SELECT id, string, position, cat, type, language, author, source, title
            FROM content;`;
    
            function __getRecords(db) {
                return new Promise(resolv => {
                    db.all(__sqlQuery, [], (err, rows) => {
                        if (err) {
                            logger.error('db', err);
                            throw err;
                        }
                        rows.forEach(row => {
                            __ret.push(row);
                        });
                        resolv(__ret);
                    });
                });
            }
    
            return __getRecords(this.m_db);
        }
    
        /* List all the next karas in the queue.
         * -  first: Integer => the first kara to consider being in the queue (the
         *    current one, starts ad 0)
         * -  count: Integer => the number of karas of the queue to load.
         * => a promize, callback with [(id: Int, string, cat, type, language,
         *    author, title, source, position: Int)] */
        queue(first, count) {
            var __ret = [];
            let __sqlQuery = `WITH content AS (
                 SELECT kara.id AS id, string,
                        category AS cat,
                        (song_type || song_number) AS type,
                        language, author_name AS author,
                        song_name AS title, source_name AS source,
                        position
                  FROM queue
                  JOIN kara ON kara_id = kara.id
                  WHERE position >= ${first} AND position <= ${count + first}
                  GROUP BY position ORDER BY position ASC, priority DESC)
            SELECT id, string, position, cat, type, language, author, source, title
            FROM content;`;
    
            function __getRecords(db) {
                return new Promise(resolv => {
                    db.all(__sqlQuery, [], (err, rows) => {
                        if (err) {
                            logger.error('db', err);
                            throw err;
                        }
                        rows.forEach(row => {
                            __ret.push(row);
                        });
                        resolv(__ret);
                    });
                });
            }
    
            return __getRecords(this.m_db);
        }
    }
    
    var db = new KaraDatabase();
    module.exports = db;