62 lines
214 KiB
HTML
62 lines
214 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
|
|
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/js/google-code-prettify/prettify.css">
|
|
<style>
|
|
code { background: none; color: none; border: none; };
|
|
li code { white-space: pre-wrap; margin: 0; padding: 0; border: 0; border-radius: 0; line-height: 18px }
|
|
.covered { background: #cfc; }
|
|
.uncovered { background: #fcc; }
|
|
a, a:visited { color:black; font-size:14pt; }
|
|
pre li .hits {
|
|
float: right;
|
|
margin-left: 10px;
|
|
padding: 2px 4px;
|
|
background: linear-gradient(#222, #666);
|
|
background: -webkit-gradient(linear, 0 0, 0 bottom, from(#222), to(#666));
|
|
background: -moz-linear-gradient(#222, #666);
|
|
background: linear-gradient(#222, #666);
|
|
color: white;
|
|
font-family: Helvetica, "Helvetica Neue", Arial, sans-serif;
|
|
font-size: 10px;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
border-radius: 3px;
|
|
line-height: 10px;
|
|
}
|
|
|
|
pre {
|
|
border: none;
|
|
background: none;
|
|
}
|
|
|
|
.S{color:red}
|
|
.func{color:blue}
|
|
.C{color:orange}
|
|
.kwrd{font-weight:bold}
|
|
.R{color:gray}
|
|
|
|
</style>
|
|
<script>
|
|
function init() {
|
|
var id = location.href.split('#')[1];
|
|
if (id)
|
|
document.getElementById(id).style.display = '';
|
|
}
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="row"><div class="span5"><a href="#lib-abstract-class-js" class="filename" name="lib-abstract-class-js" onclick="var el = document.getElementById('lib-abstract-class-js'); el.style.display = el.style.display ? '' : 'none';">lib/abstract-class.js</a></div><div class="span6"><div class="progress progress-warning"> <div class="bar" style="width: 78%"><strong>78%</strong> [310/938]</div></div></div></div><div id="lib-abstract-class-js" style="display:none;"><pre><ol><li class="covered"><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Module dependencies</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code><span class="kwrd">var</span> util = <span class="func">require</span>(<span class="S">'util'</span>);</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> jutil = <span class="func">require</span>(<span class="S">'./jutil'</span>);</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> Validatable = <span class="func">require</span>(<span class="S">'./validatable'</span>).Validatable;</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> Hookable = <span class="func">require</span>(<span class="S">'./hookable'</span>).Hookable;</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> DEFAULT_CACHE_LIMIT = 1000;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code>exports.AbstractClass = AbstractClass;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code>jutil.<span class="func">inherits</span>(AbstractClass, Validatable);</code><span class="hits">1</span></li><li class="covered"><code>jutil.<span class="func">inherits</span>(AbstractClass, Hookable);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Abstract class - base class for all persist objects</span></code></li><li class=""><code><span class="C"> * provides **common API** to access any database adapter.</span></code></li><li class=""><code><span class="C"> * This class describes only abstract behavior layer, refer to `lib/adapters/*.js`</span></code></li><li class=""><code><span class="C"> * to learn more about specific adapter implementations</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * `AbstractClass` mixes `Validatable` and `Hookable` classes methods</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @constructor</span></code></li><li class=""><code><span class="C"> * @param {Object} data - initial object data</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">AbstractClass</span>(data) <span class="gly">{</span></code></li><li class="covered"><code> this.<span class="func">_initProperties</span>(data, true);</code><span class="hits">152</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code>AbstractClass.prototype._initProperties = <span class="kwrd">function</span> (data, applySetters) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> self = this;</code><span class="hits">267</span></li><li class="covered"><code> <span class="kwrd">var</span> ctor = this.constructor;</code><span class="hits">267</span></li><li class="covered"><code> <span class="kwrd">var</span> ds = ctor.schema.definitions<span class="gly">[</span>ctor.modelName<span class="gly">]</span>;</code><span class="hits">267</span></li><li class="covered"><code> <span class="kwrd">var</span> properties = ds.properties;</code><span class="hits">267</span></li><li class="covered"><code> data = data <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">267</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (data.id) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">defineReadonlyProp</span>(this, <span class="S">'id'</span>, data.id);</code><span class="hits">109</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(this, <span class="S">'cachedRelations'</span>, <span class="gly">{</span></code></li><li class=""><code> writable: true,</code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> value: <span class="gly">{</span><span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">267</span></li><li class=""><code></code></li><li class=""><code> Object.<span class="func">keys</span>(properties).<span class="func">forEach</span>(<span class="kwrd">function</span> (attr) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">var</span> _attr = <span class="S">'_'</span> + attr,</code></li><li class="covered"><code> attr_was = attr + <span class="S">'_was'</span>;</code><span class="hits">1696</span></li><li class=""><code></code></li><li class=""><code> // Hidden property to store currrent value</code></li><li class=""><code> Object.<span class="func">defineProperty</span>(this, _attr, <span class="gly">{</span></code></li><li class=""><code> writable: true,</code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> value: <span class="func">isdef</span>(data<span class="gly">[</span>attr<span class="gly">]</span>) ? data<span class="gly">[</span>attr<span class="gly">]</span> :</code></li><li class=""><code> (<span class="func">isdef</span>(this<span class="gly">[</span>attr<span class="gly">]</span>) ? this<span class="gly">[</span>attr<span class="gly">]</span> : (</code></li><li class=""><code> <span class="func">getDefault</span>(attr)</code></li><li class=""><code> ))</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1696</span></li><li class=""><code></code></li><li class=""><code> // Public setters and getters</code></li><li class=""><code> Object.<span class="func">defineProperty</span>(this, attr, <span class="gly">{</span></code></li><li class=""><code> get: <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (ctor.getter<span class="gly">[</span>attr<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> ctor.getter<span class="gly">[</span>attr<span class="gly">]</span>.<span class="func">call</span>(this);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> this<span class="gly">[</span>_attr<span class="gly">]</span>;</code><span class="hits">601</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span>,</code></li><li class=""><code> set: <span class="kwrd">function</span> (value) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (ctor.setter<span class="gly">[</span>attr<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="covered"><code> ctor.setter<span class="gly">[</span>attr<span class="gly">]</span>.<span class="func">call</span>(this, value);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> this<span class="gly">[</span>_attr<span class="gly">]</span> = value;</code><span class="hits">9</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span>,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> enumerable: true</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1696</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (data.<span class="func">hasOwnProperty</span>(attr)) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (applySetters && ctor.setter<span class="gly">[</span>attr<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="covered"><code> ctor.setter<span class="gly">[</span>attr<span class="gly">]</span>.<span class="func">call</span>(this, data<span class="gly">[</span>attr<span class="gly">]</span>);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> // Getter <span class="kwrd">for</span> initial property</code></li><li class=""><code> Object.<span class="func">defineProperty</span>(this, attr_was, <span class="gly">{</span></code></li><li class=""><code> writable: true,</code></li><li class=""><code> value: this<span class="gly">[</span>_attr<span class="gly">]</span>,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> enumerable: false</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">156</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">267</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">getDefault</span>(attr) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">var</span> def = properties<span class="gly">[</span>attr<span class="gly">]</span><span class="gly">[</span><span class="S">'default'</span><span class="gly">]</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="func">isdef</span>(def)) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> def === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> <span class="func">def</span>();</code><span class="hits">102</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> def;</code><span class="hits">117</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> null;</code><span class="hits">688</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> this.<span class="func">trigger</span>(<span class="S">"initialize"</span>);</code><span class="hits">267</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code>AbstractClass.setter = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class="covered"><code>AbstractClass.getter = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * @param {String} prop - property name</span></code></li><li class=""><code><span class="C"> * @param {Object} params - various property configuration</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.defineProperty = <span class="kwrd">function</span> (prop, params) <span class="gly">{</span></code></li><li class="uncovered"><code> this.schema.<span class="func">defineProperty</span>(this.modelName, prop, params);</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>AbstractClass.whatTypeName = <span class="kwrd">function</span> (propName) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> ds = this.schema.definitions<span class="gly">[</span>this.modelName<span class="gly">]</span>;</code><span class="hits">4</span></li><li class="covered"><code> <span class="kwrd">return</span> ds.properties<span class="gly">[</span>propName<span class="gly">]</span>.type.name;</code><span class="hits">4</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>AbstractClass.prototype.whatTypeName = <span class="kwrd">function</span> (propName) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> this.constructor.<span class="func">whatTypeName</span>(propName);</code><span class="hits">2</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Create new instance of Model class, saved in database</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param data [optional]</span></code></li><li class=""><code><span class="C"> * @param callback(err, obj)</span></code></li><li class=""><code><span class="C"> * callback called with arguments:</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - err (null or Error)</span></code></li><li class=""><code><span class="C"> * - instance (null or Model)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.create = <span class="kwrd">function</span> (data, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">39</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> modelName = this.modelName;</code><span class="hits">39</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> data === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> callback = data;</code><span class="hits">5</span></li><li class="covered"><code> data = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">5</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> callback !== <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> callback = <span class="kwrd">function</span> () <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> obj = null;</code><span class="hits">39</span></li><li class=""><code> // <span class="kwrd">if</span> we come from save</code></li><li class=""><code> <span class="kwrd">if</span> (data instanceof AbstractClass && !data.id) <span class="gly">{</span></code></li><li class="covered"><code> obj = data;</code><span class="hits">5</span></li><li class="covered"><code> data = obj.<span class="func">toObject</span>(true);</code><span class="hits">5</span></li><li class="covered"><code> this.prototype._initProperties.<span class="func">call</span>(obj, data, false);</code><span class="hits">5</span></li><li class="covered"><code> <span class="func">create</span>();</code><span class="hits">5</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> obj = <span class="kwrd">new</span> <span class="func">this</span>(data);</code><span class="hits">34</span></li><li class="covered"><code> data = obj.<span class="func">toObject</span>(true);</code><span class="hits">34</span></li><li class=""><code></code></li><li class=""><code> // validation required</code></li><li class=""><code> obj.<span class="func">isValid</span>(<span class="kwrd">function</span> (valid) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!valid) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">callback</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Validation error'</span>), obj);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">create</span>();</code><span class="hits">34</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">34</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">create</span>() <span class="gly">{</span></code></li><li class=""><code> obj.<span class="func">trigger</span>(<span class="S">'create'</span>, <span class="kwrd">function</span> (done) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">_adapter</span>().<span class="func">create</span>(modelName, data, <span class="kwrd">function</span> (err, id) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (id) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">defineReadonlyProp</span>(obj, <span class="S">'id'</span>, id);</code><span class="hits">39</span></li><li class="covered"><code> <span class="func">addToCache</span>(this.constructor, obj);</code><span class="hits">39</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> done.<span class="func">call</span>(this, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, obj);</code><span class="hits">39</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">39</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">39</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">39</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">stillConnecting</span>(schema, obj, args) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (schema.connected) <span class="kwrd">return</span> false;</code></li><li class="uncovered"><code> <span class="kwrd">var</span> method = args.callee;</code></li><li class=""><code> schema.<span class="func">on</span>(<span class="S">'connected'</span>, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="uncovered"><code> method.<span class="func">apply</span>(obj, <span class="gly">[</span><span class="gly">]</span>.slice.<span class="func">call</span>(args));</code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class="uncovered"><code> <span class="kwrd">return</span> true;</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Update or insert</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.upsert = AbstractClass.updateOrCreate = <span class="kwrd">function</span> <span class="func">upsert</span>(data, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> Model = this;</code><span class="hits">1</span></li><li class="uncovered"><code> <span class="kwrd">if</span> (!data.id) <span class="kwrd">return</span> this.<span class="func">create</span>(data, callback);</code></li><li class=""><code> <span class="kwrd">if</span> (this.schema.adapter.updateOrCreate) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> inst = <span class="kwrd">new</span> <span class="func">Model</span>(data);</code></li><li class=""><code> this.schema.adapter.<span class="func">updateOrCreate</span>(Model.modelName, inst.<span class="func">toObject</span>(), <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> obj;</code></li><li class=""><code> <span class="kwrd">if</span> (data) <span class="gly">{</span></code></li><li class="uncovered"><code> inst.<span class="func">_initProperties</span>(data);</code></li><li class="uncovered"><code> obj = inst;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> obj = null;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (obj) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">addToCache</span>(Model, obj);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="func">callback</span>(err, obj);</code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">find</span>(data.id, <span class="kwrd">function</span> (err, inst) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">callback</span>(err);</code></li><li class=""><code> <span class="kwrd">if</span> (inst) <span class="gly">{</span></code></li><li class="uncovered"><code> inst.<span class="func">updateAttributes</span>(data, callback);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> obj = <span class="kwrd">new</span> <span class="func">Model</span>(data);</code></li><li class="uncovered"><code> obj.<span class="func">save</span>(data, callback);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Check whether object exitst in database</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {id} id - identifier of object (primary key value)</span></code></li><li class=""><code><span class="C"> * @param {Function} cb - callbacl called with (err, exists: Bool)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.exists = <span class="kwrd">function</span> <span class="func">exists</span>(id, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (id) <span class="gly">{</span></code></li><li class="covered"><code> this.schema.adapter.<span class="func">exists</span>(this.modelName, id, cb);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Model::exists requires positive id argument'</span>));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Find object by id</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {id} id - primary key value</span></code></li><li class=""><code><span class="C"> * @param {Function} cb - callback called with (err, instance)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.find = <span class="kwrd">function</span> <span class="func">find</span>(id, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">7</span></li><li class=""><code></code></li><li class=""><code> this.schema.adapter.<span class="func">find</span>(this.modelName, id, <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> obj = null;</code><span class="hits">7</span></li><li class=""><code> <span class="kwrd">if</span> (data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> cached = <span class="func">getCached</span>(this, data.id);</code><span class="hits">6</span></li><li class=""><code> <span class="kwrd">if</span> (cached) <span class="gly">{</span></code></li><li class="uncovered"><code> obj = cached;</code></li><li class="uncovered"><code> <span class="func">substractDirtyAttributes</span>(obj, data);</code></li><li class=""><code> // maybe just obj.<span class="func">_initProperties</span>(data); instead of</code></li><li class="uncovered"><code> this.prototype._initProperties.<span class="func">call</span>(obj, data);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> data.id = id;</code><span class="hits">6</span></li><li class="covered"><code> obj = <span class="kwrd">new</span> <span class="func">this</span>();</code><span class="hits">6</span></li><li class="covered"><code> obj.<span class="func">_initProperties</span>(data, false);</code><span class="hits">6</span></li><li class="covered"><code> <span class="func">addToCache</span>(this, id);</code><span class="hits">6</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="func">cb</span>(err, obj);</code><span class="hits">7</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">7</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Find all instances of Model, matched by query</span></code></li><li class=""><code><span class="C"> * make sure you have marked as `index: true` fields for filter or sort</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Object} params (optional)</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - where: Object `{ key: val, key2: {gt: 'val2'}}`</span></code></li><li class=""><code><span class="C"> * - order: String</span></code></li><li class=""><code><span class="C"> * - limit: Number</span></code></li><li class=""><code><span class="C"> * - skip: Number</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Function} callback (required) called with arguments:</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - err (null or Error)</span></code></li><li class=""><code><span class="C"> * - Array of instances</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.all = <span class="kwrd">function</span> <span class="func">all</span>(params, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">23</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (arguments.length === 1) <span class="gly">{</span></code></li><li class="covered"><code> cb = params;</code><span class="hits">2</span></li><li class="covered"><code> params = null;</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">var</span> constr = this;</code><span class="hits">23</span></li><li class=""><code> this.schema.adapter.<span class="func">all</span>(this.modelName, params, <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> collection = null;</code><span class="hits">23</span></li><li class=""><code> <span class="kwrd">if</span> (data && data.map) <span class="gly">{</span></code></li><li class=""><code> collection = data.<span class="func">map</span>(<span class="kwrd">function</span> (d) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> obj = null;</code><span class="hits">99</span></li><li class=""><code> // <span class="kwrd">do</span> not create different instances <span class="kwrd">for</span> the same object</code></li><li class="covered"><code> <span class="kwrd">var</span> cached = <span class="func">getCached</span>(constr, d.id);</code><span class="hits">99</span></li><li class=""><code> <span class="kwrd">if</span> (cached) <span class="gly">{</span></code></li><li class="uncovered"><code> obj = cached;</code></li><li class=""><code> // keep dirty attributes <span class="func">untouthed</span>(remove from dataset)</code></li><li class="uncovered"><code> <span class="func">substractDirtyAttributes</span>(obj, d);</code></li><li class="uncovered"><code> // maybe just obj.<span class="func">_initProperties</span>(d);</code></li><li class="uncovered"><code> constr.prototype._initProperties.<span class="func">call</span>(obj, d);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> obj = <span class="kwrd">new</span> constr;</code><span class="hits">99</span></li><li class="covered"><code> obj.<span class="func">_initProperties</span>(d, false);</code><span class="hits">99</span></li><li class="covered"><code> <span class="kwrd">if</span> (obj.id) <span class="func">addToCache</span>(constr, obj);</code><span class="hits">99</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">return</span> obj;</code><span class="hits">99</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">23</span></li><li class="covered"><code> <span class="func">cb</span>(err, collection);</code><span class="hits">23</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">23</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Find one record, same as `all`, limited by 1 and return object, not collection</span></code></li><li class=""><code><span class="C"> * </span></code></li><li class=""><code><span class="C"> * @param {Object} params - search conditions</span></code></li><li class=""><code><span class="C"> * @param {Function} cb - callback called with (err, instance)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.findOne = <span class="kwrd">function</span> <span class="func">findOne</span>(params, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> params === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> cb = params;</code><span class="hits">1</span></li><li class="covered"><code> params = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> params.limit = 1;</code><span class="hits">3</span></li><li class=""><code> this.<span class="func">all</span>(params, <span class="kwrd">function</span> (err, collection) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (err <span class="gly">|</span><span class="gly">|</span> !collection <span class="gly">|</span><span class="gly">|</span> !collection.length > 0) <span class="kwrd">return</span> <span class="func">cb</span>(err);</code><span class="hits">2</span></li><li class="covered"><code> <span class="func">cb</span>(err, collection<span class="gly">[</span>0<span class="gly">]</span>);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">substractDirtyAttributes</span>(object, data) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(object.<span class="func">toObject</span>()).<span class="func">forEach</span>(<span class="kwrd">function</span> (attr) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (data.<span class="func">hasOwnProperty</span>(attr) && object.<span class="func">propertyChanged</span>(attr)) <span class="gly">{</span></code></li><li class="uncovered"><code> delete data<span class="gly">[</span>attr<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Destroy all records</span></code></li><li class=""><code><span class="C"> * @param {Function} cb - callback called with (err)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.destroyAll = <span class="kwrd">function</span> <span class="func">destroyAll</span>(cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> this.schema.adapter.<span class="func">destroyAll</span>(this.modelName, <span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">clearCache</span>(this);</code><span class="hits">3</span></li><li class="covered"><code> <span class="func">cb</span>(err);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Return count of matched records</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Object} where - search conditions (optional)</span></code></li><li class=""><code><span class="C"> * @param {Function} cb - callback, called with (err, count)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.count = <span class="kwrd">function</span> (where, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> where === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> cb = where;</code><span class="hits">2</span></li><li class="covered"><code> where = null;</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> this.schema.adapter.<span class="func">count</span>(this.modelName, cb, where);</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Return string representation of class</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @override default toString method</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.toString = <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="S">'[Model '</span> + this.modelName + <span class="S">']'</span>;</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Save instance. When instance haven't id, create method called instead.</span></code></li><li class=""><code><span class="C"> * Triggers: validate, save, update | create</span></code></li><li class=""><code><span class="C"> * @param options {validate: true, throws: false} [optional]</span></code></li><li class=""><code><span class="C"> * @param callback(err, obj)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.save = <span class="kwrd">function</span> (options, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.constructor.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">8</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> options == <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> callback = options;</code><span class="hits">8</span></li><li class="covered"><code> options = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> callback = callback <span class="gly">|</span><span class="gly">|</span> <span class="kwrd">function</span> () <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">8</span></li><li class="covered"><code> options = options <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">8</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (!(<span class="S">'validate'</span> <span class="kwrd">in</span> options)) <span class="gly">{</span></code></li><li class="covered"><code> options.validate = true;</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (!(<span class="S">'throws'</span> <span class="kwrd">in</span> options)) <span class="gly">{</span></code></li><li class="covered"><code> options.throws = false;</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (options.validate) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">isValid</span>(<span class="kwrd">function</span> (valid) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (valid) <span class="gly">{</span></code></li><li class="covered"><code> save.<span class="func">call</span>(this);</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> err = <span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Validation error'</span>);</code></li><li class=""><code> // throws option is dangerous <span class="kwrd">for</span> async usage</code></li><li class=""><code> <span class="kwrd">if</span> (options.throws) <span class="gly">{</span></code></li><li class="uncovered"><code> throw err;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="func">callback</span>(err, this);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> save.<span class="func">call</span>(this);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">save</span>() <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">trigger</span>(<span class="S">'save'</span>, <span class="kwrd">function</span> (saveDone) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> modelName = this.constructor.modelName;</code><span class="hits">8</span></li><li class="covered"><code> <span class="kwrd">var</span> data = this.<span class="func">toObject</span>(true);</code><span class="hits">8</span></li><li class="covered"><code> <span class="kwrd">var</span> inst = this;</code><span class="hits">8</span></li><li class=""><code> <span class="kwrd">if</span> (inst.id) <span class="gly">{</span></code></li><li class=""><code> inst.<span class="func">trigger</span>(<span class="S">'update'</span>, <span class="kwrd">function</span> (updateDone) <span class="gly">{</span></code></li><li class=""><code> inst.<span class="func">_adapter</span>().<span class="func">save</span>(modelName, data, <span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> console.<span class="func">log</span>(err);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> inst.<span class="func">_initProperties</span>(data, false);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> updateDone.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> saveDone.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, inst);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>, data);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> inst.constructor.<span class="func">create</span>(inst, <span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class=""><code> saveDone.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, inst);</code><span class="hits">5</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">5</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">5</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>AbstractClass.prototype.isNewRecord = <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> !this.id;</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Return adapter of current record</span></code></li><li class=""><code><span class="C"> * @private</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype._adapter = <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> this.constructor.schema.adapter;</code><span class="hits">45</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Convert instance to Object</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Boolean} onlySchema - restrict properties to schema only, default false</span></code></li><li class=""><code><span class="C"> * when onlySchema == true, only properties defined in schema returned, </span></code></li><li class=""><code><span class="C"> * otherwise all enumerable properties returned</span></code></li><li class=""><code><span class="C"> * @returns {Object} - canonical object representation (no getters and setters)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.toObject = <span class="kwrd">function</span> (onlySchema) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> data = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">47</span></li><li class="covered"><code> <span class="kwrd">var</span> ds = this.constructor.schema.definitions<span class="gly">[</span>this.constructor.modelName<span class="gly">]</span>;</code><span class="hits">47</span></li><li class="covered"><code> <span class="kwrd">var</span> properties = ds.properties;</code><span class="hits">47</span></li><li class=""><code> // weird</code></li><li class=""><code> Object.<span class="func">keys</span>(onlySchema ? properties : this).<span class="func">concat</span>(<span class="gly">[</span><span class="S">'id'</span><span class="gly">]</span>).<span class="func">forEach</span>(<span class="kwrd">function</span> (property) <span class="gly">{</span></code></li><li class="covered"><code> data<span class="gly">[</span>property<span class="gly">]</span> = this<span class="gly">[</span>property<span class="gly">]</span>;</code><span class="hits">355</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">47</span></li><li class="covered"><code> <span class="kwrd">return</span> data;</code><span class="hits">47</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Delete object from persistence</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @triggers `destroy` hook (async) before and after destroying object</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.destroy = <span class="kwrd">function</span> (cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.constructor.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> this.<span class="func">trigger</span>(<span class="S">'destroy'</span>, <span class="kwrd">function</span> (destroyed) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">_adapter</span>().<span class="func">destroy</span>(this.constructor.modelName, this.id, <span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">removeFromCache</span>(this.constructor, this.id);</code><span class="hits">1</span></li><li class=""><code> <span class="func">destroyed</span>(<span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> cb && <span class="func">cb</span>(err);</code><span class="hits">1</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">1</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Update single attribute</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * equals to `updateAttributes({name: value}, cb)</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {String} name - name of property</span></code></li><li class=""><code><span class="C"> * @param {Mixed} value - value of property</span></code></li><li class=""><code><span class="C"> * @param {Function} callback - callback called with (err, instance)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.updateAttribute = <span class="kwrd">function</span> <span class="func">updateAttribute</span>(name, value, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> data = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class="covered"><code> data<span class="gly">[</span>name<span class="gly">]</span> = value;</code><span class="hits">1</span></li><li class="covered"><code> this.<span class="func">updateAttributes</span>(data, callback);</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Update set of attributes</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * this method performs validation before updating</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @trigger `validation`, `save` and `update` hooks</span></code></li><li class=""><code><span class="C"> * @param {Object} data - data to update</span></code></li><li class=""><code><span class="C"> * @param {Function} callback - callback called with (err, instance)</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.updateAttributes = <span class="kwrd">function</span> <span class="func">updateAttributes</span>(data, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.constructor.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">2</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> inst = this;</code><span class="hits">2</span></li><li class="covered"><code> <span class="kwrd">var</span> model = this.constructor.modelName;</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> // update instance's properties</code></li><li class=""><code> Object.<span class="func">keys</span>(data).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> inst<span class="gly">[</span>key<span class="gly">]</span> = data<span class="gly">[</span>key<span class="gly">]</span>;</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> inst.<span class="func">isValid</span>(<span class="kwrd">function</span> (valid) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!valid) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (cb) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Validation error'</span>));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">update</span>();</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">update</span>() <span class="gly">{</span></code></li><li class=""><code> inst.<span class="func">trigger</span>(<span class="S">'save'</span>, <span class="kwrd">function</span> (saveDone) <span class="gly">{</span></code></li><li class=""><code> inst.<span class="func">trigger</span>(<span class="S">'update'</span>, <span class="kwrd">function</span> (done) <span class="gly">{</span></code></li><li class=""><code></code></li><li class=""><code> Object.<span class="func">keys</span>(data).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> data<span class="gly">[</span>key<span class="gly">]</span> = inst<span class="gly">[</span>key<span class="gly">]</span>;</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> inst.<span class="func">_adapter</span>().<span class="func">updateAttributes</span>(model, inst.id, data, <span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!err) <span class="gly">{</span></code></li><li class="covered"><code> inst.<span class="func">_initProperties</span>(data, false);</code><span class="hits">2</span></li><li class=""><code> <span class="C">/*</span></code></li><li class=""><code><span class="C"> Object.keys(data).forEach(function (key) {</span></code></li><li class=""><code><span class="C"> inst[key] = data[key];</span></code></li><li class=""><code><span class="C"> Object.defineProperty(inst, key + '_was', {</span></code></li><li class=""><code><span class="C"> writable: false,</span></code></li><li class=""><code><span class="C"> configurable: true,</span></code></li><li class=""><code><span class="C"> enumerable: false,</span></code></li><li class=""><code><span class="C"> value: data[key]</span></code></li><li class=""><code><span class="C"> });</span></code></li><li class=""><code><span class="C"> });</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> done.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> saveDone.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">cb</span>(err, inst);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>, data);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>AbstractClass.prototype.fromObject = <span class="kwrd">function</span> (obj) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(obj).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="uncovered"><code> this<span class="gly">[</span>key<span class="gly">]</span> = obj<span class="gly">[</span>key<span class="gly">]</span>;</code></li><li class="uncovered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Checks is property changed based on current property and initial value</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {String} attr - property name</span></code></li><li class=""><code><span class="C"> * @return Boolean</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.propertyChanged = <span class="kwrd">function</span> <span class="func">propertyChanged</span>(attr) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> this<span class="gly">[</span><span class="S">'_'</span> + attr<span class="gly">]</span> !== this<span class="gly">[</span>attr + <span class="S">'_was'</span><span class="gly">]</span>;</code><span class="hits">11</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Reload object from persistence</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @requires `id` member of `object` to be able to call `find`</span></code></li><li class=""><code><span class="C"> * @param {Function} callback - called with (err, instance) arguments</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.reload = <span class="kwrd">function</span> <span class="func">reload</span>(callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">stillConnecting</span>(this.constructor.schema, this, arguments)) <span class="kwrd">return</span>;</code><span class="hits">2</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> obj = <span class="func">getCached</span>(this.constructor, this.id);</code><span class="hits">2</span></li><li class="covered"><code> <span class="kwrd">if</span> (obj) obj.<span class="func">reset</span>();</code><span class="hits">2</span></li><li class="covered"><code> this.constructor.<span class="func">find</span>(this.id, callback);</code><span class="hits">2</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Reset dirty attributes</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * this method does not perform any database operation it just reset object to it's</span></code></li><li class=""><code><span class="C"> * initial state</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.prototype.reset = <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> obj = this;</code></li><li class=""><code> Object.<span class="func">keys</span>(obj).<span class="func">forEach</span>(<span class="kwrd">function</span> (k) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (k !== <span class="S">'id'</span> && !obj.constructor.schema.definitions<span class="gly">[</span>obj.constructor.modelName<span class="gly">]</span>.properties<span class="gly">[</span>k<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> delete obj<span class="gly">[</span>k<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (obj.<span class="func">propertyChanged</span>(k)) <span class="gly">{</span></code></li><li class="uncovered"><code> obj<span class="gly">[</span>k<span class="gly">]</span> = obj<span class="gly">[</span>k + <span class="S">'_was'</span><span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Declare hasMany relation</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Class} anotherClass - class to has many</span></code></li><li class=""><code><span class="C"> * @param {Object} params - configuration {as:, foreignKey:}</span></code></li><li class=""><code><span class="C"> * @example `User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});`</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.hasMany = <span class="kwrd">function</span> <span class="func">hasMany</span>(anotherClass, params) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">var</span> methodName = params.as; // or <span class="func">pluralize</span>(anotherClass.modelName)</code></li><li class="covered"><code> <span class="kwrd">var</span> fk = params.foreignKey;</code><span class="hits">1</span></li><li class=""><code> // each instance of this class should have method named</code></li><li class=""><code> // <span class="func">pluralize</span>(anotherClass.modelName)</code></li><li class="uncovered"><code> // which is actually just anotherClass.<span class="func">all</span>(<span class="gly">{</span>where: <span class="gly">{</span>thisModelNameId: this.id<span class="gly">}</span><span class="gly">}</span>, cb);</code></li><li class=""><code> <span class="func">defineScope</span>(this.prototype, anotherClass, methodName, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> x = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">8</span></li><li class="covered"><code> x<span class="gly">[</span>fk<span class="gly">]</span> = this.id;</code><span class="hits">8</span></li><li class="covered"><code> <span class="kwrd">return</span> <span class="gly">{</span>where: x<span class="gly">}</span>;</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span>, <span class="gly">{</span></code></li><li class=""><code> find: find,</code></li><li class=""><code> destroy: destroy</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> // obviously, anotherClass should have attribute called `fk`</code></li><li class="covered"><code> anotherClass.schema.<span class="func">defineForeignKey</span>(anotherClass.modelName, fk);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">find</span>(id, cb) <span class="gly">{</span></code></li><li class=""><code> anotherClass.<span class="func">find</span>(id, <span class="kwrd">function</span> (err, inst) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">cb</span>(err);</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (!inst) <span class="kwrd">return</span> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Not found'</span>));</code></li><li class=""><code> <span class="kwrd">if</span> (inst<span class="gly">[</span>fk<span class="gly">]</span> == this.id) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(null, inst);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Permission denied'</span>));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">destroy</span>(id, cb) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">find</span>(id, <span class="kwrd">function</span> (err, inst) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">cb</span>(err);</code></li><li class=""><code> <span class="kwrd">if</span> (inst) <span class="gly">{</span></code></li><li class="uncovered"><code> inst.<span class="func">destroy</span>(cb);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Not found'</span>));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Declare belongsTo relation</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Class} anotherClass - class to belong</span></code></li><li class=""><code><span class="C"> * @param {Object} params - configuration {as: 'propertyName', foreignKey: 'keyName'}</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.belongsTo = <span class="kwrd">function</span> (anotherClass, params) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> methodName = params.as;</code><span class="hits">2</span></li><li class="covered"><code> <span class="kwrd">var</span> fk = params.foreignKey;</code><span class="hits">2</span></li><li class=""><code></code></li><li class="covered"><code> this.schema.<span class="func">defineForeignKey</span>(this.modelName, fk);</code><span class="hits">2</span></li><li class=""><code> this.prototype<span class="gly">[</span><span class="S">'__finders__'</span><span class="gly">]</span> = this.prototype<span class="gly">[</span><span class="S">'__finders__'</span><span class="gly">]</span> <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> this.prototype<span class="gly">[</span><span class="S">'__finders__'</span><span class="gly">]</span><span class="gly">[</span>methodName<span class="gly">]</span> = <span class="kwrd">function</span> (id, cb) <span class="gly">{</span></code></li><li class=""><code> anotherClass.<span class="func">find</span>(id, <span class="kwrd">function</span> (err,inst) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">cb</span>(err);</code></li><li class=""><code> <span class="kwrd">if</span> (inst<span class="gly">[</span>fk<span class="gly">]</span> === this.id) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(null, inst);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(<span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Permission denied'</span>));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> this.prototype<span class="gly">[</span>methodName<span class="gly">]</span> = <span class="kwrd">function</span> (p) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (p instanceof AbstractClass) <span class="gly">{</span> // acts as setter</code></li><li class="uncovered"><code> this<span class="gly">[</span>fk<span class="gly">]</span> = p.id;</code></li><li class="uncovered"><code> this.cachedRelations<span class="gly">[</span>methodName<span class="gly">]</span> = p;</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (<span class="kwrd">typeof</span> p === <span class="S">'function'</span>) <span class="gly">{</span> // acts as async getter</code></li><li class="uncovered"><code> this.__finders__<span class="gly">[</span>methodName<span class="gly">]</span>(this<span class="gly">[</span>fk<span class="gly">]</span>, p);</code></li><li class="uncovered"><code> <span class="kwrd">return</span> this<span class="gly">[</span>fk<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (<span class="kwrd">typeof</span> p === <span class="S">'undefined'</span>) <span class="gly">{</span> // acts as sync getter</code></li><li class="covered"><code> <span class="kwrd">return</span> this<span class="gly">[</span>fk<span class="gly">]</span>;</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span> // setter</code></li><li class="covered"><code> this<span class="gly">[</span>fk<span class="gly">]</span> = p;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">2</span></li><li class=""><code></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define scope</span></code></li><li class=""><code><span class="C"> * TODO: describe behavior and usage examples</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>AbstractClass.scope = <span class="kwrd">function</span> (name, params) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">defineScope</span>(this, this, name, params);</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">defineScope</span>(cls, targetClass, name, params, methods) <span class="gly">{</span></code></li><li class=""><code></code></li><li class=""><code> // collect meta info about scope</code></li><li class=""><code> <span class="kwrd">if</span> (!cls._scopeMeta) <span class="gly">{</span></code></li><li class="covered"><code> cls._scopeMeta = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> // anly make sence to add scope <span class="kwrd">in</span> meta <span class="kwrd">if</span> base and target classes</code></li><li class=""><code> // are same</code></li><li class=""><code> <span class="kwrd">if</span> (cls === targetClass) <span class="gly">{</span></code></li><li class="covered"><code> cls._scopeMeta<span class="gly">[</span>name<span class="gly">]</span> = params;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!targetClass._scopeMeta) <span class="gly">{</span></code></li><li class="covered"><code> targetClass._scopeMeta = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(cls, name, <span class="gly">{</span></code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> get: <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">var</span> f = <span class="kwrd">function</span> <span class="func">caller</span>(cond, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> actualCond;</code><span class="hits">1</span></li><li class=""><code> <span class="kwrd">if</span> (arguments.length === 1) <span class="gly">{</span></code></li><li class="covered"><code> actualCond = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class="covered"><code> cb = cond;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (arguments.length === 2) <span class="gly">{</span></code></li><li class="uncovered"><code> actualCond = cond;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> throw <span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Method only can be called with one or two arguments'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">return</span> targetClass.<span class="func">all</span>(<span class="func">mergeParams</span>(actualCond, caller._scope), cb);</code><span class="hits">1</span></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">12</span></li><li class="covered"><code> f._scope = <span class="kwrd">typeof</span> params === <span class="S">'function'</span> ? params.<span class="func">call</span>(this) : params;</code><span class="hits">12</span></li><li class="covered"><code> f.build = build;</code><span class="hits">12</span></li><li class="covered"><code> f.create = create;</code><span class="hits">12</span></li><li class="covered"><code> f.destroyAll = destroyAll;</code><span class="hits">12</span></li><li class=""><code> <span class="kwrd">for</span> (<span class="kwrd">var</span> i <span class="kwrd">in</span> methods) <span class="gly">{</span></code></li><li class="covered"><code> f<span class="gly">[</span>i<span class="gly">]</span> = methods<span class="gly">[</span>i<span class="gly">]</span>.<span class="func">bind</span>(this);</code><span class="hits">16</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> // define sub-scopes</code></li><li class=""><code> Object.<span class="func">keys</span>(targetClass._scopeMeta).<span class="func">forEach</span>(<span class="kwrd">function</span> (name) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(f, name, <span class="gly">{</span></code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> get: <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">mergeParams</span>(f._scope, targetClass._scopeMeta<span class="gly">[</span>name<span class="gly">]</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">return</span> f;</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">7</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">12</span></li><li class="covered"><code> <span class="kwrd">return</span> f;</code><span class="hits">12</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> // and it should have create/build methods with binded thisModelNameId param</code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">build</span>(data) <span class="gly">{</span></code></li><li class="covered"><code> data = data <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">return</span> <span class="kwrd">new</span> <span class="func">targetClass</span>(<span class="func">mergeParams</span>(this._scope, <span class="gly">{</span>where:data<span class="gly">}</span>).where);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">create</span>(data, cb) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> data === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> cb = data;</code><span class="hits">2</span></li><li class="covered"><code> data = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> this.<span class="func">build</span>(data).<span class="func">save</span>(cb);</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">destroyAll</span>(id, cb) <span class="gly">{</span></code></li><li class=""><code> // implement me</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">mergeParams</span>(base, update) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (update.where) <span class="gly">{</span></code></li><li class="covered"><code> base.where = <span class="func">merge</span>(base.where, update.where);</code><span class="hits">7</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> // overwrite order</code></li><li class=""><code> <span class="kwrd">if</span> (update.order) <span class="gly">{</span></code></li><li class="uncovered"><code> base.order = update.order;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">return</span> base;</code><span class="hits">7</span></li><li class=""><code></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Check whether `s` is not undefined</span></code></li><li class=""><code><span class="C"> * @param {Mixed} s</span></code></li><li class=""><code><span class="C"> * @return {Boolean} s is undefined</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">isdef</span>(s) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> undef;</code><span class="hits">3603</span></li><li class="covered"><code> <span class="kwrd">return</span> s !== undef;</code><span class="hits">3603</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Merge `base` and `update` params</span></code></li><li class=""><code><span class="C"> * @param {Object} base - base object (updating this object)</span></code></li><li class=""><code><span class="C"> * @param {Object} update - object with new data to update base</span></code></li><li class=""><code><span class="C"> * @returns {Object} `base`</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">merge</span>(base, update) <span class="gly">{</span></code></li><li class="covered"><code> base = base <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">7</span></li><li class=""><code> <span class="kwrd">if</span> (update) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(update).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> base<span class="gly">[</span>key<span class="gly">]</span> = update<span class="gly">[</span>key<span class="gly">]</span>;</code><span class="hits">4</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">7</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">return</span> base;</code><span class="hits">7</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define readonly property on object</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Object} obj</span></code></li><li class=""><code><span class="C"> * @param {String} key</span></code></li><li class=""><code><span class="C"> * @param {Mixed} value</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">defineReadonlyProp</span>(obj, key, value) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(obj, key, <span class="gly">{</span></code></li><li class=""><code> writable: false,</code></li><li class=""><code> enumerable: true,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> value: value</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">148</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Add object to cache</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">addToCache</span>(constr, obj) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span>;</code><span class="hits">144</span></li><li class="uncovered"><code> <span class="func">touchCache</span>(constr, obj.id);</code></li><li class="uncovered"><code> constr.cache<span class="gly">[</span>obj.id<span class="gly">]</span> = obj;</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Renew object position in LRU cache index</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">touchCache</span>(constr, id) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> cacheLimit = constr.CACHE_LIMIT <span class="gly">|</span><span class="gly">|</span> DEFAULT_CACHE_LIMIT;</code><span class="hits">101</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> ind = constr.mru.<span class="func">indexOf</span>(id);</code><span class="hits">101</span></li><li class="covered"><code> <span class="kwrd">if</span> (~ind) constr.mru.<span class="func">splice</span>(ind, 1);</code><span class="hits">101</span></li><li class=""><code> <span class="kwrd">if</span> (constr.mru.length >= cacheLimit * 2) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">for</span> (<span class="kwrd">var</span> i = 0; i < cacheLimit;i += 1) <span class="gly">{</span></code></li><li class="uncovered"><code> delete constr.cache<span class="gly">[</span>constr.mru<span class="gly">[</span>i<span class="gly">]</span><span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> constr.mru.<span class="func">splice</span>(0, cacheLimit);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Retrieve cached object</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">getCached</span>(constr, id) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (id) <span class="func">touchCache</span>(constr, id);</code><span class="hits">107</span></li><li class="covered"><code> <span class="kwrd">return</span> id && constr.cache<span class="gly">[</span>id<span class="gly">]</span>;</code><span class="hits">107</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Clear cache (fully)</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * removes both cache and LRU index</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Class} constr - class constructor</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">clearCache</span>(constr) <span class="gly">{</span></code></li><li class="covered"><code> constr.cache = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">3</span></li><li class="covered"><code> constr.mru = <span class="gly">[</span><span class="gly">]</span>;</code><span class="hits">3</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Remove object from cache</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Class} constr</span></code></li><li class=""><code><span class="C"> * @param {id} id</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">removeFromCache</span>(constr, id) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> ind = constr.mru.<span class="func">indexOf</span>(id);</code><span class="hits">1</span></li><li class="covered"><code> <span class="kwrd">if</span> (!~ind) constr.mru.<span class="func">splice</span>(ind, 1);</code><span class="hits">1</span></li><li class="covered"><code> delete constr.cache<span class="gly">[</span>id<span class="gly">]</span>;</code><span class="hits">1</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-validatable-js" class="filename" name="lib-validatable-js" onclick="var el = document.getElementById('lib-validatable-js'); el.style.display = el.style.display ? '' : 'none';">lib/validatable.js</a></div><div class="span6"><div class="progress progress-warning"> <div class="bar" style="width: 53%"><strong>53%</strong> [116/530]</div></div></div></div><div id="lib-validatable-js" style="display:none;"><pre><ol><li class="covered"><code>exports.Validatable = Validatable;</code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validation encapsulated in this abstract class.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Basically validation configurators is just class methods, which adds validations</span></code></li><li class=""><code><span class="C"> * configs to AbstractClass._validations. Each of this validations run when</span></code></li><li class=""><code><span class="C"> * `obj.isValid()` method called.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Each configurator can accept n params (n-1 field names and one config). Config</span></code></li><li class=""><code><span class="C"> * is {Object} depends on specific validation, but all of them has one common part:</span></code></li><li class=""><code><span class="C"> * `message` member. It can be just string, when only one situation possible,</span></code></li><li class=""><code><span class="C"> * e.g. `Post.validatesPresenceOf('title', { message: 'can not be blank' });`</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * In more complicated cases it can be {Hash} of messages (for each case):</span></code></li><li class=""><code><span class="C"> * `User.validatesLengthOf('password', { min: 6, max: 20, message: {min: 'too short', max: 'too long'}});`</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">Validatable</span>() <span class="gly">{</span></code></li><li class=""><code> // validatable class</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate presence. This validation fails when validated field is blank.</span></code></li><li class=""><code><span class="C"> * </span></code></li><li class=""><code><span class="C"> * Default error message "can't be blank"</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example presence of title</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * Post.validatesPresenceOf('title');</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * @example with custom message</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * Post.validatesPresenceOf('title', {message: 'Can not be blank'});</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @sync</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validatePresence</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesPresenceOf = <span class="func">getConfigurator</span>(<span class="S">'presence'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate length. Three kinds of validations: min, max, is.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error messages:</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - min: too short</span></code></li><li class=""><code><span class="C"> * - max: too long</span></code></li><li class=""><code><span class="C"> * - is: length is wrong</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example length validations</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('password', {min: 7});</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('email', {max: 100});</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('state', {is: 2});</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('nick', {min: 3, max: 15});</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * @example length validations with custom error messages</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('password', {min: 7, message: {min: 'too weak'}});</span></code></li><li class=""><code><span class="C"> * User.validatesLengthOf('state', {is: 2, message: {is: 'is not valid state name'}});</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @sync</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateLength</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesLengthOf = <span class="func">getConfigurator</span>(<span class="S">'length'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate numericality.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * User.validatesNumericalityOf('age', { message: { number: '...' }});</span></code></li><li class=""><code><span class="C"> * User.validatesNumericalityOf('age', {int: true, message: { int: '...' }});</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error messages:</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - number: is not a number</span></code></li><li class=""><code><span class="C"> * - int: is not an integer</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @sync</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateNumericality</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesNumericalityOf = <span class="func">getConfigurator</span>(<span class="S">'numericality'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate inclusion in set</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example </span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * User.validatesInclusionOf('gender', {in: ['male', 'female']});</span></code></li><li class=""><code><span class="C"> * User.validatesInclusionOf('role', {</span></code></li><li class=""><code><span class="C"> * in: ['admin', 'moderator', 'user'], message: 'is not allowed'</span></code></li><li class=""><code><span class="C"> * });</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is not included in the list</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @sync</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateInclusion</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesInclusionOf = <span class="func">getConfigurator</span>(<span class="S">'inclusion'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate exclusion</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example `Company.validatesExclusionOf('domain', {in: ['www', 'admin']});`</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is reserved</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateExclusion</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesExclusionOf = <span class="func">getConfigurator</span>(<span class="S">'exclusion'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate format</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is invalid</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateFormat</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesFormatOf = <span class="func">getConfigurator</span>(<span class="S">'format'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate using custom validator</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is invalid</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateCustom</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validate = <span class="func">getConfigurator</span>(<span class="S">'custom'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate using custom async validator</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is invalid</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @async</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateCustom</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validateAsync = <span class="func">getConfigurator</span>(<span class="S">'custom'</span>, <span class="gly">{</span>async: true<span class="gly">}</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Validate uniqueness</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * Default error message: is not unique</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @async</span></code></li><li class=""><code><span class="C"> * @nocode</span></code></li><li class=""><code><span class="C"> * @see helper/validateUniqueness</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>Validatable.validatesUniquenessOf = <span class="func">getConfigurator</span>(<span class="S">'uniqueness'</span>, <span class="gly">{</span>async: true<span class="gly">}</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>// implementation of validators</code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Presence validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validatePresence</span>(attr, conf, err) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="func">blank</span>(this<span class="gly">[</span>attr<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Length validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateLength</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (nullCheck.<span class="func">call</span>(this, attr, conf, err)) <span class="kwrd">return</span>;</code></li><li class=""><code></code></li><li class="uncovered"><code> <span class="kwrd">var</span> len = this<span class="gly">[</span>attr<span class="gly">]</span>.length;</code></li><li class=""><code> <span class="kwrd">if</span> (conf.m<span class="kwrd">in</span> && len < conf.m<span class="kwrd">in</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>(<span class="S">'min'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (conf.max && len > conf.max) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>(<span class="S">'max'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (conf.is && len !== conf.is) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>(<span class="S">'is'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Numericality validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateNumericality</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (nullCheck.<span class="func">call</span>(this, attr, conf, err)) <span class="kwrd">return</span>;</code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> this<span class="gly">[</span>attr<span class="gly">]</span> !== <span class="S">'number'</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">err</span>(<span class="S">'number'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (conf.int && this<span class="gly">[</span>attr<span class="gly">]</span> !== Math.<span class="func">round</span>(this<span class="gly">[</span>attr<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">err</span>(<span class="S">'int'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Inclusion validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateInclusion</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (nullCheck.<span class="func">call</span>(this, attr, conf, err)) <span class="kwrd">return</span>;</code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (!~conf.<span class="kwrd">in</span>.<span class="func">indexOf</span>(this<span class="gly">[</span>attr<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class=""><code> <span class="func">err</span>()</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Exclusion validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateExclusion</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (nullCheck.<span class="func">call</span>(this, attr, conf, err)) <span class="kwrd">return</span>;</code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (~conf.<span class="kwrd">in</span>.<span class="func">indexOf</span>(this<span class="gly">[</span>attr<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class=""><code> <span class="func">err</span>()</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Format validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateFormat</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (nullCheck.<span class="func">call</span>(this, attr, conf, err)) <span class="kwrd">return</span>;</code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> this<span class="gly">[</span>attr<span class="gly">]</span> === <span class="S">'string'</span>) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!this<span class="gly">[</span>attr<span class="gly">]</span>.<span class="func">match</span>(conf<span class="gly">[</span><span class="S">'with'</span><span class="gly">]</span>)) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Custom validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateCustom</span>(attr, conf, err, done) <span class="gly">{</span></code></li><li class="covered"><code> conf.customValidator.<span class="func">call</span>(this, err, done);</code><span class="hits">32</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Uniqueness validator</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validateUniqueness</span>(attr, conf, err, done) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> cond = <span class="gly">{</span>where: <span class="gly">{</span><span class="gly">}</span><span class="gly">}</span>;</code></li><li class="uncovered"><code> cond.where<span class="gly">[</span>attr<span class="gly">]</span> = this<span class="gly">[</span>attr<span class="gly">]</span>;</code></li><li class=""><code> this.constructor.<span class="func">all</span>(cond, <span class="kwrd">function</span> (error, found) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (found.length > 1) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>();</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (found.length === 1 && found<span class="gly">[</span>0<span class="gly">]</span>.id != this.id) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="func">done</span>();</code></li><li class="uncovered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">var</span> validators = <span class="gly">{</span></code></li><li class=""><code> presence: validatePresence,</code></li><li class=""><code> length: validateLength,</code></li><li class=""><code> numericality: validateNumericality,</code></li><li class=""><code> inclusion: validateInclusion,</code></li><li class=""><code> exclusion: validateExclusion,</code></li><li class=""><code> format: validateFormat,</code></li><li class=""><code> custom: validateCustom,</code></li><li class=""><code> uniqueness: validateUniqueness</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">getConfigurator</span>(name, opts) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> <span class="kwrd">function</span> () <span class="gly">{</span></code><span class="hits">9</span></li><li class="covered"><code> <span class="func">configure</span>(this, name, arguments, opts);</code><span class="hits">1</span></li><li class="uncovered"><code> <span class="gly">}</span>;</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * This method performs validation, triggers validation hooks.</span></code></li><li class=""><code><span class="C"> * Before validation `obj.errors` collection cleaned.</span></code></li><li class=""><code><span class="C"> * Each validation can add errors to `obj.errors` collection.</span></code></li><li class=""><code><span class="C"> * If collection is not blank, validation failed.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @warning This method can be called as sync only when no async validation</span></code></li><li class=""><code><span class="C"> * configured. It's strongly recommended to run all validations as asyncronous.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Function} callback called with (valid)</span></code></li><li class=""><code><span class="C"> * @return {Boolean} true if no async validation configured and all passed</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example ExpressJS controller: render user if valid, show flash otherwise</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * user.isValid(function (valid) {</span></code></li><li class=""><code><span class="C"> * if (valid) res.render({user: user});</span></code></li><li class=""><code><span class="C"> * else res.flash('error', 'User is not valid'), console.log(user.errors), res.redirect('/users');</span></code></li><li class=""><code><span class="C"> * });</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Validatable.prototype.isValid = <span class="kwrd">function</span> (callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> valid = true, inst = this, wait = 0, async = false;</code><span class="hits">44</span></li><li class=""><code></code></li><li class=""><code> // exit with success when no errors</code></li><li class=""><code> <span class="kwrd">if</span> (!this.constructor._validations) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">cleanErrors</span>(this);</code><span class="hits">12</span></li><li class=""><code> <span class="kwrd">if</span> (callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(valid);</code><span class="hits">12</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">return</span> valid;</code><span class="hits">12</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(this, <span class="S">'errors'</span>, <span class="gly">{</span></code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> value: <span class="kwrd">new</span> Errors</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code></code></li><li class=""><code> this.<span class="func">trigger</span>(<span class="S">'validation'</span>, <span class="kwrd">function</span> (validationsDone) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> inst = this;</code><span class="hits">32</span></li><li class=""><code> this.constructor._validations.<span class="func">forEach</span>(<span class="kwrd">function</span> (v) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (v<span class="gly">[</span>2<span class="gly">]</span> && v<span class="gly">[</span>2<span class="gly">]</span>.async) <span class="gly">{</span></code></li><li class="covered"><code> async = true;</code><span class="hits">32</span></li><li class="covered"><code> wait += 1;</code><span class="hits">32</span></li><li class="covered"><code> <span class="func">validationFailed</span>(inst, v, done);</code><span class="hits">32</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="func">validationFailed</span>(inst, v)) <span class="gly">{</span></code></li><li class="uncovered"><code> valid = false;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (!async) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">validationsDone</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> asyncFail = false;</code><span class="hits">32</span></li><li class=""><code> <span class="kwrd">function</span> <span class="func">done</span>(fail) <span class="gly">{</span></code></li><li class="covered"><code> asyncFail = asyncFail <span class="gly">|</span><span class="gly">|</span> fail;</code><span class="hits">32</span></li><li class=""><code> <span class="kwrd">if</span> (--wait === 0 && callback) <span class="gly">{</span></code></li><li class=""><code> validationsDone.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span>( valid && !asyncFail ) <span class="func">cleanErrors</span>(inst);</code><span class="hits">32</span></li><li class="covered"><code> <span class="func">callback</span>(valid && !asyncFail);</code><span class="hits">32</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (!async) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (valid) <span class="func">cleanErrors</span>(this);</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (callback) <span class="func">callback</span>(valid);</code></li><li class="uncovered"><code> <span class="kwrd">return</span> valid;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> // <span class="kwrd">in</span> <span class="kwrd">case</span> of async validation we should <span class="kwrd">return</span> undefined here,</code></li><li class=""><code> // because not all validations are finished yet</code></li><li class="covered"><code> <span class="kwrd">return</span>;</code><span class="hits">32</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">cleanErrors</span>(inst) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(inst, <span class="S">'errors'</span>, <span class="gly">{</span></code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> value: false</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">44</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">validationFailed</span>(inst, v, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> attr = v<span class="gly">[</span>0<span class="gly">]</span>;</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">var</span> conf = v<span class="gly">[</span>1<span class="gly">]</span>;</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">var</span> opts = v<span class="gly">[</span>2<span class="gly">]</span> <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">32</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> attr !== <span class="S">'string'</span>) <span class="kwrd">return</span> false;</code><span class="hits">32</span></li><li class=""><code></code></li><li class=""><code> // here we should check skip validation <span class="func">conditions</span>(<span class="kwrd">if</span>, unless)</code></li><li class=""><code> // that can be specified <span class="kwrd">in</span> conf</code></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">skipValidation</span>(inst, conf, <span class="S">'if'</span>)) <span class="kwrd">return</span> false;</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">if</span> (<span class="func">skipValidation</span>(inst, conf, <span class="S">'unless'</span>)) <span class="kwrd">return</span> false;</code><span class="hits">32</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> fail = false;</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">var</span> validator = validators<span class="gly">[</span>conf.validation<span class="gly">]</span>;</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">var</span> validatorArguments = <span class="gly">[</span><span class="gly">]</span>;</code><span class="hits">32</span></li><li class="covered"><code> validatorArguments.<span class="func">push</span>(attr);</code><span class="hits">32</span></li><li class="covered"><code> validatorArguments.<span class="func">push</span>(conf);</code><span class="hits">32</span></li><li class=""><code> validatorArguments.<span class="func">push</span>(<span class="kwrd">function</span> <span class="func">onerror</span>(kind) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> message;</code></li><li class=""><code> <span class="kwrd">if</span> (conf.message) <span class="gly">{</span></code></li><li class="uncovered"><code> message = conf.message;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (!message && defaultMessages<span class="gly">[</span>conf.validation<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> message = defaultMessages<span class="gly">[</span>conf.validation<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (!message) <span class="gly">{</span></code></li><li class="uncovered"><code> message = <span class="S">'is invalid'</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (kind) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (message<span class="gly">[</span>kind<span class="gly">]</span>) <span class="gly">{</span></code></li><li class=""><code> // get deeper</code></li><li class="uncovered"><code> message = message<span class="gly">[</span>kind<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (defaultMessages.common<span class="gly">[</span>kind<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> message = defaultMessages.common<span class="gly">[</span>kind<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> inst.errors.<span class="func">add</span>(attr, message);</code></li><li class="uncovered"><code> fail = true;</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code> <span class="kwrd">if</span> (cb) <span class="gly">{</span></code></li><li class=""><code> validatorArguments.<span class="func">push</span>(<span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">cb</span>(fail);</code><span class="hits">32</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">32</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> validator.<span class="func">apply</span>(inst, validatorArguments);</code><span class="hits">32</span></li><li class="covered"><code> <span class="kwrd">return</span> fail;</code><span class="hits">32</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">skipValidation</span>(inst, conf, kind) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> doValidate = true;</code><span class="hits">64</span></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> conf<span class="gly">[</span>kind<span class="gly">]</span> === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> doValidate = conf<span class="gly">[</span>kind<span class="gly">]</span>.<span class="func">call</span>(inst);</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (kind === <span class="S">'unless'</span>) doValidate = !doValidate;</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (<span class="kwrd">typeof</span> conf<span class="gly">[</span>kind<span class="gly">]</span> === <span class="S">'string'</span>) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (inst.<span class="func">hasOwnProperty</span>(conf<span class="gly">[</span>kind<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class="uncovered"><code> doValidate = inst<span class="gly">[</span>conf<span class="gly">[</span>kind<span class="gly">]</span><span class="gly">]</span>;</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (kind === <span class="S">'unless'</span>) doValidate = !doValidate;</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (<span class="kwrd">typeof</span> inst<span class="gly">[</span>conf<span class="gly">[</span>kind<span class="gly">]</span><span class="gly">]</span> === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> doValidate = inst<span class="gly">[</span>conf<span class="gly">[</span>kind<span class="gly">]</span><span class="gly">]</span>.<span class="func">call</span>(inst);</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (kind === <span class="S">'unless'</span>) doValidate = !doValidate;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> doValidate = kind === <span class="S">'if'</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">return</span> !doValidate;</code><span class="hits">64</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">var</span> defaultMessages = <span class="gly">{</span></code></li><li class=""><code> presence: <span class="S">'can\'t be blank'</span>,</code></li><li class=""><code> length: <span class="gly">{</span></code></li><li class=""><code> m<span class="kwrd">in</span>: <span class="S">'too short'</span>,</code></li><li class=""><code> max: <span class="S">'too long'</span>,</code></li><li class=""><code> is: <span class="S">'length is wrong'</span></code></li><li class=""><code> <span class="gly">}</span>,</code></li><li class=""><code> common: <span class="gly">{</span></code></li><li class=""><code> blank: <span class="S">'is blank'</span>,</code></li><li class=""><code> <span class="S">'null'</span>: <span class="S">'is null'</span></code></li><li class=""><code> <span class="gly">}</span>,</code></li><li class=""><code> numericality: <span class="gly">{</span></code></li><li class=""><code> <span class="S">'int'</span>: <span class="S">'is not an integer'</span>,</code></li><li class=""><code> <span class="S">'number'</span>: <span class="S">'is not a number'</span></code></li><li class=""><code> <span class="gly">}</span>,</code></li><li class=""><code> inclusion: <span class="S">'is not included in the list'</span>,</code></li><li class=""><code> exclusion: <span class="S">'is reserved'</span>,</code></li><li class=""><code> uniqueness: <span class="S">'is not unique'</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">nullCheck</span>(attr, conf, err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> isNull = this<span class="gly">[</span>attr<span class="gly">]</span> === null <span class="gly">|</span><span class="gly">|</span> !(attr <span class="kwrd">in</span> this);</code></li><li class=""><code> <span class="kwrd">if</span> (isNull) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!conf.allowNull) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>(<span class="S">'null'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> true;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="func">blank</span>(this<span class="gly">[</span>attr<span class="gly">]</span>)) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!conf.allowBlank) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">err</span>(<span class="S">'blank'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> true;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> false;</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Return true when v is undefined, blank array, null or empty string</span></code></li><li class=""><code><span class="C"> * otherwise returns false</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {Mix} v</span></code></li><li class=""><code><span class="C"> * @returns {Boolean} whether `v` blank or not</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">blank</span>(v) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> v === <span class="S">'undefined'</span>) <span class="kwrd">return</span> true;</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (v instanceof Array && v.length === 0) <span class="kwrd">return</span> true;</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (v === null) <span class="kwrd">return</span> true;</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> v == <span class="S">'string'</span> && v === <span class="S">''</span>) <span class="kwrd">return</span> true;</code></li><li class="uncovered"><code> <span class="kwrd">return</span> false;</code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">configure</span>(cls, validation, args, opts) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!cls._validations) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(cls, <span class="S">'_validations'</span>, <span class="gly">{</span></code></li><li class=""><code> writable: true,</code></li><li class=""><code> configurable: true,</code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> value: <span class="gly">[</span><span class="gly">]</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> args = <span class="gly">[</span><span class="gly">]</span>.slice.<span class="func">call</span>(args);</code><span class="hits">1</span></li><li class="covered"><code> <span class="kwrd">var</span> conf;</code><span class="hits">1</span></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> args<span class="gly">[</span>args.length - 1<span class="gly">]</span> === <span class="S">'object'</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> conf = args.<span class="func">pop</span>();</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> conf = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (validation === <span class="S">'custom'</span> && <span class="kwrd">typeof</span> args<span class="gly">[</span>args.length - 1<span class="gly">]</span> === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> conf.customValidator = args.<span class="func">pop</span>();</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> conf.validation = validation;</code><span class="hits">1</span></li><li class=""><code> args.<span class="func">forEach</span>(<span class="kwrd">function</span> (attr) <span class="gly">{</span></code></li><li class="covered"><code> cls._validations.<span class="func">push</span>(<span class="gly">[</span>attr, conf, opts<span class="gly">]</span>);</code><span class="hits">1</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">Errors</span>() <span class="gly">{</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code>Errors.prototype.add = <span class="kwrd">function</span> (field, message) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!this<span class="gly">[</span>field<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="uncovered"><code> this<span class="gly">[</span>field<span class="gly">]</span> = <span class="gly">[</span>message<span class="gly">]</span>;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> this<span class="gly">[</span>field<span class="gly">]</span>.<span class="func">push</span>(message);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-adapters-mongoose-js" class="filename" name="lib-adapters-mongoose-js" onclick="var el = document.getElementById('lib-adapters-mongoose-js'); el.style.display = el.style.display ? '' : 'none';">lib/adapters/mongoose.js</a></div><div class="span6"><div class="progress progress-success"> <div class="bar" style="width: 82%"><strong>82%</strong> [111/232]</div></div></div></div><div id="lib-adapters-mongoose-js" style="display:none;"><pre><ol><li class="covered"><code><span class="kwrd">var</span> safeRequire = <span class="func">require</span>(<span class="S">'../utils'</span>).safeRequire;</code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Module dependencies</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code><span class="kwrd">var</span> mongoose = <span class="func">safeRequire</span>(<span class="S">'mongoose'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>exports.initialize = <span class="kwrd">function</span> <span class="func">initializeSchema</span>(schema, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (!mongoose) <span class="kwrd">return</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (!schema.settings.url) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> url = schema.settings.host <span class="gly">|</span><span class="gly">|</span> <span class="S">'localhost'</span>;</code></li><li class="uncovered"><code> <span class="kwrd">if</span> (schema.settings.port) url += <span class="S">':'</span> + schema.settings.port;</code></li><li class="uncovered"><code> <span class="kwrd">var</span> auth = <span class="S">''</span>;</code></li><li class=""><code> <span class="kwrd">if</span> (schema.settings.username) <span class="gly">{</span></code></li><li class="uncovered"><code> auth = schema.settings.username;</code></li><li class=""><code> <span class="kwrd">if</span> (schema.settings.password) <span class="gly">{</span></code></li><li class="uncovered"><code> auth += <span class="S">':'</span> + schema.settings.password;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (auth) <span class="gly">{</span></code></li><li class="uncovered"><code> url = auth + <span class="S">'@'</span> + url;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (schema.settings.database) <span class="gly">{</span></code></li><li class="uncovered"><code> url += <span class="S">'/'</span> + schema.settings.database;</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> url += <span class="S">'/'</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="uncovered"><code> url = <span class="S">'mongodb://'</span> + url;</code></li><li class="uncovered"><code> schema.settings.url = url;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> schema.client = mongoose.<span class="func">connect</span>(schema.settings.url);</code><span class="hits">1</span></li><li class="covered"><code> schema.adapter = <span class="kwrd">new</span> <span class="func">MongooseAdapter</span>(schema.client);</code><span class="hits">1</span></li><li class="covered"><code> process.<span class="func">nextTick</span>(callback);</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">MongooseAdapter</span>(client) <span class="gly">{</span></code></li><li class="covered"><code> this._models = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class="covered"><code> this.client = client;</code><span class="hits">1</span></li><li class="covered"><code> this.cache = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.define = <span class="kwrd">function</span> (descr) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> props = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">3</span></li><li class=""><code> Object.<span class="func">keys</span>(descr.properties).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> props<span class="gly">[</span>key<span class="gly">]</span> = descr.properties<span class="gly">[</span>key<span class="gly">]</span>.type;</code><span class="hits">14</span></li><li class="covered"><code> <span class="kwrd">if</span> (props<span class="gly">[</span>key<span class="gly">]</span>.name === <span class="S">'Text'</span>) props<span class="gly">[</span>key<span class="gly">]</span> = String;</code><span class="hits">14</span></li><li class="covered"><code> <span class="kwrd">if</span> (props<span class="gly">[</span>key<span class="gly">]</span>.name === <span class="S">'Object'</span>) props<span class="gly">[</span>key<span class="gly">]</span> = mongoose.Schema.Types.Mixed;</code><span class="hits">14</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">var</span> schema = <span class="kwrd">new</span> mongoose.<span class="func">Schema</span>(props);</code><span class="hits">3</span></li><li class="covered"><code> this._models<span class="gly">[</span>descr.model.modelName<span class="gly">]</span> = mongoose.<span class="func">model</span>(descr.model.modelName, schema);</code><span class="hits">3</span></li><li class="covered"><code> this.cache<span class="gly">[</span>descr.model.modelName<span class="gly">]</span> = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.defineForeignKey = <span class="kwrd">function</span> (model, key, cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> piece = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">2</span></li><li class="covered"><code> piece<span class="gly">[</span>key<span class="gly">]</span> = <span class="gly">{</span>type: mongoose.Schema.ObjectId, index: true<span class="gly">}</span>;</code><span class="hits">2</span></li><li class="covered"><code> this._models<span class="gly">[</span>model<span class="gly">]</span>.schema.<span class="func">add</span>(piece);</code><span class="hits">2</span></li><li class="covered"><code> <span class="func">cb</span>(null, String);</code><span class="hits">2</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.setCache = <span class="kwrd">function</span> (model, instance) <span class="gly">{</span></code></li><li class="uncovered"><code> this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>instance.id<span class="gly">]</span> = instance;</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.getCached = <span class="kwrd">function</span> (model, id, cb) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>id<span class="gly">]</span>) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">cb</span>(null, this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>id<span class="gly">]</span>);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> this._models<span class="gly">[</span>model<span class="gly">]</span>.<span class="func">findById</span>(id, <span class="kwrd">function</span> (err, instance) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">cb</span>(err);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>id<span class="gly">]</span> = instance;</code><span class="hits">15</span></li><li class="covered"><code> <span class="func">cb</span>(null, instance);</code><span class="hits">15</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">15</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.create = <span class="kwrd">function</span> (model, data, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> m = <span class="kwrd">new</span> this._models<span class="gly">[</span>model<span class="gly">]</span>(data);</code><span class="hits">39</span></li><li class=""><code> m.<span class="func">save</span>(<span class="kwrd">function</span> (err) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, err ? null : m.id);</code><span class="hits">39</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">39</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.save = <span class="kwrd">function</span> (model, data, callback) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">getCached</span>(model, data.id, <span class="kwrd">function</span> (err, inst) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">callback</span>(err);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="func">merge</span>(inst, data);</code><span class="hits">3</span></li><li class="covered"><code> inst.<span class="func">save</span>(callback);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.exists = <span class="kwrd">function</span> (model, id, callback) <span class="gly">{</span></code></li><li class="covered"><code> delete this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>id<span class="gly">]</span>;</code><span class="hits">3</span></li><li class=""><code> this.<span class="func">getCached</span>(model, id, <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">callback</span>(err);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, !!data);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.find = <span class="kwrd">function</span> <span class="func">find</span>(model, id, callback) <span class="gly">{</span></code></li><li class="covered"><code> delete this.cache<span class="gly">[</span>model<span class="gly">]</span><span class="gly">[</span>id<span class="gly">]</span>;</code><span class="hits">7</span></li><li class=""><code> this.<span class="func">getCached</span>(model, id, <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">callback</span>(err);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="func">callback</span>(err, data ? data.<span class="func">toObject</span>() : null);</code><span class="hits">7</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">7</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.destroy = <span class="kwrd">function</span> <span class="func">destroy</span>(model, id, callback) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">getCached</span>(model, id, <span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">callback</span>(err);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (data) <span class="gly">{</span></code></li><li class="covered"><code> data.<span class="func">remove</span>(callback);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">callback</span>(null);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.all = <span class="kwrd">function</span> <span class="func">all</span>(model, filter, callback) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!filter) <span class="gly">{</span></code></li><li class="covered"><code> filter = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">var</span> query = this._models<span class="gly">[</span>model<span class="gly">]</span>.<span class="func">find</span>(<span class="gly">{</span><span class="gly">}</span>);</code><span class="hits">23</span></li><li class=""><code> <span class="kwrd">if</span> (filter.where) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(filter.where).<span class="func">forEach</span>(<span class="kwrd">function</span> (k) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> cond = filter.where<span class="gly">[</span>k<span class="gly">]</span>;</code><span class="hits">16</span></li><li class="covered"><code> <span class="kwrd">var</span> spec = false;</code><span class="hits">16</span></li><li class=""><code> <span class="kwrd">if</span> (cond && cond.constructor.name === <span class="S">'Object'</span>) <span class="gly">{</span></code></li><li class="covered"><code> spec = Object.<span class="func">keys</span>(cond)<span class="gly">[</span>0<span class="gly">]</span>;</code><span class="hits">5</span></li><li class="covered"><code> cond = cond<span class="gly">[</span>spec<span class="gly">]</span>;</code><span class="hits">5</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (spec) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (spec === <span class="S">'between'</span>) <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">where</span>(k).<span class="func">gte</span>(cond<span class="gly">[</span>0<span class="gly">]</span>).<span class="func">lte</span>(cond<span class="gly">[</span>1<span class="gly">]</span>);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">where</span>(k)<span class="gly">[</span>spec<span class="gly">]</span>(cond);</code><span class="hits">4</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">where</span>(k, cond);</code><span class="hits">11</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">16</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (filter.order) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">var</span> keys = filter.order; // can be Array or String</code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span>(keys) == <span class="S">"string"</span>) <span class="gly">{</span></code></li><li class="covered"><code> keys = keys.<span class="func">split</span>(<span class="S">','</span>);</code><span class="hits">8</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="kwrd">var</span> args = <span class="gly">[</span><span class="gly">]</span>;</code><span class="hits">8</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">for</span>(index <span class="kwrd">in</span> keys) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> m = keys<span class="gly">[</span>index<span class="gly">]</span>.<span class="func">match</span>(/\s+(A<span class="gly">|</span>DE)SC$/);</code><span class="hits">10</span></li><li class=""><code></code></li><li class="covered"><code> keys<span class="gly">[</span>index<span class="gly">]</span> = keys<span class="gly">[</span>index<span class="gly">]</span>.<span class="func">replace</span>(/\s+(A<span class="gly">|</span>DE)SC$/, <span class="S">''</span>);</code><span class="hits">10</span></li><li class=""><code> <span class="kwrd">if</span> (m && m<span class="gly">[</span>1<span class="gly">]</span> === <span class="S">'DE'</span>) <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">sort</span>(keys<span class="gly">[</span>index<span class="gly">]</span>.<span class="func">trim</span>(), -1);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">sort</span>(keys<span class="gly">[</span>index<span class="gly">]</span>.<span class="func">trim</span>(), 1);</code><span class="hits">7</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (filter.limit) <span class="gly">{</span></code></li><li class="covered"><code> query.<span class="func">limit</span>(filter.limit);</code><span class="hits">5</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="kwrd">if</span> (filter.skip) <span class="gly">{</span></code></li><li class="uncovered"><code> query.<span class="func">skip</span>(filter.skip);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (filter.offset) <span class="gly">{</span></code></li><li class="uncovered"><code> query.<span class="func">skip</span>(filter.offset);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> query.<span class="func">exec</span>(<span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">callback</span>(err);</code><span class="hits">23</span></li><li class="covered"><code> <span class="func">callback</span>(null, data);</code><span class="hits">23</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">23</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.destroyAll = <span class="kwrd">function</span> <span class="func">destroyAll</span>(model, callback) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> wait = 0;</code><span class="hits">3</span></li><li class=""><code> this._models<span class="gly">[</span>model<span class="gly">]</span>.<span class="func">find</span>(<span class="kwrd">function</span> (err, data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (err) <span class="kwrd">return</span> <span class="func">callback</span>(err);</code><span class="hits">3</span></li><li class="covered"><code> wait = data.length;</code><span class="hits">3</span></li><li class=""><code> data.<span class="func">forEach</span>(<span class="kwrd">function</span> (obj) <span class="gly">{</span></code></li><li class=""><code> obj.<span class="func">remove</span>(done)</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">var</span> error = null;</code><span class="hits">3</span></li><li class=""><code> <span class="kwrd">function</span> <span class="func">done</span>(err) <span class="gly">{</span></code></li><li class="covered"><code> error = error <span class="gly">|</span><span class="gly">|</span> err;</code><span class="hits">38</span></li><li class=""><code> <span class="kwrd">if</span> (--wait === 0) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">callback</span>(error);</code><span class="hits">3</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.count = <span class="kwrd">function</span> <span class="func">count</span>(model, callback, where) <span class="gly">{</span></code></li><li class="covered"><code> this._models<span class="gly">[</span>model<span class="gly">]</span>.<span class="func">count</span>(where <span class="gly">|</span><span class="gly">|</span> <span class="gly">{</span><span class="gly">}</span>, callback);</code><span class="hits">3</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.updateAttributes = <span class="kwrd">function</span> <span class="func">updateAttrs</span>(model, id, data, cb) <span class="gly">{</span></code></li><li class=""><code> this.<span class="func">getCached</span>(model, id, <span class="kwrd">function</span> (err, inst) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (err) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">return</span> <span class="func">cb</span>(err);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (inst) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">merge</span>(inst, data);</code><span class="hits">2</span></li><li class="covered"><code> inst.<span class="func">save</span>(cb);</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span> else <span class="func">cb</span>();</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>MongooseAdapter.prototype.disconnect = <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class="covered"><code> this.client.connection.<span class="func">close</span>();</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">merge</span>(base, update) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(update).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> base<span class="gly">[</span>key<span class="gly">]</span> = update<span class="gly">[</span>key<span class="gly">]</span>;</code><span class="hits">24</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">5</span></li><li class="covered"><code> <span class="kwrd">return</span> base;</code><span class="hits">5</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-schema-js" class="filename" name="lib-schema-js" onclick="var el = document.getElementById('lib-schema-js'); el.style.display = el.style.display ? '' : 'none';">lib/schema.js</a></div><div class="span6"><div class="progress progress-warning"> <div class="bar" style="width: 75%"><strong>75%</strong> [81/314]</div></div></div></div><div id="lib-schema-js" style="display:none;"><pre><ol><li class="covered"><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Module dependencies</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code><span class="kwrd">var</span> AbstractClass = <span class="func">require</span>(<span class="S">'./abstract-class'</span>).AbstractClass;</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> util = <span class="func">require</span>(<span class="S">'util'</span>);</code><span class="hits">1</span></li><li class="covered"><code><span class="kwrd">var</span> path = <span class="func">require</span>(<span class="S">'path'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Export public API</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code>exports.Schema = Schema;</code><span class="hits">1</span></li><li class="uncovered"><code>// exports.AbstractClass = AbstractClass;</code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Helpers</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class="covered"><code><span class="kwrd">var</span> slice = Array.prototype.slice;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Schema - adapter-specific classes factory.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * All classes in single schema shares same adapter type and</span></code></li><li class=""><code><span class="C"> * one database connection</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param name - type of schema adapter (mysql, mongoose, sequelize, redis)</span></code></li><li class=""><code><span class="C"> * @param settings - any database-specific settings which we need to</span></code></li><li class=""><code><span class="C"> * establish connection (of course it depends on specific adapter)</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * - host</span></code></li><li class=""><code><span class="C"> * - port</span></code></li><li class=""><code><span class="C"> * - username</span></code></li><li class=""><code><span class="C"> * - password</span></code></li><li class=""><code><span class="C"> * - database</span></code></li><li class=""><code><span class="C"> * - debug {Boolean} = false</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example Schema creation, waiting for connection callback</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * var schema = new Schema('mysql', { database: 'myapp_test' });</span></code></li><li class=""><code><span class="C"> * schema.define(...);</span></code></li><li class=""><code><span class="C"> * schema.on('connected', function () {</span></code></li><li class=""><code><span class="C"> * // work with database</span></code></li><li class=""><code><span class="C"> * });</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">Schema</span>(name, settings) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> schema = this;</code><span class="hits">1</span></li><li class=""><code> // just save everything we get</code></li><li class="covered"><code> this.name = name;</code><span class="hits">1</span></li><li class="covered"><code> this.settings = settings;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> // Disconnected by default</code></li><li class="covered"><code> this.connected = false;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> // create blank models pool</code></li><li class="covered"><code> this.models = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class="covered"><code> this.definitions = <span class="gly">{</span><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> // and initialize schema using adapter</code></li><li class=""><code> // this is only one initialization entry point of adapter</code></li><li class=""><code> // this module should define `adapter` member of `this` (schema)</code></li><li class="covered"><code> <span class="kwrd">var</span> adapter;</code><span class="hits">1</span></li><li class=""><code> <span class="kwrd">if</span> (path.<span class="func">existsSync</span>(__dirname + <span class="S">'/adapters/'</span> + name + <span class="S">'.js'</span>)) <span class="gly">{</span></code></li><li class="covered"><code> adapter = <span class="func">require</span>(<span class="S">'./adapters/'</span> + name);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class=""><code> try <span class="gly">{</span></code></li><li class="uncovered"><code> adapter = <span class="func">require</span>(name);</code></li><li class=""><code> <span class="gly">}</span> <span class="func">catch</span>(e) <span class="gly">{</span></code></li><li class="uncovered"><code> throw <span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Adapter '</span> + name + <span class="S">' is not defined, try\n npm install '</span> + name);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> adapter.<span class="func">initialize</span>(this, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code></code></li><li class=""><code> // we have an adaper now?</code></li><li class=""><code> <span class="kwrd">if</span> (!this.adapter) <span class="gly">{</span></code></li><li class="uncovered"><code> throw <span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Adapter is not defined correctly: it should create `adapter` member of schema'</span>);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> this.adapter.log = <span class="kwrd">function</span> (query, start) <span class="gly">{</span></code></li><li class="uncovered"><code> schema.<span class="func">log</span>(query, start);</code></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code> this.adapter.logger = <span class="kwrd">function</span> (query) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="kwrd">var</span> t1 = Date.<span class="func">now</span>();</code></li><li class="uncovered"><code> <span class="kwrd">var</span> log = this.log;</code></li><li class=""><code> <span class="kwrd">return</span> <span class="kwrd">function</span> (q) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">log</span>(q <span class="gly">|</span><span class="gly">|</span> query, t1);</code></li><li class="uncovered"><code> <span class="gly">}</span>;</code></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code> this.connected = true;</code><span class="hits">1</span></li><li class="covered"><code> this.<span class="func">emit</span>(<span class="S">'connected'</span>);</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">1</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code>util.<span class="func">inherits</span>(Schema, <span class="func">require</span>(<span class="S">'events'</span>).EventEmitter);</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">Text</span>() <span class="gly">{</span><span class="gly">}</span></code></li><li class="covered"><code>Schema.Text = Text;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define class</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {String} className</span></code></li><li class=""><code><span class="C"> * @param {Object} properties - hash of class properties in format</span></code></li><li class=""><code><span class="C"> * `{property: Type, property2: Type2, ...}`</span></code></li><li class=""><code><span class="C"> * or</span></code></li><li class=""><code><span class="C"> * `{property: {type: Type}, property2: {type: Type2}, ...}`</span></code></li><li class=""><code><span class="C"> * @param {Object} settings - other configuration of class</span></code></li><li class=""><code><span class="C"> * @return newly created class</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @example simple case</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * var User = schema.define('User', {</span></code></li><li class=""><code><span class="C"> * email: String,</span></code></li><li class=""><code><span class="C"> * password: String,</span></code></li><li class=""><code><span class="C"> * birthDate: Date,</span></code></li><li class=""><code><span class="C"> * activated: Boolean</span></code></li><li class=""><code><span class="C"> * });</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * @example more advanced case</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> * var User = schema.defind('User', {</span></code></li><li class=""><code><span class="C"> * email: { type: String, limit: 150, index: true },</span></code></li><li class=""><code><span class="C"> * password: { type: String, limit: 50 },</span></code></li><li class=""><code><span class="C"> * birthDate: Date,</span></code></li><li class=""><code><span class="C"> * registrationDate: {type: Date, default: function () { return new Date }},</span></code></li><li class=""><code><span class="C"> * activated: { type: Boolean, default: false }</span></code></li><li class=""><code><span class="C"> * });</span></code></li><li class=""><code><span class="C"> * ```</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.define = <span class="kwrd">function</span> <span class="func">defineClass</span>(className, properties, settings) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> schema = this;</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">var</span> args = slice.<span class="func">call</span>(arguments);</code><span class="hits">3</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">if</span> (!className) throw <span class="kwrd">new</span> <span class="func">Error</span>(<span class="S">'Class name required'</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">if</span> (args.length == 1) properties = <span class="gly">{</span><span class="gly">}</span>, args.<span class="func">push</span>(properties);</code><span class="hits">3</span></li><li class="covered"><code> <span class="kwrd">if</span> (args.length == 2) settings = <span class="gly">{</span><span class="gly">}</span>, args.<span class="func">push</span>(settings);</code><span class="hits">3</span></li><li class=""><code></code></li><li class="covered"><code> <span class="func">standartize</span>(properties, settings);</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> // every class can receive hash of data as optional param</code></li><li class=""><code> <span class="kwrd">var</span> newClass = <span class="kwrd">function</span> <span class="func">ModelConstructor</span>(data) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (!(this instanceof ModelConstructor)) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> <span class="kwrd">new</span> <span class="func">ModelConstructor</span>(data);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> AbstractClass.<span class="func">call</span>(this, data);</code><span class="hits">152</span></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class="covered"><code> <span class="func">hiddenProperty</span>(newClass, <span class="S">'schema'</span>, schema);</code><span class="hits">3</span></li><li class="covered"><code> <span class="func">hiddenProperty</span>(newClass, <span class="S">'modelName'</span>, className);</code><span class="hits">3</span></li><li class="covered"><code> <span class="func">hiddenProperty</span>(newClass, <span class="S">'cache'</span>, <span class="gly">{</span><span class="gly">}</span>);</code><span class="hits">3</span></li><li class="covered"><code> <span class="func">hiddenProperty</span>(newClass, <span class="S">'mru'</span>, <span class="gly">[</span><span class="gly">]</span>);</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> // setup inheritance</code></li><li class="covered"><code> newClass.__proto__ = AbstractClass;</code><span class="hits">3</span></li><li class="covered"><code> util.<span class="func">inherits</span>(newClass, AbstractClass);</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> // store class <span class="kwrd">in</span> model pool</code></li><li class="covered"><code> this.models<span class="gly">[</span>className<span class="gly">]</span> = newClass;</code><span class="hits">3</span></li><li class=""><code> this.definitions<span class="gly">[</span>className<span class="gly">]</span> = <span class="gly">{</span></code></li><li class=""><code> properties: properties,</code></li><li class=""><code> settings: settings</code></li><li class="covered"><code> <span class="gly">}</span>;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> // pass controll to adapter</code></li><li class=""><code> this.adapter.<span class="func">define</span>(<span class="gly">{</span></code></li><li class=""><code> model: newClass,</code></li><li class=""><code> properties: properties,</code></li><li class=""><code> settings: settings</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class=""><code></code></li><li class="covered"><code> <span class="kwrd">return</span> newClass;</code><span class="hits">3</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">standartize</span>(properties, settings) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(properties).<span class="func">forEach</span>(<span class="kwrd">function</span> (key) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> v = properties<span class="gly">[</span>key<span class="gly">]</span>;</code><span class="hits">14</span></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> v === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> properties<span class="gly">[</span>key<span class="gly">]</span> = <span class="gly">{</span> type: v <span class="gly">}</span>;</code><span class="hits">7</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">3</span></li><li class=""><code> // TO<span class="kwrd">DO</span>: add timestamps fields</code></li><li class=""><code> // when present <span class="kwrd">in</span> settings: <span class="gly">{</span>timestamps: true<span class="gly">}</span></code></li><li class=""><code> // or <span class="gly">{</span>timestamps: <span class="gly">{</span>created: <span class="S">'created_at'</span>, updated: false<span class="gly">}</span><span class="gly">}</span></code></li><li class=""><code> // by default property names: createdAt, updatedAt</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define single property named `prop` on `model`</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @param {String} model - name of model</span></code></li><li class=""><code><span class="C"> * @param {String} prop - name of propery</span></code></li><li class=""><code><span class="C"> * @param {Object} params - property settings</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.defineProperty = <span class="kwrd">function</span> (model, prop, params) <span class="gly">{</span></code></li><li class="uncovered"><code> this.definitions<span class="gly">[</span>model<span class="gly">]</span>.properties<span class="gly">[</span>prop<span class="gly">]</span> = params;</code></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.defineProperty) <span class="gly">{</span></code></li><li class="uncovered"><code> this.adapter.<span class="func">defineProperty</span>(model, prop, params);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Drop each model table and re-create.</span></code></li><li class=""><code><span class="C"> * This method make sense only for sql adapters.</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @warning All data will be lost! Use autoupdate if you need your data.</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.automigrate = <span class="kwrd">function</span> (cb) <span class="gly">{</span></code></li><li class="covered"><code> this.<span class="func">freeze</span>();</code><span class="hits">1</span></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.automigrate) <span class="gly">{</span></code></li><li class="uncovered"><code> this.adapter.<span class="func">automigrate</span>(cb);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (cb) <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">cb</span>();</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Update existing database tables.</span></code></li><li class=""><code><span class="C"> * This method make sense only for sql adapters.</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.autoupdate = <span class="kwrd">function</span> (cb) <span class="gly">{</span></code></li><li class="uncovered"><code> this.<span class="func">freeze</span>();</code></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.autoupdate) <span class="gly">{</span></code></li><li class="uncovered"><code> this.adapter.<span class="func">autoupdate</span>(cb);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (cb) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Check whether migrations needed</span></code></li><li class=""><code><span class="C"> * This method make sense only for sql adapters.</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.isActual = <span class="kwrd">function</span> (cb) <span class="gly">{</span></code></li><li class="uncovered"><code> this.<span class="func">freeze</span>();</code></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.isActual) <span class="gly">{</span></code></li><li class="uncovered"><code> this.adapter.<span class="func">isActual</span>(cb);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (cb) <span class="gly">{</span></code></li><li class="uncovered"><code> <span class="func">cb</span>(null, true);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Log benchmarked message. Do not redefine this method, if you need to grab</span></code></li><li class=""><code><span class="C"> * chema logs, use `schema.on('log', ...)` emitter event</span></code></li><li class=""><code><span class="C"> *</span></code></li><li class=""><code><span class="C"> * @private used by adapters</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.log = <span class="kwrd">function</span> (sql, t) <span class="gly">{</span></code></li><li class="uncovered"><code> this.<span class="func">emit</span>(<span class="S">'log'</span>, sql, t);</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Freeze schema. Behavior depends on adapter</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.freeze = <span class="kwrd">function</span> <span class="func">freeze</span>() <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.freezeSchema) <span class="gly">{</span></code></li><li class="uncovered"><code> this.adapter.<span class="func">freezeSchema</span>();</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Return table name for specified `modelName`</span></code></li><li class=""><code><span class="C"> * @param {String} modelName</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.tableName = <span class="kwrd">function</span> (modelName) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">return</span> this.definitions<span class="gly">[</span>modelName<span class="gly">]</span>.settings.table = this.definitions<span class="gly">[</span>modelName<span class="gly">]</span>.settings.table <span class="gly">|</span><span class="gly">|</span> modelName</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define foreign key</span></code></li><li class=""><code><span class="C"> * @param {String} className</span></code></li><li class=""><code><span class="C"> * @param {String} key - name of key field</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.defineForeignKey = <span class="kwrd">function</span> <span class="func">defineForeignKey</span>(className, key) <span class="gly">{</span></code></li><li class=""><code> // <span class="kwrd">return</span> <span class="kwrd">if</span> already defined</code></li><li class="covered"><code> <span class="kwrd">if</span> (this.definitions<span class="gly">[</span>className<span class="gly">]</span>.properties<span class="gly">[</span>key<span class="gly">]</span>) <span class="kwrd">return</span>;</code><span class="hits">2</span></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">if</span> (this.adapter.defineForeignKey) <span class="gly">{</span></code></li><li class=""><code> this.adapter.<span class="func">defineForeignKey</span>(className, key, <span class="kwrd">function</span> (err, keyType) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">if</span> (err) throw err;</code><span class="hits">2</span></li><li class="covered"><code> this.definitions<span class="gly">[</span>className<span class="gly">]</span>.properties<span class="gly">[</span>key<span class="gly">]</span> = <span class="gly">{</span>type: keyType<span class="gly">}</span>;</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>.<span class="func">bind</span>(this));</code><span class="hits">2</span></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="uncovered"><code> this.definitions<span class="gly">[</span>className<span class="gly">]</span>.properties<span class="gly">[</span>key<span class="gly">]</span> = <span class="gly">{</span>type: Number<span class="gly">}</span>;</code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Close database connection</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code>Schema.prototype.disconnect = <span class="kwrd">function</span> <span class="func">disconnect</span>() <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (<span class="kwrd">typeof</span> this.adapter.disconnect === <span class="S">'function'</span>) <span class="gly">{</span></code></li><li class="covered"><code> this.adapter.<span class="func">disconnect</span>();</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="C">/**</span></code></li><li class=""><code><span class="C"> * Define hidden property</span></code></li><li class=""><code><span class="C"> */</span></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">hiddenProperty</span>(where, property, value) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">defineProperty</span>(where, property, <span class="gly">{</span></code></li><li class=""><code> writable: false,</code></li><li class=""><code> enumerable: false,</code></li><li class=""><code> configurable: false,</code></li><li class=""><code> value: value</code></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">12</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-hookable-js" class="filename" name="lib-hookable-js" onclick="var el = document.getElementById('lib-hookable-js'); el.style.display = el.style.display ? '' : 'none';">lib/hookable.js</a></div><div class="span6"><div class="progress progress-success"> <div class="bar" style="width: 88%"><strong>88%</strong> [25/52]</div></div></div></div><div id="lib-hookable-js" style="display:none;"><pre><ol><li class="covered"><code>exports.Hookable = Hookable;</code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">Hookable</span>() <span class="gly">{</span></code></li><li class=""><code> // hookable class</code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class="covered"><code>Hookable.afterInitialize = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.beforeValidation = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.afterValidation = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.beforeSave = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.afterSave = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.beforeCreate = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.afterCreate = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.beforeUpdate = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.afterUpdate = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.beforeDestroy = null;</code><span class="hits">1</span></li><li class="covered"><code>Hookable.afterDestroy = null;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code>Hookable.prototype.trigger = <span class="kwrd">function</span> <span class="func">trigger</span>(actionName, work, data) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">var</span> capitalizedName = <span class="func">capitalize</span>(actionName);</code><span class="hits">354</span></li><li class="covered"><code> <span class="kwrd">var</span> afterHook = this.constructor<span class="gly">[</span><span class="S">"after"</span> + capitalizedName<span class="gly">]</span>;</code><span class="hits">354</span></li><li class="covered"><code> <span class="kwrd">var</span> beforeHook = this.constructor<span class="gly">[</span><span class="S">"before"</span> + capitalizedName<span class="gly">]</span>;</code><span class="hits">354</span></li><li class="covered"><code> <span class="kwrd">var</span> inst = this;</code><span class="hits">354</span></li><li class=""><code></code></li><li class=""><code> // we only call <span class="S">"before"</span> hook when we have actual <span class="func">action</span>(work) to perform</code></li><li class=""><code> <span class="kwrd">if</span> (work) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (beforeHook) <span class="gly">{</span></code></li><li class=""><code> // before hook should be called on instance with one param: callback</code></li><li class=""><code> beforeHook.<span class="func">call</span>(inst, <span class="kwrd">function</span> () <span class="gly">{</span></code></li><li class=""><code> // actual action also have one param: callback</code></li><li class="uncovered"><code> work.<span class="func">call</span>(inst, next);</code></li><li class="uncovered"><code> <span class="gly">}</span>, data);</code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> work.<span class="func">call</span>(inst, next);</code><span class="hits">87</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span> else <span class="gly">{</span></code></li><li class="covered"><code> <span class="func">next</span>();</code><span class="hits">267</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code> <span class="kwrd">function</span> <span class="func">next</span>(done) <span class="gly">{</span></code></li><li class=""><code> <span class="kwrd">if</span> (afterHook) <span class="gly">{</span></code></li><li class="uncovered"><code> afterHook.<span class="func">call</span>(inst, done);</code></li><li class=""><code> <span class="gly">}</span> else <span class="kwrd">if</span> (done) <span class="gly">{</span></code></li><li class="covered"><code> done.<span class="func">call</span>(this);</code><span class="hits">87</span></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code> <span class="gly">}</span></code></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">capitalize</span>(string) <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> string.<span class="func">charAt</span>(0).toUpper<span class="kwrd">Case</span>() + string.<span class="func">slice</span>(1);</code><span class="hits">354</span></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-jutil-js" class="filename" name="lib-jutil-js" onclick="var el = document.getElementById('lib-jutil-js'); el.style.display = el.style.display ? '' : 'none';">lib/jutil.js</a></div><div class="span6"><div class="progress progress-success"> <div class="bar" style="width: 100%"><strong>100%</strong> [5/10]</div></div></div></div><div id="lib-jutil-js" style="display:none;"><pre><ol><li class="covered"><code>exports.inherits = <span class="kwrd">function</span> (newClass, baseClass) <span class="gly">{</span></code></li><li class=""><code> Object.<span class="func">keys</span>(baseClass).<span class="func">forEach</span>(<span class="kwrd">function</span> (classMethod) <span class="gly">{</span></code></li><li class="covered"><code> newClass<span class="gly">[</span>classMethod<span class="gly">]</span> = baseClass<span class="gly">[</span>classMethod<span class="gly">]</span>;</code><span class="hits">20</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class=""><code> Object.<span class="func">keys</span>(baseClass.prototype).<span class="func">forEach</span>(<span class="kwrd">function</span> (instanceMethod) <span class="gly">{</span></code></li><li class="covered"><code> newClass.prototype<span class="gly">[</span>instanceMethod<span class="gly">]</span> = baseClass.prototype<span class="gly">[</span>instanceMethod<span class="gly">]</span>;</code><span class="hits">2</span></li><li class="covered"><code> <span class="gly">}</span>);</code><span class="hits">2</span></li><li class="covered"><code><span class="gly">}</span>;</code><span class="hits">1</span></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
<div class="row"><div class="span5"><a href="#lib-utils-js" class="filename" name="lib-utils-js" onclick="var el = document.getElementById('lib-utils-js'); el.style.display = el.style.display ? '' : 'none';">lib/utils.js</a></div><div class="span6"><div class="progress progress-warning"> <div class="bar" style="width: 50%"><strong>50%</strong> [4/12]</div></div></div></div><div id="lib-utils-js" style="display:none;"><pre><ol><li class="covered"><code>exports.safeRequire = safeRequire;</code></li><li class=""><code></code></li><li class=""><code><span class="kwrd">function</span> <span class="func">safeRequire</span>(module) <span class="gly">{</span></code></li><li class=""><code> try <span class="gly">{</span></code></li><li class="covered"><code> <span class="kwrd">return</span> <span class="func">require</span>(module);</code><span class="hits">1</span></li><li class=""><code> <span class="gly">}</span> <span class="func">catch</span>(e) <span class="gly">{</span></code></li><li class="uncovered"><code> console.<span class="func">log</span>(<span class="S">'Run "npm install '</span> + module + <span class="S">'" command to use jugglingdb using this database engine'</span>);</code></li><li class="uncovered"><code> process.<span class="func">exit</span>(1);</code></li><li class=""><code> <span class="gly">}</span></code></li><li class=""><code><span class="gly">}</span></code></li><li class=""><code></code></li><li class=""><code></code></li></ol></pre></div>
|
|
</div>
|
|
</body>
|
|
</html>
|