class Geoff class Error < StandardError ; end class << self def log(message) $stdout.puts message unless silent? end def silent? false end end module Importer class LockedDatabase < Geoff::Error ; end class MissingIndexedProperty < Geoff::Error ; end class InvalidRules < Geoff::Error ; end Subgraph = org.neo4j.geoff.Subgraph EmbeddedDB = Java::OrgNeo4jKernel::EmbeddedGraphDatabase HaDb = Java::OrgNeo4jKernel::HighlyAvailableGraphDatabase class << self def import geoff, db, node_map = {}, options = {} @options = options set_geoff(geoff) set_db(db) import_geoff(node_map) shutdown if db.is_a? String end private def set_db db if db.is_a?(String) raise Geoff::Importer::LockedDatabase.new('database is running') if locked?(db) start_db(db) else @graph_db = db end end def set_geoff geoff @geoff = if geoff.is_a? String geoff.split "\n" else geoff.to_geoff end raise Geoff::Importer::InvalidRules.new('Invalid rules') unless validate_rules(@geoff) end def locked?(db) Geoff.log 'check if database is running' lock_file = File.join(db, 'neostore') return false unless File.exist?(lock_file) rfile = java.io.RandomAccessFile.new(lock_file, 'rw') begin lock = rfile.getChannel.tryLock lock.release if lock return lock == nil rescue Exception => e return false end end def start_db(db_path) @graph_db = if ha_enabled? start_ha_db(db_path) else start_embedded_db(db_path) end end def start_embedded_db(db_path) Geoff.log 'starting embedded database' EmbeddedDB.new(db_path, config) end def start_ha_db(db_path) Geoff.log 'starting ha embedded database' HaDb.new(db_path, config) end def ha_enabled? !!@options['ha.db'] end def shutdown Geoff.log 'shutdown db' @graph_db.shutdown end def import_geoff node_map node_map = map_root_node if node_map.empty? Geoff.log 'importing geoff' sub_graph = Subgraph.new(@geoff) org.neo4j.geoff.Geoff.mergeIntoNeo4j(sub_graph, @graph_db, node_map ); end def map_root_node Geoff.log 'creating node_map' {"ROOT" => @graph_db.reference_node} end def validate_rules(rules) @invalid = Array(rules).map do |r| validate_rule(r) end.compact @invalid.each { |r, message| Geoff.log "Rule '#{r}' is invalid: #{message}" } @invalid.empty? end def config map = java.util.HashMap.new @options.each_pair do |k, v| case v when TrueClass map[k.to_s] = "true" when FalseClass map[k.to_s] = "false" when String, Fixnum, Float map[k.to_s] = v.to_s # skip list and hash values - not accepted by the Java Neo4j API end end map end def validate_rule(rule) Subgraph.new(Array(rule)) nil rescue Exception => e return [rule, e.message] end end end end