-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.js
132 lines (120 loc) · 3.73 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const { not, equals, pick, isEmpty } = require('ramda')
async function createTable({
dynamodb,
name,
attributeDefinitions,
keySchema,
globalSecondaryIndexes,
localSecondaryIndexes
}) {
const res = await dynamodb
.createTable({
TableName: name,
AttributeDefinitions: attributeDefinitions,
KeySchema: keySchema,
GlobalSecondaryIndexes: globalSecondaryIndexes.length ? globalSecondaryIndexes : undefined,
LocalSecondaryIndexes: localSecondaryIndexes,
BillingMode: 'PAY_PER_REQUEST'
})
.promise()
return res.TableDescription.TableArn
}
async function describeTable({ dynamodb, name }) {
let res
try {
const data = await dynamodb.describeTable({ TableName: name }).promise()
res = {
arn: data.Table.TableArn,
name: data.Table.TableName,
attributeDefinitions: data.Table.AttributeDefinitions,
keySchema: data.Table.KeySchema,
globalSecondaryIndexes: data.Table.GlobalSecondaryIndexes
}
} catch (error) {
if (error.code === 'ResourceNotFoundException') {
res = null
}
} finally {
return res
}
}
async function updateTable({
dynamodb,
prevGlobalSecondaryIndexes,
globalSecondaryIndexes,
name,
attributeDefinitions
}) {
// find a globalSecondaryIndex that is not in any previous globalSecondaryIndex
const toCreate = globalSecondaryIndexes.filter(
(globalSecondardyIndex) =>
prevGlobalSecondaryIndexes.findIndex(
(element) => element.IndexName === globalSecondardyIndex.IndexName
) === -1
)
// If previous globalSecondaryIndex has an item that is not now present, then delete
const toDelete = prevGlobalSecondaryIndexes
.filter(
(prevGlobalSecondaryIndex) =>
globalSecondaryIndexes.findIndex(
(element) => element.IndexName === prevGlobalSecondaryIndex.IndexName
) === -1
)
.map(({ IndexName }) => ({ IndexName }))
// Only take the first item since only one delete and create can be done at a time
const indexUpdates = {}
if (toCreate.length) {
indexUpdates.Create = toCreate[0]
if (toCreate.length > 1) {
this.context.debug(
`Only ${toCreate[0].IndexName} will be created since a limitation of Dynamodb is that only one Gloabl secondary index can be created during an upate.
Run this operation after the index has been created on AWS to create the additional indexes`
)
}
}
if (toDelete.length) {
indexUpdates.Delete = toDelete[0]
if (toDelete.length > 1) {
this.context.debug(
`Only ${toDelete[0].IndexName} will be deleted since a limitation of Dynamodb is that only one Gloabl secondary index can be deleted during an upate.
Run this operation after the index has been deleted on AWS to delete the additional indexes`
)
}
}
const res = await dynamodb
.updateTable({
TableName: name,
AttributeDefinitions: attributeDefinitions,
BillingMode: 'PAY_PER_REQUEST',
GlobalSecondaryIndexUpdates: !isEmpty(indexUpdates) ? [indexUpdates] : undefined
})
.promise()
return res.TableDescription.TableArn
}
async function deleteTable({ dynamodb, name }) {
let res = false
try {
res = await dynamodb
.deleteTable({
TableName: name
})
.promise()
} catch (error) {
if (error.code !== 'ResourceNotFoundException') {
throw error
}
}
return !!res
}
function configChanged(prevTable, table) {
const prevInputs = pick(['name', 'attributeDefinitions', 'globalSecondaryIndexes'], prevTable)
const inputs = pick(['name', 'attributeDefinitions', 'globalSecondaryIndexes'], table)
return not(equals(inputs, prevInputs))
}
module.exports = {
createTable,
describeTable,
updateTable,
deleteTable,
configChanged
}