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.
21 # A storage medium for a graph.
23 # Provides a way to save a Neo4j graph.
24 abstract class GraphStore
26 # Escape control sequence to save the cursor position.
27 private var term_save_cursor
: String = (new TermSaveCursor).to_s
29 # Escape control sequence to rewind to the last saved cursor position.
30 private var term_rewind
: String = "{new TermRestoreCursor}{new TermEraseDisplayDown}"
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
35 # Save all specified Neo4j entities.
36 fun save_all
(neo_entities
: Collection[NeoEntity]) is abstract
38 # Prepare the output to show the progress.
40 # This method must be called before the first call to `show_progress` or
42 protected fun prepare_display
do printn
"{term_save_cursor} "
44 # Show the progress, in percentage.
46 # For use in the implementation of `save_all` only.
47 protected fun show_progress
(progress
: Int) do
48 printn
"{term_rewind} {progress}% "
51 # Show a message to indicate that the task finished with success.
53 # For use in the implementation of `save_all` only.
54 protected fun show_done
do
55 print
"{term_rewind} Done."
59 # An actual Neo4j database as a storage medium.
63 # How many operations can be executed in one batch?
64 private var batch_max_size
= 1000
66 # The Neo4j client to use.
67 var client
: Neo4jClient
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)
78 redef fun save_all
(neo_entities
: Collection[NeoEntity]) do
79 var batch
= new NeoBatch(client
)
80 var len
= neo_entities
.length
85 for nentity
in neo_entities
do
86 batch
.save_entity
(nentity
)
87 if i
== batch_max_size
then
90 show_progress
(sum
* 100 / len
)
91 batch
= new NeoBatch(client
)
101 # Execute `batch` and check for errors.
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")