fetch messages before/after based on order

This way, if the reference message was deleted at some point, the fetch request can still go through.
Also it's easier to run the queries directly on an order id/text anyway
This commit is contained in:
Michael Peters 2022-01-23 17:23:43 -06:00
parent b97db81fa2
commit afd2939fa1
13 changed files with 86 additions and 96 deletions

View File

@ -8,7 +8,7 @@ import { Changes, WithEquals } from "./data-types";
export interface PartialMessageListQuery { export interface PartialMessageListQuery {
channelId: string; channelId: string;
messageId: string | null; messageOrderId: string | null;
number: number; number: number;
} }
@ -35,7 +35,7 @@ export class AutoVerifierWithArg<T, K> {
changesFunc: (query: PartialMessageListQuery, changesType: AutoVerifierChangesType, changes: Changes<T>) => Promise<boolean> changesFunc: (query: PartialMessageListQuery, changesType: AutoVerifierChangesType, changes: Changes<T>) => Promise<boolean>
) { ) {
return new AutoVerifierWithArg<T[], PartialMessageListQuery>( return new AutoVerifierWithArg<T[], PartialMessageListQuery>(
query => `ch#${query.channelId} m#${query.messageId}->${query.number}`, query => `ch#${query.channelId} mo#${query.messageOrderId}->${query.number}`,
query => primaryFunc(query), query => primaryFunc(query),
query => trustedFunc(query), query => trustedFunc(query),
async (query: PartialMessageListQuery, primaryResult: T[] | null, trustedResult: T[] | null) => { async (query: PartialMessageListQuery, primaryResult: T[] | null, trustedResult: T[] | null) => {

View File

@ -146,7 +146,7 @@ export class Message implements WithEquals<Message> {
public channel: Channel | { id: string }, public channel: Channel | { id: string },
public member: Member | { id: string }, public member: Member | { id: string },
public readonly sent: Date, public readonly sent: Date,
public readonly _order: string, // access through order functions/methods public readonly _order: string, // for sorting, access through order functions/methods
public readonly text: string | null, public readonly text: string | null,
public readonly resourceId: string | null, public readonly resourceId: string | null,
public readonly resourceName: string | null, public readonly resourceName: string | null,

View File

@ -814,11 +814,11 @@ export function useMessagesScrollingSubscription(guild: CombinedGuild, channel:
}, [ guild, channelGuild, channel.id, maxFetchElements ]); }, [ guild, channelGuild, channel.id, maxFetchElements ]);
const fetchAboveFunc = useCallback(async (reference: Message) => { const fetchAboveFunc = useCallback(async (reference: Message) => {
if (guild !== channelGuild) return []; if (guild !== channelGuild) return [];
return await guild.fetchMessagesBefore(channel.id, reference.id, maxFetchElements); return await guild.fetchMessagesBefore(channel.id, reference._order, maxFetchElements);
}, [ guild, channelGuild, channel.id, maxFetchElements ]); }, [ guild, channelGuild, channel.id, maxFetchElements ]);
const fetchBelowFunc = useCallback(async (reference: Message) => { const fetchBelowFunc = useCallback(async (reference: Message) => {
if (guild !== channelGuild) return []; if (guild !== channelGuild) return [];
return await guild.fetchMessagesAfter(channel.id, reference.id, maxFetchElements); return await guild.fetchMessagesAfter(channel.id, reference._order, maxFetchElements);
}, [ guild, channelGuild, channel.id, maxFetchElements ]); }, [ guild, channelGuild, channel.id, maxFetchElements ]);
return useMultipleGuildSubscriptionScrolling( return useMultipleGuildSubscriptionScrolling(
guild, { guild, {

View File

@ -23,11 +23,11 @@ export default class EnsuredFetchable implements GuaranteedFetchable {
async fetchMessagesRecent(channelId: string, number: number): Promise<Message[]> { async fetchMessagesRecent(channelId: string, number: number): Promise<Message[]> {
return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesRecent(channelId, number)); return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesRecent(channelId, number));
} }
async fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesBefore(channelId, messageId, number)); return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesBefore(channelId, messageOrderId, number));
} }
async fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesAfter(channelId, messageId, number)); return EnsuredFetchable.guarantee(await this.fetchable.fetchMessagesAfter(channelId, messageOrderId, number));
} }
async fetchResource(resourceId: string): Promise<Resource> { async fetchResource(resourceId: string): Promise<Resource> {
return EnsuredFetchable.guarantee(await this.fetchable.fetchResource(resourceId)); return EnsuredFetchable.guarantee(await this.fetchable.fetchResource(resourceId));

View File

@ -77,14 +77,14 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
); );
this.fetchMessagesBeforeVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier( this.fetchMessagesBeforeVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier(
async (query: PartialMessageListQuery) => await this.primary.fetchMessagesBefore(query.channelId, query.messageId as string, query.number), async (query: PartialMessageListQuery) => await this.primary.fetchMessagesBefore(query.channelId, query.messageOrderId as string, query.number),
async (query: PartialMessageListQuery) => await this.trusted.fetchMessagesBefore(query.channelId, query.messageId as string, query.number), async (query: PartialMessageListQuery) => await this.trusted.fetchMessagesBefore(query.channelId, query.messageOrderId as string, query.number),
this.handleMessagesConflict.bind(this) this.handleMessagesConflict.bind(this)
); );
this.fetchMessagesAfterVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier( this.fetchMessagesAfterVerifier = AutoVerifierWithArg.createStandardPartialMessageListAutoVerifier(
async (query: PartialMessageListQuery) => await this.primary.fetchMessagesAfter(query.channelId, query.messageId as string, query.number), async (query: PartialMessageListQuery) => await this.primary.fetchMessagesAfter(query.channelId, query.messageOrderId as string, query.number),
async (query: PartialMessageListQuery) => await this.trusted.fetchMessagesAfter(query.channelId, query.messageId as string, query.number), async (query: PartialMessageListQuery) => await this.trusted.fetchMessagesAfter(query.channelId, query.messageOrderId as string, query.number),
this.handleMessagesConflict.bind(this) this.handleMessagesConflict.bind(this)
); );
} }
@ -195,13 +195,13 @@ export default class PairVerifierFetchable extends EventEmitter<Conflictable> im
return await this.fetchChannelsVerifier.fetchAndVerifyIfNeeded(); return await this.fetchChannelsVerifier.fetchAndVerifyIfNeeded();
} }
async fetchMessagesRecent(channelId: string, number: number): Promise<Message[] | null> { async fetchMessagesRecent(channelId: string, number: number): Promise<Message[] | null> {
return await this.fetchMessagesRecentVerifier.fetchAndVerifyIfNeded({ channelId, messageId: null, number }); return await this.fetchMessagesRecentVerifier.fetchAndVerifyIfNeded({ channelId, messageOrderId: null, number });
} }
async fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
return await this.fetchMessagesBeforeVerifier.fetchAndVerifyIfNeded({ channelId, messageId, number }); return await this.fetchMessagesBeforeVerifier.fetchAndVerifyIfNeded({ channelId, messageOrderId, number });
} }
async fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
return await this.fetchMessagesAfterVerifier.fetchAndVerifyIfNeded({ channelId, messageId, number }); return await this.fetchMessagesAfterVerifier.fetchAndVerifyIfNeded({ channelId, messageOrderId, number });
} }
async fetchResource(resourceId: string): Promise<Resource | null> { async fetchResource(resourceId: string): Promise<Resource | null> {
return await this.fetchResourceVerifier.fetchAndVerifyIfNeded({ id: resourceId }, true); // lazy verification return await this.fetchResourceVerifier.fetchAndVerifyIfNeded({ id: resourceId }, true); // lazy verification

View File

@ -353,19 +353,19 @@ export default class CombinedGuild extends EventEmitter<Connectable & Conflictab
} }
return messages; return messages;
} }
async fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
const members = await this.grabRAMMembersMap(); const members = await this.grabRAMMembersMap();
const channels = await this.grabRAMChannelsMap(); const channels = await this.grabRAMChannelsMap();
const messages = await this.fetchable.fetchMessagesBefore(channelId, messageId, number); const messages = await this.fetchable.fetchMessagesBefore(channelId, messageOrderId, number);
for (const message of messages) { for (const message of messages) {
message.fill(members, channels); message.fill(members, channels);
} }
return messages; return messages;
} }
async fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
const members = await this.grabRAMMembersMap(); const members = await this.grabRAMMembersMap();
const channels = await this.grabRAMChannelsMap(); const channels = await this.grabRAMChannelsMap();
const messages = await this.fetchable.fetchMessagesAfter(channelId, messageId, number); const messages = await this.fetchable.fetchMessagesAfter(channelId, messageOrderId, number);
for (const message of messages) { for (const message of messages) {
message.fill(members, channels); message.fill(members, channels);
} }

View File

@ -1,8 +1,3 @@
import * as electronRemote from '@electron/remote';
const electronConsole = electronRemote.getGlobal('console') as Console;
import Logger from '../../logger/logger';
const LOG = Logger.create(__filename, electronConsole);
import { AsyncFetchable, AsyncLackable } from "./guild-types"; import { AsyncFetchable, AsyncLackable } from "./guild-types";
import { Channel, GuildMetadata, GuildMetadataLocal, Member, Message, Resource, SocketConfig, Token } from "./data-types"; import { Channel, GuildMetadata, GuildMetadataLocal, Member, Message, Resource, SocketConfig, Token } from "./data-types";
@ -13,7 +8,7 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
constructor( constructor(
private readonly db: PersonalDB, private readonly db: PersonalDB,
private readonly guildId: number, private readonly guildId: number,
private readonly memberId: string, // would be used if we want to cache-update the status/display name of members /*private */readonly _memberId: string, // would be used if we want to cache-update the status/display name of members
) {} ) {}
// Fetched Methods // Fetched Methods
@ -38,12 +33,12 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
return await this.db.fetchMessagesRecent(this.guildId, channelId, number); return await this.db.fetchMessagesRecent(this.guildId, channelId, number);
} }
async fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
return await this.db.fetchMessagesBefore(this.guildId, channelId, messageId, number); return await this.db.fetchMessagesBefore(this.guildId, channelId, messageOrderId, number);
} }
async fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
return await this.db.fetchMessagesAfter(this.guildId, channelId, messageId, number); return await this.db.fetchMessagesAfter(this.guildId, channelId, messageOrderId, number);
} }
async fetchResource(resourceId: string): Promise<Resource | null> { async fetchResource(resourceId: string): Promise<Resource | null> {
@ -97,9 +92,9 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
async handleMessagesAdded( async handleMessagesAdded(
addedMessages: Message[], addedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): Promise<boolean> { ): Promise<boolean> {
// The PersonalDB does not remove old messages (yet) so nothing here would unverify // The PersonalDB does not remove old messages (yet) so nothing here would unverify
//LOG.debug(addedMessages.length + ' personal messages added'); //LOG.debug(addedMessages.length + ' personal messages added');
@ -108,9 +103,9 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
} }
async handleMessagesChanged( async handleMessagesChanged(
changedMessages: Message[], changedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): Promise<boolean> { ): Promise<boolean> {
// The PersonalDB does not remove old messages (yet) so nothing here would unverify // The PersonalDB does not remove old messages (yet) so nothing here would unverify
//LOG.debug(changedMessages.length + ' personal messages changed'); //LOG.debug(changedMessages.length + ' personal messages changed');
@ -119,9 +114,9 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
} }
async handleMessagesDeleted( async handleMessagesDeleted(
deletedMessages: Message[], deletedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): Promise<boolean> { ): Promise<boolean> {
// The PersonalDB does not remove old messages (yet) so nothing here would unverify // The PersonalDB does not remove old messages (yet) so nothing here would unverify
//LOG.debug(deletedMessages.length + ' personal messages deleted'); //LOG.debug(deletedMessages.length + ' personal messages deleted');
@ -145,13 +140,13 @@ export default class PersonalDBGuild implements AsyncFetchable, AsyncLackable {
return true; return true;
} }
async handleTokensAdded(addedTokens: Token[]): Promise<boolean> { async handleTokensAdded(_addedTokens: Token[]): Promise<boolean> {
return false; // cache currently does not handle tokens return false; // cache currently does not handle tokens
} }
async handleTokensChanged(changedTokens: Token[]): Promise<boolean> { async handleTokensChanged(_changedTokens: Token[]): Promise<boolean> {
return false; // cache currently does not handle tokens return false; // cache currently does not handle tokens
} }
async handleTokensDeleted(deletedTokens: Token[]): Promise<boolean> { async handleTokensDeleted(_deletedTokens: Token[]): Promise<boolean> {
return false; // cache currently does not handle tokens return false; // cache currently does not handle tokens
} }
} }

View File

@ -1,8 +1,3 @@
import * as electronRemote from '@electron/remote';
const electronConsole = electronRemote.getGlobal('console') as Console;
import Logger from '../../logger/logger';
const LOG = Logger.create(__filename, electronConsole);
import { SyncFetchable, SyncLackable } from "./guild-types"; import { SyncFetchable, SyncLackable } from "./guild-types";
import { GuildMetadata, Member, Channel, Message, Resource, Token } from "./data-types"; import { GuildMetadata, Member, Channel, Message, Resource, Token } from "./data-types";
import MessageRAMCache from "./message-ram-cache"; import MessageRAMCache from "./message-ram-cache";
@ -39,10 +34,10 @@ export default class RAMGuild implements SyncFetchable, SyncLackable {
fetchMessagesRecent(channelId: string, number: number): Message[] | null { fetchMessagesRecent(channelId: string, number: number): Message[] | null {
return this.recentMessages.fetchRecentMessages(this.guildId, channelId, number); return this.recentMessages.fetchRecentMessages(this.guildId, channelId, number);
} }
fetchMessagesBefore(channelId: string, messageId: string, number: number): Message[] | null { fetchMessagesBefore(_channelId: string, _messageOrderId: string, _number: number): Message[] | null {
return null; // not planning on doing this unless someone wants to do a scrolling cache return null; // not planning on doing this unless someone wants to do a scrolling cache
} }
fetchMessagesAfter(channelId: string, messageId: string, number: number): Message[] | null { fetchMessagesAfter(_channelId: string, _messageOrderId: string, _number: number): Message[] | null {
return null; // not planning on doing this unless someone wants to do a scrolling cache return null; // not planning on doing this unless someone wants to do a scrolling cache
} }
fetchResource(resourceId: string): Resource | null { fetchResource(resourceId: string): Resource | null {
@ -101,8 +96,8 @@ export default class RAMGuild implements SyncFetchable, SyncLackable {
handleMessagesAdded( handleMessagesAdded(
addedMessages: Message[], addedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): boolean { ): boolean {
const byChannel = new Map<string, Message[]>(); const byChannel = new Map<string, Message[]>();
for (const message of addedMessages) { for (const message of addedMessages) {
@ -120,8 +115,8 @@ export default class RAMGuild implements SyncFetchable, SyncLackable {
handleMessagesChanged( handleMessagesChanged(
changedMessages: Message[], changedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): boolean { ): boolean {
const byChannel = new Map<string, Message[]>(); const byChannel = new Map<string, Message[]>();
for (const message of changedMessages) { for (const message of changedMessages) {
@ -139,8 +134,8 @@ export default class RAMGuild implements SyncFetchable, SyncLackable {
handleMessagesDeleted( handleMessagesDeleted(
deletedMessages: Message[], deletedMessages: Message[],
recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, recentAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>, _beforeAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>,
afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery> _afterAutoVerifier: AutoVerifierWithArg<Message[], PartialMessageListQuery>
): boolean { ): boolean {
const byChannel = new Map<string, Message[]>(); const byChannel = new Map<string, Message[]>();
for (const message of deletedMessages) { for (const message of deletedMessages) {
@ -165,19 +160,19 @@ export default class RAMGuild implements SyncFetchable, SyncLackable {
this.resources.putResource(this.guildId, changedResource); this.resources.putResource(this.guildId, changedResource);
return true; return true;
} }
handleResourceDeleted(deletedResource: Resource): boolean { handleResourceDeleted(_deletedResource: Resource): boolean {
// do nothing, the cache will garbage collect itself and this is probably fine to leave as verified :) // do nothing, the cache will garbage collect itself and this is probably fine to leave as verified :)
// also resource deletion should be pretty rare, especially in a cache // also resource deletion should be pretty rare, especially in a cache
return true; return true;
} }
handleTokensAdded(addedTokens: Token[]): boolean { handleTokensAdded(_addedTokens: Token[]): boolean {
return false; // TODO: token ram cache return false; // TODO: token ram cache
} }
handleTokensChanged(changedTokens: Token[]): boolean { handleTokensChanged(_changedTokens: Token[]): boolean {
return false; // TODO: token ram cache return false; // TODO: token ram cache
} }
handleTokensDeleted(deletedTokens: Token[]): boolean { handleTokensDeleted(_deletedTokens: Token[]): boolean {
return false; // TODO: token ram cache return false; // TODO: token ram cache
} }
} }

View File

@ -146,12 +146,12 @@ export default class SocketGuild extends EventEmitter<Connectable> implements As
const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-recent', channelId, number); const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-recent', channelId, number);
return data.map((dataMessage: any) => Message.fromDBData(dataMessage)); return data.map((dataMessage: any) => Message.fromDBData(dataMessage));
} }
async fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-before', channelId, messageId, number); const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-before', channelId, messageOrderId, number);
return data.map((dataMessage: any) => Message.fromDBData(dataMessage)); return data.map((dataMessage: any) => Message.fromDBData(dataMessage));
} }
async fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[]> { async fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[]> {
const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-after', channelId, messageId, number); const data = await this.queryOnceVerifiedDedup(Globals.DEFAULT_SOCKET_TIMEOUT, 'fetch-messages-after', channelId, messageOrderId, number);
return data.map((dataMessage: any) => Message.fromDBData(dataMessage)); return data.map((dataMessage: any) => Message.fromDBData(dataMessage));
} }
async fetchResource(resourceId: string): Promise<Resource> { async fetchResource(resourceId: string): Promise<Resource> {
@ -165,10 +165,10 @@ export default class SocketGuild extends EventEmitter<Connectable> implements As
// We don't want to dedup these // We don't want to dedup these
async requestSendMessage(channelId: string, text: string): Promise<void> { async requestSendMessage(channelId: string, text: string): Promise<void> {
const _dataMessage = await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'send-message', channelId, text); /*const _dataMessage = */await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'send-message', channelId, text);
} }
async requestSendMessageWithResource(channelId: string, text: string | null, resource: Buffer, resourceName: string): Promise<void> { async requestSendMessageWithResource(channelId: string, text: string | null, resource: Buffer, resourceName: string): Promise<void> {
const _dataMessage = await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'send-message-with-resource', channelId, text, resource, resourceName); /*const _dataMessage = */await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'send-message-with-resource', channelId, text, resource, resourceName);
} }
async requestSetStatus(status: string): Promise<void> { async requestSetStatus(status: string): Promise<void> {
await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'set-status', status); await this.queryOnceVerified(Globals.DEFAULT_SOCKET_TIMEOUT, 'set-status', status);

View File

@ -9,8 +9,8 @@ export interface SyncFetchable {
fetchMembers(): Member[] | null; fetchMembers(): Member[] | null;
fetchChannels(): Channel[] | null; fetchChannels(): Channel[] | null;
fetchMessagesRecent(channelId: string, number: number): Message[] | null; fetchMessagesRecent(channelId: string, number: number): Message[] | null;
fetchMessagesBefore(channelId: string, messageId: string, number: number): Message[] | null; fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Message[] | null;
fetchMessagesAfter(channelId: string, messageId: string, number: number): Message[] | null; fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Message[] | null;
fetchResource(resourceId: string): Resource | null; fetchResource(resourceId: string): Resource | null;
fetchTokens(): Token[] | null; fetchTokens(): Token[] | null;
} }
@ -19,8 +19,8 @@ export interface AsyncFetchable {
fetchMembers(): Promise<Member[] | null>; fetchMembers(): Promise<Member[] | null>;
fetchChannels(): Promise<Channel[] | null>; fetchChannels(): Promise<Channel[] | null>;
fetchMessagesRecent(channelId: string, number: number): Promise<Message[] | null>; fetchMessagesRecent(channelId: string, number: number): Promise<Message[] | null>;
fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[] | null>; fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null>;
fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[] | null>; fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[] | null>;
fetchResource(resourceId: string): Promise<Resource | null>; fetchResource(resourceId: string): Promise<Resource | null>;
fetchTokens(): Promise<Token[] | null>; fetchTokens(): Promise<Token[] | null>;
} }
@ -31,8 +31,8 @@ export interface AsyncGuaranteedFetchable {
fetchMembers(): Promise<Member[]>; fetchMembers(): Promise<Member[]>;
fetchChannels(): Promise<Channel[]>; fetchChannels(): Promise<Channel[]>;
fetchMessagesRecent(channelId: string, number: number): Promise<Message[]>; fetchMessagesRecent(channelId: string, number: number): Promise<Message[]>;
fetchMessagesBefore(channelId: string, messageId: string, number: number): Promise<Message[]>; fetchMessagesBefore(channelId: string, messageOrderId: string, number: number): Promise<Message[]>;
fetchMessagesAfter(channelId: string, messageId: string, number: number): Promise<Message[]>; fetchMessagesAfter(channelId: string, messageOrderId: string, number: number): Promise<Message[]>;
fetchResource(resourceId: string): Promise<Resource>; fetchResource(resourceId: string): Promise<Resource>;
fetchTokens(): Promise<Token[]>; fetchTokens(): Promise<Token[]>;
} }

View File

@ -522,7 +522,7 @@ export default class PersonalDB {
return messages.map(dataMessage => Message.fromDBData(dataMessage)); return messages.map(dataMessage => Message.fromDBData(dataMessage));
} }
async fetchMessagesBefore(guildId: number, channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesBefore(guildId: number, channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
const messages = await this.db.all(` const messages = await this.db.all(`
SELECT * FROM ( SELECT * FROM (
SELECT * SELECT *
@ -530,26 +530,26 @@ export default class PersonalDB {
WHERE WHERE
"guild_id"=:guild_id "guild_id"=:guild_id
AND "channel_id"=:channel_id AND "channel_id"=:channel_id
AND "order" < (SELECT "order" FROM "messages" WHERE "id"=:message_id) AND "order" < :order
ORDER BY "order" DESC, "id" DESC ORDER BY "order" DESC, "id" DESC
LIMIT :number LIMIT :number
) AS "r" ORDER BY "r"."order" ASC ) AS "r" ORDER BY "r"."order" ASC
`, { ':guild_id': guildId, ':channel_id': channelId, ':message_id': messageId, ':number': number }); `, { ':guild_id': guildId, ':channel_id': channelId, ':order': messageOrderId, ':number': number });
if (messages.length === 0) return null; if (messages.length === 0) return null;
return messages.map(dataMessage => Message.fromDBData(dataMessage)); return messages.map(dataMessage => Message.fromDBData(dataMessage));
} }
async fetchMessagesAfter(guildId: number, channelId: string, messageId: string, number: number): Promise<Message[] | null> { async fetchMessagesAfter(guildId: number, channelId: string, messageOrderId: string, number: number): Promise<Message[] | null> {
const messages = await this.db.all(` const messages = await this.db.all(`
SELECT * SELECT *
FROM "messages" FROM "messages"
WHERE WHERE
"guild_id"=:guild_id "guild_id"=:guild_id
AND "channel_id"=:channel_id AND "channel_id"=:channel_id
AND "order" > (SELECT "order" FROM "messages" WHERE "id"=:message_id) AND "order" > :order
ORDER BY "order" ASC ORDER BY "order" ASC
LIMIT :number LIMIT :number
`, { ':guild_id': guildId, ':channel_id': channelId, ':message_id': messageId, ':number': number }); `, { ':guild_id': guildId, ':channel_id': channelId, ':order': messageOrderId, ':number': number });
if (messages.length === 0) return null; if (messages.length === 0) return null;
return messages.map(dataMessage => Message.fromDBData(dataMessage)); return messages.map(dataMessage => Message.fromDBData(dataMessage));
} }

View File

@ -173,7 +173,7 @@ export default class DB {
return result.rows; return result.rows;
} }
static async getMessagesBefore(guildId: string, channelId: string, messageId: string, number: number): Promise<any[]> { static async getMessagesBefore(guildId: string, channelId: string, messageOrderId: string, number: number): Promise<any[]> {
const result = await db.query(` const result = await db.query(`
SELECT * FROM ( SELECT * FROM (
SELECT SELECT
@ -189,14 +189,14 @@ export default class DB {
WHERE WHERE
"guild_id"=$1 "guild_id"=$1
AND "channel_id"=$2 AND "channel_id"=$2
AND "order" < (SELECT "order" FROM "messages" WHERE "id"=$3) AND "order" < $3
ORDER BY "order" DESC ORDER BY "order" DESC
LIMIT $4 LIMIT $4
) AS "r" ORDER BY "r"."order" ASC`, [ guildId, channelId, messageId, number ]); ) AS "r" ORDER BY "r"."order" ASC`, [ guildId, channelId, messageOrderId, number ]);
return result.rows; return result.rows;
} }
static async getMessagesAfter(guildId: string, channelId: string, messageId: string, number: number): Promise<any[]> { static async getMessagesAfter(guildId: string, channelId: string, messageOrderId: string, number: number): Promise<any[]> {
const result = await db.query(` const result = await db.query(`
SELECT SELECT
"id", "channel_id", "member_id" "id", "channel_id", "member_id"
@ -211,9 +211,9 @@ export default class DB {
WHERE WHERE
"guild_id"=$1 "guild_id"=$1
AND "channel_id"=$2 AND "channel_id"=$2
AND "order" > (SELECT "order" FROM "messages" WHERE "id"=$3) AND "order" > $3
ORDER BY "order" ASC, "id" ASC ORDER BY "order" ASC, "id" ASC
LIMIT $4`, [ guildId, channelId, messageId, number ]); LIMIT $4`, [ guildId, channelId, messageOrderId, number ]);
return result.rows; return result.rows;
} }

View File

@ -778,7 +778,7 @@ function bindFetchEvents(client: socketio.Socket, identity: IIdentity): void { /
* client.on('fetch-messages-before', (channelId, messageId, number, respond(errStr, messages))) * client.on('fetch-messages-before', (channelId, messageId, number, respond(errStr, messages)))
* Fetch messages coming before the specified message * Fetch messages coming before the specified message
* @param channelId The channel uuid of the channel * @param channelId The channel uuid of the channel
* @param messageId The id of the base message (will not be included in results) * @param messageOrderId The order string of the base message (will not be included in results)
* @param number The maximum number of messages to get * @param number The maximum number of messages to get
* @param respond function(errStr, messages) as a socket.io response function * @param respond function(errStr, messages) as a socket.io response function
* @param respond.errStr Error string if an error, else null * @param respond.errStr Error string if an error, else null
@ -788,11 +788,11 @@ function bindFetchEvents(client: socketio.Socket, identity: IIdentity): void { /
client, identity, client, identity,
{ verified: true }, { verified: true },
'fetch-messages-before', [ 'string', 'string', 'number', 'function' ], 'fetch-messages-before', [ 'string', 'string', 'number', 'function' ],
async (channelId, messageId, number, respond) => { async (channelId, messageOrderId, number, respond) => {
if (!identity.guildId) throw new EventError('identity no guildId'); if (!identity.guildId) throw new EventError('identity no guildId');
if (!identity.memberId) throw new EventError('identity no memberId'); if (!identity.memberId) throw new EventError('identity no memberId');
LOG.info(`u#${identity.memberId}: fetching messages before ch#${channelId} m#${messageId} number: ${number}`); LOG.info(`u#${identity.memberId}: fetching messages before ch#${channelId} mo#${messageOrderId} number: ${number}`);
const messages = await DB.getMessagesBefore(identity.guildId, channelId, messageId, number); const messages = await DB.getMessagesBefore(identity.guildId, channelId, messageOrderId, number);
respond(null, messages); respond(null, messages);
} }
); );
@ -800,7 +800,7 @@ function bindFetchEvents(client: socketio.Socket, identity: IIdentity): void { /
/* /*
* Fetch messages coming after the specified message * Fetch messages coming after the specified message
* @param channelId The channel uuid of the channel * @param channelId The channel uuid of the channel
* @param messageId The id of the base message (will not be included in results) * @param messageOrderId The order string of the base message (will not be included in results)
* @param number The maximum number of messages to get * @param number The maximum number of messages to get
* @param respond function(errStr, messages) as a socket.io response function * @param respond function(errStr, messages) as a socket.io response function
* @param respond.errStr Error string if an error, else null * @param respond.errStr Error string if an error, else null
@ -810,11 +810,11 @@ function bindFetchEvents(client: socketio.Socket, identity: IIdentity): void { /
client, identity, client, identity,
{ verified: true }, { verified: true },
'fetch-messages-after', [ 'string', 'string', 'number', 'function' ], 'fetch-messages-after', [ 'string', 'string', 'number', 'function' ],
async (channelId, messageId, number, respond) => { async (channelId, messageOrderId, number, respond) => {
if (!identity.guildId) throw new EventError('identity no guildId'); if (!identity.guildId) throw new EventError('identity no guildId');
if (!identity.memberId) throw new EventError('identity no memberId'); if (!identity.memberId) throw new EventError('identity no memberId');
LOG.info(`u#${identity.memberId}: fetching messages after ch#${channelId} m#${messageId} number: ${number}`); LOG.info(`u#${identity.memberId}: fetching messages after ch#${channelId} mo#${messageOrderId} number: ${number}`);
const messages = await DB.getMessagesAfter(identity.guildId, channelId, messageId, number); const messages = await DB.getMessagesAfter(identity.guildId, channelId, messageOrderId, number);
respond(null, messages); respond(null, messages);
} }
); );