summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-10-21 12:37:00 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-10-21 12:37:00 +0900
commit6cccd9d2885af94277070056c8f00cb7a87c3a05 (patch)
tree12ecb9a3acb1def8876a372e974572d24e9d8986 /src
parentUpdate stats.ts (diff)
downloadsharkey-6cccd9d2885af94277070056c8f00cb7a87c3a05.tar.gz
sharkey-6cccd9d2885af94277070056c8f00cb7a87c3a05.tar.bz2
sharkey-6cccd9d2885af94277070056c8f00cb7a87c3a05.zip
Implement unique incremebt
Diffstat (limited to 'src')
-rw-r--r--src/services/stats.ts100
1 files changed, 72 insertions, 28 deletions
diff --git a/src/services/stats.ts b/src/services/stats.ts
index 7479c2cb94..3d2e52f710 100644
--- a/src/services/stats.ts
+++ b/src/services/stats.ts
@@ -3,6 +3,7 @@
*/
const nestedProperty = require('nested-property');
+import autobind from 'autobind-decorator';
import * as mongo from 'mongodb';
import db from '../db/mongodb';
import { INote } from '../models/note';
@@ -45,6 +46,11 @@ type ChartDocument<T extends Obj> = {
* データ
*/
data: T;
+
+ /**
+ * ユニークインクリメント用
+ */
+ unique?: Obj;
};
/**
@@ -61,7 +67,28 @@ abstract class Chart<T> {
this.collection.createIndex('group');
}
- protected async getCurrentStats(span: Span, group?: Obj): Promise<ChartDocument<T>> {
+ @autobind
+ private convertQuery(x: Obj, path: string): Obj {
+ const query: Obj = {};
+
+ const dive = (x: Obj, path: string) => {
+ Object.entries(x).forEach(([k, v]) => {
+ const p = path ? `${path}.${k}` : k;
+ if (typeof v === 'number') {
+ query[p] = v;
+ } else {
+ dive(v, p);
+ }
+ });
+ };
+
+ dive(x, path);
+
+ return query;
+ }
+
+ @autobind
+ private async getCurrentStats(span: Span, group?: Obj): Promise<ChartDocument<T>> {
const now = new Date();
const y = now.getFullYear();
const m = now.getMonth();
@@ -129,39 +156,42 @@ abstract class Chart<T> {
}
}
- protected inc(inc: Partial<T>, group?: Obj): void {
- const query: Obj = {};
+ @autobind
+ protected commit(query: Obj, group?: Obj, uniqueKey?: string, uniqueValue?: string): void {
+ const update = (stats: ChartDocument<T>) => {
+ // ユニークインクリメントの場合、指定のキーに指定の値が既に存在していたら弾く
+ if (uniqueKey && stats.unique && stats.unique[uniqueKey] && stats.unique[uniqueKey].includes(uniqueValue)) return;
- const dive = (x: Obj, path?: string) => {
- Object.entries(x).forEach(([k, v]) => {
- const p = path ? `${path}.${k}` : k;
- if (typeof v === 'number') {
- query[`data.${p}`] = v;
- } else {
- dive(v, p);
- }
- });
+ if (uniqueKey) {
+ query['$push'] = {
+ [`unique.${uniqueKey}`]: uniqueValue
+ };
+ }
+
+ this.collection.update({
+ _id: stats._id
+ }, query);
};
- dive(inc);
+ this.getCurrentStats('day', group).then(stats => update(stats));
+ this.getCurrentStats('hour', group).then(stats => update(stats));
+ }
- this.getCurrentStats('day', group).then(stats => {
- this.collection.findOneAndUpdate({
- _id: stats._id
- }, {
- $inc: query
- });
- });
+ @autobind
+ protected inc(inc: Partial<T>, group?: Obj): void {
+ this.commit({
+ $inc: this.convertQuery(inc, 'data')
+ }, group);
+ }
- this.getCurrentStats('hour', group).then(stats => {
- this.collection.findOneAndUpdate({
- _id: stats._id
- }, {
- $inc: query
- });
- });
+ @autobind
+ protected incIfUnique(inc: Partial<T>, key: string, value: string, group?: Obj): void {
+ this.commit({
+ $inc: this.convertQuery(inc, 'data')
+ }, group, key, value);
}
+ @autobind
public async getStats(span: Span, range: number, group?: Obj): Promise<ArrayValue<T>> {
const chart: T[] = [];
@@ -296,6 +326,7 @@ class UsersChart extends Chart<UsersStats> {
super('usersStats');
}
+ @autobind
protected generateInitialStats(): UsersStats {
return {
local: {
@@ -311,6 +342,7 @@ class UsersChart extends Chart<UsersStats> {
};
}
+ @autobind
protected generateEmptyStats(mostRecentStats: UsersStats): UsersStats {
return {
local: {
@@ -326,6 +358,7 @@ class UsersChart extends Chart<UsersStats> {
};
}
+ @autobind
public async update(user: IUser, isAdditional: boolean) {
const update: Obj = {};
@@ -424,6 +457,7 @@ class NotesChart extends Chart<NotesStats> {
super('notesStats');
}
+ @autobind
protected generateInitialStats(): NotesStats {
return {
local: {
@@ -449,6 +483,7 @@ class NotesChart extends Chart<NotesStats> {
};
}
+ @autobind
protected generateEmptyStats(mostRecentStats: NotesStats): NotesStats {
return {
local: {
@@ -474,8 +509,11 @@ class NotesChart extends Chart<NotesStats> {
};
}
+ @autobind
public async update(note: INote, isAdditional: boolean) {
- const update: Obj = {};
+ const update: Obj = {
+ diffs: {}
+ };
update.total = isAdditional ? 1 : -1;
@@ -577,6 +615,7 @@ class DriveChart extends Chart<DriveStats> {
super('driveStats');
}
+ @autobind
protected generateInitialStats(): DriveStats {
return {
local: {
@@ -598,6 +637,7 @@ class DriveChart extends Chart<DriveStats> {
};
}
+ @autobind
protected generateEmptyStats(mostRecentStats: DriveStats): DriveStats {
return {
local: {
@@ -619,6 +659,7 @@ class DriveChart extends Chart<DriveStats> {
};
}
+ @autobind
public async update(file: IDriveFile, isAdditional: boolean) {
const update: Obj = {};
@@ -678,6 +719,7 @@ class NetworkChart extends Chart<NetworkStats> {
super('networkStats');
}
+ @autobind
protected generateInitialStats(): NetworkStats {
return {
incomingRequests: 0,
@@ -688,6 +730,7 @@ class NetworkChart extends Chart<NetworkStats> {
};
}
+ @autobind
protected generateEmptyStats(mostRecentStats: NetworkStats): NetworkStats {
return {
incomingRequests: 0,
@@ -698,6 +741,7 @@ class NetworkChart extends Chart<NetworkStats> {
};
}
+ @autobind
public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) {
const inc: Partial<NetworkStats> = {
incomingRequests: incomingRequests,