-
Notifications
You must be signed in to change notification settings - Fork 137
/
PropertyContainer._coffee
145 lines (123 loc) · 3.76 KB
/
PropertyContainer._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
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
133
134
135
136
137
138
139
140
141
142
143
144
145
status = require 'http-status'
util = require './util'
adjustError = util.adjustError
#
# The abstract class corresponding to a Neo4j property container.
#
# @abstract
#
module.exports = class PropertyContainer
#
# Construct a new wrapper around a Neo4j property container with the given
# data directly from the server at the given Neo4j {GraphDatabase}.
#
# @private
# @param db {GraphDatbase}
# @param data {Object}
#
constructor: (db, data) ->
@db = db
@_request = db._request # convenience alias
@_data = data or {}
@_data.self = data?.self or null
### Language helpers: ###
get = (props) =>
@::__defineGetter__ name, getter for name, getter of props
set = (props) =>
@::__defineSetter__ name, setter for name, setter of props
### Properties: ###
#
# @property {String} The URL of this property container.
#
# @todo This might be an implementation detail; should we remove it?
# If not, should it at least be renamed to just URL?
#
get self: -> @_data.self or null
#
# @property {Boolean} Whether this property container exists in
# (has been persisted to) the Neo4j database.
#
get exists: -> @self?
#
# @property {Number} If this property container exists, its Neo4j
# integer ID.
#
get id: ->
if not @exists
null
else
match = /(?:node|relationship)\/(\d+)$/.exec @self
parseInt match[1]
#
# @property {Object} This property container's properties. This is a map
# of key-value pairs.
#
get data: -> @_data.data or null
set data: (value) -> @_data.data = value
### Methods: ###
#
# Test whether the given object represents the same property container as
# this one. They can be separate instances with separate data.
#
# @param other {Object}
# @return {Boolean}
#
equals: (other) ->
@self is other?.self
#
# Delete this property container from the database.
#
# @param callback {Function}
#
delete: (_) ->
if not @exists
return
try
response = @_request.del @self, _
if response.statusCode isnt status.NO_CONTENT
switch response.statusCode
when status.NOT_FOUND
throw new Error 'PropertyContainer not found'
when status.CONFLICT
throw new Error 'Node could not be deleted (still has relationships?)'
else
throw response
# success
@_data.self = null
return
catch error
throw adjustError error
#
# A convenience alias for {#delete} since `delete` is a reserved keyword
# in JavaScript.
#
# @see #delete
#
del: ->
@delete.apply @, arguments
#
# Return a JSON representation of this property container, suitable for
# serialization (e.g. caching).
#
# @return {Object}
#
toJSON: ->
# take the basic info for this db, then just add the data object
# directly since we need that for deserialization/construction.
# TODO it'd be great if we could store a trimmed down version of
# the data object instead of e.g. all the hypermedia URLs...
# but we need those hypermedia URLs for making requests for now.
json = @db._toJSON @
json._data = @_data
json
#
# Returns an instance of this property container for the given object,
# parsed from JSON.
#
# @private
# @param db {GraphDatabase}
# @param obj {Object}
#
@_fromJSON: (db, obj) ->
{_data} = obj
new @ db, _data