Source: models/hydrants.js


const qrcodehelper = require('./qrcodehelper');

class hydrants {


    // Constructor    
    constructor(logger) {
        // always initialize all instance properties
        this._logger = logger;
    }


    /**
     * reads data for a given hydrant
     * @param {integer} hydrantId id of hydrant in table hydrants
     * @param {function} callback row or null
     */
    getHydrantDataForId(hydrantId, callback) {
        let query = "SELECT hydrants.*," +
            "hydrants_states.name AS statename, " +
            "hydrants_types.title AS typename, " +
            "hydrants_connections.title AS connectionstitle " +
            "FROM `hydrants` " +
            "INNER JOIN `hydrants_states` ON hydrants.state = hydrants_states.id " +
            "INNER JOIN `hydrants_types` ON hydrants.type = hydrants_types.id " +
            "INNER JOIN `hydrants_connections` ON hydrants.connections = hydrants_connections.id " +
            "WHERE hydrants.id = ?";

        global.coreDb.all(query, [
            hydrantId
        ], (err, rows) => {
            if (err) {
                this._logger.error('AUTH-MODEL | Error loading single hydrant from core data: ' + err.message);
                return callback(null);
            } else {
                return callback(rows);

            }
        });
    }

    /**
     * Returns list of hydrants from core database
     * @param {function} callback rows or null
     */
    getListOfHydrants(callback) {
        this._logger.info('Reading Hydrants');
        let query = "SELECT hydrants.*," +
            "hydrants_states.name AS statename, " +
            "hydrants_states.usable AS usable," +
            "hydrants_states.maintenance AS maintenance, " +
            "hydrants_types.title AS typename, " +
            "hydrants_connections.title AS connectionstitle " +
            "FROM `hydrants` " +
            "INNER JOIN `hydrants_states` ON hydrants.state = hydrants_states.id " +
            "INNER JOIN `hydrants_types` ON hydrants.type = hydrants_types.id " +
            "INNER JOIN `hydrants_connections` ON hydrants.connections = hydrants_connections.id ";

        global.coreDb.all(query, [], (err, rows) => {
            if (err) {
                this._logger.error('HYDRANTS-MODEL | Error loading list of hydrants from core data: ' + err.message);
                return callback(null);
            } else {
                return callback(rows);
            }
        });
    }

    /**
     * Returns list of hydtants from core database as JSON
     * @param {function} callback JSON String of hydrants
     */
    getListOfHydrantsJSON(callback) {
        this._logger.info('Reading Hydrants as JSON');
        let query = "SELECT hydrants.*," +
            "hydrants_states.name AS statename, " +
            "hydrants_states.usable AS usable," +
            "hydrants_states.maintenance AS maintenance, " +
            "hydrants_types.iconSvg AS iconsvg, " +
            "hydrants_types.iconSvgOutOfOrder AS iconsvgOutOfOrder, " +
            "hydrants_types.iconSvgUnknown AS iconsvgUnknown, " +
            "hydrants_types.title AS hydranttypename " +
            "FROM `hydrants` " +
            "INNER JOIN `hydrants_states` ON hydrants.state = hydrants_states.id " +
            "INNER JOIN `hydrants_types` ON hydrants.type = hydrants_types.id";

        global.coreDb.all(query, [], (err, rows) => {
            if (err) {
                this._logger.error('HYDRANTS-MODEL | Error loading list of hydrants from core data: ' + err.message);
                return callback(null);
            } else {
                var counter = 0;
                this._logger.info('HYDRANTS-MODEL | Read ' + rows.length + ' hydrants successfully');
                var returnJSON = "[";

                rows.forEach(hydrant => {
                    counter++;
                    var dividerStr = '';
                    if (counter > 0) {
                        dividerStr = ', ';
                    }
                    returnJSON = returnJSON + dividerStr + '{ lat: ' + hydrant.latitude + ', lon: ' + hydrant.longitude + ', streetname: \'' + hydrant.streetname + '\'}';
                });

                returnJSON = returnJSON + ']';
                //TEST
                returnJSON = JSON.stringify(rows);
                return callback(returnJSON);
            }
        });
    }


    addHydrantImage(reqFiles, hId, callback) {
        let uploadedFile = '';
        if (reqFiles === null) {
            this.logger.info('ROUTES-HYDRANT | no image file uploaded');
        } else {
            this.logger.info('ROUTES-HYDRANT | image file has been uploaded');
            uploadedFile = reqFiles.image;
            if (uploadedFile.mimetype === 'image/png' || uploadedFile.mimetype === 'image/jpeg' || uploadedFile.mimetype === 'image/gif') {
                this.logger.debug('ROUTES-HYDRANTS | User uploaded an accepted image with hydrant, add image to database entry in database');
                // upload the file to the /public/assets/img directory
                // get extension first
                switch (uploadedFile.mimetype) {
                    case 'image/png':
                        extension = '.png';
                        break;
                    case 'image/jpeg':
                        extension = '.png';
                        break;
                    case 'image/gif':
                        extension = '.gif';
                        break;
                    default:
                        extension = '.gif';
                }
                // Generate uuid for having more or less unique filename for image
                uuidFilename = uuidv1() + extension;
                // Move file
                this.logger.debug('ROUTES-HYDRANTS | Moving file to destination ' + `public/assets/img/${uuidFilename}`);
                uploadedFile.mv(`public/assets/img/${uuidFilename}`, (err) => {
                    if (err) {
                        this.logger.error('ROUTES-HYDRANTS | Error moving file to destination ' + `public/assets/img/${uuidFilename}: ` + err.message);
                    } else {
                        this.logger.debug('ROUTES-HYDRANTS | moved file to destination ' + `public/assets/img/${uuidFilename}. Updating database entry for hydrant`);
                        query = "UPDATE hydrants SET imgpath = " + db.escape(uuidFilename) + " WHERE id = " + db.escape(newID);
                        db.query(query, (err, result) => {
                            if (err) {
                                this.logger.error('ROUTES-HYDRANTS | error writing image to hydrant in database: ' + err.message);
                                res.redirect('/assets/hydrants/map');
                            } else {
                                this.logger.debug('ROUTES-HYDRANTS | generating QR-Code for Hydrant');
                                let qrcode = new qrcodehelper(this.logger);
                                qrcode.generateQrCodeToFileDestination('/assets/hydrants/edit/' + newID, 'public/assets/img/hydrants/qrcodes/' + newID + '.png', (err) => {
                                    if (err === true) {
                                        // QRCode generated
                                        //this.logger.error('ROUTES-HYDRANTS | Error generating QR-Code: ' + err.message);
                                        console.log('ROUTES-HYDRANTS | Error generating QR-Code: ' + err.message);
                                    } else {
                                        hydrants.setQrCodeForHydrantWithId(newID);
                                    }
                                    if ((latitude.length > 0) && (longitude.length > 0)) {
                                        res.redirect('/assets/hydrants/map/' + latitude + '/' + longitude);
                                    } else {
                                        res.redirect('/assets/hydrants/map');
                                    }
    
                                })
                            }
                        });
                    }
                });
            } else {
                this.logger.debug('ROUTES-HYDRANTS | User uploaded no image. Start generating QR-Code for Hydrant');
                let qrcode = new qrcodehelper(this.logger);
                this.logger.debug('ROUTES-HYDRANTS | Initializing QRCode helper');
                qrcode.generateQrCodeToFileDestination('/assets/hydrants/edit/' + newID, 'public/assets/img/hydrants/qrcodes/' + newID + '.svg', (qrresult) => {
                    if (qrresult) {
                        console.log('callback called');
                        // QRCode not generated
                        if ((latitude.length > 0) && (longitude.length > 0)) {
                            res.redirect('/assets/hydrants/map/' + latitude + '/' + longitude);
                        } else {
                            res.redirect('/assets/hydrants/map');
                        }
                    } else {
                        console.log('callback called 2');
                        // QRCode generated
                        hydrants.setQrCodeForHydrantWithId(newID);
                        if ((latitude.length > 0) && (longitude.length > 0)) {
                            res.redirect('/assets/hydrants/map/' + latitude + '/' + longitude);
                        } else {
                            res.redirect('/assets/hydrants/map');
                        }
                    }
                })
            }
        }
        
    }

    /**
     * 
     * @param {object} reqBody req.body containing form fields
     * @param {object} reqFiles req.files containing eventuelly uploaded images
     * @param {function} callback success (true or false), id of new hydrant in table
     */
    addHydrant(reqBody, reqFiles, callback) {
        let title = reqBody.title;
        let type = reqBody.type;
        let streetname = reqBody.streetname;
        let streetno = reqBody.streetno;
        let latitude = reqBody.latitude;
        let longitude = reqBody.longitude;
        let inflow = reqBody.inflow;
        if (inflow === '') { inflow = 0 };
        let pressureStatic = reqBody.pressure_static;
        if (pressureStatic === '') { pressureStatic = 0 };
        let pressureDynmic = reqBody.pressure_dynamic;
        if (pressureDynmic === '') { pressureDynmic = 0 };
        let diameterNominal = reqBody.diameter_nominal;
        if (diameterNominal === '') { diameterNominal = 0 };
        let freezesave = reqBody.freezesave;
        let allseason = reqBody.allseason;
        let connections = reqBody.connections;
        

        let state = reqBody.status;
        let notes = reqBody.notes;
        let accessdescription = reqBody.accessdescription;

        let query = `INSERT INTO hydrants (latitude, longitude, title, streetname, streetno, type, inflow, pressure_static, pressure_dynamic, freezesave, allseason, diameter_nominal, registered, state, connections, notes, accessdescription)
        VALUES
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`;

        global.coreDb.run(query,
            [
                latitude,
                longitude,
                title,
                streetname,
                streetno,
                type,
                inflow,
                pressureStatic,
                pressureDynmic,
                freezesave,
                allseason,
                diameterNominal,
                '',
                connections,
                notes,
                accessdescription
            ],
            function (err) {
                if (err) {
                    console.log('ERROR: ' + err.message);
                    callback(false, null);
                } else {
                    var insertId = this.lastID;
                    callback(true, insertId);
                }
            });








        db.query(query, (err, result) => {
            if (err) {
                // TODO: error handling needs to be done!
                this.logger.error('ROUTES-HYDRANTS | Error writing new Hydrant to database: ' + err.message);
            } else {
                // get ID of last inserted datbase record to add imagepath later
                let newID = result.insertId;
                this.logger.debug('ROUTES-HYDRANTS | Written new Hydrant successfully to database with id ' + newID);
                // Check if file has been uploaded and
                // check the filetype before uploading it
                
            }
        });
    }

    

    /**
     * Function returns types of hydrants 
     *
     * @param {*} callback
     * @returns list of hydrant types as mysql result
     * @memberof hydrants
     */
    getListOfHydrantTypes(callback) {
        this._logger.info('Reading Hydrants Types');
        let query = "SELECT * FROM `hydrants_types` WHERE state=1";
        global.coreDb.all(query, [], (err, rows) => {
            if (err) {
                this._logger.error('HYDRANTS-MODEL | Error loading list of hydrant types from core data: ' + err.message);
                return callback(null);
            } else {
                return callback(rows);
            }
        });
    }

    /**
    * Function returns types of hydrants 
    * @param {*} callback
    * @returns list of hydrant states as mysql result
    * @memberof hydrants
    */
    getListOfHydrantStates(callback) {
        this._logger.info('Reading Hydrant States');
        let query = "SELECT * FROM `hydrants_states` WHERE state=1";
        global.coreDb.all(query, [], (err, rows) => {
            if (err) {
                this._logger.error('HYDRANTS-MODEL | Error loading list of hydrant states from core data: ' + err.message);
                return callback(null);
            } else {
                return callback(rows);
            }
        });
    }

    /**
     * Sets the QR-Code Path and URL for a hydrant object in core database
     * @param {integer} id id of hydtant from core database
     */
    setQrCodeForHydrantWithId(id) {
        var qrcode = new qrcodehelper(this.logger);
        var qrCodeFileFullPath = qrcode.qrCodeFileFullPath(id);
        var qrCodeUrl = qrcode.qrCodeUrl(id);

        let query = "UPDATE `hydrants` SET qrcodepath = ?, qrcodeurl = ? WHERE id = ' + id";

        global.coreDb.run(query,
            [
                qrCodeFileFullPath,
                qrCodeUrl
            ],
            function (err) {
                if (err) {
                    console.log('ERROR: ' + err.message);
                    callback(false);
                } else {
                    callback(true);
                }
            });
    }

    /**
     * Deletes a hydrant from core database
     * @param {integer} hydrantId id of hydrant
     * @param {*} callback success (true/false)
     */
    deleteHydrant(hydrantId, callback) {
        let query = "DELETE FROM hydrants WHERE id = ?";
        global.coreDb.run(query,
            [
                hydrantId
            ],
            function (err) {
                if (err) {
                    console.log('ERROR: ' + err.message);
                    callback(false);
                } else {
                    callback(true);
                }
            });
    }
}

// export the class
module.exports = hydrants;