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 605
Expand file tree
/
Copy pathsubcollection.coffee
More file actions
executable file
·122 lines (114 loc) · 3.71 KB
/
Copy pathsubcollection.coffee
File metadata and controls
executable file
·122 lines (114 loc) · 3.71 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
###
Bongo.js
Unfancy models for MongoDB
(c) 2011 Koding, Inc.
@class: Subcollection
@author: Christopher Thorn
###
Base = require './base'
module.exports = class Subcollection
__proto__: do ->
###
Begin clever hack
###
#vm = require 'vm'
#PoachedArray = vm.runInNewContext 'Array', null, 'arrayPoacher.vm'
# safeMethods = 'forEach indexOf join pop reverse shift sort splice unshift'
# .split(' ')
# .reduce (acc, method) ->
# acc[method] = 1
# return acc
# , {}
# Object.keys(PoachedArray.prototype).forEach (method) ->
# delete PoachedArray::[method] unless method of safeMethods
Array.prototype
###
End clever hack
###
###
@vars.
###
{ defineProperty } = Object
###
@snippet.
@description: import the non-buggy methods from the Array
prototype i.e., the destructive ones that modify the
instance itself. Other ones (e.g. slice, concat) will
actually return instances of Array, not "this.constructor",
which would take into account inheritance. I think this is
going to be fixed in Harmony. By not importing them, we
prevent astonishment, and spread awareness of the
shortcomings of some Array prototype methods.
###
# for method in 'forEach, indexOf, join, pop, reverse, shift, sort, splice, unshift'.split ', '
# @::[method] = Array::[method]
###
@constructor.
@signature: new Subcollection(parent, children, annotation)
@param: parent - the containing model
@param: children - an array containing the new members of
this subcollection.
@param: annotation - the constructor/cast of the arrayed instances/primitives.
@description: create a new subcollection, and push all the
items from the supplied array onto it. Subcollections are
psuedo-typed.
###
constructor:(parent, children, annotation) ->
defineProperty this, 'parent_', { value: parent }
# avoid a(n explicit) circular dependency here:
defineProperty this, 'parentConstructor_', { value: parent.constructor }
defineProperty this, 'annotation_', { value: annotation }
@push children...
###
@method.
@signature: Subcollection::findById(id);
@param: id - an id matching the _id property of the sought-
after document.
@description: find a child element by its _id property
###
findById:(id, indexOnly = no) ->
for doc, index in this when doc._id?.equals id
return if indexOnly then index else doc
###
@method.
@signature: Subcollection::get()
###
###
@method.
@signature: Subcollection::push(children...)
@param: children... - rest params containing the objects to push to the end of the array.
@description: override native Array::push to add value casting
###
push:(children...) ->
[].push.apply this,
for child, index in children
annotation = @annotation_?.getExactConstructor?(child) or @annotation_
child =
if annotation
@parentConstructor_.castValue child, annotation
else
child
if child instanceof @parentConstructor_
child.inSubcollection_ = yes
unless child._id?
child._id = new ObjectId
child
###
@method.
@signature: Subcollection::remove(id);
@param: id - an id matching the _id property of the sought-
after document.
@description: remove a child element by its _id property
###
remove:(id) ->
@splice @indexOf @findById(id), 1
###
@method.
@signature: Subcollection::toJSON()
@return: an array slice of the entire subcollection. (This
is ((perhaps a hack)) so we can have array notation in the JSON.
Anyone know of a better trick?)
@todo: reimplement?
###
toJSON: ->
[].slice.call this