Socket
Socket
Sign inDemoInstall

quell

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quell - npm Package Compare versions

Comparing version 0.1.3 to 1.0.0

.eslintignore

10

CHANGELOG.md
1.0.0 / 2016-12-13
==================
* Now requires Node 4.2 or later
* Fewer dependencies
* Fixed bug where find.exec() could throw an error instead of passing it via callback/promise
* Fixed a bug that could cause date columns to be parsed with the wrong timezone.
* Pre-defined connections are now copied at instantiation instead of model definition.
* New test suite.
0.1.3 / 2016-10-27

@@ -3,0 +13,0 @@ ==================

550

lib/quell.js

@@ -1,6 +0,6 @@

var assign = require('lodash.assign');
'use strict';
var clone = require('lodash.clone');
var types = require('./types');
var queryize = require('queryize');
var Promise = require('es6-promise').Promise;
var proxmis = require('proxmis');

@@ -11,3 +11,4 @@ var util = require('util');

/**
* Creates a Model constructor, using provided the tablename and/or prototype, for creating records representing rows in the table.
* Creates a Model constructor, using provided the tablename and/or prototype, for
* creating records representing rows in the table.
* All properties of the options object will be mixed into to the model's prototype.

@@ -73,7 +74,7 @@ *

if (!options.tablename || typeof options.tablename !== 'string') {throw new TypeError('Tablename must be a string.');}
if (!options.tablename || typeof options.tablename !== 'string') { throw new TypeError('Tablename must be a string.'); }
var model = function () {
if (model.connection) {
this.connection = model.connection;
if (!this.connection) {
this.connection = model.prototype.connection || options.connection || quell.connection || false;
}

@@ -84,3 +85,3 @@ modelBase.apply(this, arguments);

// Copy over the Model members
assign(model, modelBase);
Object.assign(model, modelBase);

@@ -91,3 +92,3 @@ // Create the new Model prototype

// Apply any overrides
assign(model.prototype, options);
Object.assign(model.prototype, options);

@@ -100,5 +101,5 @@ model.prototype.tablename = model.tablename = options.tablename;

assign(quell, types);
Object.assign(quell, types);
module.exports = quell;
module.exports = exports = quell;

@@ -168,3 +169,4 @@ /**

/**
* Function called at model initialization. Abstract method intended to be overridden during model creation, not intended to be called directly.
* Function called at model initialization. Abstract method intended to be overridden during
* model creation, not intended to be called directly.
*

@@ -186,3 +188,3 @@ * Receives all arguments passed to `new Model()`.

*/
initialize: function () {
initialize () {
// override me

@@ -195,3 +197,3 @@ },

*/
toJSON: function () {
toJSON () {
return clone(this.data);

@@ -205,12 +207,13 @@ },

* @param {string} field The column to retrieve.
* @param {boolean} [formatted] Indicates if the data should be returned in the format MySQL would store it in. Defaults to true.
* @return {[type]}
* @param {boolean} [formatted] Indicates if the data should be returned in the format
* MySQL would store it in. Defaults to true.
* @return {mixed}
*/
get: function (field, formatted) {
get (field, formatted) {
// default to formatted unless the user passed false
if ((formatted || formatted === undefined) && this.schema && this.schema.columns && this.schema.columns[field]) {
return this.schema.columns[field].format(this.data[field]);
} else {
return this.data[field];
}
return this.data[field];
},

@@ -221,3 +224,6 @@

*
* If any of the attributes change the model's state, a "change" event will be triggered on the model. Change events for specific attributes are also triggered, and you can bind to those as well, for example: change:title, and change:content. You may also pass individual keys and values.
* If any of the attributes change the model's state, a "change" event will be triggered
* on the model. Change events for specific attributes are also triggered, and you can bind
* to those as well, for example: change:title, and change:content. You may also pass
* individual keys and values.
*

@@ -229,4 +235,3 @@ * @memberOf Record

*/
set: function (field, value, options) {
var attr, attrs, unset, changes, silent, changing, prev, current;
set (field, value, options) {
if (!field) {

@@ -237,2 +242,3 @@ return this;

// Handle both `"field", value` and `{field: value}` -style arguments.
var attrs;
if (typeof field === 'object') {

@@ -248,6 +254,6 @@ attrs = field;

// Extract data and options.
unset = options.unset;
silent = options.silent;
changes = [];
changing = this._changing;
var unset = options.unset;
var silent = options.silent;
var changes = [];
var changing = this._changing;
this._changing = true;

@@ -259,11 +265,13 @@

}
current = this.data;
prev = this._previousData;
var current = this.data;
var prev = this._previousData;
// For each `set` data, update or delete the current value.
for (attr in attrs) {
value = attrs[attr];
if (!isEqual(current[attr], value, this.schema && this.schema[attr])) {changes.push(attr);}
if (!isEqual(prev[attr], value, this.schema && this.schema[attr])) {
this.changed[attr] = value;
Object.keys(attrs).forEach((attr) => {
var attrValue = attrs[attr];
if (!isEqual(current[attr], attrValue, this.schema && this.schema[attr])) {
changes.push(attr);
}
if (!isEqual(prev[attr], attrValue, this.schema && this.schema[attr])) {
this.changed[attr] = attrValue;
} else {

@@ -275,9 +283,9 @@ delete this.changed[attr];

} else {
current[attr] = value;
current[attr] = attrValue;
}
}
});
// Trigger all relevant data changes.
if (!silent) {
if (changes.length) {this._pending = true;}
if (changes.length) { this._pending = true; }
for (var i = 0, l = changes.length; i < l; i++) {

@@ -290,3 +298,3 @@ this.emit('change:' + changes[i], this, current[changes[i]], options);

// be recursively nested within `"change"` events.
if (changing) {return this;}
if (changing) { return this; }
if (!silent) {

@@ -311,4 +319,4 @@ while (this._pending) {

*/
unset: function (field, options) {
return this.set(field, void 0, assign({}, options, {unset: true}));
unset (field, options) {
return this.set(field, undefined, Object.assign({}, options, { unset: true }));
},

@@ -323,4 +331,4 @@

*/
has: function (field) {
return this.get(field, false) !== undefined;
has (field) {
return Boolean(typeof this.data[field] !== 'undefined');
},

@@ -374,10 +382,8 @@

*/
load: function (value, field, options, callback) {
load (value, field, options, callback) {
switch (arguments.length) {
case 4:
break;
case 3:
if (typeof options === 'function') {
callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -403,2 +409,5 @@ options = options || {};

}
break;
default:
break;
}

@@ -421,8 +430,8 @@

return defer.then(
function (exists) { callback(null, exists); },
function (err) { callback(err || true); }
(exists) => { callback(null, exists); },
(err) => { callback(err || true); }
);
} else {
return defer;
}
return defer;
},

@@ -449,3 +458,3 @@

*/
save: function (options, callback) {
save (options, callback) {
var self = this;

@@ -455,3 +464,3 @@

callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -472,9 +481,9 @@ options = options || {};

return Promise.cast(self.exists === null ? self._promiseIfExists(options) : self.exists)
.then(function (exists) {
return Promise.resolve(self.exists === null ? self._promiseIfExists(options) : self.exists)
.then((exists) => {
if (exists) {
return self.update(options, callback);
} else {
return self.insert(options, callback);
}
return self.insert(options, callback);
});

@@ -502,6 +511,6 @@ },

*/
insert: function (options, callback) {
insert (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -513,38 +522,40 @@ options = options || {};

var self = this;
return this._promiseValidateSchema().then(function () {
var write = {},
fields = Object.keys(self.data),
field, type,
i = 0,
c = fields.length;
return this._promiseValidateSchema()
.then(() => {
var write = {};
var fields = Object.keys(self.data);
for (;i < c;i++) {
field = fields[i];
type = self.schema.columns[field];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const type = self.schema.columns[field];
if (type && typeof self.data[field] !== 'undefined' && (options.replace || self.schema.autoincrement !== field)) {
write[field] = type.prepare(self.data[field]);
if (type && typeof self.data[field] !== 'undefined' && (options.replace || self.schema.autoincrement !== field)) {
write[field] = type.prepare(self.data[field]);
}
}
}
return quell._buildInsertQuery(self.tablename, write, options.replace);
}).then(function (query) {
return quell._promiseQueryRun(query.query, query.data, (options && options.connection) || self.connection || quell.connection);
}).then(function (result) {
if (self.schema.autoincrement && result && result.insertId !== undefined) {
self.data[self.schema.autoincrement] = result.insertId;
}
return quell._buildInsertQuery(self.tablename, write, options.replace);
})
.then((query) => quell._promiseQueryRun(
query.query,
query.data,
(options && options.connection) || self.connection || quell.connection
))
.then((result) => {
if (self.schema.autoincrement && result && result.insertId !== undefined) {
self.data[self.schema.autoincrement] = result.insertId;
}
if (options.callback) {
options.callback(null, self);
}
if (options.callback) {
options.callback(null, self);
}
return self;
}).catch(function (err) {
if (options.callback) {
callback(err);
}
return self;
}).catch((err) => {
if (options.callback) {
callback(err);
}
return Promise.reject(err);
});
return Promise.reject(err);
});
},

@@ -571,6 +582,6 @@

*/
update: function (options, callback) {
update (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -582,58 +593,61 @@ options = options || {};

var self = this;
return this._promiseValidateSchema().then(function () {
var lookup = {},
lookupCount = 0,
write = {},
fields = Object.keys(self.data),
field, type,
i,c;
return this._promiseValidateSchema()
.then(() => {
var lookup = {};
var lookupCount = 0;
var write = {};
var fields = Object.keys(self.data);
if (typeof options.using === 'object') {
lookup = options.using;
lookupCount = Object.keys(lookup).length;
} else {
if (typeof options.using === 'object') {
lookup = options.using;
lookupCount = Object.keys(lookup).length;
} else {
for (i = 0, c = self.schema.primaries.length;i < c;i++) {
field = self.schema.primaries[i];
type = self.schema.columns[field];
for (let i = 0; i < self.schema.primaries.length; i++) {
const field = self.schema.primaries[i];
const type = self.schema.columns[field];
if (!self.has(field)) {
throw new Error('Could not update quell record, required primary key value was absent: ' + field);
} else {
lookup[field] = type.prepare(self.data[field]);
lookupCount++;
if (!self.has(field)) {
throw new Error('Could not update quell record, required primary key value was absent: ' + field);
} else {
lookup[field] = type.prepare(self.data[field]);
lookupCount++;
}
}
}
}
if (!lookupCount) {
throw new Error('Could not update quell record, no primary keys was available to update against.');
}
if (!lookupCount) {
throw new Error('Could not update quell record, no primary keys was available to update against.');
}
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const type = self.schema.columns[field];
for (i = 0, c = fields.length;i < c;i++) {
field = fields[i];
type = self.schema.columns[field];
if (type && typeof self.data[field] !== 'undefined' && (options.replace || self.schema.autoincrement !== field)) {
write[field] = type.prepare(self.data[field]);
}
}
if (type && typeof self.data[field] !== 'undefined' && (options.replace || self.schema.autoincrement !== field)) {
write[field] = type.prepare(self.data[field]);
return quell._buildUpdateQuery(self.tablename, write, lookup);
})
.then((query) => quell._promiseQueryRun(
query.query,
query.data,
(options && options.connection) || self.connection || quell.connection
))
.then(() => {
if (options.callback) {
options.callback(null, self);
}
}
return quell._buildUpdateQuery(self.tablename, write, lookup);
}).then(function (query) {
return quell._promiseQueryRun(query.query, query.data, (options && options.connection) || self.connection || quell.connection);
}).then(function () {
if (options.callback) {
options.callback(null, self);
}
return self;
}).catch((err) => {
if (options.callback) {
callback(err);
}
return self;
}).catch(function (err) {
if (options.callback) {
callback(err);
}
return Promise.reject(err);
});
return Promise.reject(err);
});
},

@@ -661,6 +675,6 @@

*/
delete: function (options, callback) {
delete (options, callback) {
if (typeof options === 'function') {
callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -672,21 +686,17 @@ options = options || {};

var self = this;
return this._promiseValidateSchema().then(function () {
var lookup = {},
lookupCount = 0,
field, type,
fields = self.schema.primaries,
i = 0,
c = fields.length;
return this._promiseValidateSchema()
.then(() => {
var lookup = {};
var lookupCount = 0;
var fields = self.schema.primaries;
if (typeof options.using === 'object') {
lookup = options.using;
lookupCount = Object.keys(lookup).length;
} else {
if (typeof options.using === 'object') {
lookup = options.using;
lookupCount = Object.keys(lookup).length;
// If the schema has no primary keys, use any column data we have.
} else if (fields.length) {
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const type = self.schema.columns[field];
// If the schema has no primary keys, use any column data we have.
if (c) {
for (;i < c;i++) {
field = fields[i];
type = self.schema.columns[field];
if (!self.has(field)) {

@@ -701,7 +711,6 @@ throw new Error('Could not delete quell record, required primary key value was absent: ' + field);

fields = Object.keys(self.schema.columns);
c = fields.length;
for (;i < c;i++) {
field = fields[i];
type = self.schema.columns[field];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const type = self.schema.columns[field];

@@ -715,27 +724,29 @@ if (self.has(field)) {

}
if (!lookupCount) {
throw new Error('Could not delete quell record, no data was available to delete against.');
}
if (!lookupCount) {
throw new Error('Could not delete quell record, no data was available to delete against.');
}
return quell._buildDeleteQuery(self.tablename, lookup);
})
.then((query) => quell._promiseQueryRun(
query.query,
query.data,
(options && options.connection) || self.connection || quell.connection
))
.then(() => {
self.exists = false;
return quell._buildDeleteQuery(self.tablename, lookup);
}).then(function (query) {
return quell._promiseQueryRun(query.query, query.data, (options && options.connection) || self.connection || quell.connection);
}).then(function () {
self.exists = false;
if (options.callback) {
options.callback(null, self);
}
if (options.callback) {
options.callback(null, self);
}
return self;
}).catch((err) => {
if (options.callback) {
callback(err);
}
return self;
}).catch(function (err) {
if (options.callback) {
callback(err);
}
return Promise.reject(err);
});
return Promise.reject(err);
});
},

@@ -750,5 +761,5 @@

*/
_loadWithExisting: function (options) {
_loadWithExisting (options) {
var self = this;
return this._promiseValidateSchema().then(function () {
return this._promiseValidateSchema().then(() => {
if (!self.schema.primaries || !self.schema.primaries.length) {

@@ -758,9 +769,7 @@ throw new Error('Could not load quell model using existing data; table has no primary keys.');

var lookup = {},
field, type,
i,c;
var lookup = {};
for (i = 0, c = self.schema.primaries.length;i < c;i++) {
field = self.schema.primaries[i];
type = self.schema.columns[field];
for (let i = 0; i < self.schema.primaries.length; i++) {
const field = self.schema.primaries[i];
const type = self.schema.columns[field];

@@ -786,5 +795,5 @@ if (!self.has(field)) {

*/
_loadWithPrimaryKey: function (value, options) {
_loadWithPrimaryKey (value, options) {
var self = this;
return this._promiseValidateSchema().then(function () {
return this._promiseValidateSchema().then(() => {
if (!self.schema.primaries.length) {

@@ -798,5 +807,5 @@ throw new Error('Could not load quell model using existing data; schema has no primary keys.');

var key = self.schema.primaries[0],
type = self.schema.columns[key],
lookup = {};
var key = self.schema.primaries[0];
var type = self.schema.columns[key];
var lookup = {};

@@ -818,7 +827,7 @@ lookup[key] = type.prepare(value);

*/
_loadWithSingleColumn: function (value, field, options) {
_loadWithSingleColumn (value, field, options) {
var self = this;
return this._promiseValidateSchema().then(function () {
var type = self.schema.columns[field],
lookup = {};
return this._promiseValidateSchema().then(() => {
var type = self.schema.columns[field];
var lookup = {};

@@ -843,5 +852,4 @@ if (!type) {

*/
_loadWithMultiColumn: function (search, options) {
var self = this;
return this._promiseValidateSchema().then(function () {
_loadWithMultiColumn (search, options) {
return this._promiseValidateSchema().then(() => {
if (typeof search !== 'object' || !Object.keys(search).length) {

@@ -851,10 +859,8 @@ throw new Error('Could not load quell model; provided data was empty or not an object.');

var lookup = {},
fields = Object.keys(search),
field, type,
i,c;
var lookup = {};
var fields = Object.keys(search);
for (i = 0, c = fields.length;i < c;i++) {
field = fields[i];
type = self.schema.columns[field];
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const type = this.schema.columns[field];

@@ -868,3 +874,3 @@ if (!type) {

return self._loadUsing(lookup, options);
return this._loadUsing(lookup, options);
});

@@ -877,10 +883,14 @@ },

* @memberOf Record
* @param {[type]} lookup
* @return {[type]}
* @param {object} lookup
* @return {boolean|self}
*/
_loadUsing: function (lookup, options) {
_loadUsing (lookup, options) {
var self = this;
var query = quell._buildSelectQuery(self.tablename, lookup);
return quell._promiseQueryRun(query.query, query.data, (options && options.connection) || self.connection || quell.connection).then(function (results) {
return quell._promiseQueryRun(
query.query,
query.data,
(options && options.connection) || self.connection || quell.connection
).then((results) => {
// If results are returned, then we found the row and can map the data onto the model

@@ -893,6 +903,6 @@ // If no results were returned, then the row wasn't found and we resolve with false.

return self;
} else {
self.exists = false;
return false;
}
self.exists = false;
return false;
});

@@ -908,9 +918,6 @@ },

*/
_promiseIfExists: function (options) {
_promiseIfExists (options) {
var self = this;
return this._promiseValidateSchema().then(function () {
var lookup = {},
key,
i = 0,
c = self.schema.primaries.length;
return this._promiseValidateSchema().then(() => {
var lookup = {};

@@ -921,3 +928,3 @@ // if there are no primary keys, then it is impossible to determine if this row existed

// primary keys will default to inserts.
if (!c) {
if (!self.schema.primaries.length) {
return (!!self.exists);

@@ -929,4 +936,4 @@ }

// and values to verify that the row exists.
for (;i < c;i++) {
key = self.schema.primaries[i];
for (let i = 0; i < self.schema.primaries.length; i++) {
const key = self.schema.primaries[i];
if (!self.has(key)) {

@@ -941,3 +948,7 @@ return (self.exists = false);

return quell._promiseQueryRun(query.query, query.data, (options && options.connection) || self.connection || quell.connection).then(function (results) {
return quell._promiseQueryRun(
query.query,
query.data,
(options && options.connection) || self.connection || quell.connection
).then((results) => {
self.exists = !!results.length;

@@ -957,3 +968,3 @@ return self.exists;

*/
_promiseValidateSchema: function () {
_promiseValidateSchema () {
var self = this;

@@ -979,12 +990,12 @@

if (!valid) {
return quell._promiseTableSchema(this.tablename, this.connection).then(function (schema) {
return quell._promiseTableSchema(this.tablename, this.connection).then((schema) => {
self.schema = schema;
});
} else {
return Promise.resolve();
}
}
return Promise.resolve();
},
};
assign(modelBase.prototype, Record);
Object.assign(modelBase.prototype, Record);

@@ -1002,3 +1013,3 @@ /**

var q = queryize()
.select(select || undefined)
.select(select || '*')
.from(tablename)

@@ -1071,7 +1082,3 @@ .where(lookup);

var callback = proxmis();
if (typeof mysql.execute === 'function') {
mysql.execute(query, data, callback);
} else {
mysql.query(query, data, callback);
}
mysql.query(query, data, callback);
return callback;

@@ -1090,7 +1097,4 @@ };

quell._promiseTableSchema = function (tablename, mysql) {
var defer = proxmis();
mysql.query('DESCRIBE ' + tablename, defer);
return defer.then(function (results) {
return this._promiseQueryRun('DESCRIBE ' + tablename, null, mysql).then((results) => {
var schema = {

@@ -1100,7 +1104,6 @@ columns: {},

autoincrement: false,
loaded: true
loaded: true,
};
var i = 0, c = results.length;
for (;i < c;i++) {
for (let i = 0; i < results.length; i++) {
parseRow(results[i]);

@@ -1112,3 +1115,3 @@ }

var column = {
NULL: row.Null === 'YES'
NULL: row.Null === 'YES',
};

@@ -1118,5 +1121,4 @@

column = types[row.Type.toUpperCase()](column);
}
else if ((matches = row.Type.match(/^(decimal|float|double)\((\d+),(\d+)\)/))) {
} else if ((matches = row.Type.match(/^(decimal|float|double)\((\d+),(\d+)\)/))) {
column.size = parseInt(matches[2], 10);

@@ -1126,22 +1128,19 @@ column.precision = parseInt(matches[3], 10);

column = types[matches[1].toUpperCase()](column);
}
else if ((matches = row.Type.match(/^((?:big|medium|small|tiny)?int(?:eger)?)\((\d+)\)/))) {
} else if ((matches = row.Type.match(/^((?:big|medium|small|tiny)?int(?:eger)?)\((\d+)\)/))) {
column.size = parseInt(matches[2], 10);
column.unsigned = row.Type.indexOf('unsigned') >= 0;
column = types[matches[1].toUpperCase()](column);
}
else if ((matches = row.Type.match(/^enum\((.*)\)/))) {
column.options = matches[1].split(',').map(function (o) { return o.slice(1, -1);});
} else if ((matches = row.Type.match(/^enum\((.*)\)/))) {
column.options = matches[1].split(',').map((opt) => opt.slice(1, -1));
column = types.ENUM(column);
}
else if ((matches = row.Type.match(/^((?:var)?char)\((\d+)\)/))) {
} else if ((matches = row.Type.match(/^((?:var)?char)\((\d+)\)/))) {
column.size = parseInt(matches[2], 10);
column = types[matches[1].toUpperCase()](column);
}
//didn't find a known type. Split the type field by opening parens to get the type name without other info.
else {
} else {
// didn't find a known type. Split the type field by opening
// parens to get the type name without other info.
column.type = row.Type.split('(')[0].toUpperCase();

@@ -1179,3 +1178,3 @@ if (types[column.type]) {

* @param {object} [where] An object hash of all columns to search against. Shortcut to calling .find().where()
* @return {[type]}
* @return {Queryize}
*/

@@ -1192,3 +1191,4 @@ modelBase.find = function (where) {

switch (arguments.length) {
case 2:
case 0:
conn = self.connection || quell.connection;
break;

@@ -1201,29 +1201,24 @@ case 1:

break;
case 0:
conn = self.connection || quell.connection;
break;
case 2:
default:
}
if (!conn) {
throw new Error('You must provide a node-mysql connection or pool for this query to use.');
const err = new Error('You must provide a node-mysql connection or pool for this query to use.');
if (callback) {
callback(err);
}
return Promise.reject(err);
}
var defer = proxmis();
exec.call(q, conn, defer);
var defer = proxmis(callback);
exec.call(q, conn, (err, results) => {
if (err) return defer(err);
return defer.then(function (results) {
results = results.map(function (row) {
return new self(row);
});
results = results.map((row) => new self(row)); // eslint-disable-line new-cap
if (callback) {
callback(null, results);
}
return results;
}, function (err) {
if (callback) {
callback(err);
}
return Promise.reject(err);
defer(null, results);
});
return defer.promise;
};

@@ -1244,3 +1239,3 @@

callback = options;
options = {callback: callback};
options = { callback };
} else {

@@ -1252,3 +1247,6 @@ options = options || {};

var self = this;
return quell._promiseTableSchema(this.tablename, (options && options.connection) || self.connection || quell.connection).then(function (schema) {
return quell._promiseTableSchema(
this.tablename,
(options && options.connection) || self.connection || quell.connection
).then((schema) => {
self.schema = schema;

@@ -1259,3 +1257,3 @@ if (options.callback) {

return self;
}, function (err) {
}, (err) => {
if (callback) {

@@ -1300,3 +1298,3 @@ callback(err);

if (a === b) {return true;}
if (a === b) { return true; }

@@ -1303,0 +1301,0 @@ return false;

@@ -0,18 +1,38 @@

'use strict';
var moment = require('moment');
var extend = require('lodash.assign');
var momentParse = require('moment-parseformat');
/**
* By default, quell will automatically load the table schema for any models that are created the first time a read/write operation is performed, but this operation may be skipped by predefining the table schema as part of the model. *Note: quell does not alter or create table structure, defining the schema in code is not a substitute for creating a table structure in the database.*
* By default, quell will automatically load the table schema for any models that are created
* the first time a read/write operation is performed, but this operation may be skipped by
* predefining the table schema as part of the model. *Note: quell does not alter or create
* table structure, defining the schema in code is not a substitute for creating a table
* structure in the database.*
*
* To make it easier to define table structure, all of the column data types are accessible directly from the quell object and can be used exactly as you would in a CREATE TABLE command (eg, `VARCHAR(10)`. If used as a value instead of a function, quell will use the default values for that type. To define extra column attributes such as integer sign and null acceptance, you must pass a column settings object as the main argument on the data type object. See the main [quell](#constructorquell) definition for an example.
* To make it easier to define table structure, all of the column data types are accessible
* directly from the quell object and can be used exactly as you would in a CREATE TABLE
* command (eg, `VARCHAR(10)`. If used as a value instead of a function, quell will use the
* default values for that type. To define extra column attributes such as integer sign and
* null acceptance, you must pass a column settings object as the main argument on the data
* type object. See the main [quell](#constructorquell) definition for an example.
*
* **Custom Types:**
*
* Every quell data type must define three functions: `format`, `prepare` and `compare` function. If any of these options are excluded from the settings object, the defaults for the base type are used.
* Every quell data type must define three functions: `format`, `prepare` and `compare`
* function. If any of these options are excluded from the settings object, the defaults
* for the base type are used.
*
* `prepare` is called right before the data is used in a query and sanitizes the input for the expected data type. In the case of integers this means stripping any non-numeric characters, for dates the value is parsed with Moment and then formatted as a MySQL date. String and Enum values are force cast to string. All values are tested for `null`.
* `prepare` is called right before the data is used in a query and sanitizes the input for
* the expected data type. In the case of integers this means stripping any non-numeric
* characters, for dates the value is parsed with Moment and then formatted as a MySQL date.
* String and Enum values are force cast to string. All values are tested for `null`.
*
* The `format` function is used when fetching data from the model via the `.get()` method. It attempts the structure whatever data is on the model in the way that MySQL would format it in the database (eg, trimming values for their column lengths). This is useful for validating model data before saving.
* The `format` function is used when fetching data from the model via the `.get()` method.
* It attempts the structure whatever data is on the model in the way that MySQL would format
* it in the database (eg, trimming values for their column lengths). This is useful for
* validating model data before saving.
*
* `compare` is called when quell is determining what columns have changed from their original values. It takes two arguments and returns a boolean.
* `compare` is called when quell is determining what columns have changed from their
* original values. It takes two arguments and returns a boolean.
* @signature quell.TYPE(settings)

@@ -25,3 +45,3 @@ * @constructor

if (typeof options === 'object' && !Array.isArray(options)) {
extend(o, this, options || {});
Object.assign(o, this, options || {});
} else if (typeof o.initialize === 'function') {

@@ -33,3 +53,3 @@ o.initialize.apply(o, arguments);

var compare = function (a,b) {
var compare = function (a, b) {
return this.format(a) === this.format(b);

@@ -42,9 +62,8 @@ };

size: 0,
format: function (o) {
format (o) {
if (o === null) {
if (this.NULL) {
return null;
} else {
return '';
}
return '';
}

@@ -56,18 +75,17 @@ if (this.size && this.size < o.length) {

},
prepare: function (o) {
prepare (o) {
if (o === null) {
if (this.NULL) {
return null;
} else {
return '';
}
return '';
}
return '' + o;
},
compare: compare,
initialize: function () {
compare,
initialize () {
if (arguments.length > 0) {
this.size = arguments[0];
}
}
},
};

@@ -79,3 +97,3 @@

options: [],
format: function (o) {
format (o) {
var NULL = this.NULL ? null : '';

@@ -88,3 +106,3 @@

o = '' + o;
var options = this.options.map(function (s) { return s.toUpperCase(); });
var options = this.options.map((s) => s.toUpperCase());
var i = options.indexOf(o.toUpperCase());

@@ -94,7 +112,8 @@

return this.options[i];
} else {
return NULL;
}
return NULL;
},
prepare: function (o) {
prepare (o) {
if (o === null) {

@@ -105,6 +124,6 @@ return this.NULL ? null : '';

},
compare: compare,
initialize: function () {
compare,
initialize () {
this.options = Array.prototype.slice.call(arguments);
}
},
};

@@ -118,3 +137,3 @@

unsigned: false,
format: function (o) {
format (o) {
var result;

@@ -136,9 +155,9 @@ var NULL = this.NULL ? null : '0';

var k = Math.pow(10, this.precision);
result = ('' + Math.round(o * k) / k).split('.');
result = String(Math.round(o * k) / k).split('.');
// if no decimal existed, make sure we create a place for it.
if (result.length === 1) {result.push('');}
if (result.length === 1) { result.push(''); }
} else {
// parse as float and round off, then store in an array to simplify below.
result = [Math.round(parseFloat(o))];
result = [ Math.round(parseFloat(o)) ];
}

@@ -162,3 +181,3 @@

},
prepare: function (o) {
prepare (o) {
if (o === null) {

@@ -176,4 +195,4 @@ return this.NULL ? null : 0;

},
compare: compare,
initialize: function () {
compare,
initialize () {
if (arguments.length > 0) {

@@ -185,3 +204,3 @@ this.size = arguments[0];

}
}
},
};

@@ -193,5 +212,9 @@

mask: 'YYYY-MM-DD HH:mm:ss',
format: function (o) {
format (o) {
var NULL = this.NULL ? null : '0000-00-00 00:00:00';
if (o === undefined) {
return undefined;
}
if (o === null) {

@@ -205,10 +228,17 @@ return NULL;

if (o instanceof Date) {
o = moment(o);
} else if (typeof o === 'string') {
o = moment(o, momentParse(o));
} else if (typeof o === 'number') {
o = moment(new Date(o));
}
o = moment(o).format(this.mask);
if (o === 'Invalid date') {
return NULL;
} else {
return o;
}
return o;
},
compare: compare
compare,
};

@@ -218,314 +248,314 @@ DATETIME.prepare = DATETIME.format;

function makeType (base, extras) {
var properties = extend({}, base, extras || {});
var properties = Object.assign({}, base, extras || {});
var type = TYPE.bind(properties);
return extend(type, properties);
return Object.assign(type, properties);
}
module.exports = {
/**
* TEXT Column Type
* @signature quell.TEXT
* @memberOf Schema
* @function TEXT
*/
TEXT : makeType(TEXT, {type: 'TEXT', size: 65535}),
/**
* BLOB Column Type
* @signature quell.BLOB
* @memberOf Schema
* @function BLOB
*/
BLOB : makeType(TEXT, {type: 'BLOB', size: 65535}),
/**
* TEXT Column Type
* @signature quell.TEXT
* @memberOf Schema
* @function TEXT
*/
exports.TEXT = makeType(TEXT, { type: 'TEXT', size: 65535 });
/**
* MEDIUMBLOB Column Type
* @signature quell.MEDIUMBLOB
* @memberOf Schema
* @function MEDIUMBLOB
*/
MEDIUMBLOB: makeType(TEXT, {type: 'MEDIUMBLOB', size: 16777215}),
/**
* BLOB Column Type
* @signature quell.BLOB
* @memberOf Schema
* @function BLOB
*/
exports.BLOB = makeType(TEXT, { type: 'BLOB', size: 65535 });
/**
* MEDIUMTEXT Column Type
* @signature quell.MEDIUMTEXT
* @memberOf Schema
* @function MEDIUMTEXT
*/
MEDIUMTEXT: makeType(TEXT, {type: 'MEDIUMTEXT', size: 16777215}),
/**
* MEDIUMBLOB Column Type
* @signature quell.MEDIUMBLOB
* @memberOf Schema
* @function MEDIUMBLOB
*/
exports.MEDIUMBLOB = makeType(TEXT, { type: 'MEDIUMBLOB', size: 16777215 });
/**
* LONGBLOB Column Type
* @signature quell.LONGBLOB
* @memberOf Schema
* @function LONGBLOB
*/
LONGBLOB : makeType(TEXT, {type: 'LONGBLOB', size: 4294967295}),
/**
* MEDIUMTEXT Column Type
* @signature quell.MEDIUMTEXT
* @memberOf Schema
* @function MEDIUMTEXT
*/
exports.MEDIUMTEXT = makeType(TEXT, { type: 'MEDIUMTEXT', size: 16777215 });
/**
* LONGTEXT Column Type
* @signature quell.LONGTEXT
* @memberOf Schema
* @function LONGTEXT
*/
LONGTEXT : makeType(TEXT, {type: 'LONGTEXT', size: 4294967295}),
/**
* LONGBLOB Column Type
* @signature quell.LONGBLOB
* @memberOf Schema
* @function LONGBLOB
*/
exports.LONGBLOB = makeType(TEXT, { type: 'LONGBLOB', size: 4294967295 });
/**
* TINYBLOB Column Type
* @signature quell.TINYBLOB
* @memberOf Schema
* @function TINYBLOB
*/
TINYBLOB : makeType(TEXT, {type: 'TINYBLOB', size: 255}),
/**
* LONGTEXT Column Type
* @signature quell.LONGTEXT
* @memberOf Schema
* @function LONGTEXT
*/
exports.LONGTEXT = makeType(TEXT, { type: 'LONGTEXT', size: 4294967295 });
/**
* TINYTEXT Column Type
* @signature quell.TINYTEXT
* @memberOf Schema
* @function TINYTEXT
*/
TINYTEXT : makeType(TEXT, {type: 'TINYTEXT', size: 255}),
/**
* TINYBLOB Column Type
* @signature quell.TINYBLOB
* @memberOf Schema
* @function TINYBLOB
*/
exports.TINYBLOB = makeType(TEXT, { type: 'TINYBLOB', size: 255 });
/**
* VARCHAR Column Type
* @signature quell.VARCHAR([size])
* @param {number} [size=255] Size of the varchar.
* @signature quell.VARCHAR(settings)
* @param {object} settings Detailed column options
* @example
* quell.VARCHAR({
* size: 10,
* NULL: false
* })
* @memberOf Schema
* @function VARCHAR
*/
VARCHAR : makeType(TEXT, {type: 'VARCHAR', size: 255}),
/**
* TINYTEXT Column Type
* @signature quell.TINYTEXT
* @memberOf Schema
* @function TINYTEXT
*/
exports.TINYTEXT = makeType(TEXT, { type: 'TINYTEXT', size: 255 });
/**
* CHAR Column Type
* @signature quell.CHAR([size])
* @param {number} [size=255] Size of the char.
* @signature quell.CHAR(settings)
* @param {object} settings Detailed column options
* @example
* quell.CHAR({
* size: 10,
* NULL: false
* })
* @memberOf Schema
* @function CHAR
*/
CHAR : makeType(TEXT, {type: 'CHAR', size: 255}),
/**
* VARCHAR Column Type
* @signature quell.VARCHAR([size])
* @param {number} [size=255] Size of the varchar.
* @signature quell.VARCHAR(settings)
* @param {object} settings Detailed column options
* @example
* quell.VARCHAR({
* size: 10,
* NULL: false
* })
* @memberOf Schema
* @function VARCHAR
*/
exports.VARCHAR = makeType(TEXT, { type: 'VARCHAR', size: 255 });
/**
* INT Column Type
* @signature quell.INT([length])
* @param {number} [length=11] Size of the integer.
* @memberOf Schema
* @signature quell.INT(settings)
* @param {object} settings Detailed column options
* @example
* quell.INT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @alias INTEGER
* @function INT
*/
INT : makeType(INT),
INTEGER : makeType(INT),
/**
* CHAR Column Type
* @signature quell.CHAR([size])
* @param {number} [size=255] Size of the char.
* @signature quell.CHAR(settings)
* @param {object} settings Detailed column options
* @example
* quell.CHAR({
* size: 10,
* NULL: false
* })
* @memberOf Schema
* @function CHAR
*/
exports.CHAR = makeType(TEXT, { type: 'CHAR', size: 255 });
/**
* TINYINT Column Type
* @signature quell.TINYINT([length])
* @param {number} [length=1] Size of the integer.
* @signature quell.TINYINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.TINYINT({
* length: 2,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function TINYINT
*/
TINYINT : makeType(INT, {type: 'TINYINT', size: 1}),
/**
* INT Column Type
* @signature quell.INT([length])
* @param {number} [length=11] Size of the integer.
* @memberOf Schema
* @signature quell.INT(settings)
* @param {object} settings Detailed column options
* @example
* quell.INT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @alias INTEGER
* @function INT
*/
exports.INT = makeType(INT);
exports.INTEGER = makeType(INT);
/**
* SMALLINT Column Type
* @signature quell.SMALLINT([length])
* @param {number} [length=4] Size of the integer.
* @signature quell.SMALLINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.SMALLINT({
* length: 3,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function SMALLINT
*/
SMALLINT : makeType(INT, {type: 'SMALLINT', size: 4}),
/**
* TINYINT Column Type
* @signature quell.TINYINT([length])
* @param {number} [length=1] Size of the integer.
* @signature quell.TINYINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.TINYINT({
* length: 2,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function TINYINT
*/
exports.TINYINT = makeType(INT, { type: 'TINYINT', size: 1 });
/**
* MEDIUMINT Column Type
* @signature quell.MEDIUMINT([length])
* @param {number} [length=8] Size of the integer.
* @signature quell.MEDIUMINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.MEDIUMINT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function MEDIUMINT
*/
MEDIUMINT : makeType(INT, {type: 'MEDIUMINT', size: 8}),
/**
* SMALLINT Column Type
* @signature quell.SMALLINT([length])
* @param {number} [length=4] Size of the integer.
* @signature quell.SMALLINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.SMALLINT({
* length: 3,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function SMALLINT
*/
exports.SMALLINT = makeType(INT, { type: 'SMALLINT', size: 4 });
/**
* BIGINT Column Type
* @signature quell.BIGINT([length])
* @param {number} [length=20] Size of the integer.
* @signature quell.BIGINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.BIGINT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function BIGINT
*/
BIGINT : makeType(INT, {type: 'BIGINT', size: 20}),
/**
* MEDIUMINT Column Type
* @signature quell.MEDIUMINT([length])
* @param {number} [length=8] Size of the integer.
* @signature quell.MEDIUMINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.MEDIUMINT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function MEDIUMINT
*/
exports.MEDIUMINT = makeType(INT, { type: 'MEDIUMINT', size: 8 });
/**
* FLOAT Column Type
* @signature quell.FLOAT([length], [precision])
* @param {number} [length=10] Display length of the float value, in characters.
* @param {number} [precision] Number of decimal places
* @signature quell.FLOAT(settings)
* @param {object} settings Detailed column options
* @example
* quell.FLOAT({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function FLOAT
*/
FLOAT : makeType(INT, {type: 'FLOAT', size: 10, precision: 2}),
/**
* BIGINT Column Type
* @signature quell.BIGINT([length])
* @param {number} [length=20] Size of the integer.
* @signature quell.BIGINT(settings)
* @param {object} settings Detailed column options
* @example
* quell.BIGINT({
* length: 10,
* unsigned: true,
* NULL: false
* })
* @memberOf Schema
* @function BIGINT
*/
exports.BIGINT = makeType(INT, { type: 'BIGINT', size: 20 });
/**
* DOUBLE Column Type
* @signature quell.DOUBLE([length], [precision])
* @param {number} [length=10] Display length of the double value.
* @param {number} [precision] Number of decimal places
* @signature quell.DOUBLE(settings)
* @param {object} settings Detailed column options
* @example
* quell.DOUBLE({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function DOUBLE
*/
DOUBLE : makeType(INT, {type: 'DOUBLE', size: 16, precision: 4}),
/**
* FLOAT Column Type
* @signature quell.FLOAT([length], [precision])
* @param {number} [length=10] Display length of the float value, in characters.
* @param {number} [precision] Number of decimal places
* @signature quell.FLOAT(settings)
* @param {object} settings Detailed column options
* @example
* quell.FLOAT({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function FLOAT
*/
exports.FLOAT = makeType(INT, { type: 'FLOAT', size: 10, precision: 2 });
/**
* DECIMAL Column Type
* @signature quell.DECIMAL([length], [precision])
* @param {number} length Display length of the decimal value.
* @param {number} precision Number of decimal places
* @signature quell.DECIMAL(settings)
* @param {object} settings Detailed column options
* @example
* quell.DECIMAL({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function DECIMAL
*/
DECIMAL : makeType(INT, {type: 'DECIMAL', size: 0, precision: 20}),
// DECIMALS must have a size and precision defined in the schema, so we're being ambiguous with the values
/**
* DOUBLE Column Type
* @signature quell.DOUBLE([length], [precision])
* @param {number} [length=10] Display length of the double value.
* @param {number} [precision] Number of decimal places
* @signature quell.DOUBLE(settings)
* @param {object} settings Detailed column options
* @example
* quell.DOUBLE({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function DOUBLE
*/
exports.DOUBLE = makeType(INT, { type: 'DOUBLE', size: 16, precision: 4 });
/**
* DATETIME Column Type
* @signature quell.DATETIME
* @memberOf Schema
* @function DATETIME
*/
DATETIME : makeType(DATETIME),
/**
* DECIMAL Column Type
* @signature quell.DECIMAL([length], [precision])
* @param {number} length Display length of the decimal value.
* @param {number} precision Number of decimal places
* @signature quell.DECIMAL(settings)
* @param {object} settings Detailed column options
* @example
* quell.DECIMAL({
* length: 6,
* precision: 4
* NULL: false
* })
* @memberOf Schema
* @function DECIMAL
*/
exports.DECIMAL = makeType(INT, { type: 'DECIMAL', size: 0, precision: 20 });
// DECIMALS must have a size and precision defined in the schema, so we're being ambiguous with the values
/**
* TIMESTAMP Column Type
* @signature quell.DATETIME
* @memberOf Schema
* @function DATETIME
*/
TIMESTAMP : makeType(DATETIME, {type: 'TIMESTAMP', NULL: false}),
/**
* DATETIME Column Type
* @signature quell.DATETIME
* @memberOf Schema
* @function DATETIME
*/
exports.DATETIME = makeType(DATETIME);
/**
* DATE Column Type
* @signature quell.DATE
* @memberOf Schema
* @function DATE
*/
DATE : makeType(DATETIME, {type: 'DATE', mask: 'YYYY-MM-DD'}),
/**
* TIMESTAMP Column Type
* @signature quell.DATETIME
* @memberOf Schema
* @function DATETIME
*/
exports.TIMESTAMP = makeType(DATETIME, { type: 'TIMESTAMP', NULL: false });
/**
* TIME Column Type
* @signature quell.TIME
* @memberOf Schema
* @function TIME
*/
TIME : makeType(DATETIME, {type: 'DATE', mask: 'HH:mm:ss'}),
/**
* DATE Column Type
* @signature quell.DATE
* @memberOf Schema
* @function DATE
*/
exports.DATE = makeType(DATETIME, { type: 'DATE', mask: 'YYYY-MM-DD' });
/**
* YEAR Column Type
* @signature quell.YEAR
* @memberOf Schema
* @function YEAR
*/
YEAR : makeType(DATETIME, {type: 'YEAR', mask: 'YYYY'}),
/**
* TIME Column Type
* @signature quell.TIME
* @memberOf Schema
* @function TIME
*/
exports.TIME = makeType(DATETIME, { type: 'DATE', mask: 'HH:mm:ss' });
/**
* ENUM Column Type
* @signature quell.ENUM(option1, option2, option3, ...)
* @param {string} options The possible values for the enum
* @signature quell.ENUM(settings)
* @param {object} settings Detailed column options
* @example
* quell.ENUM({
* options: ['Normal', 'Moderator', 'Admin'],
* NULL: false
* })
* @memberOf Schema
* @function ENUM
*/
ENUM : makeType(ENUM),
/**
* YEAR Column Type
* @signature quell.YEAR
* @memberOf Schema
* @function YEAR
*/
exports.YEAR = makeType(DATETIME, { type: 'YEAR', mask: 'YYYY' });
/**
* Used to define any column type not natively supported by Quell.
*
* See the Schema entry for details of the column format.
*
* @signature quell.UNKNOWN(settings)
* @param {Object} settings Type prototype
* @memberOf Schema
* @type {[type]}
*/
UNKNOWN : makeType(TEXT)
};
/**
* ENUM Column Type
* @signature quell.ENUM(option1, option2, option3, ...)
* @param {string} options The possible values for the enum
* @signature quell.ENUM(settings)
* @param {object} settings Detailed column options
* @example
* quell.ENUM({
* options: ['Normal', 'Moderator', 'Admin'],
* NULL: false
* })
* @memberOf Schema
* @function ENUM
*/
exports.ENUM = makeType(ENUM);
/**
* Used to define any column type not natively supported by Quell.
*
* See the Schema entry for details of the column format.
*
* @signature quell.UNKNOWN(settings)
* @param {Object} settings Type prototype
* @memberOf Schema
* @function UNKNOWN
*/
exports.UNKNOWN = makeType(TEXT);
{
"name": "quell",
"version": "0.1.3",
"version": "1.0.0",
"description": "A no-frills active record implementation for node-mysql.",
"main": "quell.js",
"main": "lib/quell.js",
"scripts": {
"test": "istanbul cover nodeunit -- tests",
"test-travis": "istanbul cover nodeunit --reporter=lcov -- tests",
"test": "eslint ./ && tap tests/unit tests/integration",
"test:int": "tap tests/integration",
"test:cover": "tap --coverage tests/unit tests/integration",
"test:travis": "npm run lint && tap --coverage tests/unit tests/integration",
"lint": "eslint ./",
"docs": "node docs/index.js"
},
"engines": {
"node": ">=4.2"
},
"repository": {

@@ -31,17 +37,32 @@ "type": "git",

"devDependencies": {
"nodeunit": "~0.8.2",
"nodeunit-dataprovider": "0.0.1",
"istanbul": "^0.2.6",
"dox": "git://github.com/ChiperSoft/dox.git#master",
"handlebars": "^1.3.0",
"lodash.foreach": "^2.4.1"
"dox": "~0.9.0",
"eslint": "^3.12.1",
"eslint-config-chiper": "^2.1.0",
"eslint-plugin-node": "~3.0.5",
"eslint-plugin-promise": "~3.4.0",
"handlebars": "^4.0.6",
"mktmpio": "^1.0.0-9",
"mysql": "^2.12.0",
"mysql2": "^1.1.2",
"promise-each": "~2.2.0",
"tap": "~8.0.1",
"tapdate": "^1.1.0",
"tapsuite": "^1.1.0"
},
"dependencies": {
"es6-promise": "^0.1.1",
"lodash.assign": "^2.4.1",
"lodash.clone": "^2.4.1",
"moment": "^2.5.1",
"proxmis": "^0.2.0",
"queryize": "^1.1.1"
"lodash.clone": "~4.5.0",
"moment": "~2.17.1",
"moment-parseformat": "~2.1.4",
"proxmis": "~1.0.0",
"queryize": "^2.0.0"
},
"nyc": {
"exclude": [
"tests"
],
"reporter": [
"lcov",
"text"
]
}
}

@@ -1,4 +0,63 @@

Quell.js
Quell
===
Readme coming soon. This project is in development and not yet ready for release.
Quell is a MySQL Active Record solution for NodeJS based on Backbone.Model.
Quell does not support joins. It is built to manage individual records in a database on a per-row basis.
Quell does not manage table schema, but will automatically load schema and sanitize input against table column types.
[![NPM version](https://img.shields.io/npm/v/quell.svg)](http://badge.fury.io/js/quell)
[![Licensed MIT](https://img.shields.io/npm/l/quell.svg)](https://github.com/ChiperSoft/quell/blob/master/LICENSE.txt)
[![Nodejs 4+](https://img.shields.io/badge/node.js-%3E=_4%20LTS-brightgreen.svg)](http://nodejs.org)
[![Downloads](http://img.shields.io/npm/dm/quell.svg)](http://npmjs.org/quell)
[![Build Status](https://img.shields.io/travis/ChiperSoft/quell.svg)](https://travis-ci.org/ChiperSoft/quell)
##Installation
NPM: `npm install mysql quell`
Quell is built to work with connection pools from [node-mysql](http://npm.im/mysql) and [mysql2](http://npm.im/mysql2).
##Usage
```js
var mysql = require('mysql');
var pool = mysql.createPool({ /* MySQL Connection Settings */});
var quell = require('quell');
var Book = quell('books', { connection: pool });
var Author = quell('authors', { connection: pool });
var tperry = new Author({
firstname: 'Terry',
lastname: 'Pratchett'
});
var nightWatch = new Book({
title: 'Night Watch'
});
tperry.save().then(function () {
nightWatch.set('authorid', tperry.get('id'));
return nightWatch.save();
});
```
**Visit [quelljs.com](http://quelljs.com/) for documentation.**
##Running Unit Tests
From inside the repository root, run `npm install` to install the test dependencies.
Run `npm run test:unit` to run just unit tests.
Run `npm run test:int` to run integration tests. Note, running the integration test requires a [mktmp.io](https://mktmp.io) account configuration.
Run `npm run test:cover` to run all tests with code coverage.
Run `npm run lint` to validate ESLint rules.
`npm test` runs all of the above.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc