This repository was archived by the owner on Aug 15, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 604
Expand file tree
/
Copy pathmongop.coffee
More file actions
executable file
·100 lines (82 loc) · 2.72 KB
/
mongop.coffee
File metadata and controls
executable file
·100 lines (82 loc) · 2.72 KB
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
class MongoOp
{ setAt, getAt, deleteAt, pushAt, popAt } = require 'jspath'
{ keys } = Object
isEqual = require 'deep-equal'
constructor:(operation) ->
return new MongoOp operation unless this instanceof MongoOp
@operation = operation
applyTo:(target) ->
@result = {}
keys(@operation).forEach (operator) =>
unless 'function' is typeof @[operator]
throw new Error "Unrecognized operator: #{operator}"
else
@[operator] target, @operation[operator]
return this
map: (fn) ->
op = @operation
@operation = {}
keys(op).forEach (operator) =>
@operation[operator] = fn operator, op[operator]
return this
forEachField:(fields, fn) ->
keys(fields).map (path) =>
val = fields[path]
@result[path] = fn path, val
$addToSet:do ->
$addToSet = (collection, val) ->
matchFound = no
for item in collection when isEqual item, val
matchFound = yes
break
collection.push val unless matchFound
(target, fields) ->
@forEachField fields, (path, val) ->
collection = getAt target, path
unless collection?
collection = []
setAt target, path, collection
if val.$each?
$addToSet collection, child for child in val.$each
else
$addToSet collection, val
$push:(target, fields) ->
@forEachField fields, (path, val) -> pushAt target, path, val
$pushAll:(target, fields) ->
@forEachField fields, (path, vals) -> pushAt target, path, vals...
$pull: ->
throw new Error \
'''
This version of MongoOp does not implement $pull...
Look for that in a future version. You can use $pullAll instead.
'''
$pullAll:(target, fields) ->
@forEachField fields, (path, val) ->
collection = getAt target, path
index = 0
while collection and index < collection.length
i = index++
if isEqual collection[i], val
collection.splice i, 1
$pop:(target, fields) ->
@forEachField fields, (path) -> popAt target, path
$set:(target, fields) ->
@forEachField fields, (path, val) ->
setAt target, path, val
val
$unset:(target, fields) ->
@forEachField fields, (path) -> deleteAt target, path
$rename:(target, fields) ->
@forEachField fields, (oldPath, newPath) ->
val = getAt target, oldPath
deleteAt target, oldPath
setAt target, newPath, val
$inc:do ->
$inc = (val, amt) -> val += amt
(target, fields) ->
@forEachField fields, (path, val) ->
setAt target, path, $inc getAt(target, path), val
if module?.exports?
module.exports = MongoOp
else if window?
window['MongoOp'] = MongoOp # for google closure compiler, use a string here.