Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

downstairs

Package Overview
Dependencies
Maintainers
3
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

downstairs - npm Package Compare versions

Comparing version 0.2.8 to 0.2.9

config/defaults.json

7

lib/downstairs.js
var Downstairs = {};
var Table = require('./table');
var Collection = require('./collection')
var pg = require('pg')

@@ -9,3 +9,3 @@ , async = require('async')

Downstairs.connections = {};
Table.use(Downstairs);
Collection.use(Downstairs);

@@ -35,4 +35,5 @@ Downstairs.add = function(connection, name){

Downstairs.Table = Table;
Downstairs.Collection = Collection;
Downstairs.Table = Collection;
Downstairs.Connection = Connection;
module.exports = Downstairs;
var async = require('async')
, _ = require('underscore');
var fieldsFinder = function(keys, record){
var data = {};
_.each(keys, function(key){
if (key !== 'id'){
data[key] = record[key];
}
})
return data;
}
var Record = function(properties){

@@ -11,6 +23,22 @@ this._isNew = true;

// this.destroy = function(cb) {}
this.destroy = function(cb) {
var data = fieldsFinder(_.keys(this.properties), this);
this._model.delete({id: this.id}, cb);
}
// this.save = function(cb) {}
this.save = function(cb){
var data = fieldsFinder(_.keys(this.properties), this);
var _model = this._model;
this.isValid(function(err, result){
if (result){
return _model.update(data, {id: this.id}, cb);
}
else {
return cb(err, null);
}
});
}
//an interim step for reaching a JSON representation of the model

@@ -21,5 +49,4 @@ this.toJson = function(options) {

}
};
module.exports = Record;

@@ -1,355 +0,3 @@

var Table = {}
, async = require('async')
, _ = require('underscore')
, Record = require('./record');
Table.Downstairs;
Table.use = function(Downstairs){
Table.Downstairs = Downstairs;
}
var jsonConditionsToSQL = function(Model, conditions){
var clauses = [];
for (var key in conditions){
if (Model.sql[key]) {
if (typeof conditions[key] === 'null') {
var clause = Model.sql[key].isNull();
clauses.push(clause);
}
else if (conditions[key] || conditions[key] === '' || conditions[key] === 0) {
var clause = Model.sql[key].equals(conditions[key]);
clauses.push(clause);
}
}
}
var anded = ander(clauses);
return anded;
}
var ander = function(clauses){
var base = clauses.shift();
var chainer = function(clause){
base = base.and(clause);
};
clauses.forEach(chainer, base);
return base;
}
var parseConditions = function (conditions, _self, sqlBaseQuery) {
if (conditions){
var sqlConditions = jsonConditionsToSQL(_self, conditions);
if (sqlConditions) {
return sqlBaseQuery.where(sqlConditions);
}
}
return sqlBaseQuery;
}
var cleanData = function(sql, data){
var objectKeys = _.keys(data);
var differences = _.difference(objectKeys, sql._initialConfig.columns);
differences.forEach(function(diff){
delete data[diff];
})
return data;
}
/*
* Mixin behaviours for all models go here
*/
Table.findAll = function(conditions, cb){
var results = [];
if (typeof conditions === 'function') {
cb = conditions;
conditions = null;
}
var sqlStr;
var sqlBaseQuery = this.sql.select(this.sql.star()).from(this.sql);
sqlBaseQuery = parseConditions(conditions, this, sqlBaseQuery);
sqlStr = sqlBaseQuery.toQuery();
if (conditions && conditions.queryParameters){
if (conditions.queryParameters.orderBy){
sqlStr.text = sqlStr.text + " ORDER BY " + conditions.queryParameters['orderBy'];
}
if (conditions.queryParameters.limit){
sqlStr.text = sqlStr.text + " LIMIT " + conditions.queryParameters['limit'];
}
// if (conditions.queryParameters.offset){
// sqlStr.text = sqlStr.text + " OFFSET " + conditions.queryParameters['offset'];
// }
}
var _self = this;
var _cb = cb;
var finderAllCb = function(err, results){
var models = [];
if (results){
for (var i in results.rows){
var model = new _self(results.rows[i]);
models.push(model);
}
}
_cb(err, models);
}
if (!this.connection.connectionString) {
this.connection.connectionString = this.Downstairs.connectionString;
}
this.connection.query(sqlStr, finderAllCb);
};
Table.find = function(conditions, cb){
if (typeof conditions === 'function') {
cb = conditions;
conditions = null;
}
var findCb = function(err, models){
if (models && models[0]) {
cb(err, models[0]);
}
else {
cb(err, null);
}
}
this.findAll(conditions, findCb);
};
Table.count = function(conditions, cb){
var results = [];
if (typeof conditions === 'function') {
cb = conditions;
conditions = null;
}
var sqlStr;
var sqlBaseQuery = this.sql.select('COUNT(*)').from(this.sql);
sqlBaseQuery = parseConditions(conditions, this, sqlBaseQuery);
sqlStr = sqlBaseQuery.toQuery();
var _self = this;
var _cb = cb;
var countCb = function(err, results){
if (results && results.rows && results.rows[0] && results.rows[0].count) {
_cb(err, results.rows[0].count);
}
else {
_cb(err, 0);
}
}
if (!this.connection.connectionString) {
this.connection.connectionString = this.Downstairs.connectionString;
}
this.connection.query(sqlStr, countCb);
};
Table.update = function(data, conditions, cb){
if (typeof data === 'function'){
cb = data;
data = null;
conditions = null;
}
if (typeof conditions === 'function') {
cb = conditions;
conditions = null;
}
if (!conditions && data) {
if (data.nodes && data.left && data.right) {
// Sniff for a where clause condition object
conditions = data;
data = null;
}
}
var _cb = cb;
if (!data || typeof data === 'function') {
return _cb({message: 'No data was provided'}, false);
}
data = cleanData(this.sql, data);
var sqlStr;
var sqlBaseQuery = this.sql.update(data);
sqlBaseQuery = parseConditions(conditions, this, sqlBaseQuery);
sqlStr = sqlBaseQuery.toQuery();
var updateCb = function(err, results){
var result = false;
if (results && results.rowCount > 0 && results.command === 'UPDATE') {
result = true;
}
_cb(err, result);
}
this.connection.query(sqlStr, updateCb);
}
Table.create = function(data, cb){
if (typeof data === 'function') {
cb = data;
data = null;
}
var _cb = cb;
if (!data || typeof data === 'function') {
return _cb({message: 'No data was provided'}, false);
}
data = cleanData(this.sql, data);
var sqlStr;
var sqlBaseQuery = this.sql.insert(data);
sqlStr = sqlBaseQuery.toQuery();
var _self = this;
var queries = {};
queries.creator = function(insertCb) {
_self.connection.query(sqlStr, insertCb);
}
queries.findCreated = function(insertCb) {
_self.find(data, insertCb);
}
async.series(queries, function(err, queryResults) {
return _cb(err, queryResults.findCreated);
});
}
Table.delete = function(data, cb) {
if (typeof data === 'function') {
cb = data;
data = null;
}
var _cb = cb;
var sqlStr;
var sqlBaseQuery = this.sql.delete(data);
sqlStr = sqlBaseQuery.toQuery();
var deleteCb = function(err, results) {
var result = false;
if (!err) {
result = true;
}
_cb(err, result);
}
this.connection.query(sqlStr, deleteCb);
}
var mixinTableFunctions = function(obj){
for (var property in Table){
if (property === "model"){ continue }
if (typeof Table[property] === 'function'){
obj[property] = Table[property];
}
}
}
var createValidator = function(model, validationName){
return function(cb){
model[validationName](cb);
}
};
/*
* The model function creates a Model constructor function
* & copies all Table level behaviours onto the Model
* & copies the node-sql object onto the Model.
*/
Table.model = function(name, sql, validations, connectionName){
var dbConnection;
if (connectionName){
dbConnection = Table.Downstairs.get(connectionName);
} else {
dbConnection = Table.Downstairs.get('default');
}
var Model = function(properties){
this.properties = properties;
var validationCycle = [];
var _modelImplInstance = this;
for (var prop in properties){
this[prop] = this.properties[prop];
}
for (var validation in this.validations){
this[validation] = this.validations[validation];
var _self = this;
validationCycle.push(createValidator(_modelImplInstance, validation));
}
this.isValid = function(cb){
if (typeof this.validations === 'undefined'){
cb("Define validations on the model first.", null);
}
async.parallel(validationCycle, function(err, results){
var validationErrors = _.filter(results, function(result){ return result != null});
if (validationErrors.length == 0){
validationErrors = null
}
cb(validationErrors, validationErrors == null);
});
}
};
Model.prototype = new Record();
Model.prototype.constructor = Record;
Model.connection = dbConnection;
Model.sql = sql;
Model.prototype.sql = sql;
Model.Downstairs = Table.Downstairs;
Model.name = name;
Model.prototype.validations = validations;
mixinTableFunctions(Model);
if (!dbConnection){
throw new Error('There is no connection defined. Make sure you have called Downstairs.add(connection)');
}
else {
dbConnection.register(name, Model);
}
return Model;
}
module.exports = Table;
//for backwards compatability
Collection = require('./collection');
module.exports = Collection;
{
"name": "downstairs",
"description": "A light ORM wrapped about brianc's node-sql and node-pg",
"version": "0.2.8",
"version": "0.2.9",
"homepage": "https://github.com/moneytribeaustralia/downstairs.js",

@@ -6,0 +6,0 @@ "author": {

@@ -23,3 +23,17 @@ var pg = require('pg')

var accountBlueprint = {
Account: {
name: function(){ return faker2.Lorem.words(1).join(''); }
}
}
var roleBlueprint = {
Role: {
name: function(){ return faker2.Lorem.words(1).join(''); }
}
}
ctx.add(userBlueprint);
ctx.add(accountBlueprint);
ctx.add(roleBlueprint);

@@ -37,17 +51,42 @@ exports.ectypes = ctx;

exports.userSQL = sql.Table.define({
name: 'users'
, quote: true
, schema: 'public'
, columns: ['id'
, 'username'
, 'created_at'
, 'updated_at'
, 'email'
, 'null_field'
, 'password'
]
});
//common sql configurations used across tests
exports.userConfig = sql.Table.define({
name: 'users'
, quote: true
, schema: 'public'
, columns: ['id'
, 'username'
, 'created_at'
, 'updated_at'
, 'email'
, 'password'
, 'role_id'
]
});
exports.userTableSQL = "CREATE TABLE users\
exports.accountConfig = sql.Table.define({
name: 'accounts'
, quote: true
, columns: ['id'
, 'user_id'
]
});
exports.roleConfig = sql.Table.define({
name: 'roles'
, quote: true
, columns: ['id'
, 'name'
]
});
exports.repeatableConfig = sql.Table.define({
name: 'repeatables'
, quote: true
, schema: 'public'
, columns: ['id'
, 'name']
});
exports.userSQL = "CREATE TABLE users\
(\

@@ -59,13 +98,26 @@ id serial NOT NULL,\

email character varying(512) unique,\
null_field character varying(50),\
password character varying(512), \
role_id integer, \
CONSTRAINT pk_users PRIMARY KEY (id)\
);"
exports.repeatableTableSQL = "CREATE TABLE repeatables\
exports.accountSQL = "CREATE TABLE accounts\
(\
id serial NOT NULL,\
user_id integer, \
name character varying(100)\
);"
exports.roleSQL = "CREATE TABLE roles\
(\
id serial NOT NULL,\
name character varying(100)\
);"
exports.repeatableSQL = "CREATE TABLE repeatables\
(\
id serial NOT NULL,\
name character varying(100)\
);"
var defaultConnection = new Connection.PostgreSQL(env.connectionString);

@@ -72,0 +124,0 @@ exports.defaultConnection = defaultConnection;

@@ -7,8 +7,5 @@ var Downstairs = require('../lib/downstairs.js')

, ectypes = helper.ectypes
, Table = require('../lib/downstairs.js').Table
, Collection = require('../lib/downstairs.js').Collection
, Validator = require('validator').Validator;
var userSQL = helper.userSQL;
var userTableSQL = helper.userTableSQL;
var userValidations = {

@@ -38,3 +35,3 @@ usernamePresent: function(cb){

Downstairs.add(helper.defaultConnection);
var User = Table.model('User', userSQL, userValidations);
var User = Collection.model('User', helper.userConfig, userValidations);

@@ -44,3 +41,3 @@ describe('validations', function(done){

beforeEach(function(done){
helper.resetDb(userTableSQL, done);
helper.resetDb(helper.userSQL, done);
})

@@ -76,3 +73,3 @@

var User = Table.model('User', userSQL, userValidation);
var User = Collection.model('User', helper.userConfig, userValidation);
var user = new User({username: 'fred'});

@@ -79,0 +76,0 @@

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