neo_doxygen: Accept classes in the root namespace.
[nit.git] / contrib / neo_doxygen / src / graph_store.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # A storage medium for a graph.
16 module graph_store
17
18 import neo4j
19 import console
20 import flush_stdout
21
22 # A storage medium for a graph.
23 #
24 # Provides a way to save a Neo4j graph.
25 abstract class GraphStore
26
27 # Escape control sequence to save the cursor position.
28 private var term_save_cursor: String = (new TermSaveCursor).to_s
29
30 # Escape control sequence to rewind to the last saved cursor position.
31 private var term_rewind: String = "{new TermRestoreCursor}{new TermEraseDisplayDown}"
32
33 # Is the storage medium already contains at least one node with the specified label?
34 fun has_node_label(name: String): Bool is abstract
35
36 # Save all specified Neo4j entities.
37 fun save_all(neo_entities: Collection[NeoEntity]) is abstract
38
39 # Prepare the output to show the progress.
40 #
41 # This method must be called before the first call to `show_progress` or
42 # `show_done`.
43 protected fun prepare_display do
44 printn "{term_save_cursor} "
45 flush_stdout
46 end
47
48 # Show the progress, in percentage.
49 #
50 # For use in the implementation of `save_all` only.
51 protected fun show_progress(progress: Int) do
52 printn "{term_rewind} {progress}% "
53 flush_stdout
54 end
55
56 # Show a message to indicate that the task finished with success.
57 #
58 # For use in the implementation of `save_all` only.
59 protected fun show_done do
60 print "{term_rewind} Done."
61 flush_stdout
62 end
63 end
64
65 # An actual Neo4j database as a storage medium.
66 class Neo4jStore
67 super GraphStore
68
69 # How many operations can be executed in one batch?
70 private var batch_max_size = 1000
71
72 # The Neo4j client to use.
73 var client: Neo4jClient
74
75 redef fun has_node_label(name: String): Bool do
76 var query = new CypherQuery.from_string(
77 "match n where \{name\} in labels(n) return count(n)")
78 query.params["name"] = name
79 var data = client.cypher(query).as(JsonObject)["data"]
80 var result = data.as(JsonArray).first.as(JsonArray).first.as(Int)
81 return result > 0
82 end
83
84 redef fun save_all(neo_entities: Collection[NeoEntity]) do
85 var batch = new NeoBatch(client)
86 var len = neo_entities.length
87 var sum = 0
88 var i = 1
89
90 prepare_display
91 for nentity in neo_entities do
92 batch.save_entity(nentity)
93 if i == batch_max_size then
94 do_batch(batch)
95 sum += batch_max_size
96 show_progress(sum * 100 / len)
97 batch = new NeoBatch(client)
98 i = 1
99 else
100 i += 1
101 end
102 end
103 do_batch(batch)
104 show_done
105 end
106
107 # Execute `batch` and check for errors.
108 #
109 # Abort if `batch.execute` returns errors.
110 private fun do_batch(batch: NeoBatch) do
111 var errors = batch.execute
112 if not errors.is_empty then
113 for e in errors do sys.stderr.write("{sys.program_name}: {e}\n")
114 exit(1)
115 end
116 end
117 end