Skip to content

Commit 5c25d39

Browse files
Merge pull request #218 from shiftcode/#216-condition-builder
fix(merge-conditions): no redundant parentheses
2 parents 7a36394 + 75f712b commit 5c25d39

10 files changed

+47
-16
lines changed

src/dynamo/expression/create-if-not-exists-condition.function.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('create ifNotExistsCondition', () => {
3535
const condition = and(...res)(undefined, metaSimple)
3636
addExpression('ConditionExpression', condition, paramsSimple)
3737

38-
expect(paramsSimple.ConditionExpression).toBe('(attribute_not_exists (#id))')
38+
expect(paramsSimple.ConditionExpression).toBe('attribute_not_exists (#id)')
3939
expect(paramsSimple.ExpressionAttributeNames).toEqual({ '#id': 'id' })
4040
expect(paramsSimple.ExpressionAttributeValues).toBeUndefined()
4141
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { attribute } from './attribute.function'
2+
import { mergeConditions } from './merge-conditions.function'
3+
4+
describe('mergeCondition statements', () => {
5+
test('no redundant parentheses for single condition', () => {
6+
const conditionDefinitionFns = [attribute('name').beginsWith('sample')]
7+
8+
const conditions = mergeConditions('OR', conditionDefinitionFns)
9+
const expression = conditions(undefined, undefined)
10+
expect(expression.statement).toEqual('begins_with (#name, :name)')
11+
})
12+
13+
test('no redundant parentheses for multiple condition', () => {
14+
const conditionDefinitionFns = [attribute('name').beginsWith('sample'), attribute('fullName').beginsWith('sample')]
15+
16+
const conditions = mergeConditions('OR', conditionDefinitionFns)
17+
const expression = conditions(undefined, undefined)
18+
19+
expect(expression.statement).toEqual('(begins_with (#name, :name) OR begins_with (#fullName, :fullName))')
20+
})
21+
22+
test('no redundant parentheses for single condition combined', () => {
23+
const conditionDefinitionFns = [attribute('name').beginsWith('sample'), attribute('fullName').beginsWith('sample')]
24+
25+
const conditions = mergeConditions('OR', conditionDefinitionFns)
26+
const andConditions = mergeConditions('AND', [conditions])
27+
const expression = andConditions(undefined, undefined)
28+
expect(expression.statement).toEqual('(begins_with (#name, :name) OR begins_with (#fullName, :fullName))')
29+
})
30+
})

src/dynamo/expression/logical-operator/merge-conditions.function.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export function mergeConditions(
5757
statements.push(condition.statement)
5858
})
5959

60-
mergedCondition.statement = `(${statements.join(' ' + operator + ' ')})`
60+
61+
mergedCondition.statement = statements.length === 1 ? statements[0] : `(${statements.join(' ' + operator + ' ')})`
6162
return mergedCondition
6263
}
6364
}

src/dynamo/expression/param-util.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ describe('ParamUtils', () => {
3939
':c': { N: '3' },
4040
':c_2': { N: '5' },
4141
})
42-
expect(params.ConditionExpression).toBe('((#a = :a AND (#b = :b OR #c BETWEEN :c AND :c_2)))')
42+
expect(params.ConditionExpression).toBe('(#a = :a AND (#b = :b OR #c BETWEEN :c AND :c_2))')
4343
})
4444

4545
it('should build correct UpdateExpression', () => {

src/dynamo/expression/prepare-and-add-update-expressions.function.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ describe('PrepareExpressions function', () => {
354354
':name': { S: 'newName' },
355355
':topics': { S: 'otherTopic' },
356356
})
357-
expect(params.ConditionExpression).toBe('(NOT contains (#topics, :topics))')
357+
expect(params.ConditionExpression).toBe('NOT contains (#topics, :topics)')
358358
})
359359

360360
it('with name conflicting where clause', () => {
@@ -378,7 +378,7 @@ describe('PrepareExpressions function', () => {
378378
':topics': { SS: ['myTopic'] },
379379
':topics_2': { S: 'otherTopic' },
380380
})
381-
expect(params.ConditionExpression).toBe('(NOT contains (#topics, :topics_2))')
381+
expect(params.ConditionExpression).toBe('NOT contains (#topics, :topics_2)')
382382
})
383383
})
384384

src/dynamo/request/put/put.request.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('put request', () => {
2323
request.ifNotExists()
2424

2525
const params: DynamoDB.PutItemInput = request.params
26-
expect(params.ConditionExpression).toBe('(attribute_not_exists (#id))')
26+
expect(params.ConditionExpression).toBe('attribute_not_exists (#id)')
2727
expect(params.ExpressionAttributeNames).toEqual({ '#id': 'id' })
2828
expect(params.ExpressionAttributeValues).toBeUndefined()
2929
})

src/dynamo/request/read-many.request.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,14 @@ describe('ReadManyRequest', () => {
119119
expect(request.params.ExpressionAttributeNames).toEqual({ '#age': 'age' })
120120
expect(request.params.ExpressionAttributeValues).toEqual({ ':age': { N: '20' } })
121121
})
122+
122123
it('where', () => {
123-
request.where(or(attribute('age').lt(10), attribute('age').gt(20)))
124-
expect(request.params.FilterExpression).toEqual('((#age < :age OR #age > :age_2))')
125-
expect(request.params.ExpressionAttributeNames).toEqual({ '#age': 'age' })
126-
expect(request.params.ExpressionAttributeValues).toEqual({
127-
':age': { N: '10' },
128-
':age_2': { N: '20' },
129-
})
124+
const conditions = or(attribute('age').lt(10), attribute('age').gt(20))
125+
const expression = conditions(undefined, undefined)
126+
request.where(conditions)
127+
expect(request.params.FilterExpression).toEqual(expression.statement)
128+
expect(request.params.ExpressionAttributeNames).toEqual(expression.attributeNames)
129+
expect(request.params.ExpressionAttributeValues).toEqual(expression.attributeValues)
130130
})
131131
})
132132

src/dynamo/request/write.request.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('write request', () => {
8181

8282
it('[onlyIf] should set condition', () => {
8383
req.onlyIf(or(attribute('age').lt(10), attribute('age').gt(20)))
84-
expect(req.params.ConditionExpression).toEqual('((#age < :age OR #age > :age_2))')
84+
expect(req.params.ConditionExpression).toEqual('(#age < :age OR #age > :age_2)')
8585
expect(req.params.ExpressionAttributeNames).toEqual({ '#age': 'age' })
8686
expect(req.params.ExpressionAttributeValues).toEqual({
8787
':age': { N: '10' },

src/dynamo/transactwrite/transact-base-operation.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('TransactBaseOperation', () => {
4343
op.onlyIf(attribute('age').gt(20))
4444
expect(op.params).toEqual({
4545
TableName: 'simple-with-partition-key-models',
46-
ConditionExpression: '(#age > :age)',
46+
ConditionExpression: '#age > :age',
4747
ExpressionAttributeNames: { '#age': 'age' },
4848
ExpressionAttributeValues: { ':age': { N: '20' } },
4949
})

src/dynamo/transactwrite/transact-put.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('TransactPut', () => {
4646
expect(op.params).toEqual({
4747
TableName: getTableName(UpdateModel),
4848
Item: toDb(item, UpdateModel),
49-
ConditionExpression: '(attribute_not_exists (#id))',
49+
ConditionExpression: 'attribute_not_exists (#id)',
5050
ExpressionAttributeNames: { '#id': 'id' },
5151
})
5252
})

0 commit comments

Comments
 (0)