export default class Recorder { constructor(db) { this.db = db; this.lines = {}; this.vehModified = {}; } async start() { await this._createTables(); await this._loadLast(); } async _createTables() { if (!this.db) return; if (!await this.db.schema.hasTable('veh_lines')) { await this.db.schema.createTable('veh_lines', t => { t.timestamp('date', { useTz: false }).defaultTo(this.db.fn.now()); t.smallint('vehicle').notNullable(); t.string('line', 32).nullable(); // 4, 9.... }); } if (!await this.db.schema.hasTable('veh_pos')) { await this.db.schema.createTable('veh_pos', t => { t.timestamp('date', { useTz: false }).defaultTo(this.db.fn.now()); t.float('lat').nullable(); t.float('long').nullable(); t.smallint('vehicle').notNullable(); t.smallint('line').nullable(); }); } } async _loadLast() { const lineData = await this.db('veh_lines') .distinctOn('vehicle') .orderBy([ { column: 'vehicle', order: 'asc' }, { column: 'date', order: 'desc' }, ]); for (let row of lineData) { this.lines[row.vehicle.toString()] = parseInt(row.line) || null; } const vehData = await this.db .select('vehicle', 'date') .from('veh_pos') .distinctOn('vehicle') .orderBy([ { column: 'vehicle', order: 'asc' }, { column: 'date', order: 'desc' }, ]); for (let row of vehData) { this.vehModified[row.vehicle.toString()] = new Date(row.date); } } async putVehicle(veh) { // TODO: Add filters for data integrity (vehicleNumber === null let lineNumber = parseInt(veh.lineNumber) || null; if (this.lines[veh.vehicleNumber.toString()] !== lineNumber) { await this.db('veh_lines').insert({ vehicle: veh.vehicleNumber, line: veh.lineNumber, date: veh.lastModified, }); this.lines[veh.vehicleNumber.toString()] = lineNumber; } if (this.vehModified[veh.vehicleNumber]?.getTime() !== veh.lastModified.getTime()) { // console.log('for', veh.vehicleNumber, this.vehModified[veh.vehicleNumber], ' vs. from open', veh.lastModified) await this.db('veh_pos').insert({ vehicle: veh.vehicleNumber, line: veh.lineNumber, date: veh.lastModified, lat: veh.gpsLatitude, long: veh.gpsLongitude, }); this.vehModified[veh.vehicleNumber] = veh.lastModified; } } async getVehicleTrace(vehId, count) { return await this.db .select('date', 'lat', 'long') .from('veh_pos') .where({ vehicle: parseInt(vehId), }) // .andWhere('date', '<', '2022-06-24T14:07:00') .orderBy('date', 'desc') .limit(count); } async getLineTrace(line, count) { return await this.db .select('date', 'lat', 'long') .from('veh_pos') .where({ line: parseInt(line), }) .orderBy('date', 'desc') .limit(count); } async getSimpleLineTrace(line, count) { return await this.db .select('lat', 'long') .from('veh_pos') .where({ line: parseInt(line), }) .limit(count); } }