Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added gitignore and dependencies in package.json

  • Loading branch information...
commit 9713891301fb623e195bd04b82dd63a3ad9dad88 1 parent a38305c
weepy@github.com authored
View
1  .gitignore
@@ -0,0 +1 @@
+node_modules
View
4 docs/index.html
@@ -370,7 +370,7 @@
<td class="code">
<pre><code><span class="class">Model</span>.<span class="variable">prototype</span>.<span class="variable">validate</span> = <span class="keyword">function</span>(<span class="variable">cb</span>) {
<span class="this">this</span>.<span class="variable">errors</span> = []
- <span class="this">this</span>.<span class="variable">_property_validate</span>()
+ <span class="this">this</span>.<span class="variable">_run_default_validations</span>()
<span class="this">this</span>.<span class="variable">trigger</span>(&<span class="variable">quot</span>;<span class="variable">saving</span>&<span class="variable">quot</span>;).<span class="variable">complete</span>(<span class="keyword">function</span>() {
<span class="variable">cb</span>.<span class="variable">call</span>(<span class="this">this</span>, !<span class="this">this</span>.<span class="variable">in_error</span>())
})
@@ -383,7 +383,7 @@
</p>
</td>
<td class="code">
-<pre><code><span class="class">Model</span>.<span class="variable">prototype</span>.<span class="variable">_property_validate</span> = <span class="keyword">function</span>() {
+<pre><code><span class="class">Model</span>.<span class="variable">prototype</span>.<span class="variable">_run_default_validations</span> = <span class="keyword">function</span>() {
<span class="keyword">for</span>(<span class="keyword">var</span> <span class="variable">i</span> <span class="keyword">in</span> <span class="variable">properties</span>) {
<span class="keyword">var</span> <span class="variable">p</span> = <span class="variable">properties</span>[<span class="variable">i</span>]
<span class="keyword">if</span>(<span class="variable">p</span>.<span class="variable">required</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="this">this</span>[<span class="variable">i</span>] == <span class="keyword">null</span>)
View
116 lib/core.js
@@ -47,7 +47,8 @@ module.exports = function(type, properties, store) {
*/
Model.type = type
Model.properties = properties
-
+ var fn = Model.prototype
+
/* Create a sychronized object (typically it would be one that been retrieved from a database)
*/
Model.load = function(props) {
@@ -86,7 +87,7 @@ module.exports = function(type, properties, store) {
* Synchonize an object
* This copies the local properties onto a _private_ _.properties object
*/
- Model.prototype._synchronize = function() {
+ fn._synchronize = function() {
this._.properties = {}
for(var k in properties) this._.properties[k] = this[k]
}
@@ -95,7 +96,7 @@ module.exports = function(type, properties, store) {
*
* @param {string} _optional_ if null, we'll check the whole function, else it will check only this property
*/
- Model.prototype.modified = function(prop) {
+ fn.modified = function(prop) {
var o = {}, modified
if(prop) {
@@ -114,13 +115,13 @@ module.exports = function(type, properties, store) {
/** Has this model been saved? I.e. is it _not_ modified
*/
- Model.prototype.saved = function() {
+ fn.saved = function() {
return !this.modified()
}
/** Update the model with the params and save it
*/
- Model.prototype.update = function(params, cb) {
+ fn.update = function(params, cb) {
params || (params == {})
Model.find(params.id, function(m) {
@@ -139,28 +140,42 @@ module.exports = function(type, properties, store) {
*
* @param {Function} optional callback. Returns the saved object
*/
- Model.prototype.save = function(cb) {
+ fn.save = function(cb) {
var self = this
+ self.errors = []
+
+ utils.achain.call(self, self._saveStack, [], function(err, results) {
+ if(!err) self._synchronize()
+ cb && cb.call(self, self)
+ })
+ }
+
+ fn._get_id = function(cb) {
+ // ignore ...
+ cb()
+ }
+
+ fn._trigger_creating = function(cb) {
if(this._.properties.id == null) {
this._.creating = true
- this.trigger("creating").complete(run_save_stack)
+ this.trigger("creating").complete(cb)
} else {
delete this._.creating
- run_save_stack()
- }
-
- function run_save_stack() {
- utils.achain.call(self, self._saveStack, [], function(err, results) {
- if(!err) self._synchronize()
- cb && cb.call(self, self)
- })
+ cb()
}
+
}
+ fn._trigger_saving = function(cb) {
+ this.trigger("saving").complete(function() {
+ cb.call(this, !this.in_error())
+ })
+ }
+
/** Add an error
*/
- Model.prototype.error = function(error) {
+ fn.error = function(error) {
this.errors || (this.errors = [])
this.errors.push(error)
}
@@ -170,7 +185,7 @@ module.exports = function(type, properties, store) {
* @param {Function} optional callback - returns if it was successful or not
* if successful triggers "destroyed"
*/
- Model.prototype.destroy = function(cb) {
+ fn.destroy = function(cb) {
var self = this
Model.destroy(this.id, function(ok) {
if(ok) self.trigger("destroyed")
@@ -182,7 +197,7 @@ module.exports = function(type, properties, store) {
* NB Does not return a string
* NB Date types are converted to numbers
*/
- Model.prototype.toJSON = function() {
+ fn.toJSON = function() {
var o = {}
for(var name in properties) {
if(name in this) {
@@ -198,13 +213,13 @@ module.exports = function(type, properties, store) {
/** Returns a JSON string representation
*/
- Model.prototype.toString = function() {
+ fn.toString = function() {
return JSON.stringify(this.toJSON())
}
/** Does this model have errors ?
*/
- Model.prototype.in_error = function() {
+ fn.in_error = function() {
return this.errors && this.errors.length != 0
}
@@ -213,7 +228,7 @@ module.exports = function(type, properties, store) {
* @param {Object} properties
* @param {Object} optional alternative for "this"
*/
- Model.prototype.merge = function(props, x) {
+ fn.merge = function(props, x) {
for(var name in properties)
if(name in props) (x || this)[name] = props[name]
return this
@@ -223,9 +238,9 @@ module.exports = function(type, properties, store) {
* performs some simple checks for 'required' and 'format' properties
* calls a "saving" callback, which on completion checks that the number of errors is zero and runs the callback
*/
- Model.prototype.validate = function(cb) {
+ fn.validate = function(cb) {
this.errors = []
- this._property_validate()
+ this._run_default_validations()
this.trigger("saving").complete(function() {
cb && cb.call(this, !this.in_error())
})
@@ -233,7 +248,7 @@ module.exports = function(type, properties, store) {
/** Simple Validation for 'required' and 'format' properties
*/
- Model.prototype._property_validate = function() {
+ fn._run_default_validations = function(cb) {
for(var i in properties) {
var p = properties[i]
if(p.required && this[i] == null)
@@ -241,32 +256,42 @@ module.exports = function(type, properties, store) {
if(p.format && this[i] && !this[i].match(p.format))
this.error(i + " is bad format")
}
+ cb && cb()
}
/** @private
* Trigger relevant callbacks and synchronize if succesful
*/
- Model.prototype._finalize_save = function(cb) {
+ fn._trigger_saved = function(cb) {
if(this.in_error()) {
this.trigger("error", "saving failed").complete(function(){
cb && cb(false)
})
} else {
this._synchronize()
- this.trigger("saved").complete(function() {
-
- if(this._.creating) {
- delete this._.creating
- this._.created = true
- this.trigger("created").complete(cb)
- } else {
- delete this._.created
- cb.call(this)
- }
- })
+ this.trigger("saved").complete(cb)
+ }
+ }
+
+ fn._trigger_created = function(cb) {
+ if(this._.creating) {
+ delete this._.creating
+ this._.created = true
+ this.trigger("created").complete(cb)
+ } else {
+ delete this._.created
+ cb.call(this)
}
}
+ fn._post_persist = function (next) {
+ next()
+ }
+
+ fn._check_errors = function(cb) {
+ cb && cb.call(this, !this.in_error())
+ }
+
/** @private
* Load the revelant store for this model
*/
@@ -278,6 +303,19 @@ module.exports = function(type, properties, store) {
if(store) Model._set_store(store)
+
+ fn._saveStack = [
+ fn._trigger_creating,
+ fn._trigger_saving,
+ fn._run_default_validations,
+ fn._check_errors,
+ fn._get_id,
+ fn._persist,
+ fn._post_persist,
+ fn._trigger_saved,
+ fn._trigger_created
+ ]
+
/** Events
* ------
@@ -293,14 +331,14 @@ module.exports = function(type, properties, store) {
@param {Function} callback to run
@param {boolean} is the callback async?
*/
- Model.bind = Model.prototype.bind = function(ev, callback, async) {
+ Model.bind = fn.bind = function(ev, callback, async) {
if(async) callback.async = true
var list = this._.callbacks[ev] || (this._.callbacks[ev] = [])
list.push(callback)
}
/* Unbind to all instances of Model or just this instance */
- Model.unbind = Model.prototype.unbind = function(ev, callback) {
+ Model.unbind = fn.unbind = function(ev, callback) {
if (!ev)
this._.callbacks = {}
else if (!callback)
@@ -323,7 +361,7 @@ module.exports = function(type, properties, store) {
@param {string} name of event
@param [further arugments]
*/
- Model.prototype.trigger = function(ev) // further args
+ fn.trigger = function(ev) // further args
{
var global = Model._.callbacks[ev] || []
local = this._.callbacks[ev] || [],
View
5 lib/edge_query.js
@@ -1,7 +1,7 @@
-function EdgeQuery(x, self) {
+function EdgeQuery(x, self, client) {
this.key = x
this.self = self
- this.client = self.client || self.constructor.client
+ this.client = client || self.client || self.constructor.client
}
EdgeQuery.prototype.range = function(low, high) {
@@ -79,6 +79,7 @@ EdgeQuery.prototype.all = function(cb) {
else cb.call(context, data)
})
+
this.client[method].apply(this.client, args)
}
View
8 lib/stores/memory.js
@@ -17,14 +17,6 @@ exports.mixin = function(Model) {
cb(true)
}
- fn._saveStack = [
- fn.validate,
- fn._get_id,
- fn._persist,
- fn._finalize_save
- ]
-
-
Model.find = function(id, cb) {
cb(Model.DB[id])
}
View
63 lib/stores/redis.js
@@ -1,6 +1,7 @@
var utils = require("../utils"),
- EdgeQuery = require("../edge_query")
-
+ EdgeQuery = require("../edge_query"),
+ redisify = require("redisify")
+
exports.mixin = function(Model) {
var fn = Model.prototype
@@ -8,23 +9,24 @@ exports.mixin = function(Model) {
return Model.type + "s"
}
+ fn.db = Model.db = redisify()
+
fn.key = function() {
return Model.type + ":" + this.id
}
-
+
Model.destroy = function(id, cb) {
- Model.client.del(Model.type + ":" + id, function(err, data) {
- Model.client.ZREM(Model.type +"s", id, function(err, data) {
+ (new Model({id: id})).db("del", "", function(data) {
+ Model.db("ZREM", "", id, function(data) {
cb && cb()
})
})
}
fn._persist = function(next) {
- var self = this, o = self.modified_as_strings()
+ var o = this.modified_as_strings()
- Model.client.HMSET(this.key(), o, function(err, data) {
- if(err) return next(false)
+ this.db("hmset", "", o, function(data) {
if(data != "OK") throw "no error and data != 1"
next()
})
@@ -33,7 +35,7 @@ exports.mixin = function(Model) {
fn._get_id = function(next) {
var self = this
if(this.id == null && Model.properties.id.auto_inc) {
- Model.client.INCR(Model.key() + ":id", function(err, data) {
+ Model.db("INCR", "id", function(data) {
self.id = data
next()
})
@@ -41,21 +43,14 @@ exports.mixin = function(Model) {
else next()
}
- fn._update_keys = function (next) {
+ fn._post_persist = function (next) {
var self = this
- Model.client.ZADD(Model.key(), self.rank(), self.id, function(err, data) {
- if(err) console.log("failed ZADD", err)
+
+ Model.db("ZADD", "", self.rank(), self.id, function(data) {
next()
})
}
-
- fn._saveStack = [
- fn.validate,
- fn._get_id,
- fn._persist,
- fn._update_keys,
- fn._finalize_save
- ]
+
fn.modified_as_strings = function() {
var o = {}
@@ -97,15 +92,15 @@ exports.mixin = function(Model) {
}
Model.count = function(cb) {
- Model.client.ZCARD(Model.key(), function(err, data) {
+ Model.db("ZCARD", "", function(data) {
cb(data)
})
}
Model.find = function(id, cb) {
- Model.client.HGETALL(Model.type + ":" +id, function(err, data) {
- if(err || !data || data.id == null) return cb(null, err)
+ (new Model({id: id})).db("HGETALL", "", function(data) {
+ if(!data || data.id == null) return cb(null)
var o = Model.new_from_strings(data)
cb(Model.load(o))
})
@@ -136,13 +131,13 @@ exports.mixin = function(Model) {
args.push(func)
// Q.add(function() {
- Model.client.sort.apply(Model.client, args)
+ Model.db.client.sort.apply(Model.db.client, args)
// })
}
Model.load_ids = function(ids, cb) {
- var ex = Model.client.multi();
+ var ex = Model.db.client.multi();
for(var i=0; i< ids.length;i++) {
var key = Model.type + ":" +ids[i]
ex = ex.hgetall(key)
@@ -159,14 +154,13 @@ exports.mixin = function(Model) {
}
Model.exists = function(id, cb) {
- Model.client.exists(Model.type + ":" + id, function(err, data) {
+ (new Model({id:id})).db("exists", "", function(err, data) {
cb(err || data == 1)
})
}
-
Model.find_edges = Model.prototype.find_edges = function(type) {
- return new EdgeQuery(this.key() +":"+type, this)
+ return new EdgeQuery(this.key() +":"+type, this, this.db.client)
}
Model.add_edge = Model.prototype.add_edge = function(type, id, score, cb) {
@@ -181,15 +175,16 @@ exports.mixin = function(Model) {
throw "ERROR: score: " + score + " is NaN"
}
- Model.client.ZADD(this.key() +":"+type, fscore, id, function(err, data) {
- cb && cb(!err)
+ this.db("ZADD", type, fscore, id, function(data) {
+ cb && cb(true)
})
}
-
+
+
Model.remove_edge = Model.prototype.remove_edge = function(type, id, cb) {
- Model.client.ZREM(this.key() +":"+type, id, function(err, data) {
- cb && cb(!err)
+ this.db("ZREM", type, id, function(data) {
+ cb && cb(1)
})
- }
+ }
}
View
8 lib/stores/rest.js
@@ -11,13 +11,7 @@ exports.mixin = function(Model) {
cb(o)
})
}
-
- fn._saveStack = [
- fn.validate,
- fn._persist,
- fn._finalize_save
- ]
-
+
Model.url = "/url/not/set/"
Model.find = function(id, cb) {
View
3  lib/utils.js
@@ -20,7 +20,8 @@ Promise.prototype.complete = function(cb) {
exports.promise = Promise
exports.achain = function achain(fns, args, done) {
- for(var i in fns) fns[i].async = true
+ for(var i in fns)
+ fns[i].async = true
exports.chain.call(this, fns, args, done)
}
View
3  package.json
@@ -7,7 +7,8 @@
"repository": "http://github.com/weepy/mmmodel",
"dependencies": {
"brequire": ">= 0.0.4",
- "redis": ">=0.5.7"
+ "redis": ">=0.5.7",
+ "redisifiy": ">=0.0.1"
},
"main": "index",
"engines": { "node": "0.4.x" }
View
12 test/test_memory.js
@@ -23,8 +23,8 @@ exports.unsaved_task_has_no_id = function(done) {
exports.save_valid_saved = function(done) {
var t = new Task({user: "billy"})
+
t.save(function(ok) {
-
ok.should.be.ok
is.ok(t.id, "is saved")
is.ok(t.saved())
@@ -43,6 +43,7 @@ exports.save_valid_saved = function(done) {
exports.invalid_task_is_not_saved = function(done) {
var t = new Task()
+
t.save(function(task) {
task.should.be.ok
is.ok(!t.saved())
@@ -91,10 +92,19 @@ exports.test_to_json = function(done) {
exports.test_failed_create = function(done) {
+
+
Task.create({id: 21}, function(p) {
is.ok(p.errors.length, "task needs owner")
+ p.saved().should.not.be.ok
+ })
+
+ Task.count(function(num) {
+ is.equal(num, 1, "task count is " + num)
done()
})
+
+
}
exports.test_create = function(done) {
View
10 test/test_redis.js
@@ -2,11 +2,13 @@ var x = {},
redis = require("redis"),
client = redis.createClient(),
is = require('assert'),
- should = require('should')
+ should = require('should'),
Task = require("./lib/task")("redis")
-Task.client = client
+Task.db.client = client
+
+// Task.db.log = console.log
client.on("error", function (err) {
console.log("Redis connection error to " + client.host + ":" + client.port + " - " + err);
@@ -34,6 +36,7 @@ exports.save_valid_task = function(done) {
ok.should.be.ok //(ok, "task saved ok")
is.ok(t.id, "is saved")
+
client.exists("Task:1", function(err, data) {
is.ok(!err)
@@ -245,9 +248,6 @@ exports.test_first = function(done) {
}
-
-
-
exports.test_destroy = function(done) {
Task.count(function(num) {
num.should.eql(4)
View
1  test/test_rest.js
@@ -29,6 +29,7 @@ Task.ajax = {
}
exports.test_non_existing_find = function(done) {
+
Task.find(1, function(task) {
is.ok(task === null)
done()
Please sign in to comment.
Something went wrong with that request. Please try again.