stats: update note count
This commit is contained in:
parent
2ab7616795
commit
bababe56f3
20
src/db.ts
20
src/db.ts
|
@ -13,6 +13,22 @@ interface DittoDB {
|
||||||
users: UserRow;
|
users: UserRow;
|
||||||
relays: RelayRow;
|
relays: RelayRow;
|
||||||
unattached_media: UnattachedMediaRow;
|
unattached_media: UnattachedMediaRow;
|
||||||
|
pubkey_stats: PubkeyStatsRow;
|
||||||
|
event_stats: EventStatsRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PubkeyStatsRow {
|
||||||
|
pubkey: string;
|
||||||
|
followers_count: number;
|
||||||
|
following_count: number;
|
||||||
|
notes_count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EventStatsRow {
|
||||||
|
event_id: string;
|
||||||
|
replies_count: number;
|
||||||
|
reposts_count: number;
|
||||||
|
reactions_count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EventRow {
|
interface EventRow {
|
||||||
|
@ -101,7 +117,7 @@ async function migrate() {
|
||||||
console.log('Everything up-to-date.');
|
console.log('Everything up-to-date.');
|
||||||
} else {
|
} else {
|
||||||
console.log('Migrations finished!');
|
console.log('Migrations finished!');
|
||||||
for (const { migrationName, status } of results.results) {
|
for (const { migrationName, status } of results.results!) {
|
||||||
console.log(` - ${migrationName}: ${status}`);
|
console.log(` - ${migrationName}: ${status}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,4 +126,4 @@ async function migrate() {
|
||||||
|
|
||||||
await migrate();
|
await migrate();
|
||||||
|
|
||||||
export { db, type DittoDB, type EventRow, type TagRow, type UserRow };
|
export { db, type DittoDB, type EventRow, type EventStatsRow, type PubkeyStatsRow, type TagRow, type UserRow };
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { isEphemeralKind } from '@/kinds.ts';
|
||||||
import * as mixer from '@/mixer.ts';
|
import * as mixer from '@/mixer.ts';
|
||||||
import { publish } from '@/pool.ts';
|
import { publish } from '@/pool.ts';
|
||||||
import { isLocallyFollowed } from '@/queries.ts';
|
import { isLocallyFollowed } from '@/queries.ts';
|
||||||
|
import { updateStats } from '@/stats.ts';
|
||||||
import { Sub } from '@/subs.ts';
|
import { Sub } from '@/subs.ts';
|
||||||
import { getTagSet } from '@/tags.ts';
|
import { getTagSet } from '@/tags.ts';
|
||||||
import { eventAge, isRelay, nostrDate, Time } from '@/utils.ts';
|
import { eventAge, isRelay, nostrDate, Time } from '@/utils.ts';
|
||||||
|
@ -68,7 +69,10 @@ async function storeEvent(event: Event, data: EventData): Promise<void> {
|
||||||
if (deletion) {
|
if (deletion) {
|
||||||
return Promise.reject(new RelayError('blocked', 'event was deleted'));
|
return Promise.reject(new RelayError('blocked', 'event was deleted'));
|
||||||
} else {
|
} else {
|
||||||
await eventsDB.insertEvent(event, data).catch(console.warn);
|
await Promise.all([
|
||||||
|
eventsDB.insertEvent(event, data).catch(console.warn),
|
||||||
|
updateStats(event),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(new RelayError('blocked', 'only registered users can post'));
|
return Promise.reject(new RelayError('blocked', 'only registered users can post'));
|
||||||
|
|
47
src/stats.ts
47
src/stats.ts
|
@ -1,11 +1,17 @@
|
||||||
import { open as lmdb } from 'npm:lmdb';
|
import { db, type PubkeyStatsRow } from '@/db.ts';
|
||||||
import { Event } from '@/deps.ts';
|
import { Event } from '@/deps.ts';
|
||||||
|
|
||||||
const db = lmdb({ path: 'data/ditto.lmdb' });
|
type PubkeyStat = keyof Omit<PubkeyStatsRow, 'pubkey'>;
|
||||||
|
|
||||||
/** Store stats for the event in LMDB. */
|
/** Store stats for the event in LMDB. */
|
||||||
async function saveStats(event: Event): Promise<void> {
|
function updateStats(event: Event) {
|
||||||
|
return updateStatsQuery(event).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateStatsQuery(event: Event) {
|
||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
|
case 1:
|
||||||
|
return incrementPubkeyStatQuery(event.pubkey, 'notes_count', 1);
|
||||||
case 6:
|
case 6:
|
||||||
return await incrementMentionedEvent(event, 'reposts');
|
return await incrementMentionedEvent(event, 'reposts');
|
||||||
case 7:
|
case 7:
|
||||||
|
@ -13,20 +19,29 @@ async function saveStats(event: Event): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Increment the subkey for the first mentioned event. */
|
function incrementPubkeyStatQuery(pubkey: string, stat: PubkeyStat, diff: number) {
|
||||||
async function incrementMentionedEvent(event: Event, subkey: string): Promise<void> {
|
const row: PubkeyStatsRow = {
|
||||||
const eventId = event.tags.find(([name]) => name === 'e')?.[1];
|
pubkey,
|
||||||
if (eventId) {
|
followers_count: 0,
|
||||||
return await incrementKey([eventId, subkey]);
|
following_count: 0,
|
||||||
}
|
notes_count: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
row[stat] = diff;
|
||||||
|
|
||||||
|
return db.insertInto('pubkey_stats')
|
||||||
|
.values(row)
|
||||||
|
.onConflict((oc) =>
|
||||||
|
oc
|
||||||
|
.column('pubkey')
|
||||||
|
.doUpdateSet((eb) => ({
|
||||||
|
[stat]: eb(stat, '+', diff),
|
||||||
|
}))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Increase the counter by 1, or set the key if it doesn't exist. */
|
function findFirstTag({ tags }: Event, name: string): string | undefined {
|
||||||
function incrementKey(key: string[]): Promise<void> {
|
return tags.find(([n]) => n === name)?.[1];
|
||||||
return db.transaction(() => {
|
|
||||||
const value = db.get(key) || 0;
|
|
||||||
db.put(key, value + 1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { saveStats };
|
export { updateStats };
|
||||||
|
|
Loading…
Reference in New Issue