Skip to content

Commit

Permalink
improve(desktop): merge duplicate topic processing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Red-Asuka committed Aug 28, 2024
1 parent 643e5c1 commit 869e077
Showing 1 changed file with 30 additions and 56 deletions.
86 changes: 30 additions & 56 deletions src/database/services/MessageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,7 @@ export default class MessageService {
} as MessageModel
}

public async get(
connectionId: string,
options: {
page?: number
limit?: number
msgType?: MessageType
topic?: string
searchParams?: { topic?: string; payload?: string }
} = {},
): Promise<MessagePaginationModel> {
const defaultOpts = { page: 1, limit: 20, msgType: 'all' }
const { page, limit, msgType } = { ...defaultOpts, ...options }
let { topic } = { ...defaultOpts, ...options }

const total = await this.messageRepository.count({ connectionId })
const publishedTotal = await this.messageRepository.count({ connectionId, out: true })
const receivedTotal = await this.messageRepository.count({ connectionId, out: false })

let query = this.messageRepository
.createQueryBuilder('msg')
.where('msg.connectionId = :connection', { connection: connectionId })

msgType !== 'all' && query.andWhere('msg.out = :out', { out: msgType === 'publish' })

public handleTopicQuery(query: $TSFixed, topic?: string) {
if (topic && topic !== '#') {
// Escape special characters for SQL LIKE
topic = topic.replace(/[\\%_]/g, '\\$&')
Expand Down Expand Up @@ -92,6 +69,34 @@ export default class MessageService {
query.andWhere('msg.topic LIKE :topic ESCAPE "\\"', { topic })
}
}
return query
}

public async get(
connectionId: string,
options: {
page?: number
limit?: number
msgType?: MessageType
topic?: string
searchParams?: { topic?: string; payload?: string }
} = {},
): Promise<MessagePaginationModel> {
const defaultOpts = { page: 1, limit: 20, msgType: 'all' }
const { page, limit, msgType } = { ...defaultOpts, ...options }
let { topic } = { ...defaultOpts, ...options }

const total = await this.messageRepository.count({ connectionId })
const publishedTotal = await this.messageRepository.count({ connectionId, out: true })
const receivedTotal = await this.messageRepository.count({ connectionId, out: false })

let query = this.messageRepository
.createQueryBuilder('msg')
.where('msg.connectionId = :connection', { connection: connectionId })

msgType !== 'all' && query.andWhere('msg.out = :out', { out: msgType === 'publish' })

query = this.handleTopicQuery(query, topic)

if (options.searchParams) {
const { topic, payload } = options.searchParams
Expand Down Expand Up @@ -142,38 +147,7 @@ export default class MessageService {

msgType !== 'all' && query.andWhere('msg.out = :out', { out: msgType === 'publish' })

if (topic && topic !== '#') {
// Escape special characters for SQL LIKE
topic = topic.replace(/[\\%_]/g, '\\$&')

// Remove $share prefix if present
if (topic.startsWith('$share/')) {
topic = topic.split('/').slice(2).join('/')
}

/*
Handle `+` wildcard
Known Issue: '+' wildcard handling in MQTT topics is incorrect.
'+' is replaced with '%' for SQL LIKE, causing multi-level match.
- Incorrect: 'testtopic/+/test' matches 'testtopic/1/2/test'
- Incorrect: 'testtopic/+/hello/+' can not matches 'testtopic/hello/hello/hello'
TODO: FIX this issue.
*/
if (topic.includes('+')) {
topic = topic.replace('+', '%')
}

// Handle '#' wildcard
if (topic.endsWith('/#')) {
const baseTopic = topic.slice(0, -2) // Remove '/#'
query.andWhere('(msg.topic LIKE :baseTopic OR msg.topic LIKE :topic ESCAPE "\\")', {
baseTopic,
topic: baseTopic + '/%',
})
} else {
query.andWhere('msg.topic LIKE :topic ESCAPE "\\"', { topic })
}
}
query = this.handleTopicQuery(query, topic)

if (options.searchParams) {
const { topic, payload } = options.searchParams
Expand Down

0 comments on commit 869e077

Please sign in to comment.