architect4r 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +53 -0
  4. data/Guardfile +10 -0
  5. data/License +20 -0
  6. data/README.md +62 -0
  7. data/Rakefile +40 -0
  8. data/ReleaseNotes.md +33 -0
  9. data/Roadmap.md +31 -0
  10. data/Specs.md +21 -0
  11. data/architect4r.gemspec +31 -0
  12. data/lib/architect4r.rb +66 -0
  13. data/lib/architect4r/adapters/carrier_wave.rb +64 -0
  14. data/lib/architect4r/core/configuration.rb +148 -0
  15. data/lib/architect4r/core/cypher_methods.rb +47 -0
  16. data/lib/architect4r/core/management_methods.rb +129 -0
  17. data/lib/architect4r/core/node_methods.rb +73 -0
  18. data/lib/architect4r/core/relationship_methods.rb +82 -0
  19. data/lib/architect4r/generic_node.rb +7 -0
  20. data/lib/architect4r/has_node.rb +80 -0
  21. data/lib/architect4r/instance_manager.rb +47 -0
  22. data/lib/architect4r/model/callbacks.rb +19 -0
  23. data/lib/architect4r/model/connection.rb +29 -0
  24. data/lib/architect4r/model/links_query_interface.rb +23 -0
  25. data/lib/architect4r/model/node.rb +117 -0
  26. data/lib/architect4r/model/persistency.rb +95 -0
  27. data/lib/architect4r/model/properties.rb +166 -0
  28. data/lib/architect4r/model/queries.rb +38 -0
  29. data/lib/architect4r/model/relationship.rb +105 -0
  30. data/lib/architect4r/model/relationships.rb +16 -0
  31. data/lib/architect4r/model/validations.rb +11 -0
  32. data/lib/architect4r/server.rb +96 -0
  33. data/lib/architect4r/version.rb +3 -0
  34. data/spec/architect4r_spec.rb +9 -0
  35. data/spec/core/configuration_spec.rb +54 -0
  36. data/spec/core/cypher_methods_spec.rb +29 -0
  37. data/spec/core/node_methods_spec.rb +47 -0
  38. data/spec/core/relationship_methods_spec.rb +92 -0
  39. data/spec/fixtures/architect4r.yml +21 -0
  40. data/spec/fixtures/graph.db.default/active_tx_log +1 -0
  41. data/spec/fixtures/graph.db.default/index/lucene-store.db +0 -0
  42. data/spec/fixtures/graph.db.default/index/lucene.log.1 +0 -0
  43. data/spec/fixtures/graph.db.default/index/lucene.log.active +0 -0
  44. data/spec/fixtures/graph.db.default/index/lucene.log.v0 +0 -0
  45. data/spec/fixtures/graph.db.default/index/lucene.log.v1 +0 -0
  46. data/spec/fixtures/graph.db.default/index/lucene.log.v2 +0 -0
  47. data/spec/fixtures/graph.db.default/lock +0 -0
  48. data/spec/fixtures/graph.db.default/messages.log +183 -0
  49. data/spec/fixtures/graph.db.default/neostore +0 -0
  50. data/spec/fixtures/graph.db.default/neostore.id +0 -0
  51. data/spec/fixtures/graph.db.default/neostore.nodestore.db +0 -0
  52. data/spec/fixtures/graph.db.default/neostore.nodestore.db.id +0 -0
  53. data/spec/fixtures/graph.db.default/neostore.propertystore.db +0 -0
  54. data/spec/fixtures/graph.db.default/neostore.propertystore.db.arrays +0 -0
  55. data/spec/fixtures/graph.db.default/neostore.propertystore.db.arrays.id +0 -0
  56. data/spec/fixtures/graph.db.default/neostore.propertystore.db.id +0 -0
  57. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index +0 -0
  58. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.id +0 -0
  59. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.keys +0 -0
  60. data/spec/fixtures/graph.db.default/neostore.propertystore.db.index.keys.id +0 -0
  61. data/spec/fixtures/graph.db.default/neostore.propertystore.db.strings +0 -0
  62. data/spec/fixtures/graph.db.default/neostore.propertystore.db.strings.id +0 -0
  63. data/spec/fixtures/graph.db.default/neostore.relationshipstore.db +0 -0
  64. data/spec/fixtures/graph.db.default/neostore.relationshipstore.db.id +0 -0
  65. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db +0 -0
  66. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.id +0 -0
  67. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.names +0 -0
  68. data/spec/fixtures/graph.db.default/neostore.relationshiptypestore.db.names.id +0 -0
  69. data/spec/fixtures/graph.db.default/nioneo_logical.log.1 +0 -0
  70. data/spec/fixtures/graph.db.default/nioneo_logical.log.active +0 -0
  71. data/spec/fixtures/graph.db.default/tm_tx_log.1 +0 -0
  72. data/spec/fixtures/graph.db.default/upgrade_backup/active_tx_log +1 -0
  73. data/spec/fixtures/graph.db.default/upgrade_backup/messages.log +142 -0
  74. data/spec/fixtures/graph.db.default/upgrade_backup/neostore +0 -0
  75. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.id +0 -0
  76. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.nodestore.db +0 -0
  77. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.nodestore.db.id +0 -0
  78. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db +0 -0
  79. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.arrays +0 -0
  80. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.arrays.id +0 -0
  81. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.id +0 -0
  82. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index +0 -0
  83. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.id +0 -0
  84. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.keys +0 -0
  85. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.index.keys.id +0 -0
  86. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.strings +0 -0
  87. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.propertystore.db.strings.id +0 -0
  88. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshipstore.db +0 -0
  89. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshipstore.db.id +0 -0
  90. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db +0 -0
  91. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.id +0 -0
  92. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.names +0 -0
  93. data/spec/fixtures/graph.db.default/upgrade_backup/neostore.relationshiptypestore.db.names.id +0 -0
  94. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.active +0 -0
  95. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v0 +0 -0
  96. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v1 +0 -0
  97. data/spec/fixtures/graph.db.default/upgrade_backup/nioneo_logical.log.v2 +0 -0
  98. data/spec/fixtures/graph.db.default/upgrade_backup/tm_tx_log.1 +0 -0
  99. data/spec/has_node_spec.rb +87 -0
  100. data/spec/model/links_query_interface_spec.rb +22 -0
  101. data/spec/model/links_spec.rb +26 -0
  102. data/spec/model/node_spec.rb +48 -0
  103. data/spec/model/persistency_spec.rb +98 -0
  104. data/spec/model/properties_spec.rb +165 -0
  105. data/spec/model/queries_spec.rb +50 -0
  106. data/spec/model/relationship_spec.rb +63 -0
  107. data/spec/model/validations_spec.rb +31 -0
  108. data/spec/server_spec.rb +33 -0
  109. data/spec/spec_helper.rb +115 -0
  110. metadata +377 -0
@@ -0,0 +1,148 @@
1
+ module Architect4r #:nodoc:
2
+ module Core #:nodoc:
3
+
4
+ # Architect4r can be configured by creating a config/architect4r file
5
+ # and provide environment specific data.
6
+ #
7
+ # Thanks to the sunspot-rails gem team, as this class is heavily inspired by their work!
8
+ #
9
+ # development:
10
+ # host: localhost
11
+ # port: 7474
12
+ # log_level: DEBUG
13
+ # test:
14
+ # host: localhost
15
+ # port: 7474
16
+ # log_level: OFF
17
+ # production:
18
+ # host: localhost
19
+ # port: 8080
20
+ # path: /my_neo_instance
21
+ # log_level: WARNING
22
+ #
23
+ class Configuration
24
+
25
+ def initialize(options = {})
26
+ options ||= {}
27
+ @environment = options.delete(:environment).to_s if options.has_key?(:environment)
28
+ self.custom_configuration = options.delete(:config) if options.has_key?(:config)
29
+ end
30
+
31
+ def environment
32
+ @environment ||= 'development'
33
+ end
34
+
35
+ def host
36
+ unless defined?(@hostname)
37
+ @hostname = neo4j_url.host if neo4j_url
38
+ @hostname ||= custom_configuration_from_key('host')
39
+ @hostname ||= default_hostname
40
+ end
41
+ @hostname
42
+ end
43
+
44
+ def port
45
+ unless defined?(@port)
46
+ @port = neo4j_url.port if neo4j_url
47
+ @port ||= custom_configuration_from_key('port')
48
+ @port ||= default_port
49
+ @port = @port.to_i
50
+ end
51
+ @port
52
+ end
53
+
54
+ def path
55
+ unless defined?(@path)
56
+ @path = neo4j_url.path if neo4j_url
57
+ @path ||= custom_configuration_from_key('path')
58
+ @path ||= default_path
59
+ end
60
+ @path
61
+ end
62
+
63
+ def log_level
64
+ @log_level ||= (custom_configuration_from_key('log_level') || default_log_level)
65
+ end
66
+
67
+ def log_file
68
+ @log_file ||= (custom_configuration_from_key('log_file') || default_log_file_location )
69
+ end
70
+
71
+
72
+ private
73
+
74
+ def default_log_file_location
75
+ File.join(Dir.pwd, 'log', "architect4r.#{self.environment}.log")
76
+ end
77
+
78
+ def custom_configuration_from_key( *keys )
79
+ keys.inject(custom_configuration) do |hash, key|
80
+ hash[key] if hash
81
+ end
82
+ end
83
+
84
+ def custom_configuration=(input)
85
+ @custom_configuration = if input.is_a?(Hash)
86
+ input.stringify_keys
87
+ elsif input.is_a?(String)
88
+ begin
89
+ if File.exist?(input)
90
+ File.open(input) do |file|
91
+ YAML.load(file)[self.environment]
92
+ end
93
+ else
94
+ {}
95
+ end
96
+ end
97
+ else
98
+ {}
99
+ end
100
+ end
101
+
102
+ def custom_configuration
103
+ @custom_configuration ||=
104
+ begin
105
+ path = File.join(Dir.pwd, 'config', 'architect4r.yml')
106
+ if File.exist?(path)
107
+ File.open(path) do |file|
108
+ YAML.load(file)[self.environment]
109
+ end
110
+ else
111
+ {}
112
+ end
113
+ end
114
+ end
115
+
116
+ protected
117
+
118
+ # Allow the user to configure the server by providing an environment variable
119
+ # with a valid url to the neo4j rest endpoint.
120
+ def neo4j_url
121
+ URI.parse(ENV['NEO4J_URL']) if ENV['NEO4J_URL']
122
+ end
123
+
124
+ def default_hostname
125
+ 'localhost'
126
+ end
127
+
128
+ def default_port
129
+ { 'test' => 7475,
130
+ 'development' => 7474,
131
+ 'production' => 7474
132
+ }[self.environment] || 7474
133
+ end
134
+
135
+ def default_path
136
+ ''
137
+ end
138
+
139
+ def default_log_level
140
+ { 'test' => 'OFF',
141
+ 'development' => 'INFO',
142
+ 'production' => 'WARNING'
143
+ }[self.environment] || 'INFO'
144
+ end
145
+
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,47 @@
1
+ module Architect4r
2
+ module Core
3
+ module CypherMethods
4
+ extend ActiveSupport::Concern
5
+
6
+ module InstanceMethods
7
+
8
+ def execute_cypher(query)
9
+ url = prepend_base_url("/ext/CypherPlugin/graphdb/execute_query")
10
+ response = Typhoeus::Request.post(url,
11
+ :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
12
+ :body => { 'query' => query }.to_json)
13
+
14
+ # Check if there might be an error with the query
15
+ if response.code == 400
16
+ raise Architect4r::InvalidCypherQuery.new(query)
17
+ elsif response.code == 500
18
+ msg = JSON.parse(response.body)
19
+
20
+ if msg['exception'].to_s.match /org.neo4j.graphdb.NotFoundException/
21
+ nil
22
+ else
23
+ raise Architect4r::InvalidCypherQuery.new(query)
24
+ end
25
+ elsif response.code == 204
26
+ nil
27
+ else
28
+ result_data = JSON.parse(response.body)
29
+
30
+ # Convert the columnized result array to hashes within an array
31
+ results = []
32
+
33
+ result_data['data'].each_with_index do |row, ri|
34
+ result_row = {}
35
+ result_data['columns'].each_with_index do |column, ci|
36
+ result_row[column] = convert_if_possible(row[ci])
37
+ end
38
+ results << result_row
39
+ end
40
+ results
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,129 @@
1
+ module Architect4r
2
+ module Core
3
+ module ManagementMethods
4
+
5
+ def get_kernel_data
6
+ #http://localhost:7475/db/manage/server/jmx/domain/org.neo4j/
7
+ end
8
+
9
+ # Deletes the database
10
+ def reset_database!
11
+
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+
18
+ =begin
19
+ {
20
+ "beans" : [ {
21
+ "description" : "Estimates of the numbers of different kinds of Neo4j primitives",
22
+ "name" : "org.neo4j:instance=kernel#0,name=Primitive count",
23
+ "attributes" : [ {
24
+ "description" : "An estimation of the number of nodes used in this Neo4j instance",
25
+ "name" : "NumberOfNodeIdsInUse",
26
+ "value" : 109,
27
+ "isReadable" : "true",
28
+ "type" : "long",
29
+ "isWriteable" : "false ",
30
+ "isIs" : "false "
31
+ }, {
32
+ "description" : "An estimation of the number of relationships used in this Neo4j instance",
33
+ "name" : "NumberOfRelationshipIdsInUse",
34
+ "value" : 0,
35
+ "isReadable" : "true",
36
+ "type" : "long",
37
+ "isWriteable" : "false ",
38
+ "isIs" : "false "
39
+ }, {
40
+ "description" : "An estimation of the number of properties used in this Neo4j instance",
41
+ "name" : "NumberOfPropertyIdsInUse",
42
+ "value" : 295,
43
+ "isReadable" : "true",
44
+ "type" : "long",
45
+ "isWriteable" : "false ",
46
+ "isIs" : "false "
47
+ }, {
48
+ "description" : "The number of relationship types used in this Neo4j instance",
49
+ "name" : "NumberOfRelationshipTypeIdsInUse",
50
+ "value" : 0,
51
+ "isReadable" : "true",
52
+ "type" : "long",
53
+ "isWriteable" : "false ",
54
+ "isIs" : "false "
55
+ } ],
56
+ "url" : "org.neo4j/instance%3Dkernel%230%2Cname%3DPrimitive+count"
57
+ }, {
58
+ "description" : "Information about the Neo4j kernel",
59
+ "name" : "org.neo4j:instance=kernel#0,name=Kernel",
60
+ "attributes" : [ {
61
+ "description" : "Whether this is a read only instance",
62
+ "name" : "ReadOnly",
63
+ "value" : false,
64
+ "isReadable" : "true",
65
+ "type" : "boolean",
66
+ "isWriteable" : "false ",
67
+ "isIs" : "true"
68
+ }, {
69
+ "description" : "An ObjectName that can be used as a query for getting all management beans for this Neo4j instance.",
70
+ "name" : "MBeanQuery",
71
+ "value" : "org.neo4j:instance=kernel#0,name=*",
72
+ "isReadable" : "true",
73
+ "type" : "javax.management.ObjectName",
74
+ "isWriteable" : "false ",
75
+ "isIs" : "false "
76
+ }, {
77
+ "description" : "The time from which this Neo4j instance was in operational mode.",
78
+ "name" : "KernelStartTime",
79
+ "value" : "Sat Sep 10 17:42:53 CEST 2011",
80
+ "isReadable" : "true",
81
+ "type" : "java.util.Date",
82
+ "isWriteable" : "false ",
83
+ "isIs" : "false "
84
+ }, {
85
+ "description" : "The time when this Neo4j graph store was created.",
86
+ "name" : "StoreCreationDate",
87
+ "value" : "Sat Sep 03 20:19:29 CEST 2011",
88
+ "isReadable" : "true",
89
+ "type" : "java.util.Date",
90
+ "isWriteable" : "false ",
91
+ "isIs" : "false "
92
+ }, {
93
+ "description" : "An identifier that uniquely identifies this Neo4j graph store.",
94
+ "name" : "StoreId",
95
+ "value" : "a75e32d2bd11e487",
96
+ "isReadable" : "true",
97
+ "type" : "java.lang.String",
98
+ "isWriteable" : "false ",
99
+ "isIs" : "false "
100
+ }, {
101
+ "description" : "The current version of the Neo4j store logical log.",
102
+ "name" : "StoreLogVersion",
103
+ "value" : 2,
104
+ "isReadable" : "true",
105
+ "type" : "long",
106
+ "isWriteable" : "false ",
107
+ "isIs" : "false "
108
+ }, {
109
+ "description" : "The version of Neo4j",
110
+ "name" : "KernelVersion",
111
+ "value" : "Neo4j - Graph Database Kernel 1.4.1",
112
+ "isReadable" : "true",
113
+ "type" : "java.lang.String",
114
+ "isWriteable" : "false ",
115
+ "isIs" : "false "
116
+ }, {
117
+ "description" : "The location where the Neo4j store is located",
118
+ "name" : "StoreDirectory",
119
+ "value" : "/Users/namxam/packages/neo4j-community-1.4.1.test/data/graph.db",
120
+ "isReadable" : "true",
121
+ "type" : "java.lang.String",
122
+ "isWriteable" : "false ",
123
+ "isIs" : "false "
124
+ } ],
125
+ "url" : "org.neo4j/instance%3Dkernel%230%2Cname%3DKernel"
126
+ } ],
127
+ "domain" : "org.neo4j"
128
+ }
129
+ =end
@@ -0,0 +1,73 @@
1
+ module Architect4r
2
+ module Core
3
+ module NodeMethods
4
+ extend ActiveSupport::Concern
5
+
6
+ module InstanceMethods
7
+
8
+ def create_node(properties)
9
+ # Send request
10
+ response = Typhoeus::Request.post(prepend_base_url('/node'),
11
+ :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
12
+ :body => properties.to_json)
13
+
14
+ # Evaluate response
15
+ response.code == 201 ? JSON.parse(response.body) : nil
16
+ end
17
+
18
+ def get_node(id)
19
+ # Example response for a node
20
+ # extensions: {}
21
+ #
22
+ # paged_traverse: http://localhost:7475/db/data/node/0/paged/traverse/{returnType}{?pageSize,leaseTime}
23
+ # self: http://localhost:7475/db/data/node/0
24
+ # property: http://localhost:7475/db/data/node/0/properties/{key}
25
+ # data: {}
26
+ #
27
+ # incoming_typed_relationships: http://localhost:7475/db/data/node/0/relationships/in/{-list|&|types}
28
+ # outgoing_typed_relationships: http://localhost:7475/db/data/node/0/relationships/out/{-list|&|types}
29
+ # incoming_relationships: http://localhost:7475/db/data/node/0/relationships/in
30
+ # all_relationships: http://localhost:7475/db/data/node/0/relationships/all
31
+ # create_relationship: http://localhost:7475/db/data/node/0/relationships
32
+ # traverse: http://localhost:7475/db/data/node/0/traverse/{returnType}
33
+ # properties: http://localhost:7475/db/data/node/0/properties
34
+ # all_typed_relationships: http://localhost:7475/db/data/node/0/relationships/all/{-list|&|types}
35
+ # outgoing_relationships: http://localhost:7475/db/data/node/0/relationships/out
36
+
37
+ # Handle cases where id might be a url
38
+
39
+ response = Typhoeus::Request.get(node_url(id), :headers => { 'Accept' => 'application/json' })
40
+ response.code == 200 ? JSON.parse(response.body) : nil
41
+ end
42
+
43
+ def update_node(id, properties)
44
+ # Handle urls
45
+ url = id.to_i == 0 ? id : node_url(id)
46
+
47
+ # Append the properties
48
+ url += "/properties"
49
+
50
+ response = Typhoeus::Request.put(url,
51
+ :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
52
+ :body => properties.to_json)
53
+ response.code == 204 ? true : false
54
+ end
55
+
56
+ def delete_node(id)
57
+ # Delete all relationships
58
+ get_node_relationships(id, :all).each do |rel|
59
+ delete_relationship(rel)
60
+ end
61
+
62
+ # Delete node itself
63
+ response = Typhoeus::Request.delete(node_url(id), :headers => { 'Accept' => 'application/json' })
64
+ response.code == 204 ? true : false
65
+ end
66
+
67
+ def root
68
+ get_node(get('/')['reference_node'])
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,82 @@
1
+ module Architect4r
2
+ module Core
3
+ module RelationshipMethods
4
+ extend ActiveSupport::Concern
5
+
6
+ module InstanceMethods
7
+
8
+ def create_relationship(start_node, end_node, type, properties={})
9
+ # POST http://localhost:7474/db/data/node/3/relationships
10
+ # {"to" : "http://localhost:7474/db/data/node/4", "type" : "LOVES"}
11
+ # 201: Created
12
+ # Location: http://localhost:7474/db/data/relationship/2
13
+
14
+ # Add the destination node and type to the properties
15
+ properties = { 'to' => node_url(end_node), 'type' => type.to_s, 'data' => properties }
16
+
17
+ # Send request
18
+ response = Typhoeus::Request.post(node_url(start_node) + "/relationships",
19
+ :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
20
+ :body => properties.to_json)
21
+
22
+ # Evaluate response
23
+ response.code == 201 ? JSON.parse(response.body) : nil
24
+ end
25
+
26
+ def get_relationship(relationship)
27
+ response = Typhoeus::Request.get(relationship_url(relationship), :headers => { 'Accept' => 'application/json' })
28
+ response.code == 200 ? JSON.parse(response.body) : nil
29
+ end
30
+
31
+ def delete_relationship(relationship)
32
+ response = Typhoeus::Request.delete(relationship_url(relationship), :headers => { 'Accept' => 'application/json' })
33
+ response.code == 204 ? true : false
34
+ end
35
+
36
+ def get_node_relationships(node, direction = :all, *types)
37
+ # GET http://localhost:7474/db/data/node/6/relationships/all
38
+ # GET http://localhost:7474/db/data/node/11/relationships/in
39
+ # GET http://localhost:7474/db/data/node/16/relationships/out
40
+ # GET http://localhost:7474/db/data/node/21/relationships/all/LIKES&HATES
41
+ # 200: OK
42
+
43
+ # Set direction
44
+ direction = case direction.to_s
45
+ when 'incoming'
46
+ 'in'
47
+ when 'outgoing'
48
+ 'out'
49
+ else
50
+ 'all'
51
+ end
52
+
53
+ # Create typ filter
54
+ types = types.map { |e| URI.escape(e) }.join('&')
55
+
56
+ # Send request
57
+ url = node_url(node) + "/relationships/#{direction}/#{types}"
58
+ response = Typhoeus::Request.get(url, :headers => { 'Accept' => 'application/json' })
59
+ response.code == 200 ? JSON.parse(response.body) : []
60
+ end
61
+
62
+ def update_relationship(id, properties)
63
+ # PUT http://localhost:7474/db/data/relationship/0/properties
64
+ # 204: No Content
65
+ url = relationship_url(id) + '/properties'
66
+ response = Typhoeus::Request.put(url,
67
+ :headers => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
68
+ :body => properties.to_json)
69
+ response.code == 204 ? true : false
70
+ end
71
+
72
+ def get_relationship_types
73
+ # GET http://localhost:7474/db/data/relationship/types
74
+ # 200: OK
75
+ response = Typhoeus::Request.get(prepend_base_url('/relationship/types'), :headers => { 'Accept' => 'application/json' })
76
+ response.code == 200 ? JSON.parse(response.body) : []
77
+ end
78
+
79
+ end
80
+ end
81
+ end
82
+ end