neo_doxygen: Do not manually flush the output.
[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
21 # A storage medium for a graph.
22 #
23 # Provides a way to save a Neo4j graph.
24 abstract class GraphStore
25
26 # Escape control sequence to save the cursor position.
27 private var term_save_cursor: String = (new TermSaveCursor).to_s
28
29 # Escape control sequence to rewind to the last saved cursor position.
30 private var term_rewind: String = "{new TermRestoreCursor}{new TermEraseDisplayDown}"
31
32 # Is the storage medium already contains at least one node with the specified label?
33 fun has_node_label(name: String): Bool is abstract
34
35 # Save all specified Neo4j entities.
36 fun save_all(neo_entities: Collection[NeoEntity]) is abstract
37
38 # Prepare the output to show the progress.
39 #
40 # This method must be called before the first call to `show_progress` or
41 # `show_done`.
42 protected fun prepare_display do printn "{term_save_cursor} "
43
44 # Show the progress, in percentage.
45 #
46 # For use in the implementation of `save_all` only.
47 protected fun show_progress(progress: Int) do
48 printn "{term_rewind} {progress}% "
49 end
50
51 # Show a message to indicate that the task finished with success.
52 #
53 # For use in the implementation of `save_all` only.
54 protected fun show_done do
55 print "{term_rewind} Done."
56 end
57 end
58
59 # An actual Neo4j database as a storage medium.
60 class Neo4jStore
61 super GraphStore
62
63 # How many operations can be executed in one batch?
64 private var batch_max_size = 1000
65
66 # The Neo4j client to use.
67 var client: Neo4jClient
68
69 redef fun has_node_label(name: String): Bool do
70 var query = new CypherQuery.from_string(
71 "match n where \{name\} in labels(n) return count(n)")
72 query.params["name"] = name
73 var data = client.cypher(query).as(JsonObject)["data"]
74 var result = data.as(JsonArray).first.as(JsonArray).first.as(Int)
75 return result > 0
76 end
77
78 redef fun save_all(neo_entities: Collection[NeoEntity]) do
79 var batch = new NeoBatch(client)
80 var len = neo_entities.length
81 var sum = 0
82 var i = 1
83
84 prepare_display
85 for nentity in neo_entities do
86 batch.save_entity(nentity)
87 if i == batch_max_size then
88 do_batch(batch)
89 sum += batch_max_size
90 show_progress(sum * 100 / len)
91 batch = new NeoBatch(client)
92 i = 1
93 else
94 i += 1
95 end
96 end
97 do_batch(batch)
98 show_done
99 end
100
101 # Execute `batch` and check for errors.
102 #
103 # Abort if `batch.execute` returns errors.
104 private fun do_batch(batch: NeoBatch) do
105 var errors = batch.execute
106 if not errors.is_empty then
107 for e in errors do sys.stderr.write("{sys.program_name}: {e}\n")
108 exit(1)
109 end
110 end
111 end