1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # A storage medium for a graph.
22 # A storage medium for a graph.
24 # Provides a way to save a Neo4j graph.
25 abstract class GraphStore
27 # Escape control sequence to save the cursor position.
28 private var term_save_cursor
: String = (new TermSaveCursor).to_s
30 # Escape control sequence to rewind to the last saved cursor position.
31 private var term_rewind
: String = "{new TermRestoreCursor}{new TermEraseDisplayDown}"
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
36 # Save all specified Neo4j entities.
37 fun save_all
(neo_entities
: Collection[NeoEntity]) is abstract
39 # Prepare the output to show the progress.
41 # This method must be called before the first call to `show_progress` or
43 protected fun prepare_display
do
44 printn
"{term_save_cursor} "
48 # Show the progress, in percentage.
50 # For use in the implementation of `save_all` only.
51 protected fun show_progress
(progress
: Int) do
52 printn
"{term_rewind} {progress}% "
56 # Show a message to indicate that the task finished with success.
58 # For use in the implementation of `save_all` only.
59 protected fun show_done
do
60 print
"{term_rewind} Done."
65 # An actual Neo4j database as a storage medium.
69 # How many operations can be executed in one batch?
70 private var batch_max_size
= 1000
72 # The Neo4j client to use.
73 var client
: Neo4jClient
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)
84 redef fun save_all
(neo_entities
: Collection[NeoEntity]) do
85 var batch
= new NeoBatch(client
)
86 var len
= neo_entities
.length
91 for nentity
in neo_entities
do
92 batch
.save_entity
(nentity
)
93 if i
== batch_max_size
then
96 show_progress
(sum
* 100 / len
)
97 batch
= new NeoBatch(client
)
107 # Execute `batch` and check for errors.
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")