Skip to content

Commit a539c78

Browse files
Merge pull request #57 from shiftcode/query-request-fix-for-custom-mapper
Query request fix for custom mapper
2 parents 5015542 + 253db3e commit a539c78

File tree

3 files changed

+81
-3
lines changed

3 files changed

+81
-3
lines changed

src/dynamo/request/query/query.request.spec.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import { QueryInput, QueryOutput } from 'aws-sdk/clients/dynamodb'
22
import * as moment from 'moment'
3-
import { Observable } from 'rxjs'
3+
import { Observable, of } from 'rxjs'
44
import { getTableName } from '../../../../test/helper/get-table-name.function'
55
import { ComplexModel } from '../../../../test/models/complex.model'
6+
import {
7+
CustomId,
8+
ModelWithCustomMapperForSortKeyModel,
9+
} from '../../../../test/models/model-with-custom-mapper-for-sort-key.model'
610
import { INDEX_ACTIVE_CREATED_AT, ModelWithABunchOfIndexes } from '../../../../test/models/model-with-indexes.model'
711
import { DynamoRx } from '../../dynamo-rx'
812
import { attribute } from '../../expression/logical-operator/attribute.function'
913
import { QueryRequest } from './query.request'
1014

1115
export const DYNAMO_RX_MOCK: DynamoRx = <DynamoRx>{
1216
query(params: QueryInput): Observable<QueryOutput> {
13-
return Observable.of({})
17+
return of({})
1418
},
1519
}
1620

@@ -88,6 +92,24 @@ describe('query request', () => {
8892
})
8993
})
9094

95+
describe('uses custom mapper for sortKey', () => {
96+
const request = new QueryRequest(
97+
<any>null,
98+
ModelWithCustomMapperForSortKeyModel,
99+
getTableName(ModelWithCustomMapperForSortKeyModel)
100+
)
101+
102+
request.whereSortKey().between(new CustomId(moment('2018-01-01'), 0), new CustomId(moment('2018-12-31'), 99999))
103+
104+
it('correct mapping', () => {
105+
expect(request.params.ExpressionAttributeValues).toBeDefined()
106+
expect(request.params.ExpressionAttributeValues).toEqual({
107+
':customId': { N: '2018010100000' },
108+
':customId_2': { N: '2018123199999' },
109+
})
110+
})
111+
})
112+
91113
describe('calls endpoint with correct params', () => {
92114
const dynamoRx: DynamoRx = DYNAMO_RX_MOCK as DynamoRx
93115
let querySpy

src/dynamo/request/query/query.request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class QueryRequest<T> extends Request<T, QueryRequest<T>, QueryInput, Que
6767
throw new Error('There was no sort key defined for current schema')
6868
}
6969

70-
return RequestExpressionBuilder.addSortKeyCondition(sortKey, this)
70+
return RequestExpressionBuilder.addSortKeyCondition(sortKey, this, this.metaData)
7171
}
7272

7373
// TODO TYPING how can we improve the typing to define the accepted value for condition function (see
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// tslint:disable:max-classes-per-file
2+
3+
import { DynamoDB } from 'aws-sdk'
4+
import * as moment from 'moment'
5+
import { PropertyMetadata, SortKey } from '../../src/decorator'
6+
import { PartitionKey } from '../../src/decorator/impl/key/partition-key.decorator'
7+
import { CustomMapper } from '../../src/decorator/impl/mapper/custom-mapper.decorator'
8+
import { Model } from '../../src/decorator/impl/model/model.decorator'
9+
import { MapperForType } from '../../src/mapper/for-type/base.mapper'
10+
11+
export class CustomId {
12+
private static MULTIPLIER = Math.pow(10, 5)
13+
private static FMT_DATE_NUM = 'YYYYMMDD'
14+
date: moment.Moment
15+
id: number
16+
17+
static parse(value: number): CustomId {
18+
const date = Math.floor(value / CustomId.MULTIPLIER)
19+
const id = value - date * CustomId.MULTIPLIER
20+
return new CustomId(moment(date, CustomId.FMT_DATE_NUM), id)
21+
}
22+
23+
static unparse(customId: CustomId): number {
24+
return parseInt(customId.date.format(CustomId.FMT_DATE_NUM), 10) * CustomId.MULTIPLIER + customId.id
25+
}
26+
27+
constructor(date: moment.Moment, id: number) {
28+
this.date = date
29+
this.id = id
30+
}
31+
}
32+
33+
export class CustomIdMapper implements MapperForType<CustomId> {
34+
fromDb(attributeValue: DynamoDB.AttributeValue, propertyMetadata?: PropertyMetadata<CustomId>): CustomId {
35+
return CustomId.parse(parseInt(attributeValue.N!, 10))
36+
}
37+
38+
toDb(propertyValue: CustomId, propertyMetadata?: PropertyMetadata<CustomId>): DynamoDB.AttributeValue {
39+
return { N: `${CustomId.unparse(propertyValue)}` }
40+
}
41+
}
42+
43+
@Model()
44+
export class ModelWithCustomMapperForSortKeyModel {
45+
@PartitionKey()
46+
name: string
47+
48+
@CustomMapper(CustomIdMapper)
49+
@SortKey()
50+
customId: CustomId
51+
52+
constructor(name: string, id: CustomId) {
53+
this.name = name
54+
this.customId = id
55+
}
56+
}

0 commit comments

Comments
 (0)