/** * Copyright (c) 2002-2013 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * This file is part of Neo4j. * * Neo4j is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.neo4j.kernel.impl.storemigration; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.HashMap; import java.util.Map; import org.neo4j.helpers.UTF8; import org.neo4j.kernel.impl.nioneo.store.NeoStore; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyDynamicStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyNodeStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyPropertyIndexStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyPropertyStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyRelationshipStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyRelationshipTypeStoreReader; import org.neo4j.kernel.impl.storemigration.legacystore.LegacyStore; public class UpgradableDatabase { private Map<String, String> fileNamesToExpectedVersions = new HashMap<String, String>(); public UpgradableDatabase() { fileNamesToExpectedVersions.put( NeoStore.DEFAULT_NAME, LegacyStore.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.nodestore.db", LegacyNodeStoreReader.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.propertystore.db", LegacyPropertyStoreReader.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.propertystore.db.arrays", LegacyDynamicStoreReader.FROM_VERSION_ARRAY ); fileNamesToExpectedVersions.put( "neostore.propertystore.db.index", LegacyPropertyIndexStoreReader.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.propertystore.db.index.keys", LegacyDynamicStoreReader.FROM_VERSION_STRING ); fileNamesToExpectedVersions.put( "neostore.propertystore.db.strings", LegacyDynamicStoreReader.FROM_VERSION_STRING ); fileNamesToExpectedVersions.put( "neostore.relationshipstore.db", LegacyRelationshipStoreReader.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.relationshiptypestore.db", LegacyRelationshipTypeStoreReader.FROM_VERSION ); fileNamesToExpectedVersions.put( "neostore.relationshiptypestore.db.names", LegacyDynamicStoreReader.FROM_VERSION_STRING ); } public void checkUpgradeable( File neoStoreFile ) { if (!storeFilesUpgradeable( neoStoreFile )) { throw new StoreUpgrader.UnableToUpgradeException( "Not all store files match the version required for successful upgrade" ); } } public boolean storeFilesUpgradeable( File neoStoreFile ) { File storeDirectory = neoStoreFile.getParentFile(); for ( String fileName : fileNamesToExpectedVersions.keySet() ) { String expectedVersion = fileNamesToExpectedVersions.get( fileName ); FileChannel fileChannel = null; byte[] expectedVersionBytes = UTF8.encode( expectedVersion ); try { File storeFile = new File( storeDirectory, fileName ); if (!storeFile.exists()) { return false; } fileChannel = new RandomAccessFile( storeFile, "r" ).getChannel(); fileChannel.position( fileChannel.size() - expectedVersionBytes.length ); byte[] foundVersionBytes = new byte[expectedVersionBytes.length]; fileChannel.read( ByteBuffer.wrap( foundVersionBytes ) ); if ( !expectedVersion.equals( UTF8.decode( foundVersionBytes ) ) ) { return false; } } catch ( IOException e ) { throw new RuntimeException( e ); } finally { if ( fileChannel != null ) { try { fileChannel.close(); } catch ( IOException e ) { // Ignore exception on close } } } } return true; } }