Implement unique incremebt
This commit is contained in:
parent
be2cde106b
commit
6cccd9d288
1 changed files with 74 additions and 30 deletions
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const nestedProperty = require('nested-property');
|
const nestedProperty = require('nested-property');
|
||||||
|
import autobind from 'autobind-decorator';
|
||||||
import * as mongo from 'mongodb';
|
import * as mongo from 'mongodb';
|
||||||
import db from '../db/mongodb';
|
import db from '../db/mongodb';
|
||||||
import { INote } from '../models/note';
|
import { INote } from '../models/note';
|
||||||
|
@ -45,6 +46,11 @@ type ChartDocument<T extends Obj> = {
|
||||||
* データ
|
* データ
|
||||||
*/
|
*/
|
||||||
data: T;
|
data: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ユニークインクリメント用
|
||||||
|
*/
|
||||||
|
unique?: Obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +67,28 @@ abstract class Chart<T> {
|
||||||
this.collection.createIndex('group');
|
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 now = new Date();
|
||||||
const y = now.getFullYear();
|
const y = now.getFullYear();
|
||||||
const m = now.getMonth();
|
const m = now.getMonth();
|
||||||
|
@ -129,39 +156,42 @@ abstract class Chart<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected inc(inc: Partial<T>, group?: Obj): void {
|
@autobind
|
||||||
const query: Obj = {};
|
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) => {
|
if (uniqueKey) {
|
||||||
Object.entries(x).forEach(([k, v]) => {
|
query['$push'] = {
|
||||||
const p = path ? `${path}.${k}` : k;
|
[`unique.${uniqueKey}`]: uniqueValue
|
||||||
if (typeof v === 'number') {
|
};
|
||||||
query[`data.${p}`] = v;
|
|
||||||
} else {
|
|
||||||
dive(v, p);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
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
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getCurrentStats('hour', 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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>> {
|
public async getStats(span: Span, range: number, group?: Obj): Promise<ArrayValue<T>> {
|
||||||
const chart: T[] = [];
|
const chart: T[] = [];
|
||||||
|
|
||||||
|
@ -296,6 +326,7 @@ class UsersChart extends Chart<UsersStats> {
|
||||||
super('usersStats');
|
super('usersStats');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateInitialStats(): UsersStats {
|
protected generateInitialStats(): UsersStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -311,6 +342,7 @@ class UsersChart extends Chart<UsersStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateEmptyStats(mostRecentStats: UsersStats): UsersStats {
|
protected generateEmptyStats(mostRecentStats: UsersStats): UsersStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -326,6 +358,7 @@ class UsersChart extends Chart<UsersStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
public async update(user: IUser, isAdditional: boolean) {
|
public async update(user: IUser, isAdditional: boolean) {
|
||||||
const update: Obj = {};
|
const update: Obj = {};
|
||||||
|
|
||||||
|
@ -424,6 +457,7 @@ class NotesChart extends Chart<NotesStats> {
|
||||||
super('notesStats');
|
super('notesStats');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateInitialStats(): NotesStats {
|
protected generateInitialStats(): NotesStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -449,6 +483,7 @@ class NotesChart extends Chart<NotesStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateEmptyStats(mostRecentStats: NotesStats): NotesStats {
|
protected generateEmptyStats(mostRecentStats: NotesStats): NotesStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -474,8 +509,11 @@ class NotesChart extends Chart<NotesStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
public async update(note: INote, isAdditional: boolean) {
|
public async update(note: INote, isAdditional: boolean) {
|
||||||
const update: Obj = {};
|
const update: Obj = {
|
||||||
|
diffs: {}
|
||||||
|
};
|
||||||
|
|
||||||
update.total = isAdditional ? 1 : -1;
|
update.total = isAdditional ? 1 : -1;
|
||||||
|
|
||||||
|
@ -577,6 +615,7 @@ class DriveChart extends Chart<DriveStats> {
|
||||||
super('driveStats');
|
super('driveStats');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateInitialStats(): DriveStats {
|
protected generateInitialStats(): DriveStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -598,6 +637,7 @@ class DriveChart extends Chart<DriveStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateEmptyStats(mostRecentStats: DriveStats): DriveStats {
|
protected generateEmptyStats(mostRecentStats: DriveStats): DriveStats {
|
||||||
return {
|
return {
|
||||||
local: {
|
local: {
|
||||||
|
@ -619,6 +659,7 @@ class DriveChart extends Chart<DriveStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
public async update(file: IDriveFile, isAdditional: boolean) {
|
public async update(file: IDriveFile, isAdditional: boolean) {
|
||||||
const update: Obj = {};
|
const update: Obj = {};
|
||||||
|
|
||||||
|
@ -678,6 +719,7 @@ class NetworkChart extends Chart<NetworkStats> {
|
||||||
super('networkStats');
|
super('networkStats');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateInitialStats(): NetworkStats {
|
protected generateInitialStats(): NetworkStats {
|
||||||
return {
|
return {
|
||||||
incomingRequests: 0,
|
incomingRequests: 0,
|
||||||
|
@ -688,6 +730,7 @@ class NetworkChart extends Chart<NetworkStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
protected generateEmptyStats(mostRecentStats: NetworkStats): NetworkStats {
|
protected generateEmptyStats(mostRecentStats: NetworkStats): NetworkStats {
|
||||||
return {
|
return {
|
||||||
incomingRequests: 0,
|
incomingRequests: 0,
|
||||||
|
@ -698,6 +741,7 @@ class NetworkChart extends Chart<NetworkStats> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@autobind
|
||||||
public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) {
|
public async update(incomingRequests: number, time: number, incomingBytes: number, outgoingBytes: number) {
|
||||||
const inc: Partial<NetworkStats> = {
|
const inc: Partial<NetworkStats> = {
|
||||||
incomingRequests: incomingRequests,
|
incomingRequests: incomingRequests,
|
||||||
|
|
Loading…
Reference in a new issue