Skip to content
This repository has been archived by the owner on Mar 4, 2019. It is now read-only.

Commit

Permalink
Cleaned up and ready to roll
Browse files Browse the repository at this point in the history
  • Loading branch information
subsonic committed Apr 27, 2012
0 parents commit 51574ad
Show file tree
Hide file tree
Showing 119 changed files with 10,843 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.DS_Store
15 changes: 15 additions & 0 deletions Cakefile
@@ -0,0 +1,15 @@
{spawn, exec} = require 'child_process'
sys = require 'util'

runCommand = (name, args...) ->
proc = spawn name, args
proc.stderr.on 'data', (buffer) -> console.log buffer.toString()
proc.stdout.on 'data', (buffer) -> console.log buffer.toString()
proc.on 'exit', (status) -> process.exit(1) if status isnt 0


task 'watch', 'compiles client CS and LESS', (options) ->
#runCommand 'sass', ['--watch', 'public/css/sass:public/css']
#runCommand 'coffee', '-o','models','-wc', 'coffeescript/models'
#runCommand 'vows', ['--spec']
runCommand 'coffee', '-o', 'lib', '-wc', 'lib/coffee'
11 changes: 11 additions & 0 deletions LICENSE
@@ -0,0 +1,11 @@
New BSD License
http://www.opensource.org/licenses/bsd-license.php
Copyright (c) 2009, Rob Conery (robconery@gmail.com)
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the SubSonic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 changes: 24 additions & 0 deletions README.markdown
@@ -0,0 +1,24 @@
Sane Data Access for Node and Relational Databases
=========================================

I don't know much about NodeJS - well I know enough to know that I love it. It's very fun, and I wanted to write a module for it. I'm not quite there yet, so the code in this repo is me, screwing around.

Wanna Help?
----------
If you know Javascript and you dig Massive - I could use some help with this. Right now it's hard-wired to PostGres and yes I know most Node folks use a document store and that's great. If you need or want to use a regular relational system - well why not use something fun like Massive?

Have a look at the test file (such as it is) and you'll see how I've wired it all together. Nothing crazy - lots of fun.

What You Need
-----------
Obviously, be sure to have NodeJS > 6.1 installed. You'll also need the following modules:

* mocha
* should
* pg

I like to use CoffeeScript for testing, so please be sure to follow that convention (I'd be very happy). However, the core is written in JS and I'd like to keep it that way.

Thank Yous
---------
Much of this code is lifted from NodeJS Orm: https://github.com/dresende/node-orm. It inspired me as the syntax was quite close to what I wanted to do - however it did just a bit more than I wanted and wasn't flexible like Massive is.
8 changes: 8 additions & 0 deletions db/massive_test.sql
@@ -0,0 +1,8 @@

-- in the terminal (assuming you have PostGres installed)...
-- createdb massive_test
-- psql massive_test
-- (run the command below)

drop table products;
create table products (id serial,name varchar(255), price decimal(8,2));
217 changes: 217 additions & 0 deletions lib/massive.model.js
@@ -0,0 +1,217 @@
var events =require("events");
var util = require("util");
var pg = require("pg");

var Query = function(_sql, _params){

events.EventEmitter.call(this);

this.params = _params || [];
this.sql =_sql;
this.connectionString = "tcp://postgres@localhost/test";

this.on("newListener", function(eventName){
//console.log(eventName);
var _that = this;
if(eventName == "row"){
//fire the query
pg.connect(this.connectionString, function(err,client){
var query = client.query(_that.sql);
query.on("row", function(row){
_that.emit("row",row);
})
});
}
})
this.execute = function(callback) {
var _that = this;
pg.connect(this.connectionString, function(err,client){
var query = client.query(_that.sql, _that.params , callback);
});
};

this.toArray = function(callback) {
var _that = this;
pg.connect(this.connectionString, function(err,client){
var query = client.query(_that.sql, _that.params, function(err,results){
if(err) throw err;
callback(null,results.rows);
});
});
}

this.limit = function (){
var _limit = "";
if(arguments.length > 1) _limit = " \nLIMIT (" + arguments[0] + "," + arguments[1] + ")";
else if(arguments.length > 0) _limit = " \nLIMIT " + arguments[0];

this.sql+=_limit;
return this;
}

this.order = function(order){
this.sql+= " \nORDER BY " + order;
return this;
}

this.where = function () {
var conditions = arguments[0];
var _conditions = [],
prop,
op,
_escapes = [],
n = _escapes.length + 1;
var k;
var limit = "";
var order = "";

for (k in conditions) {
if (!conditions.hasOwnProperty(k)) continue;

if (k.indexOf(" ") > 0) {
op = k.substr(k.indexOf(" ") + 1, k.length).replace(/^\s+/, "").trim();
prop = k.substr(0, k.indexOf(" "));

if ([ "=", "!", ">", "<", ">=", "<=", "!=", "<>" ].indexOf(op) == -1) {
op = "=";
}else if([ "!=", "<>"].indexOf(op) > -1) {
op = "<>";
} else if (op == "!") {
op = "!=";
}

} else {
prop = k;
op = "=";
}

switch (typeof conditions[k]) {
case "boolean":
_conditions.push("\"" + prop + "\"" + op + (conditions[k] ? 1 : 0));
break;
case "number":
_conditions.push("\"" + prop + "\"" + op + conditions[k]);
break;
default:
if (Array.isArray(conditions[k])) {
var array_conditions = [];

for (var i = 0; i < conditions[k].length; i++) {
array_conditions.push("$" + (n++));
_escapes.push(conditions[k][i]);
}
_conditions.push("\"" + prop + "\"" + ((op == "!=" || op == "<>") ? " NOT" : "") + " IN (" + array_conditions.join(", ") + ")");
} else {
_conditions.push("\"" + prop + "\"" + op + "$" + (n++));
_escapes.push(conditions[k]);
}
}
}

this.sql+= " \nWHERE " + _conditions.join(" \nAND ");
this.params = _escapes;
return this;
};
}

util.inherits(Query,events.EventEmitter);

var Massive = function(_tableName,options){

options || (options = {});

this.tableName = _tableName;

this.primaryKey = options["primaryKeyField"] || "id";
this.connectionString = options["connection"] || "postgresql://postgres@localhost/test";

this.client = require("pg");

this.options = {};

//this.emit("initialized");
this.parseArgs = function(args){
var argLength = args.length;
this.options = args;
if(argLength > 0){
this.options = args[0];
if(this.options.columns) this.columnsSpecified = true;
else this.whereSpecified = true;
}
};

this.select = function(){
this.parseArgs(arguments);
var _columns = this.options.columns || "*";
var query = new Query("SELECT " + _columns + " FROM " + this.tableName);
if(this.whereSpecified) query.where(arguments[0]);
return query;
};

this.inline= function(sql, params) {
return new Query(sql,params);
}

this.delete = function() {
this.parseArgs(arguments);
var query = new Query("DELETE FROM " + this.tableName);
if(arguments.length > 0) query = query.where(arguments[0]);
return query;
}

this.insert = function(){
if(arguments.length == 0 ) throw "Have to pass in some kind of value yo..."
var item = arguments[0];
var _sql = "INSERT INTO " + this.tableName;
var _args = [];
var _counter=1;
var _cols = [];
var _vals= [];
for(var prop in item){
_cols.push(prop);
_vals.push("$"+_counter);
_args.push(item[prop]);
_counter++;
};
_sql = _sql + "("+_cols.join(", ")+") VALUES ("+_vals.join(", ")+")";
return new Query(_sql,_args);

};

this.update = function(){
if(arguments.length < 2 ) throw "Have to pass in the update criteria and a key";

var item = arguments[0];
var key = arguments[1];

var _sql ="UPDATE " + _tableName+ " SET ";
var _args = []
var _counter=1;
var _vals = []
var _criteria = {};

for(var prop in item){
if (!item.hasOwnProperty(prop)) continue;
_vals.push(prop+"=$"+_counter);
_args.push(item[prop]);
_counter++;
}
_sql += _vals.join(", ");

_args.push(key);
var query = new Query(_sql,_args);
if(typeof(key) === "number"){
_criteria[this.primaryKey] = key;
return query.where(_criteria);
}else{
return query.where(key);
}



}

};

exports.Model = Massive;

9 changes: 9 additions & 0 deletions node_modules/pg/.lock-wscript

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions node_modules/pg/.npmignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions node_modules/pg/Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 51574ad

Please sign in to comment.