Search in sources :

Example 1 with MultiChunkId

use of org.syncany.database.MultiChunkEntry.MultiChunkId in project syncany by syncany.

the class MultiChunkSqlDao method createMultiChunkEntriesWithoutChunks.

private Map<MultiChunkId, MultiChunkEntry> createMultiChunkEntriesWithoutChunks(ResultSet resultSet) throws SQLException {
    Map<MultiChunkId, MultiChunkEntry> unusedMultiChunkIds = new HashMap<MultiChunkId, MultiChunkEntry>();
    while (resultSet.next()) {
        MultiChunkId multiChunkId = MultiChunkId.parseMultiChunkId(resultSet.getString("id"));
        long multiChunkSize = resultSet.getLong("size");
        unusedMultiChunkIds.put(multiChunkId, new MultiChunkEntry(multiChunkId, multiChunkSize));
    }
    return unusedMultiChunkIds;
}
Also used : MultiChunkId(org.syncany.database.MultiChunkEntry.MultiChunkId) HashMap(java.util.HashMap) MultiChunkEntry(org.syncany.database.MultiChunkEntry)

Example 2 with MultiChunkId

use of org.syncany.database.MultiChunkEntry.MultiChunkId in project syncany by syncany.

the class MultiChunkSqlDao method getMultiChunkIdsByChecksums.

/**
	 * Note: This method selects also {@link DatabaseVersionStatus#DIRTY DIRTY}.
	 */
public Map<ChunkChecksum, MultiChunkId> getMultiChunkIdsByChecksums(List<ChunkChecksum> chunkChecksums) {
    // Gather a unique array of checksum strings (required for query!)
    Set<ChunkChecksum> chunkChecksumSet = new HashSet<ChunkChecksum>(chunkChecksums);
    String[] checksums = new String[chunkChecksumSet.size()];
    int i = 0;
    for (ChunkChecksum checksum : chunkChecksumSet) {
        checksums[i] = checksum.toString();
        i++;
    }
    // Execute query
    Map<ChunkChecksum, MultiChunkId> result = new HashMap<ChunkChecksum, MultiChunkId>();
    try (PreparedStatement preparedStatement = getStatement("multichunk.select.all.getMultiChunkIdForChunks.sql")) {
        preparedStatement.setArray(1, connection.createArrayOf("varchar", checksums));
        try (ResultSet resultSet = preparedStatement.executeQuery()) {
            while (resultSet.next()) {
                result.put(ChunkChecksum.parseChunkChecksum(resultSet.getString("chunk_checksum")), MultiChunkId.parseMultiChunkId(resultSet.getString("multichunk_id")));
            }
        }
        return result;
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}
Also used : MultiChunkId(org.syncany.database.MultiChunkEntry.MultiChunkId) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) ChunkChecksum(org.syncany.database.ChunkEntry.ChunkChecksum) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) HashSet(java.util.HashSet)

Example 3 with MultiChunkId

use of org.syncany.database.MultiChunkEntry.MultiChunkId in project syncany by syncany.

the class Assembler method assembleToCache.

/**
	 * Assembles the given file version to the local cache and returns a reference
	 * to the cached file after successfully assembling the file. 
	 */
public File assembleToCache(FileVersion fileVersion) throws Exception {
    File reconstructedFileInCache = config.getCache().createTempFile("reconstructedFileVersion");
    logger.log(Level.INFO, "     - Creating file " + fileVersion.getPath() + " to " + reconstructedFileInCache + " ...");
    FileContent fileContent = localDatabase.getFileContent(fileVersion.getChecksum(), true);
    if (fileContent == null && memoryDatabase != null) {
        fileContent = memoryDatabase.getContent(fileVersion.getChecksum());
    }
    // Check consistency!
    if (fileContent == null && fileVersion.getChecksum() != null) {
        throw new Exception("Cannot determine file content for checksum " + fileVersion.getChecksum());
    }
    // Create empty file
    if (fileContent == null) {
        FileUtils.touch(reconstructedFileInCache);
        return reconstructedFileInCache;
    }
    // Create non-empty file
    Chunker chunker = config.getChunker();
    MultiChunker multiChunker = config.getMultiChunker();
    FileOutputStream reconstructedFileOutputStream = new FileOutputStream(reconstructedFileInCache);
    MessageDigest reconstructedFileChecksum = MessageDigest.getInstance(chunker.getChecksumAlgorithm());
    if (fileContent != null) {
        // File can be empty!
        Collection<ChunkChecksum> fileChunks = fileContent.getChunks();
        for (ChunkChecksum chunkChecksum : fileChunks) {
            MultiChunkId multiChunkIdForChunk = localDatabase.getMultiChunkId(chunkChecksum);
            if (multiChunkIdForChunk == null && memoryDatabase != null) {
                multiChunkIdForChunk = memoryDatabase.getMultiChunkIdForChunk(chunkChecksum);
            }
            File decryptedMultiChunkFile = config.getCache().getDecryptedMultiChunkFile(multiChunkIdForChunk);
            MultiChunk multiChunk = multiChunker.createMultiChunk(decryptedMultiChunkFile);
            InputStream chunkInputStream = multiChunk.getChunkInputStream(chunkChecksum.getBytes());
            byte[] buffer = new byte[4096];
            int read = 0;
            while (-1 != (read = chunkInputStream.read(buffer))) {
                reconstructedFileChecksum.update(buffer, 0, read);
                reconstructedFileOutputStream.write(buffer, 0, read);
            }
            chunkInputStream.close();
            multiChunk.close();
        }
    }
    reconstructedFileOutputStream.close();
    // Validate checksum
    byte[] reconstructedFileExpectedChecksum = fileContent.getChecksum().getBytes();
    byte[] reconstructedFileActualChecksum = reconstructedFileChecksum.digest();
    if (!Arrays.equals(reconstructedFileActualChecksum, reconstructedFileExpectedChecksum)) {
        throw new Exception("Checksums do not match: expected " + StringUtil.toHex(reconstructedFileExpectedChecksum) + " != actual " + StringUtil.toHex(reconstructedFileActualChecksum));
    }
    return reconstructedFileInCache;
}
Also used : MultiChunkId(org.syncany.database.MultiChunkEntry.MultiChunkId) InputStream(java.io.InputStream) Chunker(org.syncany.chunk.Chunker) MultiChunker(org.syncany.chunk.MultiChunker) MultiChunk(org.syncany.chunk.MultiChunk) MultiChunker(org.syncany.chunk.MultiChunker) ChunkChecksum(org.syncany.database.ChunkEntry.ChunkChecksum) FileContent(org.syncany.database.FileContent) FileOutputStream(java.io.FileOutputStream) MessageDigest(java.security.MessageDigest) File(java.io.File)

Example 4 with MultiChunkId

use of org.syncany.database.MultiChunkEntry.MultiChunkId in project syncany by syncany.

the class DatabaseVersionDaoTest method testRemoveDirtyDatabaseVersions.

@Test
public void testRemoveDirtyDatabaseVersions() throws Exception {
    // Setup
    Config testConfig = TestConfigUtil.createTestLocalConfig();
    Connection databaseConnection = testConfig.createDatabaseConnection();
    // Run
    TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set1.sql");
    ChunkSqlDao chunkDao = new ChunkSqlDao(databaseConnection);
    MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
    FileVersionSqlDao fileVersionDao = new FileVersionSqlDao(databaseConnection);
    FileHistorySqlDao fileHistoryDao = new FileHistorySqlDao(databaseConnection, fileVersionDao);
    FileContentSqlDao fileContentDao = new FileContentSqlDao(databaseConnection);
    DatabaseVersionSqlDao databaseVersionDao = new DatabaseVersionSqlDao(databaseConnection, chunkDao, fileContentDao, fileVersionDao, fileHistoryDao, multiChunkDao);
    // a. Test before
    List<DatabaseVersion> dirtyDatabaseVersionsBefore = TestCollectionUtil.toList(databaseVersionDao.getDirtyDatabaseVersions());
    assertNotNull(dirtyDatabaseVersionsBefore);
    assertNotNull(chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef")));
    assertNotNull(multiChunkDao.getDirtyMultiChunkIds());
    assertEquals(1, multiChunkDao.getDirtyMultiChunkIds().size());
    // b. Add new database version with DIRTY multichunk; remove DIRTY version		
    DatabaseVersion newDatabaseVersion = new DatabaseVersion();
    newDatabaseVersion.setVectorClock(TestDatabaseUtil.createVectorClock("A5,B2"));
    long newDatabaseVersionId = databaseVersionDao.writeDatabaseVersion(newDatabaseVersion);
    databaseVersionDao.removeDirtyDatabaseVersions(newDatabaseVersionId);
    // c. Test after		
    // Database version
    List<DatabaseVersion> dirtyDatabaseVersionsAfter = TestCollectionUtil.toList(databaseVersionDao.getDirtyDatabaseVersions());
    assertNotNull(dirtyDatabaseVersionsAfter);
    assertEquals(0, dirtyDatabaseVersionsAfter.size());
    // Multichunk from dirty version "moved" to new version
    Map<MultiChunkId, MultiChunkEntry> multiChunksA5B2 = multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("A5,B2"));
    assertNotNull(multiChunksA5B2);
    assertEquals(1, multiChunksA5B2.size());
    assertNotNull(multiChunksA5B2.get(MultiChunkId.parseMultiChunkId("1234567890987654321123456789098765433222")));
    // File version/history/content ARE removed
    assertNull(fileContentDao.getFileContent(FileChecksum.parseFileChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef"), true));
    // TODO [low] Test file version and file history removal		
    // Chunks and multichunks are NOT removed!
    assertNotNull(chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef")));
    assertNotNull(multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("B1")));
    assertEquals(0, multiChunkDao.getMultiChunks(TestDatabaseUtil.createVectorClock("B1")).size());
    assertNotNull(multiChunkDao.getDirtyMultiChunkIds());
    assertEquals(0, multiChunkDao.getDirtyMultiChunkIds().size());
    // Tear down
    databaseConnection.close();
    TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
}
Also used : MultiChunkId(org.syncany.database.MultiChunkEntry.MultiChunkId) Config(org.syncany.config.Config) Connection(java.sql.Connection) DatabaseVersionSqlDao(org.syncany.database.dao.DatabaseVersionSqlDao) MultiChunkSqlDao(org.syncany.database.dao.MultiChunkSqlDao) ChunkSqlDao(org.syncany.database.dao.ChunkSqlDao) MultiChunkSqlDao(org.syncany.database.dao.MultiChunkSqlDao) FileVersionSqlDao(org.syncany.database.dao.FileVersionSqlDao) FileContentSqlDao(org.syncany.database.dao.FileContentSqlDao) MultiChunkEntry(org.syncany.database.MultiChunkEntry) FileHistorySqlDao(org.syncany.database.dao.FileHistorySqlDao) DatabaseVersion(org.syncany.database.DatabaseVersion) Test(org.junit.Test)

Example 5 with MultiChunkId

use of org.syncany.database.MultiChunkEntry.MultiChunkId in project syncany by syncany.

the class MultiChunkDaoTest method testGetMultiChunkIdsByFileChecksum.

@Test
public void testGetMultiChunkIdsByFileChecksum() throws Exception {
    // Setup
    Config testConfig = TestConfigUtil.createTestLocalConfig();
    Connection databaseConnection = testConfig.createDatabaseConnection();
    // Run
    TestSqlUtil.runSqlFromResource(databaseConnection, "test.insert.set3.sql");
    MultiChunkSqlDao multiChunkDao = new MultiChunkSqlDao(databaseConnection);
    List<MultiChunkId> multiChunkIds1 = multiChunkDao.getMultiChunkIds(FileChecksum.parseFileChecksum("254416e71ae50431fc6ced6751075b3366db7cc8"));
    List<MultiChunkId> multiChunkIds2 = multiChunkDao.getMultiChunkIds(FileChecksum.parseFileChecksum("7666fd3b860c9d7588d9ca1807eebdf8cfaa8be3"));
    List<MultiChunkId> multiChunkIdsDoesNotExist = multiChunkDao.getMultiChunkIds(FileChecksum.parseFileChecksum("beefbeefbeefbeefbeefbeefbeefbeefbeefbeef"));
    // Test
    // - Multi chunk for file 254416e71ae50431fc6ced6751075b3366db7cc8
    assertNotNull(multiChunkIds1);
    assertEquals(1, multiChunkIds1.size());
    MultiChunkId multiChunkId1 = multiChunkIds1.get(0);
    assertEquals("51aaca5c1280b1cf95cff8a3266a6bb44b482ad4", multiChunkId1.toString());
    // - Multi chunk for file a7405a0bada0035ed52a1a44a4d381b78dc59d19
    assertNotNull(multiChunkIds2);
    assertEquals(1, multiChunkIds2.size());
    MultiChunkId multiChunkId2 = multiChunkIds2.get(0);
    assertEquals("53dbeafe18eb2cd6dc519f8b861cf974fda8f26a", multiChunkId2.toString());
    // - Multi chunk for non existent file
    assertNotNull(multiChunkIdsDoesNotExist);
    assertEquals(0, multiChunkIdsDoesNotExist.size());
    // Tear down
    databaseConnection.close();
    TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
}
Also used : MultiChunkId(org.syncany.database.MultiChunkEntry.MultiChunkId) Config(org.syncany.config.Config) Connection(java.sql.Connection) MultiChunkSqlDao(org.syncany.database.dao.MultiChunkSqlDao) Test(org.junit.Test)

Aggregations

MultiChunkId (org.syncany.database.MultiChunkEntry.MultiChunkId)25 MultiChunkEntry (org.syncany.database.MultiChunkEntry)12 Test (org.junit.Test)10 ChunkChecksum (org.syncany.database.ChunkEntry.ChunkChecksum)10 Connection (java.sql.Connection)8 Config (org.syncany.config.Config)8 MultiChunkSqlDao (org.syncany.database.dao.MultiChunkSqlDao)8 File (java.io.File)6 DatabaseVersion (org.syncany.database.DatabaseVersion)6 FileContent (org.syncany.database.FileContent)6 ChunkEntry (org.syncany.database.ChunkEntry)5 FileOutputStream (java.io.FileOutputStream)4 FileVersion (org.syncany.database.FileVersion)4 FileHistoryId (org.syncany.database.PartialFileHistory.FileHistoryId)4 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 MultiChunk (org.syncany.chunk.MultiChunk)3 PartialFileHistory (org.syncany.database.PartialFileHistory)3 IOException (java.io.IOException)2