-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This release improves the module structure by separating the builers into different files, also it improves the properties documentation and adds a Stats Wrapper example - Separated builders into files - Improves documentation - Adds example of stats wrapper
- Loading branch information
Jonathan Casarrubias
committed
Apr 1, 2016
1 parent
e106446
commit 6838de2
Showing
10 changed files
with
310 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
'use strict'; | ||
/** | ||
* Builds Parameters object for dynamic remote method | ||
*/ | ||
module.exports = class AcceptBuilder { | ||
/** | ||
* Setters | ||
*/ | ||
constructor(ctx) { this.ctx = ctx; } | ||
/** | ||
* Parse params according ctx type | ||
*/ | ||
build() { | ||
let accepts = []; | ||
if (this.ctx.type === "relation" || this.ctx.type === "nested") | ||
accepts.push({ arg: 'id', type: 'string', required: true, description: this.ctx.Model.definition.name + ' ID' }); | ||
if (this.ctx.type === "relation" && !this.ctx.relation) | ||
accepts.push({ arg: 'relation', type: 'string', required: true, description: 'Relationship name' }); | ||
if (this.ctx.type === "nested") | ||
accepts.push({ arg: 'nested', type: 'string', required: true, description: 'Nested array property name' }); | ||
accepts.push({ arg: 'range', type: 'string', required: true, description: 'Scale range (daily, weekly, monthly, annual)' }); | ||
accepts.push({ arg: 'where', type: 'object', description: 'Statement to filter ' + (this.ctx.relation || this.ctx.nested) }); | ||
return accepts; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
'use strict'; | ||
/** | ||
* Builds Parameters object from dynamic arguments | ||
*/ | ||
module.exports = class ParamsBuilder { | ||
/** | ||
* Setters | ||
*/ | ||
constructor(ctx) { this.ctx = ctx; } | ||
/** | ||
* Parse params according ctx type | ||
*/ | ||
build() { | ||
if (this.ctx.type === "model") | ||
return { range: this.ctx.arguments[0], where: this.ctx.arguments[1], next: this.ctx.arguments[2] }; | ||
if (this.ctx.type === "relation" && this.ctx.relation) | ||
return { id: this.ctx.arguments[0], range: this.ctx.arguments[1], where: this.ctx.arguments[2], next: this.ctx.arguments[3] }; | ||
if (this.ctx.type === "relation" && !this.ctx.relation) | ||
return { id: this.ctx.arguments[0], relation: this.ctx.arguments[1], range: this.ctx.arguments[2], where: this.ctx.arguments[3], next: this.ctx.arguments[4] }; | ||
if (this.ctx.type === "nested") | ||
return { id: this.ctx.arguments[0], nested: this.ctx.arguments[1], range: this.ctx.arguments[2], where: this.ctx.arguments[3], next: this.ctx.arguments[4] }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
'use strict'; | ||
/** | ||
* Builds the primary key name depending on model configurations | ||
*/ | ||
module.exports = class PrimaryKeyBuilder { | ||
constructor(Model) { this.Model = Model; } | ||
build() { | ||
let pk = 'id'; | ||
if (!this.Model.settings.idInjection) | ||
for (let key in this.Model.rawProperties) | ||
if (this.Model.rawProperties[key].id) pk = key; | ||
return pk; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
'use strict'; | ||
/** | ||
* Query Builder Dependencies | ||
*/ | ||
var moment = require('moment'); | ||
/** | ||
* Builds Loopback Query | ||
*/ | ||
module.exports = class QueryBuilder { | ||
/** | ||
* Setters | ||
*/ | ||
constructor(ctx) { this.ctx = ctx; } | ||
onComplete(next) { this.finish = next; return this; } | ||
/** | ||
* Build Query | ||
*/ | ||
build() { | ||
// Build query object in scope | ||
let query = {}; | ||
// lets add a where statement | ||
query.where = this.ctx.params.where || {}; | ||
// If stat type is relation, then we set the root id | ||
if ((this.ctx.type === 'relation' || this.ctx.type === 'nested') && this.ctx.params.id) | ||
query.where[this.ctx.params.pk] = this.ctx.params.id; | ||
// query.where[this.ctx.Model.settings.relations[this.ctx.params.relation].] = this.ctx.params.id; | ||
// If stat type is relation, then we set the root id | ||
if (this.ctx.type === 'relation' && this.ctx.params.relation) | ||
query.include = this.ctx.params.relation; | ||
// Set Range | ||
if (this.ctx.params.range && this.ctx.count.on) { | ||
query.where[this.ctx.count.on] = {}; | ||
switch (this.ctx.params.range) { | ||
case 'weekly': | ||
query.where[this.ctx.count.on].gt = moment(this.ctx.nowISOString).subtract(7, 'days').toDate(); | ||
break; | ||
case 'monthly': | ||
query.where[this.ctx.count.on].gt = moment(this.ctx.nowISOString).subtract(1, 'months').toDate(); | ||
break; | ||
case 'annual': | ||
query.where[this.ctx.count.on].gt = moment(this.ctx.nowISOString).subtract(1, 'years').toDate(); | ||
break; | ||
case 'daily': | ||
default: | ||
query.where[this.ctx.count.on].gt = this.ctx.now.toDate(); | ||
break; | ||
} | ||
} | ||
// Return result query | ||
this.finish(null, query); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
'use strict'; | ||
/** | ||
* Stats Builder Dependencies | ||
*/ | ||
var moment = require('moment'); | ||
/** | ||
* Builds Statistic Array from List of Resuls | ||
*/ | ||
module.exports = class StatsBuilder { | ||
|
||
constructor(ctx) { this.ctx = ctx; } | ||
|
||
process(list) { | ||
this.list = list; | ||
let dataset = []; | ||
let iterator = this.getIteratorCount(); | ||
for (let i = 1, dateIndex = iterator; i <= iterator; i++ , dateIndex--) { | ||
let current = this.getCurrentMoment(dateIndex); | ||
let count = this.getCurrentCount(current); | ||
dataset.push({ | ||
date: current.toISOString(), | ||
count: this.ctx.count.avg ? (count / list.length) : count | ||
}); | ||
} | ||
return dataset; | ||
} | ||
|
||
getCurrentCount(current) { | ||
let count = 0; | ||
this.list.forEach(item => { | ||
let itemDate = moment(item[this.ctx.count.on]); | ||
let itemFactor = this.getFactor(item); | ||
switch (this.ctx.params.range) { | ||
case 'weekly': | ||
case 'monthly': | ||
if (current.isSame(itemDate, 'day')) count = count + itemFactor; | ||
break; | ||
case 'annual': | ||
if (current.isSame(itemDate, 'month')) count = count + itemFactor; | ||
break; | ||
case 'daily': | ||
default: | ||
if (current.isSame(itemDate, 'hour')) count = count + itemFactor; | ||
break; | ||
} | ||
}); | ||
return count; | ||
} | ||
|
||
getFactor(item) { | ||
let value; | ||
// When count by index, the factor will always be 1 | ||
if (this.ctx.count.by === 'index') { | ||
value = 1; | ||
} else { | ||
// We get the value from the property, can be number or boolean | ||
// When number we set that value as factor, else we evaluate | ||
// the value depending on true/false value and this.ctx.count.as value | ||
if (this.ctx.count.by.match(/\./)) { | ||
value = this.ctx.count.by.split('.').reduce((a, b) => a[b] ? a[b] : 0, item); | ||
} else { | ||
value = item[this.ctx.count.by]; | ||
} | ||
// When value is boolean we set 0, 1 or this.ctx.count.as to set a value when true | ||
if (typeof value === 'boolean' && value === true) { | ||
value = this.ctx.count.as ? this.ctx.count.as : 1; | ||
} else if (typeof value === 'boolean' && value === false) { | ||
value = 0; | ||
} | ||
} | ||
// Make sure we send back a number | ||
return typeof value === 'number' ? value : parseInt(value); | ||
} | ||
|
||
getCurrentMoment(index) { | ||
let current; | ||
switch (this.ctx.params.range) { | ||
case 'weekly': | ||
current = moment(this.ctx.nowISOString).subtract(index - 1, 'days'); | ||
break; | ||
case 'monthly': | ||
current = moment(this.ctx.nowISOString).subtract(index - 1, 'days'); | ||
break; | ||
case 'annual': | ||
current = moment(this.ctx.nowISOString).subtract(index - 1, 'months'); | ||
break; | ||
case 'daily': | ||
default: | ||
current = moment(this.ctx.nowISOString).subtract(index - 1, 'hours'); | ||
break; | ||
} | ||
return current; | ||
} | ||
|
||
getIteratorCount() { | ||
let iterator; | ||
|
||
switch (this.ctx.params.range) { | ||
case 'weekly': | ||
iterator = 7; | ||
break; | ||
case 'monthly': | ||
iterator = this.ctx.now.daysInMonth(); | ||
break; | ||
case 'annual': | ||
iterator = 12; | ||
break; | ||
case 'daily': | ||
default: | ||
iterator = 24; | ||
break; | ||
} | ||
|
||
return iterator; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.