samedi 17 septembre 2016

Writing a mysql model instance module - new to node, am I doing this right?

I'm fairly new to node (about 2 weeks in) and am trying to wrap my head around writing more complex modules. There's a number of patterns I've seen across a number of 3rd party modules for doing these types of things, but I'm more curious in my case if there's a better way I should consider going about this?

It seems there's a more appropriate way to break this up and flatten it out. I thought about using prototypes but the context of this within prototyped functions maps to the main node object.

What can I do?

var mysql = require('../mysql');

module.exports = createModelInstance;

function createModelInstance(model, data) {
    var modelInstance = {};
        modelInstance.model = model;
        modelInstance.getProperties = getProperties;
        modelInstance.setProperties = setProperties;
        modelInstance.insert = insert;
        modelInstance.upsert = upsert;

    var modelInstanceProperties = {};

    setProperties(data);

    /**/
    function getProperties(matchingFields) {
        matchingFields = matchingFields || [];

        if (matchingFields.length > 0) {
            var properties = {};

            matchingFields.forEach(function(property) {
                if (modelInstanceProperties.hasOwnProperty(property)) {
                    properties[property] = modelInstanceProperties[property];
                }
            });

            return properties;
        } else {
            return modelInstanceProperties;
        }
    }

    function setProperties(data) {
        model.schema.forEach(function(field) {
            if (data.hasOwnProperty(field)) {
                modelInstanceProperties[field] = data[field];
            }
        });
    }

    function insert(callback) {
        mysql.writeConnection(function(error, writeConnection) {
            if (error) {
                callback(error);
                return;
            }

            var fields = [];
            var values = [];

            Object.keys(modelInstanceProperties).forEach(function(field) {
                if (mysql.isIllegalField(field)) { return; }

                fields.push(field);
                values.push(modelInstanceProperties[field]);
            });

            fields = "(" + fields.join(",") + ")";
            values = "('" + values.join("','") + "')";

            writeConnection.query(`INSERT INTO ${model.table} ${fields} VALUES${values}`, function(error, result) {
                writeConnection.release();

                if (error || !result.insertId) {
                    callback(error);
                    return;
                }

                setProperties({ id: result.insertId });

                callback(error, result);
            });
        });
    }

    function upsert(matchingFields, callback) {
        var matching = getProperties(matchingFields);

        model.getRow(matching, function(error, row) {
            if (row) {
                model.update(matching, modelInstanceProperties, callback);
            } else {
                insert(callback);
            }
        });
    }

    /**/
    return modelInstance;
}

Aucun commentaire:

Enregistrer un commentaire