From d49cea72f6bcfc2e4a5349b7d178200328a318d8 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 21 May 2025 08:01:49 +0400 Subject: [PATCH] Api fixes v5 (#55) Signed-off-by: Kristina Fefelova --- .version | 2 +- packages/cockroach/src/adapter.ts | 6 +++--- packages/cockroach/src/connection.ts | 10 +++++----- packages/cockroach/src/db/message.ts | 15 ++++++++++++--- packages/cockroach/src/utils.ts | 6 ++++-- packages/sdk-types/src/db.ts | 2 +- packages/server/src/middleware/db.ts | 11 +++-------- packages/server/src/triggers/card.ts | 23 ----------------------- 8 files changed, 29 insertions(+), 46 deletions(-) diff --git a/.version b/.version index fd39f6dee6..64b5cd7f13 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.1.187 +0.1.188 diff --git a/packages/cockroach/src/adapter.ts b/packages/cockroach/src/adapter.ts index d9f736c0f4..0b092e2494 100644 --- a/packages/cockroach/src/adapter.ts +++ b/packages/cockroach/src/adapter.ts @@ -96,7 +96,7 @@ export class CockroachAdapter implements DbAdapter { data?: MessageData, externalId?: string, id?: MessageID - ): Promise { + ): Promise<{ id: MessageID; created: Date }> { return await this.message.createMessage(card, type, content, creator, created, data, externalId, id) } @@ -340,9 +340,9 @@ class CockroachClient implements SqlClient { } cursor(query: string, params?: SqlParams, size?: number): AsyncIterable[]> { - const sql = params !== undefined && params.length > 0 ? injectVars(query, params) : query + // const sql = params !== undefined && params.length > 0 ? injectVars(query, params) : query - return this.sql.unsafe(sql).cursor(size) + return this.sql.unsafe(query, params).cursor(size) } close(): void { diff --git a/packages/cockroach/src/connection.ts b/packages/cockroach/src/connection.ts index 7480097f54..c799a3c494 100644 --- a/packages/cockroach/src/connection.ts +++ b/packages/cockroach/src/connection.ts @@ -97,14 +97,14 @@ export function connect(connectionString: string, database?: string): PostgresCl if (existing === undefined) { const sql = postgres(connectionString, { - connection: { - application_name: 'communication' - }, database, max: 5, fetch_types: false, - prepare: false, - ...extraOptions + prepare: true, + ...extraOptions, + connection: { + application_name: 'communication' + } }) existing = new PostgresClientReferenceImpl(sql, () => { diff --git a/packages/cockroach/src/db/message.ts b/packages/cockroach/src/db/message.ts index 85f3469b94..a2c87719ca 100644 --- a/packages/cockroach/src/db/message.ts +++ b/packages/cockroach/src/db/message.ts @@ -65,7 +65,7 @@ export class MessagesDb extends BaseDb { data?: MessageData, externalId?: string, id?: MessageID - ): Promise { + ): Promise<{ id: MessageID; created: Date }> { const db: Omit & { id?: MessageID } = { type, workspace_id: this.workspace, @@ -89,13 +89,22 @@ export class MessagesDb extends BaseDb { } const placeholders = keys.map((key, i) => `$${i + 1}::${(messageSchema as any)[key]}`) + const conflictClause = + externalId != null + ? `ON CONFLICT (workspace_id, card_id, external_id) + DO UPDATE SET external_id = EXCLUDED.external_id` + : '' + const sql = `INSERT INTO ${TableName.Message} (${keys.join(', ')}) VALUES (${placeholders.join(', ')}) - RETURNING id::text` + ${conflictClause} + RETURNING id::text, created` const result = await this.execute(sql, values, 'insert message') + const createdR = new Date(result[0].created) + const idR = result[0].id as MessageID - return result.map((it: any) => it.id)[0] + return { id: idR, created: createdR } } async removeMessages(card: CardID, query: RemoveMessageQuery): Promise { diff --git a/packages/cockroach/src/utils.ts b/packages/cockroach/src/utils.ts index 213f6d7f3f..2ad47592c2 100644 --- a/packages/cockroach/src/utils.ts +++ b/packages/cockroach/src/utils.ts @@ -44,8 +44,10 @@ function escape(value: any): string { return `'${value.replace(/'/g, "''")}'` case 'bigint': return value.toString() - case 'object': - return `'${JSON.stringify(value)}'` + case 'object': { + const json = JSON.stringify(value).replace(/'/g, "''") + return `'${json}'` + } default: throw new Error(`Unsupported value type: ${typeof value}`) } diff --git a/packages/sdk-types/src/db.ts b/packages/sdk-types/src/db.ts index 068d4335ff..ddc3f449ea 100644 --- a/packages/sdk-types/src/db.ts +++ b/packages/sdk-types/src/db.ts @@ -58,7 +58,7 @@ export interface DbAdapter { data?: MessageData, externalId?: string, id?: MessageID - ): Promise + ): Promise<{ id: MessageID; created: Date }> removeMessages(card: CardID, query: RemoveMessageQuery): Promise createPatch( diff --git a/packages/server/src/middleware/db.ts b/packages/server/src/middleware/db.ts index 9818cc3148..3adb58a3c6 100644 --- a/packages/server/src/middleware/db.ts +++ b/packages/server/src/middleware/db.ts @@ -36,7 +36,6 @@ import { type CreateFileEvent, type CreateLabelEvent, type CreateMessageEvent, - type CreateMessageResult, type CreateMessagesGroupEvent, type CreateNotificationContextEvent, type CreateNotificationEvent, @@ -235,7 +234,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware { private async createMessage(event: CreateMessageEvent): Promise { const created = event.created ?? new Date() - const id = await this.db.createMessage( + const result = await this.db.createMessage( event.card, event.messageType, event.content, @@ -246,12 +245,12 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware { event.id ) const message: Message = { - id, + id: result.id, type: event.messageType, card: event.card, content: event.content, creator: event.creator, - created, + created: result.created, data: event.data, externalId: event.externalId, reactions: [], @@ -263,10 +262,6 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware { cardType: event.cardType, message } - const result: CreateMessageResult = { - id, - created - } return { responseEvent, result diff --git a/packages/server/src/triggers/card.ts b/packages/server/src/triggers/card.ts index 21c583c114..e274c9ad43 100644 --- a/packages/server/src/triggers/card.ts +++ b/packages/server/src/triggers/card.ts @@ -20,7 +20,6 @@ import { NotificationRequestEventType, type RequestEvent } from '@hcengineering/communication-sdk-types' -import type { CardID } from '@hcengineering/communication-types' import type { TriggerCtx, TriggerFn, Triggers } from '../types' @@ -46,15 +45,6 @@ async function removeThreads(ctx: TriggerCtx, event: CardRemovedEvent): Promise< return [] } -async function removeMessages(ctx: TriggerCtx, event: CardRemovedEvent): Promise { - await ctx.db.removeMessages(event.card, {}) - await ctx.db.removePatches(event.card) - await ctx.db.removeFiles(event.card, {}) - await removeMessageGroups(ctx, event.card) - - return [] -} - async function removeNotificationContexts(ctx: TriggerCtx, event: CardRemovedEvent): Promise { const result: RequestEvent[] = [] const contexts = await ctx.db.findNotificationContexts({ card: event.card }) @@ -68,24 +58,11 @@ async function removeNotificationContexts(ctx: TriggerCtx, event: CardRemovedEve return result } -async function removeMessageGroups(ctx: TriggerCtx, card: CardID): Promise { - while (true) { - const groups = await ctx.db.findMessagesGroups({ card }) - if (groups.length === 0) return - - for (const group of groups) { - ///TODO: delete blob - await ctx.db.removeMessagesGroup(group.card, group.blobId) - } - } -} - const triggers: Triggers = [ ['on_card_type_updates', CardResponseEventType.CardTypeUpdated, onCardTypeUpdates as TriggerFn], ['remove_collaborators_on_card_removed', CardResponseEventType.CardRemoved, removeCollaborators as TriggerFn], ['remove_labels_on_card_removed', CardResponseEventType.CardRemoved, removeLabels as TriggerFn], ['remove_threads_on_card_removed', CardResponseEventType.CardRemoved, removeThreads as TriggerFn], - ['remove_messages_on_card_removed', CardResponseEventType.CardRemoved, removeMessages as TriggerFn], [ 'remove_notification_contexts_on_card_removed', CardResponseEventType.CardRemoved,