heavily modified database interaction

This commit is contained in:
Daniel Sommer 2022-06-03 17:04:44 +02:00
parent 038603314a
commit f9eede4fea
13 changed files with 291 additions and 127 deletions

View file

@ -43,7 +43,7 @@ class Database {
continue;
}
const model = require(modelFile);
if (model.createTable === undefined) {
if (model.prototype?.createTable === undefined || model.name === 'Base') {
continue;
}
modelFile = path.basename(modelFile);
@ -62,10 +62,10 @@ class Database {
const model = models[index];
try {
const timestamp = new Date().getTime();
await model.createTable();
logger.debug('creation/alteration of table \'' + model.tableName + '\' finished after ' + (new Date().getTime() - timestamp) + 'ms');
await model.prototype.createTable();
logger.debug('creation/alteration of table \'' + model.name + '\' finished after ' + (new Date().getTime() - timestamp) + 'ms');
} catch (err) {
logger.error('an error occured creating table \'' + model.tableName + '\' > ' + err);
logger.error('an error occured creating table \'' + model.name + '\' > ' + err);
}
}

View file

@ -1,6 +1,8 @@
const metadata = require('../libs/metadata.js');
const { extname } = require('path');
const Artist = require('../models/Artist.js');
class Queue {
constructor() {
@ -111,18 +113,9 @@ class Queue {
artists.push(artist);
}
for (let index = 0; index < artists.length; index++) {
artist = artists[index].trim();
try {
const [element, created] = await database.models.Artist.findOrCreate({
where: { name: artist }
});
if (created) {
logger.debug('created artist: ' + JSON.stringify(element));
}
return element;
} catch (err) {
logger.error('error finding or creating artist \'' + JSON.stringify(tags) + '\' > ' + err);
}
artist = new Artist(artists[index]);
artist = await artist.save();
return artist;
}
}

View file

@ -2,6 +2,8 @@ const path = require('path');
const chokidar = require('chokidar');
const { open, writeFile } = require('fs/promises');
const Environment = require('../models/Environment.js');
class Watcher {
constructor() {
@ -23,6 +25,12 @@ class Watcher {
const directory = path.resolve(config.library.sources[index]);
let ignoreInitial = !initialScan;
if (ignoreInitial === false) {
let env = new Environment(constants.ENVIRONMENT_LASTSCAN);
await env.find('key');
if (env === undefined) {
env = new Environment(constants.ENVIRONMENT_LASTSCAN, new Date().getTime().toString());
env.save();
}
ignoreInitial = (new Date().getTime() - await this.#checkHiddenFile(directory)) < (config?.library?.initialscan?.maxage || 86400000);
}
logger.debug('watching directory \'' + directory + '\'...');

View file

@ -17,14 +17,14 @@
"library": {
"enabled": true,
"sources": [
"/home/velvettear/mounts/samsung/music"
"/home/velvettear/downloads"
],
"formats": [
"mp3",
"flac"
],
"initialscan": {
"enabled": false,
"enabled": true,
"maxage": 3600000
}
},
@ -41,6 +41,6 @@
"listen": "0.0.0.0",
"port": 3001,
"nodelay": false,
"threshold": 8
"threshold": 10
}
}

View file

@ -19,5 +19,7 @@ module.exports = {
API_PLAY: '/play',
API_PAUSE: '/pause',
API_RESUME: '/resume',
API_STOP: '/stop'
API_STOP: '/stop',
ENVIRONMENT_LASTSCAN:'lastscan'
}

View file

@ -1,23 +1,28 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'album';
const Base = require('./Base.js');
class Album {
const tableName = path.basename(__filename, '.js').toLowerCase();
constructor() {
class Album extends Base {
constructor(name) {
super();
this.tableName = tableName;
this.name = name;
}
isValid() {
return this.name !== undefined;
}
async getModel() {
return database.connection.define(tableName, {
name: DataTypes.TEXT
});
}
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
return database.connection.define(tableName, {
name: DataTypes.TEXT
});
}
module.exports = { Album, createTable, tableName };
module.exports = Album;

View file

@ -1,20 +1,24 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'albumtoartist';
const Base = require('./Base.js');
class AlbumToArtist {
const tableName = path.basename(__filename, '.js').toLowerCase();
constructor() {
class AlbumToArtist extends Base {
constructor(album, artist) {
super();
this.tableName = tableName;
this.album = album;
this.artist = artist;
}
}
isValid() {
return this.album !== undefined || this.artist !== undefined;
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
async getModel() {
return database.connection.define(tableName, {
album: DataTypes.INTEGER,
artist: DataTypes.INTEGER
@ -23,6 +27,8 @@ async function getModel() {
freezeTableName: true
}
);
}
}
module.exports = { AlbumToArtist, createTable, tableName };
module.exports = AlbumToArtist;

View file

@ -1,23 +1,26 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'artist';
const Base = require('./Base.js');
class Artist {
const tableName = path.basename(__filename, '.js').toLowerCase();
constructor() {
class Artist extends Base {
constructor(name) {
this.name = name;
}
isValid() {
return this.name !== undefined;
}
async getModel() {
return database.connection.define(tableName, {
name: DataTypes.TEXT
});
}
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
return database.connection.define(tableName, {
name: DataTypes.TEXT
});
}
module.exports = { Artist, createTable, tableName };
module.exports = Artist;

98
models/Base.js Normal file
View file

@ -0,0 +1,98 @@
class Base {
constructor() {
}
async save() {
if (!this.isValid()) {
return;
}
try {
const [element, created] = await (await this.getModel()).findOrCreate({
where: await this.#createWhereClause()
});
if (created) {
logger.debug('created \'' + this.tableName + '\' entry: ' + JSON.stringify(element));
}
if (element?.id === undefined) {
return undefined;
}
return element;
} catch (error) {
logger.error('error finding or creating \'' + this.tableName + '\' entry: \'' + JSON.stringify(this) + '\' > ' + error);
}
}
async find() {
if (!this.isValid()) {
return;
}
try {
const element = await (await this.getModel()).findOne({
where: await this.#createWhereClause()
});
if (element?.id === undefined) {
return undefined;
}
this.#fillThis(element);
} catch (error) {
logger.error('error finding \'' + this.tableName + '\' entry: \'' + JSON.stringify(this) + '\' > ' + error);
}
}
async createTable() {
return await createTable();
}
async createTable() {
const model = await this.getModel();
if (model === undefined) {
return;
}
await model.sync({ alter: true });
}
async getModel() {
return undefined;
}
isValid() {
return false;
}
#fillThis(data) {
if (data === undefined || data.dataValues === undefined || data.dataValues.id === undefined || data.dataValues.id < 0) {
return;
}
for (const key in data.dataValues) {
this[key] = data.dataValues[key];
}
}
async #createWhereClause(fields) {
const model = await this.getModel();
if (model === undefined || model.tableAttributes === undefined) {
return undefined;
}
const where = {};
for (const key in model.tableAttributes) {
if (key === 'id' || key === 'createdAt' || key === 'updatedAt' || fields !== undefined && (key !== fields || !fields.includes(key))) {
continue;
}
const value = this[key];
if (value === undefined) {
continue;
}
where[key] = value;
}
return where;
}
}
module.exports = Base;

37
models/Environment.js Normal file
View file

@ -0,0 +1,37 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const Base = require('./Base.js');
const tableName = path.basename(__filename, '.js').toLowerCase();
class Environment extends Base {
constructor(key, value) {
super();
this.tableName = tableName;
this.key = key;
this.value = value;
}
isValid() {
return this.key !== undefined;
}
async getModel() {
if (this.model === undefined) {
this.model = await database.connection.define(tableName, {
key: DataTypes.TEXT,
value: DataTypes.TEXT
},
{
freezeTableName: true
}
);
}
return this.model;
}
}
module.exports = Environment;

View file

@ -1,20 +1,22 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'track';
const Base = require('./Base.js');
class Track {
const tableName = path.basename(__filename, '.js').toLowerCase();
class Track extends Base {
constructor() {
}
}
isValid() {
return this.title !== undefined &&
this.file !== undefined;
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
async getModel() {
return database.connection.define(tableName, {
title: DataTypes.TEXT,
year: DataTypes.INTEGER,
@ -26,6 +28,8 @@ async function getModel() {
trackof: DataTypes.INTEGER,
file: DataTypes.TEXT
});
}
}
module.exports = { Track, createTable, tableName };
module.exports = Track;

View file

@ -1,20 +1,22 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'tracktoalbum';
const Base = require('./Base.js');
const tableName = path.basename(__filename, '.js').toLowerCase();
class TrackToAlbum {
constructor() {
constructor(track, album) {
this.track = track;
this.album = album;
}
}
isValid() {
return this.track !== undefined || this.album !== undefined;
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
async getModel() {
return database.connection.define(tableName, {
track: DataTypes.INTEGER,
album: DataTypes.INTEGER
@ -23,6 +25,8 @@ async function getModel() {
freezeTableName: true
}
);
}
}
module.exports = { TrackToAlbum, createTable, tableName };
module.exports = TrackToAlbum;

View file

@ -1,20 +1,22 @@
const path = require('path');
const { DataTypes } = require('sequelize');
const tableName = 'tracktoartist'
const Base = require('./Base.js');
const tableName = path.basename(__filename, '.js').toLowerCase();
class TrackToArtist {
constructor() {
constructor(track, artist) {
this.track = track;
this.artist = artist;
}
}
isValid() {
return this.track !== undefined || this.artist !== undefined;
}
async function createTable() {
(await getModel()).sync({ alter: true });
}
async function getModel() {
async getModel() {
return database.connection.define(tableName, {
track: DataTypes.INTEGER,
artist: DataTypes.INTEGER
@ -23,6 +25,8 @@ async function getModel() {
freezeTableName: true
}
);
}
}
module.exports = { TrackToArtist, createTable, tableName };
module.exports = TrackToArtist;