-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodel.coffee
83 lines (66 loc) · 2.29 KB
/
model.coffee
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
uuid = require 'node-uuid'
class SynthModel extends (require './object')
@set synth: 'model', name: undefined, records: undefined
@instanceof = (x) ->
return false unless x?
x instanceof this or x instanceof this.__super__?.constructor
@modelof = (x) ->
return false unless x instanceof Object
for k of x
return false unless (@get "bindings.#{k}")?
return true
@mixin (require 'events').EventEmitter
@belongsTo = (model, opts) ->
class extends (require './property/belongsTo')
@set model: model
@merge opts
@hasMany = (model, opts) ->
class extends (require './property/hasMany')
@set model: model
@merge opts
constructor: ->
# register a default 'save' and 'destroy' handler event (can be overridden)
@attach 'save', (resolve, reject) -> return resolve this
@attach 'destroy', (resolve, reject) -> return resolve this
super
@name = @meta 'name'
unless @name?
throw new Error "Model must have a 'name' metadata specified for construction"
@store = @parent # every model should have a parent that is it's datastore
@id = (@get 'id') ? @uuid() # every model instance has a unique ID
uuid: -> uuid.v4()
fetch: (key) -> @meta "records.#{key}"
find: (query) -> (v for k, v of (@meta 'records')).where query
match: (query) ->
for k, v of query
x = (@access k)?.normalize (@get k)
x = "#{x}" if typeof x is 'boolean' and typeof v is 'string'
return false unless x is v
return true
toString: -> "#{@meta 'name'}:#{@id}"
save: ->
@emit 'saving'
@invoke 'save', arguments...
.then (res) =>
@id = (@get 'id') ? @id
@set 'id', @id
super
@constructor.set "records.#{@id}", this
@emit 'saved'
return res
rollback: ->
# TBD
super
destroy: ->
@emit 'destroying'
@invoke 'destroy', arguments...
.then (res) =>
#record.destroy() for record in @get '_bindings'
@constructor.delete "records.#{@id}"
@emit 'destroyed'
return res
RelationshipProperty = (require './property/relationship')
getRelationships: (kind) ->
@everyProperty (key) -> this if this instanceof RelationshipProperty
.filter (x) -> x? and (not kind? or kind is (x.constructor.get 'kind'))
module.exports = SynthModel