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;
}
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);
}
}
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;
}
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);
}
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);
}
Aggregations