UNPKG

4.39 kBtext/coffeescriptView Raw
1typeUtil = require "./typeUtil"
2AWS = require "aws-sdk"
3_ = require "lodash"
4Flat = require "flat"
5flatten = Flat.flatten
6unflatten = Flat.unflatten
7
8class Dynoga
9 constructor: (options) ->
10 @dynamo = new AWS.DynamoDB options
11
12 # Create an item
13 #
14 # @param {String} table
15 # @param {Object} item - New item (with primary keys)
16 # @return {Error}
17 # @return {Object} new item
18 create: (table, item, callback) ->
19 # Generate an id if undefined
20 item.id = do Date.now().toString unless item.id
21
22 # Generate a private attribute for future array order
23 item._createTimeStamp = do Date.now
24
25 dynamoItem = typeUtil.packObjectOrArray item
26
27 @dynamo.putItem
28 TableName: table
29 Item: dynamoItem
30 (err, data) ->
31 delete item._createTimeStamp
32 callback? err, item
33
34 # Read one or many item(s)
35 #
36 # @param {String} table
37 # @param {Object} keys - ex: {key1: "plop", key2: "rafiki"}
38 # @return {Error}
39 # @return {Object|Array} one item or list of items
40 read: (table, keys, callback) ->
41 keysLength = _.toArray(keys).length
42 keyConditions = typeUtil.objectToQuery keys
43
44 @dynamo.query
45 TableName: table
46 KeyConditions: keyConditions
47 (err, data) ->
48 result = typeUtil.unpackObjectOrArray data
49 if result? and keysLength is 2 then result = result[0]
50 callback? err, typeUtil.sortAndClean result
51
52 # Update one item
53 #
54 # @param {String} table
55 # @param {Object} item to update (with primary keys)
56 # @return {Error}
57 # @return {Object} item after udpate
58 update: (table, item, callback) ->
59 # Extract keys from item
60 @_findKeys table, (err, keys) =>
61 if err
62 callback? err
63 return
64
65 objectKey = {}
66 objectKey[keys[0]] = item[keys[0]]
67 objectKey[keys[1]] = item[keys[1]]
68 dynamoKey = typeUtil.packObjectOrArray objectKey
69
70 delete item[keys[0]]
71 delete item[keys[1]]
72 dynamoItem = typeUtil.formatForUpdate item
73
74 @read table, objectKey, (err, data) =>
75
76 # Extract old objects key into database
77 oldKeys = [] # ex: toto.choco
78 for key, value of flatten data
79 if /\./.test key then oldKeys.push key
80
81 # Extract objects to update
82 updatedKeys = [] # ex: toto
83 for key, value of dynamoItem
84 if /\./.test key then updatedKeys.push key.split(".")[0]
85 updatedKeys = _.uniq updatedKeys
86
87 # Prepare with defaults objects to delete
88 updateQuery = {}
89 for i in updatedKeys
90 for j in oldKeys
91 regex = new RegExp "^" + i + "\." # string beginning by `{{key}}.`
92 if regex.test j
93 updateQuery[j] =
94 Action: "DELETE"
95
96 # Prepare final query
97 for key, value of dynamoItem
98 updateQuery[key] = value
99
100 @dynamo.updateItem
101 TableName: table
102 Key: dynamoKey
103 AttributeUpdates: updateQuery
104 ReturnValues: "ALL_NEW"
105 (err, data) =>
106 if err then callback err
107 callback? err, typeUtil.sortAndClean typeUtil.unpackObjectOrArray data
108
109 # Delete one item
110 #
111 # @param {String} table
112 # @param {Object} item or keys
113 # @return {Error}
114 # @return {Object} deleted item
115 delete: (table, item, callback) ->
116 # Extract keys from item
117 @_findKeys table, (err, keys) =>
118 if err
119 callback? err
120 return
121
122 objectKey = {}
123 objectKey[keys[0]] = item[keys[0]]
124 objectKey[keys[1]] = item[keys[1]]
125 dynamoKey = typeUtil.packObjectOrArray objectKey
126
127 # Stock item and delete it
128 @dynamo.deleteItem
129 TableName: table
130 Key: dynamoKey
131 ReturnValues: "ALL_OLD"
132 (err, data) ->
133 callback? err, typeUtil.sortAndClean typeUtil.unpackObjectOrArray data
134
135 # Extract primary keys of a given table
136 #
137 # @param {String} table
138 # @return {Error}
139 # @return {Array} list of primary keys
140 _findKeys: (table, callback) ->
141 @dynamo.describeTable
142 TableName: table
143 (err, data) ->
144 if data?
145 keySchema = data.Table.KeySchema
146 keys = _.map keySchema, (key) ->
147 key.AttributeName
148 callback? err, keys
149
150module.exports = Dynoga