use of org.syncany.database.ChunkEntry in project syncany by syncany.
the class ChunkSqlDao method createChunkEntries.
protected Map<ChunkChecksum, ChunkEntry> createChunkEntries(ResultSet resultSet) throws SQLException {
Map<ChunkChecksum, ChunkEntry> chunks = new HashMap<ChunkChecksum, ChunkEntry>();
while (resultSet.next()) {
ChunkEntry chunkEntry = createChunkEntryFromRow(resultSet);
chunks.put(chunkEntry.getChecksum(), chunkEntry);
}
return chunks;
}
use of org.syncany.database.ChunkEntry in project syncany by syncany.
the class DatabaseVersionSqlDao method createDatabaseVersionFromRow.
protected DatabaseVersion createDatabaseVersionFromRow(ResultSet resultSet, boolean excludeChunkData, int fileHistoryMaxCount) throws SQLException {
DatabaseVersionHeader databaseVersionHeader = createDatabaseVersionHeaderFromRow(resultSet);
DatabaseVersion databaseVersion = new DatabaseVersion();
databaseVersion.setHeader(databaseVersionHeader);
// Add chunk/multichunk/filecontent data
if (!excludeChunkData) {
Map<ChunkChecksum, ChunkEntry> chunks = chunkDao.getChunks(databaseVersionHeader.getVectorClock());
Map<MultiChunkId, MultiChunkEntry> multiChunks = multiChunkDao.getMultiChunks(databaseVersionHeader.getVectorClock());
Map<FileChecksum, FileContent> fileContents = fileContentDao.getFileContents(databaseVersionHeader.getVectorClock());
for (ChunkEntry chunk : chunks.values()) {
databaseVersion.addChunk(chunk);
}
for (MultiChunkEntry multiChunk : multiChunks.values()) {
databaseVersion.addMultiChunk(multiChunk);
}
for (FileContent fileContent : fileContents.values()) {
databaseVersion.addFileContent(fileContent);
}
}
// Add file histories
Map<FileHistoryId, PartialFileHistory> fileHistories = fileHistoryDao.getFileHistoriesWithFileVersions(databaseVersionHeader.getVectorClock(), fileHistoryMaxCount);
for (PartialFileHistory fileHistory : fileHistories.values()) {
databaseVersion.addFileHistory(fileHistory);
}
return databaseVersion;
}
use of org.syncany.database.ChunkEntry in project syncany by syncany.
the class DatabaseXmlParseHandler method startElement.
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
elementPath += "/" + qName;
if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion")) {
databaseVersion = new DatabaseVersion();
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/header/time")) {
Date timeValue = new Date(Long.parseLong(attributes.getValue("value")));
databaseVersion.setTimestamp(timeValue);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/header/client")) {
String clientName = attributes.getValue("name");
databaseVersion.setClient(clientName);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/header/vectorClock")) {
vectorClock = new VectorClock();
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/header/vectorClock/client")) {
String clientName = attributes.getValue("name");
Long clientValue = Long.parseLong(attributes.getValue("value"));
vectorClock.setClock(clientName, clientValue);
} else if (readType == DatabaseReadType.FULL) {
if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/chunks/chunk")) {
String chunkChecksumStr = attributes.getValue("checksum");
ChunkChecksum chunkChecksum = ChunkChecksum.parseChunkChecksum(chunkChecksumStr);
int chunkSize = Integer.parseInt(attributes.getValue("size"));
ChunkEntry chunkEntry = new ChunkEntry(chunkChecksum, chunkSize);
databaseVersion.addChunk(chunkEntry);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/fileContents/fileContent")) {
String checksumStr = attributes.getValue("checksum");
long size = Long.parseLong(attributes.getValue("size"));
fileContent = new FileContent();
fileContent.setChecksum(FileChecksum.parseFileChecksum(checksumStr));
fileContent.setSize(size);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/fileContents/fileContent/chunkRefs/chunkRef")) {
String chunkChecksumStr = attributes.getValue("ref");
fileContent.addChunk(ChunkChecksum.parseChunkChecksum(chunkChecksumStr));
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/multiChunks/multiChunk")) {
String multChunkIdStr = attributes.getValue("id");
MultiChunkId multiChunkId = MultiChunkId.parseMultiChunkId(multChunkIdStr);
long size = Long.parseLong(attributes.getValue("size"));
if (multiChunkId == null) {
throw new SAXException("Cannot read ID from multichunk " + multChunkIdStr);
}
multiChunk = new MultiChunkEntry(multiChunkId, size);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/multiChunks/multiChunk/chunkRefs/chunkRef")) {
String chunkChecksumStr = attributes.getValue("ref");
multiChunk.addChunk(ChunkChecksum.parseChunkChecksum(chunkChecksumStr));
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/fileHistories/fileHistory")) {
String fileHistoryIdStr = attributes.getValue("id");
FileHistoryId fileId = FileHistoryId.parseFileId(fileHistoryIdStr);
fileHistory = new PartialFileHistory(fileId);
} else if (elementPath.equalsIgnoreCase("/database/databaseVersions/databaseVersion/fileHistories/fileHistory/fileVersions/fileVersion")) {
String fileVersionStr = attributes.getValue("version");
String path = attributes.getValue("path");
String pathEncoded = attributes.getValue("pathEncoded");
String sizeStr = attributes.getValue("size");
String typeStr = attributes.getValue("type");
String statusStr = attributes.getValue("status");
String lastModifiedStr = attributes.getValue("lastModified");
String updatedStr = attributes.getValue("updated");
String checksumStr = attributes.getValue("checksum");
String linkTarget = attributes.getValue("linkTarget");
String dosAttributes = attributes.getValue("dosattrs");
String posixPermissions = attributes.getValue("posixperms");
if (fileVersionStr == null || (path == null && pathEncoded == null) || typeStr == null || statusStr == null || sizeStr == null || lastModifiedStr == null) {
throw new SAXException("FileVersion: Attributes missing: version, path/pathEncoded, type, status, size and last modified are mandatory");
}
// Filter it if it was purged somewhere in the future, see #58
Long fileVersionNum = Long.parseLong(fileVersionStr);
// Go add it!
FileVersion fileVersion = new FileVersion();
fileVersion.setVersion(fileVersionNum);
if (path != null) {
fileVersion.setPath(path);
} else {
try {
fileVersion.setPath(new String(Base64.decodeBase64(pathEncoded), "UTF-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Invalid Base64 encoding for filename: " + pathEncoded);
}
}
fileVersion.setType(FileType.valueOf(typeStr));
fileVersion.setStatus(FileStatus.valueOf(statusStr));
fileVersion.setSize(Long.parseLong(sizeStr));
fileVersion.setLastModified(new Date(Long.parseLong(lastModifiedStr)));
if (updatedStr != null) {
fileVersion.setUpdated(new Date(Long.parseLong(updatedStr)));
}
if (checksumStr != null) {
fileVersion.setChecksum(FileChecksum.parseFileChecksum(checksumStr));
}
if (linkTarget != null) {
fileVersion.setLinkTarget(linkTarget);
}
if (dosAttributes != null) {
fileVersion.setDosAttributes(dosAttributes);
}
if (posixPermissions != null) {
fileVersion.setPosixPermissions(posixPermissions);
}
fileHistory.addFileVersion(fileVersion);
}
}
}
use of org.syncany.database.ChunkEntry in project syncany by syncany.
the class UpOperation method addDirtyData.
/**
* This methods iterates over all {@link DatabaseVersion}s that are dirty. Dirty means that they are not in the winning
* branch. All data which is contained in these dirty DatabaseVersions is added to the newDatabaseVersion, so that it
* is included in the new Up. Note that only metadata is reuploaded, the actual multichunks are still in the repository.
*
* @param newDatabaseVersion {@link DatabaseVersion} to which dirty data should be added.
*/
private void addDirtyData(DatabaseVersion newDatabaseVersion) {
Iterator<DatabaseVersion> dirtyDatabaseVersions = localDatabase.getDirtyDatabaseVersions();
if (!dirtyDatabaseVersions.hasNext()) {
logger.log(Level.INFO, "No DIRTY data found in database (no dirty databases); Nothing to do here.");
} else {
logger.log(Level.INFO, "Adding DIRTY data to new database version: ");
while (dirtyDatabaseVersions.hasNext()) {
DatabaseVersion dirtyDatabaseVersion = dirtyDatabaseVersions.next();
logger.log(Level.INFO, "- Adding chunks/multichunks/filecontents from database version " + dirtyDatabaseVersion.getHeader());
for (ChunkEntry chunkEntry : dirtyDatabaseVersion.getChunks()) {
newDatabaseVersion.addChunk(chunkEntry);
}
for (MultiChunkEntry multiChunkEntry : dirtyDatabaseVersion.getMultiChunks()) {
newDatabaseVersion.addMultiChunk(multiChunkEntry);
}
for (FileContent fileContent : dirtyDatabaseVersion.getFileContents()) {
newDatabaseVersion.addFileContent(fileContent);
}
}
}
}
use of org.syncany.database.ChunkEntry in project syncany by syncany.
the class DatabaseVersionDaoTest method testPersistDatabaseVersion.
@Test
public void testPersistDatabaseVersion() 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. Capture database version header (now)
DatabaseVersionHeader lastDatabaseVersionHeaderBefore = databaseVersionDao.getLastDatabaseVersionHeader();
// b. Add new database header (with one file history)
DatabaseVersion newDatabaseVersion = new DatabaseVersion();
DatabaseVersionHeader newDatabaseVersionHeader = new DatabaseVersionHeader();
newDatabaseVersionHeader.setClient("C");
newDatabaseVersionHeader.setDate(new Date(1489977288000L));
newDatabaseVersionHeader.setVectorClock(TestDatabaseUtil.createVectorClock("A5,C1"));
newDatabaseVersion.setHeader(newDatabaseVersionHeader);
PartialFileHistory newFileHistory = new PartialFileHistory(FileHistoryId.secureRandomFileId());
FileVersion newFileVersion = new FileVersion();
newFileVersion.setVersion(1L);
newFileVersion.setPath("newfile");
newFileVersion.setChecksum(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"));
newFileVersion.setLinkTarget(null);
newFileVersion.setPosixPermissions("rwxrwxrwx");
newFileVersion.setDosAttributes(null);
newFileVersion.setStatus(FileStatus.NEW);
newFileVersion.setLastModified(new Date());
newFileVersion.setUpdated(new Date());
newFileVersion.setSize(1L);
newFileVersion.setType(FileType.FILE);
newFileHistory.addFileVersion(newFileVersion);
newDatabaseVersion.addFileHistory(newFileHistory);
ChunkEntry newChunkEntry = new ChunkEntry(ChunkChecksum.parseChunkChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"), 1);
newDatabaseVersion.addChunk(newChunkEntry);
MultiChunkEntry newMultiChunkEntry = new MultiChunkEntry(MultiChunkId.parseMultiChunkId("1234567890987654321234567876543456555555"), 10);
newMultiChunkEntry.addChunk(newChunkEntry.getChecksum());
newDatabaseVersion.addMultiChunk(newMultiChunkEntry);
FileContent newFileContent = new FileContent();
newFileContent.setChecksum(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"));
newFileContent.setSize(1L);
newFileContent.addChunk(newChunkEntry.getChecksum());
newDatabaseVersion.addFileContent(newFileContent);
// c. Persist database version
databaseVersionDao.writeDatabaseVersion(newDatabaseVersion);
// d. Capture new last database version header
DatabaseVersionHeader lastDatabaseVersionHeaderAfter = databaseVersionDao.getLastDatabaseVersionHeader();
// Test
assertNotNull(lastDatabaseVersionHeaderBefore);
assertEquals("A/(A5)/T=1388935689000", lastDatabaseVersionHeaderBefore.toString());
assertNotNull(lastDatabaseVersionHeaderAfter);
assertEquals("C/(A5,C1)/T=1489977288000", lastDatabaseVersionHeaderAfter.toString());
assertEquals(newDatabaseVersionHeader.getVectorClock(), lastDatabaseVersionHeaderAfter.getVectorClock());
assertEquals(newChunkEntry, chunkDao.getChunk(ChunkChecksum.parseChunkChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f")));
assertEquals(newFileContent, fileContentDao.getFileContent(FileChecksum.parseFileChecksum("aaaaaaaaaaaaaaaaaaaaab2b263ffa4cc48e282f"), true));
Map<MultiChunkId, MultiChunkEntry> multiChunkIds = multiChunkDao.getMultiChunks(newDatabaseVersionHeader.getVectorClock());
assertNotNull(multiChunkIds);
assertEquals(1, multiChunkIds.size());
MultiChunkEntry actualNewMultiChunkEntry = multiChunkIds.get(MultiChunkId.parseMultiChunkId("1234567890987654321234567876543456555555"));
assertNotNull(actualNewMultiChunkEntry);
assertEquals(newMultiChunkEntry.getId(), actualNewMultiChunkEntry.getId());
// Tear down
databaseConnection.close();
TestConfigUtil.deleteTestLocalConfigAndData(testConfig);
}
Aggregations