Skip to content

Commit

Permalink
feat: add pagination params to storage service (#1883)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrlunin committed Jun 12, 2024
1 parent a648af5 commit f8198b6
Show file tree
Hide file tree
Showing 44 changed files with 312 additions and 149 deletions.
10 changes: 7 additions & 3 deletions packages/action-menu/src/services/ActionMenuService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
} from './ActionMenuServiceOptions'
import type { ActionMenuStateChangedEvent } from '../ActionMenuEvents'
import type { ActionMenuProblemReportMessage } from '../messages'
import type { AgentContext, InboundMessageContext, Logger, Query } from '@credo-ts/core'
import type { AgentContext, InboundMessageContext, Logger, Query, QueryOptions } from '@credo-ts/core'

import { AgentConfig, EventEmitter, CredoError, injectable } from '@credo-ts/core'

Expand Down Expand Up @@ -343,8 +343,12 @@ export class ActionMenuService {
})
}

public async findAllByQuery(agentContext: AgentContext, options: Query<ActionMenuRecord>) {
return await this.actionMenuRepository.findByQuery(agentContext, options)
public async findAllByQuery(
agentContext: AgentContext,
options: Query<ActionMenuRecord>,
queryOptions?: QueryOptions
) {
return await this.actionMenuRepository.findByQuery(agentContext, options, queryOptions)
}

private emitStateChangedEvent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -796,8 +796,12 @@ describe('V1CredentialProtocol', () => {
const expected = [mockCredentialRecord(), mockCredentialRecord()]

mockFunction(credentialRepository.findByQuery).mockReturnValue(Promise.resolve(expected))
const result = await credentialProtocol.findAllByQuery(agentContext, { state: CredentialState.OfferSent })
expect(credentialRepository.findByQuery).toHaveBeenCalledWith(agentContext, { state: CredentialState.OfferSent })
const result = await credentialProtocol.findAllByQuery(agentContext, { state: CredentialState.OfferSent }, {})
expect(credentialRepository.findByQuery).toHaveBeenCalledWith(
agentContext,
{ state: CredentialState.OfferSent },
{}
)

expect(result).toEqual(expect.arrayContaining(expected))
})
Expand Down
14 changes: 12 additions & 2 deletions packages/askar/src/storage/AskarStorageService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import type { BaseRecordConstructor, AgentContext, BaseRecord, Query, StorageService } from '@credo-ts/core'
import type {
BaseRecordConstructor,
AgentContext,
BaseRecord,
Query,
QueryOptions,
StorageService,
} from '@credo-ts/core'

import { RecordDuplicateError, WalletError, RecordNotFoundError, injectable, JsonTransformer } from '@credo-ts/core'
import { Scan } from '@hyperledger/aries-askar-shared'
Expand Down Expand Up @@ -132,7 +139,8 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
public async findByQuery(
agentContext: AgentContext,
recordClass: BaseRecordConstructor<T>,
query: Query<T>
query: Query<T>,
queryOptions?: QueryOptions
): Promise<T[]> {
const wallet = agentContext.wallet
assertAskarWallet(wallet)
Expand All @@ -144,6 +152,8 @@ export class AskarStorageService<T extends BaseRecord> implements StorageService
store: wallet.store,
tagFilter: askarQuery,
profile: wallet.profile,
offset: queryOptions?.offset,
limit: queryOptions?.limit,
})

const instances = []
Expand Down
30 changes: 30 additions & 0 deletions packages/askar/src/storage/__tests__/AskarStorageService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,35 @@ describe('AskarStorageService', () => {
})
).toEqual(expectedQuery)
})

it('should retrieve correct paginated records', async () => {
await insertRecord({ tags: { myTag: 'notfoobar' } })
await insertRecord({ tags: { myTag: 'foobar' } })
await insertRecord({ tags: { myTag: 'foobar' } })
await insertRecord({ tags: { myTag: 'notfoobar' } })

const records = await storageService.findByQuery(agentContext, TestRecord, {}, { offset: 3, limit: 2 })

expect(records.length).toBe(1)
})

it('should retrieve correct paginated records that match the query', async () => {
await insertRecord({ tags: { myTag: 'notfoobar' } })
const expectedRecord1 = await insertRecord({ tags: { myTag: 'foobar' } })
const expectedRecord2 = await insertRecord({ tags: { myTag: 'foobar' } })
await insertRecord({ tags: { myTag: 'notfoobar' } })

const records = await storageService.findByQuery(
agentContext,
TestRecord,
{
myTag: 'foobar',
},
{ offset: 0, limit: 2 }
)

expect(records.length).toBe(2)
expect(records).toEqual(expect.arrayContaining([expectedRecord1, expectedRecord2]))
})
})
})
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export * from './storage/BaseRecord'
export { DidCommMessageRecord, DidCommMessageRole, DidCommMessageRepository } from './storage/didcomm'
export { Repository } from './storage/Repository'
export * from './storage/RepositoryEvents'
export { StorageService, Query, SimpleQuery, BaseRecordConstructor } from './storage/StorageService'
export { StorageService, Query, QueryOptions, SimpleQuery, BaseRecordConstructor } from './storage/StorageService'
export * from './storage/migration'
export { getDirFromFilePath, joinUriParts } from './utils/path'
export { InjectionSymbols } from './constants'
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/modules/basic-messages/BasicMessagesApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BasicMessageRecord } from './repository/BasicMessageRecord'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'

import { AgentContext } from '../../agent'
import { MessageHandlerRegistry } from '../../agent/MessageHandlerRegistry'
Expand Down Expand Up @@ -64,10 +64,11 @@ export class BasicMessagesApi {
* Retrieve all basic messages matching a given query
*
* @param query The query
* @param queryOptions The query options
* @returns array containing all matching records
*/
public async findAllByQuery(query: Query<BasicMessageRecord>) {
return this.basicMessageService.findAllByQuery(this.agentContext, query)
public async findAllByQuery(query: Query<BasicMessageRecord>, queryOptions?: QueryOptions) {
return this.basicMessageService.findAllByQuery(this.agentContext, query, queryOptions)
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AgentContext } from '../../../agent'
import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext'
import type { Query } from '../../../storage/StorageService'
import type { Query, QueryOptions } from '../../../storage/StorageService'
import type { ConnectionRecord } from '../../connections/repository/ConnectionRecord'
import type { BasicMessageStateChangedEvent } from '../BasicMessageEvents'

Expand Down Expand Up @@ -77,8 +77,12 @@ export class BasicMessageService {
})
}

public async findAllByQuery(agentContext: AgentContext, query: Query<BasicMessageRecord>) {
return this.basicMessageRepository.findByQuery(agentContext, query)
public async findAllByQuery(
agentContext: AgentContext,
query: Query<BasicMessageRecord>,
queryOptions?: QueryOptions
) {
return this.basicMessageRepository.findByQuery(agentContext, query, queryOptions)
}

public async getById(agentContext: AgentContext, basicMessageRecordId: string) {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/modules/connections/ConnectionsApi.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ConnectionType } from './models'
import type { ConnectionRecord } from './repository/ConnectionRecord'
import type { Routing } from './services'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'
import type { OutOfBandRecord } from '../oob/repository'

import { AgentContext } from '../../agent'
Expand Down Expand Up @@ -395,8 +395,8 @@ export class ConnectionsApi {
*
* @returns List containing all connection records matching specified query paramaters
*/
public findAllByQuery(query: Query<ConnectionRecord>) {
return this.connectionService.findAllByQuery(this.agentContext, query)
public findAllByQuery(query: Query<ConnectionRecord>, queryOptions?: QueryOptions) {
return this.connectionService.findAllByQuery(this.agentContext, query, queryOptions)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1012,12 +1012,20 @@ describe('ConnectionService', () => {
const expected = [getMockConnection(), getMockConnection()]

mockFunction(connectionRepository.findByQuery).mockReturnValue(Promise.resolve(expected))
const result = await connectionService.findAllByQuery(agentContext, {
state: DidExchangeState.InvitationReceived,
})
expect(connectionRepository.findByQuery).toBeCalledWith(agentContext, {
state: DidExchangeState.InvitationReceived,
})
const result = await connectionService.findAllByQuery(
agentContext,
{
state: DidExchangeState.InvitationReceived,
},
undefined
)
expect(connectionRepository.findByQuery).toBeCalledWith(
agentContext,
{
state: DidExchangeState.InvitationReceived,
},
undefined
)

expect(result).toEqual(expect.arrayContaining(expected))
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AgentContext } from '../../../agent'
import type { AgentMessage } from '../../../agent/AgentMessage'
import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext'
import type { Query } from '../../../storage/StorageService'
import type { Query, QueryOptions } from '../../../storage/StorageService'
import type { AckMessage } from '../../common'
import type { OutOfBandDidCommService } from '../../oob/domain/OutOfBandDidCommService'
import type { OutOfBandRecord } from '../../oob/repository'
Expand Down Expand Up @@ -770,8 +770,12 @@ export class ConnectionService {
return null
}

public async findAllByQuery(agentContext: AgentContext, query: Query<ConnectionRecord>): Promise<ConnectionRecord[]> {
return this.connectionRepository.findByQuery(agentContext, query)
public async findAllByQuery(
agentContext: AgentContext,
query: Query<ConnectionRecord>,
queryOptions?: QueryOptions
): Promise<ConnectionRecord[]> {
return this.connectionRepository.findByQuery(agentContext, query, queryOptions)
}

public async createConnection(agentContext: AgentContext, options: ConnectionRecordProps): Promise<ConnectionRecord> {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/modules/credentials/CredentialsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { CredentialProtocol } from './protocol/CredentialProtocol'
import type { CredentialFormatsFromProtocols } from './protocol/CredentialProtocolOptions'
import type { CredentialExchangeRecord } from './repository/CredentialExchangeRecord'
import type { AgentMessage } from '../../agent/AgentMessage'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'

import { AgentContext } from '../../agent'
import { MessageSender } from '../../agent/MessageSender'
Expand Down Expand Up @@ -75,7 +75,10 @@ export interface CredentialsApi<CPs extends CredentialProtocol[]> {

// Record Methods
getAll(): Promise<CredentialExchangeRecord[]>
findAllByQuery(query: Query<CredentialExchangeRecord>): Promise<CredentialExchangeRecord[]>
findAllByQuery(
query: Query<CredentialExchangeRecord>,
queryOptions?: QueryOptions
): Promise<CredentialExchangeRecord[]>
getById(credentialRecordId: string): Promise<CredentialExchangeRecord>
findById(credentialRecordId: string): Promise<CredentialExchangeRecord | null>
deleteById(credentialRecordId: string, options?: DeleteCredentialOptions): Promise<void>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { AgentMessage } from '../../../agent/AgentMessage'
import type { FeatureRegistry } from '../../../agent/FeatureRegistry'
import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext'
import type { DependencyManager } from '../../../plugins'
import type { Query } from '../../../storage/StorageService'
import type { Query, QueryOptions } from '../../../storage/StorageService'
import type { ProblemReportMessage } from '../../problem-reports'
import type { CredentialStateChangedEvent } from '../CredentialEvents'
import type { CredentialFormatService, ExtractCredentialFormats } from '../formats'
Expand Down Expand Up @@ -236,11 +236,12 @@ export abstract class BaseCredentialProtocol<CFs extends CredentialFormatService

public async findAllByQuery(
agentContext: AgentContext,
query: Query<CredentialExchangeRecord>
query: Query<CredentialExchangeRecord>,
queryOptions?: QueryOptions
): Promise<CredentialExchangeRecord[]> {
const credentialRepository = agentContext.dependencyManager.resolve(CredentialRepository)

return credentialRepository.findByQuery(agentContext, query)
return credentialRepository.findByQuery(agentContext, query, queryOptions)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type { AgentMessage } from '../../../agent/AgentMessage'
import type { FeatureRegistry } from '../../../agent/FeatureRegistry'
import type { InboundMessageContext } from '../../../agent/models/InboundMessageContext'
import type { DependencyManager } from '../../../plugins'
import type { Query } from '../../../storage/StorageService'
import type { Query, QueryOptions } from '../../../storage/StorageService'
import type { ProblemReportMessage } from '../../problem-reports'
import type { CredentialFormatService, ExtractCredentialFormats } from '../formats'
import type { CredentialRole } from '../models'
Expand Down Expand Up @@ -105,7 +105,8 @@ export interface CredentialProtocol<CFs extends CredentialFormatService[] = Cred
getAll(agentContext: AgentContext): Promise<CredentialExchangeRecord[]>
findAllByQuery(
agentContext: AgentContext,
query: Query<CredentialExchangeRecord>
query: Query<CredentialExchangeRecord>,
queryOptions?: QueryOptions
): Promise<CredentialExchangeRecord[]>
findById(agentContext: AgentContext, credentialExchangeId: string): Promise<CredentialExchangeRecord | null>
delete(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,12 @@ describe('credentialProtocol', () => {
const expected = [mockCredentialRecord(), mockCredentialRecord()]

mockFunction(credentialRepository.findByQuery).mockReturnValue(Promise.resolve(expected))
const result = await credentialProtocol.findAllByQuery(agentContext, { state: CredentialState.OfferSent })
expect(credentialRepository.findByQuery).toHaveBeenCalledWith(agentContext, { state: CredentialState.OfferSent })
const result = await credentialProtocol.findAllByQuery(agentContext, { state: CredentialState.OfferSent }, {})
expect(credentialRepository.findByQuery).toHaveBeenCalledWith(
agentContext,
{ state: CredentialState.OfferSent },
{}
)

expect(result).toEqual(expect.arrayContaining(expected))
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { GenericRecord, SaveGenericRecordOption } from './repository/GenericRecord'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'

import { AgentContext } from '../../agent'
import { InjectionSymbols } from '../../constants'
Expand Down Expand Up @@ -80,8 +80,8 @@ export class GenericRecordsApi {
return this.genericRecordsService.findById(this.agentContext, id)
}

public async findAllByQuery(query: Query<GenericRecord>): Promise<GenericRecord[]> {
return this.genericRecordsService.findAllByQuery(this.agentContext, query)
public async findAllByQuery(query: Query<GenericRecord>, queryOptions?: QueryOptions): Promise<GenericRecord[]> {
return this.genericRecordsService.findAllByQuery(this.agentContext, query, queryOptions)
}

public async getAll(): Promise<GenericRecord[]> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgentContext } from '../../../agent'
import type { Query } from '../../../storage/StorageService'
import type { Query, QueryOptions } from '../../../storage/StorageService'
import type { SaveGenericRecordOption } from '../repository/GenericRecord'

import { CredoError } from '../../../error'
Expand Down Expand Up @@ -50,8 +50,8 @@ export class GenericRecordService {
}
}

public async findAllByQuery(agentContext: AgentContext, query: Query<GenericRecord>) {
return this.genericRecordsRepository.findByQuery(agentContext, query)
public async findAllByQuery(agentContext: AgentContext, query: Query<GenericRecord>, queryOptions?: QueryOptions) {
return this.genericRecordsRepository.findByQuery(agentContext, query, queryOptions)
}

public async findById(agentContext: AgentContext, id: string): Promise<GenericRecord | null> {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/modules/oob/OutOfBandApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HandshakeReusedEvent } from './domain/OutOfBandEvents'
import type { AgentMessage } from '../../agent/AgentMessage'
import type { AgentMessageReceivedEvent } from '../../agent/Events'
import type { Attachment } from '../../decorators/attachment/Attachment'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'
import type { PlaintextMessage } from '../../types'
import type { ConnectionInvitationMessage, ConnectionRecord, Routing } from '../connections'

Expand Down Expand Up @@ -650,8 +650,8 @@ export class OutOfBandApi {
*
* @returns List containing all out of band records matching specified query params
*/
public findAllByQuery(query: Query<OutOfBandRecord>) {
return this.outOfBandService.findAllByQuery(this.agentContext, query)
public findAllByQuery(query: Query<OutOfBandRecord>, queryOptions?: QueryOptions) {
return this.outOfBandService.findAllByQuery(this.agentContext, query, queryOptions)
}

/**
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/modules/oob/OutOfBandService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { HandshakeReusedEvent, OutOfBandStateChangedEvent } from './domain/
import type { AgentContext } from '../../agent'
import type { InboundMessageContext } from '../../agent/models/InboundMessageContext'
import type { Key } from '../../crypto'
import type { Query } from '../../storage/StorageService'
import type { Query, QueryOptions } from '../../storage/StorageService'
import type { ConnectionRecord } from '../connections'
import type { HandshakeProtocol } from '../connections/models'

Expand Down Expand Up @@ -250,8 +250,8 @@ export class OutOfBandService {
return this.outOfBandRepository.getAll(agentContext)
}

public async findAllByQuery(agentContext: AgentContext, query: Query<OutOfBandRecord>) {
return this.outOfBandRepository.findByQuery(agentContext, query)
public async findAllByQuery(agentContext: AgentContext, query: Query<OutOfBandRecord>, queryOptions?: QueryOptions) {
return this.outOfBandRepository.findByQuery(agentContext, query, queryOptions)
}

public async deleteById(agentContext: AgentContext, outOfBandId: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,8 @@ describe('OutOfBandService', () => {
const expected = [getMockOutOfBand(), getMockOutOfBand()]

mockFunction(outOfBandRepository.findByQuery).mockReturnValue(Promise.resolve(expected))
const result = await outOfBandService.findAllByQuery(agentContext, { state: OutOfBandState.Initial })
expect(outOfBandRepository.findByQuery).toBeCalledWith(agentContext, { state: OutOfBandState.Initial })
const result = await outOfBandService.findAllByQuery(agentContext, { state: OutOfBandState.Initial }, {})
expect(outOfBandRepository.findByQuery).toBeCalledWith(agentContext, { state: OutOfBandState.Initial }, {})

expect(result).toEqual(expect.arrayContaining(expected))
})
Expand Down
Loading

0 comments on commit f8198b6

Please sign in to comment.