total4
Version:
Total.js framework v4
221 lines (176 loc) • 5.88 kB
JavaScript
function Counter(name) {
var t = this;
t.db = require('./textdb-wrapper').make('nosql', PATH.databases(name + '.counter'));
t.cache = {};
ON('service', function(counter) {
if (counter % 5 === 0)
t.flush();
});
}
const CP = Counter.prototype;
CP.hit = function(id, value) {
if (value == null)
value = 1;
var self = this;
var key = '+' + id;
if (self.cache[key]) {
self.cache[key].sum += value;
if (self.cache[key].min == null || self.cache[key].min > value)
self.cache[key].min = value;
if (self.cache[key].max == null || self.cache[key].max < value)
self.cache[key].max = value;
} else
self.cache[key] = { sum: value, min: value, max: value };
return self;
};
CP.flush = function() {
var self = this;
for (var key in self.cache) {
var val = self.cache[key];
var m = {};
m.id = key.substring(1);
m['+sum'] = val.sum;
m['<min'] = val.min;
m['>max'] = val.max;
m.day = NOW.getDate();
m.month = NOW.getMonth() + 1;
m.year = NOW.getFullYear();
m.ts = +NOW.format('yyyyMMdd');
m.date = NOW;
self.db.modify(m, true).where('id', m.id).where('ts', m.ts);
}
self.cache = {};
return self;
};
CP.find = function() {
return this.db.find();
};
CP.count = function(id, callback) {
if (typeof(id) === 'function') {
callback = id;
id = null;
}
var self = this;
var builder = self.find();
builder.callback(callback);
builder.options.scalar = 'arg.count=(arg.count?arg.count:0)+doc.sum';
builder.options.scalararg = {};
id && builder.id(id);
builder.$custom = function() {
return function(err, response, meta) {
response = response.count || 0;
builder.$callback && builder.$callback(err, response, meta);
};
};
return builder;
};
CP.scalar = function(type, field, key, callback) {
if (typeof(key) === 'function') {
callback = key;
key = null;
} else if (typeof(field) === 'function' || !field) {
callback = field;
field = type;
type = '*';
}
var self = this;
var builder = self.db.scalar(type, field, key);
callback && builder.callback(callback);
return builder;
};
CP.daily = function(id, callback) {
var self = this;
var builder = self.find().callback(callback);
builder.fields('-id');
builder.where('id', id);
return builder;
};
CP.monthly = function(id, callback) {
var self = this;
var builder = self.find();
callback && builder.callback(callback);
builder.options.scalar = 'tmp.id=((doc.ts)+\'\').substring(0,6);if(arg[tmp.id]){arg[tmp.id].sum+=doc.sum;if(arg[tmp.id].min>doc.min)arg[tmp.id].min=doc.min;if(arg[tmp.id].max<doc.max)arg[tmp.id].max=doc.max;arg[tmp.id].count++}else{arg[tmp.id]={count:1,sum:doc.sum,min:doc.min,max:doc.max,year:doc.year,month:doc.month,ts:+tmp.id}}';
builder.options.scalararg = {};
builder.where('id', id);
builder.$custom = function() {
return function(err, response, meta) {
var arr = [];
for (var key in response) {
var item = response[key];
item.date = key;
arr.push(item);
}
response = null;
builder.$callback && builder.$callback(err, arr, meta);
};
};
return builder;
};
CP.yearly = function(id, callback) {
var self = this;
var builder = self.find();
callback && builder.callback(callback);
builder.options.scalar = 'tmp.id=((doc.ts)+\'\').substring(0,4);if(arg[tmp.id]){arg[tmp.id].sum+=doc.sum;if(arg[tmp.id].min>doc.min)arg[tmp.id].min=doc.min;if(arg[tmp.id].max<doc.max)arg[tmp.id].max=doc.max;arg[tmp.id].count++}else{arg[tmp.id]={count:1,sum:doc.sum,min:doc.min,max:doc.max,year:doc.year,ts:doc.year}}';
builder.options.scalararg = {};
builder.where('id', id);
builder.$custom = function() {
return function(err, response, meta) {
var arr = [];
for (var key in response) {
var item = response[key];
item.date = key;
arr.push(item);
}
response = null;
builder.$callback && builder.$callback(err, arr, meta);
};
};
return builder;
};
CP.summarize = function(type, callback) {
if (typeof(type) === 'function') {
callback = type;
type = null;
}
var self = this;
var builder = self.find();
callback && builder.callback(callback);
switch (type) {
case 'yearly':
builder.options.scalar = 'tmp.ts=(doc.ts+\'\').substring(0,4);tmp.id=(tmp.ts+\'_\'+doc.id);if(arg[tmp.id]){arg[tmp.id].sum+=doc.sum;if(arg[tmp.id].min>doc.min)arg[tmp.id].min=doc.min;if(arg[tmp.id].max<doc.max)arg[tmp.id].max=doc.max;arg[tmp.id].count++}else{arg[tmp.id]={id:doc.id,count:1,sum:doc.sum,min:doc.min,max:doc.max,ts:+tmp.ts,date:tmp.ts,year:+tmp.ts}}';
break;
case 'monthly':
builder.options.scalar = 'tmp.ts=(doc.ts+\'\').substring(0,6);tmp.id=(tmp.ts+\'_\'+doc.id);if(arg[tmp.id]){arg[tmp.id].sum+=doc.sum;if(arg[tmp.id].min>doc.min)arg[tmp.id].min=doc.min;if(arg[tmp.id].max<doc.max)arg[tmp.id].max=doc.max;arg[tmp.id].count++}else{arg[tmp.id]={id:doc.id,count:1,sum:doc.sum,min:doc.min,max:doc.max,ts:+tmp.ts,date:tmp.ts,year:+tmp.ts.substring(0,4),month:+tmp.ts.substring(4)}}';
break;
default:
builder.options.scalar = 'if(arg[doc.id]){arg[doc.id].sum+=doc.sum;if(arg[doc.id].min>doc.min)arg[doc.id].min=doc.min;if(arg[doc.id].max<doc.max)arg[doc.id].max=doc.max;arg[doc.id].count++}else{arg[doc.id]={id:doc.id,count:1,sum:doc.sum,min:doc.min,max:doc.max}}';
break;
}
builder.options.scalararg = {};
builder.$custom = function() {
return function(err, response, meta) {
var arr = [];
for (var key in response) {
var item = response[key];
item.date = item.ts + '';
arr.push(item);
}
response = null;
builder.$callback && builder.$callback(err, arr, meta);
};
};
return builder;
};
CP.clear = function() {
this.db.clear();
return this;
};
CP.remove = function(id, callback) {
var builder = this.db.remove();
id && builder.where('id', id);
callback && builder.callback(callback);
return builder;
};
exports.make = function(name) {
return new Counter(name);
};