确定Neo4j数据库版本

时间:2017-11-19 15:39:00

标签: java neo4j neo4j-java-api

当我调用

时,Neo4j Java API会自动将过时的数据库更新为当前版本

new GraphDatabaseFactory().newEmbeddedDatabase(File storeDir)

我想在执行此操作之前检查数据库的版本。有没有办法用Java API做到这一点?或者:存储数据库版本在哪里,以便我可以手动读出它?

1 个答案:

答案 0 :(得分:1)

发布版本

我挖掘了Neo4j API源并找到了答案。 Neo4j从debug.log目录中的logs文件中读出以前的版本。每当启动数据库时,版本都会以Kernel version: (this is where you'll find the version)的形式打印到日志文件中。例如,它看起来像这样:

2017-11-21 06:21:43.460+0000 INFO [o.n.k.i.DiagnosticsManager] Kernel version: 3.3.0,5b700972242a5ec3e0140261120f2845fb3520ad

你可以用Neo4j方式读出debug.log:

import java.io.File;

import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.kernel.impl.transaction.log.LogTailScanner;
import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile;
import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion;
import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader;

public class Neo4jVersionChecker {

    //Note that this method needs the store directory NOT the debug.log file
    public static String getNeo4jVersion(File storeDir) {   
        FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
        final PhysicalLogFiles logFiles = new PhysicalLogFiles( storeDir, PhysicalLogFile.DEFAULT_NAME, fileSystem );
        final LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader = new VersionAwareLogEntryReader<>();
        LogTailScanner tailScanner = new LogTailScanner( logFiles, fileSystem, logEntryReader );

        LogEntryVersion version = tailScanner.getTailInformation().latestLogEntryVersion;

        if(version!=null) {
                return version.toString();
        } else {
                return null;
        }
    }

}

上述方法会为V3_0_10返回debug.log,其中Kernel version条目的最新值为Kernel version

不幸的是,Neo4j方式不是很精确。您可以看到debug.log中的3.3.0V3_0_10开头,但Neo方法显示为import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.commons.io.input.ReversedLinesFileReader; public class VersionChecker { public static String getVersion(File storeDir) { File debugLog = new File(storeDir, "logs" + File.separator + "debug.log"); if(debugLog.exists()) { try { //The ReversedLinesFileReader reads the last line of a file first and so on ReversedLinesFileReader reader = new ReversedLinesFileReader(debugLog, StandardCharsets.UTF_8); //Read last line String line = reader.readLine(); while(line!=null) { //Line can't be null at this point if(line.contains("Kernel version: ")) { //This line contains the version line = line.substring(line.indexOf("Kernel version: ")).substring(16); //get rid of everything except the version line = line.split(",")[0]; //get rid of the second part of the Kernel version that we don't want return line; } //Next line line = reader.readLine(); } reader.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } } 。我假设这与Neo在内部处理版本的方式有关。

但是既然我们现在知道Neo4j如何获得版本,我们可以更准确地做同样的事情:

3.3.0

上述方法将返回neostore

商店版

当然,只有存在debug.log文件时,这两种方法才有效。并非所有以前的Neo4j版本都有它们。只要商店目录包含store version文件,您就可以读出StoreVersionCheck,这不如读取发行版本那么好,但至少它是一些东西。所以这是如何工作的:

有一个名为getVersion(File neostoreFile)的Neo4j类,它包含一个非常方便的方法PageCache。不幸的是,我们需要一个名为StoreVersionCheck的实例来初始化PageCache的实例。我们可以制作import java.io.File; import java.io.IOException; import java.util.Optional; import java.util.function.Consumer; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.io.fs.DefaultFileSystemAbstraction; import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory; import org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory; import org.neo4j.kernel.impl.storemigration.StoreVersionCheck; import org.neo4j.kernel.impl.util.Neo4jJobScheduler; import org.neo4j.kernel.monitoring.Monitors; import org.neo4j.kernel.monitoring.tracing.Tracers; import org.neo4j.logging.Log; import org.neo4j.logging.Logger; import org.neo4j.scheduler.JobScheduler; public class StoreVersionChecker { public static String getStoreVersion(File storeDir) { File storeFile = new File(storeDir, "neostore"); if(!storeFile.exists()) { return null; } StoreVersionCheck check = new StoreVersionCheck(buildPageCache()); try { Optional<String> version = check.getVersion(storeFile); if(version.isPresent()) { return version.get(); } } catch (IOException e) { e.printStackTrace(); } return null; } private static PageCache buildPageCache() { FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction(); Config config = Config.defaults(); Log pageCacheLog = new DummyLog(); String desiredImplementationName = config.get( GraphDatabaseFacadeFactory.Configuration.tracer ); Monitors monitors = new Monitors(); JobScheduler jobScheduler = new Neo4jJobScheduler(); Tracers tracers = new Tracers( desiredImplementationName, new DummyLog(), monitors, jobScheduler ); ConfiguringPageCacheFactory pageCacheFactory = new ConfiguringPageCacheFactory(fileSystem, config, tracers.pageCacheTracer, tracers.pageCursorTracerSupplier, pageCacheLog ); PageCache pageCache = pageCacheFactory.getOrCreatePageCache(); if ( config.get( GraphDatabaseSettings.dump_configuration ) ) { pageCacheFactory.dumpConfiguration(); } return pageCache; } //We need this so we can give the Tracers a Log private static class DummyLog implements Log { @Override public boolean isDebugEnabled() {return false;} @Override public Logger debugLogger() {return null;} @Override public void debug(String message) {} @Override public void debug(String message, Throwable throwable) {} @Override public void debug(String format, Object... arguments) {} @Override public Logger infoLogger() {return null;} @Override public void info(String message) {} @Override public void info(String message, Throwable throwable) {} @Override public void info(String format, Object... arguments) {} @Override public Logger warnLogger() {return null;} @Override public void warn(String message) {} @Override public void warn(String message, Throwable throwable) {} @Override public void warn(String format, Object... arguments) {} @Override public Logger errorLogger() {return null;} @Override public void error(String message) {} @Override public void error(String message, Throwable throwable) {} @Override public void error(String format, Object... arguments) {} @Override public void bulk(Consumer<Log> consumer) {} } } ,这就是我们要做的。

using (MuseumDBEntities db = new MuseumDBEntities())
{
   db.Database.ExecuteSqlCommand("truncate table childTable");
   db.Database.ExecuteSqlCommand("truncate table parentTable");
}