1 import { db } from './lib/db';
2 import { version } from '../../package.json';
3 import { CreatedEvent, Event, EventName } from '../shared/event';
4 import { isEqual } from 'lodash';
5 import { logger } from './lib/logger';
6 import { EVENT_FLUSH_INTERVAL, EVENT_SECOND_BUCKET } from '../shared/constants';
7 import { clickhouse } from './lib/clickhouse';
9 const eventBuffer: CreatedEvent[] = [];
12 export async function flushBuffer() {
13 const events = eventBuffer.splice(0, maxToAdd);
15 await addEvents(events);
16 logger.log(`Flushed ${events.length} events`);
18 setTimeout(flushBuffer, EVENT_FLUSH_INTERVAL);
21 function bucketTime(date: Date): Date {
23 d.setFullYear(date.getFullYear());
24 d.setMonth(date.getMonth());
25 d.setDate(date.getDate());
26 d.setHours(date.getHours());
27 d.setMinutes(date.getMinutes());
30 const s = date.getSeconds();
32 // round down to closest 5 second interval
33 d.setSeconds(s - (s%EVENT_SECOND_BUCKET));
38 export async function addEvent(event_name: EventName, player_id: string, props?: any, created?: Date) {
48 export async function addEvents(events: CreatedEvent[]) {
49 return db('events').insert(events);
52 export async function getEventHistory(player_id: string, event_name: EventName) {
53 return db.select('*').from<Event<any>>('events').where({
59 export async function getEventHistoryToday(player_id: string, event_name: EventName) {
60 return db.select('*').from<Event<any>>('events').where({
63 }).andWhere('created', '>=', db.raw('current_date::timestamp'));
67 export async function hasNeverHappenedBefeore(name: EventName, player_id: string, props?: any): Promise<boolean> {
68 return hasHappendXTimes(0, name, player_id, props);
71 export async function hasHappendXTimes(times: number, event_name: EventName, player_id: string, props?: any): Promise<boolean> {
72 const res: Event<any>[] = await getEventHistory(player_id, event_name);
75 return res.filter(row => isEqual(row.props, props)).length === times;
77 return res.length === times;