use of org.syncany.database.ChunkEntry.ChunkChecksum 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.ChunkEntry.ChunkChecksum 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.ChunkEntry.ChunkChecksum in project syncany by syncany.
the class DatabaseXmlWriter method writeFileContents.
private void writeFileContents(IndentXmlStreamWriter xmlOut, Collection<FileContent> fileContents) throws XMLStreamException {
if (fileContents.size() > 0) {
xmlOut.writeStartElement("fileContents");
for (FileContent fileContent : fileContents) {
xmlOut.writeStartElement("fileContent");
xmlOut.writeAttribute("checksum", fileContent.getChecksum().toString());
xmlOut.writeAttribute("size", fileContent.getSize());
xmlOut.writeStartElement("chunkRefs");
Collection<ChunkChecksum> fileContentChunkChunks = fileContent.getChunks();
for (ChunkChecksum chunkChecksum : fileContentChunkChunks) {
xmlOut.writeEmptyElement("chunkRef");
xmlOut.writeAttribute("ref", chunkChecksum.toString());
}
// </chunkRefs>
xmlOut.writeEndElement();
// </fileContent>
xmlOut.writeEndElement();
}
// </fileContents>
xmlOut.writeEndElement();
}
}
use of org.syncany.database.ChunkEntry.ChunkChecksum in project syncany by syncany.
the class FileContentSqlDao method writeFileContentChunkRefs.
private void writeFileContentChunkRefs(Connection connection, FileContent fileContent) throws SQLException {
PreparedStatement preparedStatement = getStatement(connection, "filecontent.insert.all.writeFileContentChunkRefs.sql");
int order = 0;
for (ChunkChecksum chunkChecksum : fileContent.getChunks()) {
preparedStatement.setString(1, fileContent.getChecksum().toString());
preparedStatement.setString(2, chunkChecksum.toString());
preparedStatement.setInt(3, order);
preparedStatement.addBatch();
order++;
}
preparedStatement.executeBatch();
preparedStatement.close();
}
use of org.syncany.database.ChunkEntry.ChunkChecksum in project syncany by syncany.
the class FileContentSqlDao method createFileContents.
private Map<FileChecksum, FileContent> createFileContents(ResultSet resultSet) throws SQLException {
Map<FileChecksum, FileContent> fileContents = new HashMap<FileChecksum, FileContent>();
FileChecksum currentFileChecksum = null;
while (resultSet.next()) {
FileChecksum fileChecksum = FileChecksum.parseFileChecksum(resultSet.getString("checksum"));
FileContent fileContent = null;
if (currentFileChecksum != null && currentFileChecksum.equals(fileChecksum)) {
fileContent = fileContents.get(fileChecksum);
} else {
fileContent = new FileContent();
fileContent.setChecksum(fileChecksum);
fileContent.setSize(resultSet.getLong("size"));
}
ChunkChecksum chunkChecksum = ChunkChecksum.parseChunkChecksum(resultSet.getString("chunk_checksum"));
fileContent.addChunk(chunkChecksum);
fileContents.put(fileChecksum, fileContent);
currentFileChecksum = fileChecksum;
}
return fileContents;
}
Aggregations