neography-down 1.6.4

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 (128) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.project +12 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +4 -0
  6. data/CHANGELOG.md +939 -0
  7. data/CONTRIBUTORS +18 -0
  8. data/Gemfile +4 -0
  9. data/Guardfile +14 -0
  10. data/LICENSE +19 -0
  11. data/README.md +281 -0
  12. data/Rakefile +14 -0
  13. data/examples/facebook.rb +40 -0
  14. data/examples/facebook_v2.rb +25 -0
  15. data/examples/greatest.rb +43 -0
  16. data/examples/linkedin.rb +39 -0
  17. data/examples/linkedin_v2.rb +22 -0
  18. data/examples/traversal_example1.rb +65 -0
  19. data/examples/traversal_example2.rb +54 -0
  20. data/lib/neography.rb +45 -0
  21. data/lib/neography/config.rb +64 -0
  22. data/lib/neography/connection.rb +263 -0
  23. data/lib/neography/equal.rb +21 -0
  24. data/lib/neography/errors.rb +60 -0
  25. data/lib/neography/index.rb +52 -0
  26. data/lib/neography/multi_json_parser.rb +28 -0
  27. data/lib/neography/neography.rb +10 -0
  28. data/lib/neography/node.rb +63 -0
  29. data/lib/neography/node_path.rb +29 -0
  30. data/lib/neography/node_relationship.rb +37 -0
  31. data/lib/neography/node_traverser.rb +146 -0
  32. data/lib/neography/path_traverser.rb +100 -0
  33. data/lib/neography/property.rb +110 -0
  34. data/lib/neography/property_container.rb +28 -0
  35. data/lib/neography/railtie.rb +19 -0
  36. data/lib/neography/relationship.rb +78 -0
  37. data/lib/neography/relationship_traverser.rb +80 -0
  38. data/lib/neography/rest.rb +99 -0
  39. data/lib/neography/rest/batch.rb +414 -0
  40. data/lib/neography/rest/clean.rb +17 -0
  41. data/lib/neography/rest/constraints.rb +38 -0
  42. data/lib/neography/rest/cypher.rb +29 -0
  43. data/lib/neography/rest/extensions.rb +21 -0
  44. data/lib/neography/rest/gremlin.rb +20 -0
  45. data/lib/neography/rest/helpers.rb +96 -0
  46. data/lib/neography/rest/node_auto_indexes.rb +60 -0
  47. data/lib/neography/rest/node_indexes.rb +139 -0
  48. data/lib/neography/rest/node_labels.rb +49 -0
  49. data/lib/neography/rest/node_paths.rb +49 -0
  50. data/lib/neography/rest/node_properties.rb +52 -0
  51. data/lib/neography/rest/node_relationships.rb +33 -0
  52. data/lib/neography/rest/node_traversal.rb +25 -0
  53. data/lib/neography/rest/nodes.rb +94 -0
  54. data/lib/neography/rest/other_node_relationships.rb +38 -0
  55. data/lib/neography/rest/relationship_auto_indexes.rb +60 -0
  56. data/lib/neography/rest/relationship_indexes.rb +142 -0
  57. data/lib/neography/rest/relationship_properties.rb +52 -0
  58. data/lib/neography/rest/relationship_types.rb +11 -0
  59. data/lib/neography/rest/relationships.rb +16 -0
  60. data/lib/neography/rest/schema_indexes.rb +26 -0
  61. data/lib/neography/rest/spatial.rb +137 -0
  62. data/lib/neography/rest/transactions.rb +101 -0
  63. data/lib/neography/tasks.rb +207 -0
  64. data/lib/neography/version.rb +3 -0
  65. data/neography.gemspec +39 -0
  66. data/spec/integration/authorization_spec.rb +40 -0
  67. data/spec/integration/broken_spatial_spec.rb +28 -0
  68. data/spec/integration/index_spec.rb +71 -0
  69. data/spec/integration/neography_spec.rb +10 -0
  70. data/spec/integration/node_encoding_spec.rb +71 -0
  71. data/spec/integration/node_path_spec.rb +222 -0
  72. data/spec/integration/node_relationship_spec.rb +381 -0
  73. data/spec/integration/node_spec.rb +260 -0
  74. data/spec/integration/parsing_spec.rb +13 -0
  75. data/spec/integration/performance_spec.rb +17 -0
  76. data/spec/integration/relationship_spec.rb +37 -0
  77. data/spec/integration/rest_batch_no_streaming_spec.rb +41 -0
  78. data/spec/integration/rest_batch_spec.rb +604 -0
  79. data/spec/integration/rest_batch_streaming_spec.rb +51 -0
  80. data/spec/integration/rest_bulk_spec.rb +106 -0
  81. data/spec/integration/rest_constraints_spec.rb +72 -0
  82. data/spec/integration/rest_experimental_spec.rb +22 -0
  83. data/spec/integration/rest_gremlin_fail_spec.rb +46 -0
  84. data/spec/integration/rest_header_spec.rb +15 -0
  85. data/spec/integration/rest_index_spec.rb +481 -0
  86. data/spec/integration/rest_labels_spec.rb +128 -0
  87. data/spec/integration/rest_node_spec.rb +274 -0
  88. data/spec/integration/rest_other_node_relationship_spec.rb +137 -0
  89. data/spec/integration/rest_path_spec.rb +231 -0
  90. data/spec/integration/rest_plugin_spec.rb +177 -0
  91. data/spec/integration/rest_relationship_spec.rb +354 -0
  92. data/spec/integration/rest_relationship_types_spec.rb +18 -0
  93. data/spec/integration/rest_schema_index_spec.rb +32 -0
  94. data/spec/integration/rest_spatial_spec.rb +166 -0
  95. data/spec/integration/rest_transaction_spec.rb +166 -0
  96. data/spec/integration/rest_traverse_spec.rb +149 -0
  97. data/spec/integration/unmanaged_spec.rb +27 -0
  98. data/spec/matchers.rb +33 -0
  99. data/spec/neography_spec.rb +23 -0
  100. data/spec/spec_helper.rb +44 -0
  101. data/spec/unit/config_spec.rb +135 -0
  102. data/spec/unit/connection_spec.rb +284 -0
  103. data/spec/unit/node_spec.rb +100 -0
  104. data/spec/unit/properties_spec.rb +285 -0
  105. data/spec/unit/relationship_spec.rb +118 -0
  106. data/spec/unit/rest/batch_spec.rb +262 -0
  107. data/spec/unit/rest/clean_spec.rb +16 -0
  108. data/spec/unit/rest/constraints_spec.rb +45 -0
  109. data/spec/unit/rest/cypher_spec.rb +20 -0
  110. data/spec/unit/rest/extensions_spec.rb +28 -0
  111. data/spec/unit/rest/gremlin_spec.rb +25 -0
  112. data/spec/unit/rest/helpers_spec.rb +124 -0
  113. data/spec/unit/rest/labels_spec.rb +77 -0
  114. data/spec/unit/rest/node_auto_indexes_spec.rb +70 -0
  115. data/spec/unit/rest/node_indexes_spec.rb +140 -0
  116. data/spec/unit/rest/node_paths_spec.rb +77 -0
  117. data/spec/unit/rest/node_properties_spec.rb +79 -0
  118. data/spec/unit/rest/node_relationships_spec.rb +57 -0
  119. data/spec/unit/rest/node_traversal_spec.rb +35 -0
  120. data/spec/unit/rest/nodes_spec.rb +187 -0
  121. data/spec/unit/rest/relationship_auto_indexes_spec.rb +66 -0
  122. data/spec/unit/rest/relationship_indexes_spec.rb +132 -0
  123. data/spec/unit/rest/relationship_properties_spec.rb +79 -0
  124. data/spec/unit/rest/relationship_types_spec.rb +15 -0
  125. data/spec/unit/rest/relationships_spec.rb +21 -0
  126. data/spec/unit/rest/schema_index_spec.rb +30 -0
  127. data/spec/unit/rest/transactions_spec.rb +43 -0
  128. metadata +372 -0
@@ -0,0 +1,29 @@
1
+ module Neography
2
+ class Rest
3
+ module Cypher
4
+ include Neography::Rest::Helpers
5
+
6
+ def execute_query(query, parameters = {}, cypher_options = nil)
7
+ options = {
8
+ :body => {
9
+ :query => query,
10
+ :params => parameters
11
+ }.to_json,
12
+ :headers => json_content_type.merge({'Accept' => 'application/json;stream=true;charset=UTF-8'})
13
+ }
14
+
15
+ @connection.post(optioned_path(cypher_options), options)
16
+ end
17
+
18
+ private
19
+ def optioned_path(cypher_options = nil)
20
+ return @connection.cypher_path unless cypher_options
21
+ options = []
22
+ options << "includeStats=true" if cypher_options[:stats]
23
+ options << "profile=true" if cypher_options[:profile]
24
+ @connection.cypher_path + "?" + options.join("&")
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ module Neography
2
+ class Rest
3
+ module Extensions
4
+ include Neography::Rest::Helpers
5
+
6
+ def get_extension(path)
7
+ @connection.get(path)
8
+ end
9
+
10
+ def post_extension(path, body = {}, headers = nil)
11
+ options = {
12
+ :body => headers.nil? ? body.to_json : body,
13
+ :headers => headers || json_content_type.merge({'Accept' => 'application/json;stream=true'})
14
+ }
15
+
16
+ @connection.post(path, options)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Neography
2
+ class Rest
3
+ module Gremlin
4
+ include Neography::Rest::Helpers
5
+
6
+ def execute_script(script, parameters = {})
7
+ options = {
8
+ :body => {
9
+ :script => script,
10
+ :params => parameters,
11
+ }.to_json,
12
+ :headers => json_content_type
13
+ }
14
+ result = @connection.post(@connection.gremlin_path, options)
15
+ result == "null" ? nil : result
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,96 @@
1
+ module Neography
2
+ class Rest
3
+ module Helpers
4
+
5
+ def get_id(id)
6
+ case id
7
+ when Array
8
+ get_id(id.first)
9
+ when Hash
10
+ id["self"].split('/').last
11
+ when String
12
+ id.split('/').last
13
+ when Neography::Node, Neography::Relationship
14
+ id.neo_id
15
+ else
16
+ id
17
+ end
18
+ end
19
+
20
+ def json_content_type
21
+ {'Content-Type' => 'application/json'}
22
+ end
23
+
24
+ def parse_direction(direction)
25
+ case direction
26
+ when :incoming, "incoming", :in, "in"
27
+ "in"
28
+ when :outgoing, "outgoing", :out, "out"
29
+ "out"
30
+ else
31
+ "all"
32
+ end
33
+ end
34
+
35
+ def encode(value)
36
+ CGI.escape(value.to_s).gsub("+", "%20")
37
+ end
38
+
39
+ def escape(value)
40
+ if value.class == String
41
+ "%22"+encode(value.to_s)+"%22";
42
+ else
43
+ encode(value.to_s)
44
+ end
45
+ end
46
+
47
+ def parse_order(order)
48
+ case order
49
+ when :breadth, "breadth", "breadth first", "breadthFirst", :wide, "wide"
50
+ "breadth first"
51
+ else
52
+ "depth first"
53
+ end
54
+ end
55
+
56
+ def parse_uniqueness(uniqueness)
57
+ case uniqueness
58
+ when :nodeglobal, "node global", "nodeglobal", "node_global"
59
+ "node global"
60
+ when :nodepath, "node path", "nodepath", "node_path"
61
+ "node path"
62
+ when :noderecent, "node recent", "noderecent", "node_recent"
63
+ "node recent"
64
+ when :relationshipglobal, "relationship global", "relationshipglobal", "relationship_global"
65
+ "relationship global"
66
+ when :relationshippath, "relationship path", "relationshippath", "relationship_path"
67
+ "relationship path"
68
+ when :relationshiprecent, "relationship recent", "relationshiprecent", "relationship_recent"
69
+ "relationship recent"
70
+ else
71
+ "none"
72
+ end
73
+ end
74
+
75
+ def parse_depth(depth)
76
+ return nil if depth.nil?
77
+ return 1 if depth.to_i == 0
78
+ depth.to_i
79
+ end
80
+
81
+ def parse_type(type)
82
+ case type
83
+ when :relationship, "relationship", :relationships, "relationships"
84
+ "relationship"
85
+ when :path, "path", :paths, "paths"
86
+ "path"
87
+ when :fullpath, "fullpath", :fullpaths, "fullpaths"
88
+ "fullpath"
89
+ else
90
+ "node"
91
+ end
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,60 @@
1
+ module Neography
2
+ class Rest
3
+ module NodeAutoIndexes
4
+
5
+ def get_node_auto_index(key, value)
6
+ index = @connection.get("/index/auto/node/%{key}/%{value}" % {:key => key, :value => encode(value)}) || []
7
+ return nil if index.empty?
8
+ index
9
+ end
10
+
11
+ def find_node_auto_index(key_or_query, value = nil)
12
+ if value
13
+ index = find_node_auto_index_by_value(key_or_query, value)
14
+ else
15
+ index = query_node_auto_index(key_or_query)
16
+ end
17
+ return nil if index.empty?
18
+ index
19
+ end
20
+
21
+ def find_node_auto_index_by_value(key, value)
22
+ @connection.get("/index/auto/node/%{key}/%{value}" % {:key => key, :value => encode(value)}) || []
23
+ end
24
+
25
+ def query_node_auto_index(query_expression)
26
+ @connection.get("/index/auto/node/?query=%{query}" % {:query => encode(query_expression)}) || []
27
+ end
28
+
29
+ def get_node_auto_index_status
30
+ @connection.get("/index/auto/node/status")
31
+ end
32
+
33
+ def set_node_auto_index_status(value = true)
34
+ options = {
35
+ :body => value.to_json,
36
+ :headers => json_content_type
37
+ }
38
+ @connection.put("/index/auto/node/status", options)
39
+ end
40
+
41
+ def get_node_auto_index_properties
42
+ @connection.get("/index/auto/node/properties")
43
+ end
44
+
45
+ def add_node_auto_index_property(property)
46
+ options = {
47
+ :body => property,
48
+ :headers => json_content_type
49
+ }
50
+ @connection.post("/index/auto/node/properties", options)
51
+ end
52
+
53
+ def remove_node_auto_index_property(property)
54
+ @connection.delete("/index/auto/node/properties/%{property}" % {:property => property})
55
+ end
56
+
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,139 @@
1
+ module Neography
2
+ class Rest
3
+ module NodeIndexes
4
+ include Neography::Rest::Helpers
5
+
6
+ def list_node_indexes
7
+ @connection.get("/index/node")
8
+ end
9
+
10
+ def create_node_index(name, type = "exact", provider = "lucene", extra_config = nil)
11
+ config = {
12
+ :type => type,
13
+ :provider => provider
14
+ }
15
+ config.merge!(extra_config) unless extra_config.nil?
16
+ options = {
17
+ :body => (
18
+ { :name => name,
19
+ :config => config
20
+ }
21
+ ).to_json,
22
+ :headers => json_content_type
23
+ }
24
+ @connection.post("/index/node", options)
25
+ end
26
+
27
+ def create_node_auto_index(type = "exact", provider = "lucene")
28
+ create_node_index("node_auto_index", type, provider)
29
+ end
30
+
31
+ def add_node_to_index(index, key, value, id, unique = false)
32
+ options = {
33
+ :body => (
34
+ { :uri => @connection.configuration + "/node/#{get_id(id)}",
35
+ :key => key,
36
+ :value => value
37
+ }
38
+ ).to_json,
39
+ :headers => json_content_type
40
+ }
41
+ path = unique ? "/index/node/%{index}?unique" % {:index => index} : "/index/node/%{index}" % {:index => index}
42
+ @connection.post(path, options)
43
+ end
44
+
45
+ def get_node_index(index, key, value)
46
+ index = @connection.get("/index/node/%{index}/%{key}/%{value}" % {:index => index, :key => key, :value => encode(value)}) || []
47
+ return nil if index.empty?
48
+ index
49
+ end
50
+
51
+ def find_node_index(index, key_or_query, value = nil)
52
+ if value
53
+ index = find_node_index_by_key_value(index, key_or_query, value)
54
+ else
55
+ index = find_node_index_by_query(index, key_or_query)
56
+ end
57
+ return nil if index.empty?
58
+ index
59
+ end
60
+
61
+ def find_node_index_by_key_value(index, key, value)
62
+ @connection.get("/index/node/%{index}/%{key}/%{value}" % {:index => index, :key => key, :value => encode(value)}) || []
63
+ end
64
+
65
+ def find_node_index_by_query(index, query)
66
+ @connection.get("/index/node/%{index}?query=%{query}" % {:index => index, :query => encode(query)}) || []
67
+ end
68
+
69
+ # Mimick original neography API in Rest class.
70
+ def remove_node_from_index(index, id_or_key, id_or_value = nil, id = nil)
71
+ if id
72
+ remove_node_index_by_value(index, id, id_or_key, id_or_value)
73
+ elsif id_or_value
74
+ remove_node_index_by_key(index, id_or_value, id_or_key)
75
+ else
76
+ remove_node_index_by_id(index, id_or_key)
77
+ end
78
+ end
79
+
80
+ def remove_node_index_by_id(index, id)
81
+ @connection.delete("/index/node/%{index}/%{id}" % {:index => index, :id => get_id(id)})
82
+ end
83
+
84
+ def remove_node_index_by_key(index, id, key)
85
+ @connection.delete("/index/node/%{index}/%{key}/%{id}" % {:index => index, :id => get_id(id), :key => key})
86
+ end
87
+
88
+ def remove_node_index_by_value(index, id, key, value)
89
+ @connection.delete("/index/node/%{index}/%{key}/%{value}/%{id}" % {:index => index, :id => get_id(id), :key => key, :value => encode(value)})
90
+ end
91
+
92
+ def drop_node_index(index)
93
+ @connection.delete("/index/node/%{index}" % {:index => index})
94
+ end
95
+
96
+ def create_unique_node(index, key, value, properties = {})
97
+ options = {
98
+ :body => (
99
+ { :properties => properties,
100
+ :key => key,
101
+ :value => value
102
+ }
103
+ ).to_json,
104
+ :headers => json_content_type
105
+ }
106
+ @connection.post("/index/node/%{index}?unique" % {:index => index}, options)
107
+ end
108
+
109
+ def get_or_create_unique_node(index, key, value, properties = {})
110
+ options = {
111
+ :body => (
112
+ { :properties => properties,
113
+ :key => key,
114
+ :value => value
115
+ }
116
+ ).to_json,
117
+ :headers => json_content_type
118
+ }
119
+ @connection.post("/index/node/%{index}?uniqueness=%{function}" % {:index => index, :function => 'get_or_create'}, options)
120
+
121
+ end
122
+
123
+ def create_or_fail_unique_node(index, key, value, properties = {})
124
+ options = {
125
+ :body => (
126
+ { :properties => properties,
127
+ :key => key,
128
+ :value => value
129
+ }
130
+ ).to_json,
131
+ :headers => json_content_type
132
+ }
133
+ @connection.post("/index/node/%{index}?uniqueness=%{function}" % {:index => index, :function => 'create_or_fail'}, options)
134
+
135
+ end
136
+
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,49 @@
1
+ module Neography
2
+ class Rest
3
+ module NodeLabels
4
+ include Neography::Rest::Helpers
5
+
6
+ def list_labels
7
+ @connection.get("/labels")
8
+ end
9
+
10
+ def get_node_labels(id)
11
+ @connection.get("/node/%{id}/labels" % {:id => get_id(id)})
12
+ end
13
+
14
+ def get_nodes_labeled(label)
15
+ @connection.get("/label/%{label}/nodes" % {:label => label})
16
+ end
17
+
18
+ def find_nodes_labeled(label, hash)
19
+ @connection.get("/label/%{label}/nodes?%{property}=%{value}" % {:label => label, :property => hash.keys.first, :value => escape(hash.values.first)})
20
+ end
21
+
22
+ def add_label(id, label)
23
+ options = {
24
+ :body => (
25
+ label
26
+ ).to_json,
27
+ :headers => json_content_type
28
+ }
29
+ @connection.post("/node/%{id}/labels" % {:id => get_id(id)}, options)
30
+ end
31
+
32
+ def set_label(id, label)
33
+ options = {
34
+ :body => (
35
+ Array(label)
36
+ ).to_json,
37
+ :headers => json_content_type
38
+ }
39
+ @connection.put("/node/%{id}/labels" % {:id => get_id(id)}, options)
40
+ end
41
+
42
+ def delete_label(id, label)
43
+ @connection.delete("/node/%{id}/labels/%{label}" % {:id => get_id(id), :label => label})
44
+ end
45
+
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ module Neography
2
+ class Rest
3
+ module NodePaths
4
+ include Neography::Rest::Helpers
5
+
6
+ def get_path(from, to, relationships, depth = 1, algorithm = "shortestPath")
7
+ options = path_options(to, relationships, depth, algorithm)
8
+ @connection.post("/node/%{id}/path" % {:id => get_id(from)}, options) || {}
9
+ end
10
+
11
+ def get_paths(from, to, relationships, depth = 1, algorithm = "allPaths")
12
+ options = path_options(to, relationships, depth, algorithm)
13
+ @connection.post("/node/%{id}/paths" % {:id => get_id(from)}, options) || []
14
+ end
15
+
16
+ def get_shortest_weighted_path(from, to, relationships, weight_attribute = "weight", depth = 1, algorithm = "dijkstra")
17
+ options = path_options(to, relationships, depth, algorithm, { :cost_property => weight_attribute })
18
+ @connection.post("/node/%{id}/paths" % {:id => get_id(from)}, options) || {}
19
+ end
20
+
21
+ private
22
+
23
+ def get_algorithm(algorithm)
24
+ case algorithm
25
+ when :shortest, "shortest", :shortestPath, "shortestPath", :short, "short"
26
+ "shortestPath"
27
+ when :allSimplePaths, "allSimplePaths", :simple, "simple"
28
+ "allSimplePaths"
29
+ when :dijkstra, "dijkstra"
30
+ "dijkstra"
31
+ else
32
+ "allPaths"
33
+ end
34
+ end
35
+
36
+ def path_options(to, relationships, depth, algorithm, extra_body = {})
37
+ options = { :body => {
38
+ "to" => @connection.configuration + "/node/#{get_id(to)}",
39
+ "relationships" => relationships,
40
+ "max_depth" => depth,
41
+ "algorithm" => get_algorithm(algorithm)
42
+ }.merge(extra_body).to_json,
43
+ :headers => json_content_type
44
+ }
45
+ end
46
+
47
+ end
48
+ end
49
+ end