Commit 1db0adaf authored by Gus Grubba's avatar Gus Grubba

Fixed an issue when importing a tile set that already exists would cause an...

Fixed an issue when importing a tile set that already exists would cause an error. When an imported set has a same name, it is renamed so the name is unique. The original logic had an error and was allowing the "new" set to be added with the same name, which would cause an error. In addition, if a new tile set brings no new unique tiles, it is now ignored.
Fixed an issue where the progress was based on the total number of incoming tiles but this total can change if a given tile already exists in the database (it is not added).
parent 3e055542
...@@ -607,19 +607,26 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask) ...@@ -607,19 +607,26 @@ QGCCacheWorker::_deleteTileSet(QGCMapTask* mtask)
return; return;
} }
QGCDeleteTileSetTask* task = static_cast<QGCDeleteTileSetTask*>(mtask); QGCDeleteTileSetTask* task = static_cast<QGCDeleteTileSetTask*>(mtask);
_deleteTileSet(task->setID());
task->setTileSetDeleted();
}
//-----------------------------------------------------------------------------
void
QGCCacheWorker::_deleteTileSet(qulonglong id)
{
QSqlQuery query(*_db); QSqlQuery query(*_db);
QString s; QString s;
//-- Only delete tiles unique to this set //-- Only delete tiles unique to this set
s = QString("DELETE FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(task->setID()); s = QString("DELETE FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(id);
query.exec(s); query.exec(s);
s = QString("DELETE FROM TilesDownload WHERE setID = %1").arg(task->setID()); s = QString("DELETE FROM TilesDownload WHERE setID = %1").arg(id);
query.exec(s); query.exec(s);
s = QString("DELETE FROM TileSets WHERE setID = %1").arg(task->setID()); s = QString("DELETE FROM TileSets WHERE setID = %1").arg(id);
query.exec(s); query.exec(s);
s = QString("DELETE FROM SetTiles WHERE setID = %1").arg(task->setID()); s = QString("DELETE FROM SetTiles WHERE setID = %1").arg(id);
query.exec(s); query.exec(s);
_updateTotals(); _updateTotals();
task->setTileSetDeleted();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -700,118 +707,146 @@ QGCCacheWorker::_importSets(QGCMapTask* mtask) ...@@ -700,118 +707,146 @@ QGCCacheWorker::_importSets(QGCMapTask* mtask)
//-- Prepare progress report //-- Prepare progress report
quint64 tileCount = 0; quint64 tileCount = 0;
quint64 currentCount = 0; quint64 currentCount = 0;
int lastProgress = -1;
QString s; QString s;
s = QString("SELECT COUNT(tileID) FROM Tiles"); s = QString("SELECT COUNT(tileID) FROM Tiles");
if(query.exec(s)) { if(query.exec(s)) {
if(query.next()) { if(query.next()) {
//-- Total number of tiles in imported database
tileCount = query.value(0).toULongLong(); tileCount = query.value(0).toULongLong();
} }
} }
if(!tileCount) { if(tileCount) {
qWarning() << "No tiles found in imported database"; //-- Iterate Tile Sets
tileCount = 1; //-- Let it run through s = QString("SELECT * FROM TileSets ORDER BY defaultSet DESC, name ASC");
} if(query.exec(s)) {
//-- Iterate Tile Sets while(query.next()) {
s = QString("SELECT * FROM TileSets ORDER BY defaultSet DESC, name ASC"); QString name = query.value("name").toString();
if(query.exec(s)) { quint64 setID = query.value("setID").toULongLong();
while(query.next()) { QString mapType = query.value("typeStr").toString();
QString name = query.value("name").toString(); double topleftLat = query.value("topleftLat").toDouble();
quint64 setID = query.value("setID").toULongLong(); double topleftLon = query.value("topleftLon").toDouble();
QString mapType = query.value("typeStr").toString(); double bottomRightLat = query.value("bottomRightLat").toDouble();
double topleftLat = query.value("topleftLat").toDouble(); double bottomRightLon = query.value("bottomRightLon").toDouble();
double topleftLon = query.value("topleftLon").toDouble(); int minZoom = query.value("minZoom").toInt();
double bottomRightLat = query.value("bottomRightLat").toDouble(); int maxZoom = query.value("maxZoom").toInt();
double bottomRightLon = query.value("bottomRightLon").toDouble(); int type = query.value("type").toInt();
int minZoom = query.value("minZoom").toInt(); quint32 numTiles = query.value("numTiles").toUInt();
int maxZoom = query.value("maxZoom").toInt(); int defaultSet = query.value("defaultSet").toInt();
int type = query.value("type").toInt(); quint64 insertSetID = _getDefaultTileSet();
quint32 numTiles = query.value("numTiles").toUInt(); //-- If not default set, create new one
int defaultSet = query.value("defaultSet").toInt(); if(!defaultSet) {
quint64 insertSetID = _getDefaultTileSet(); //-- Check if we have this tile set already
//-- If not default set, create new one if(_findTileSetID(name, insertSetID)) {
if(!defaultSet) { int testCount = 0;
//-- Check if we have this tile set already //-- Set with this name already exists. Make name unique.
int testCount = 0; while (true) {
while (true) { QString testName;
QString testName; testName.sprintf("%s %02d", name.toLatin1().data(), ++testCount);
testName.sprintf("%s %03d", name.toLatin1().data(), ++testCount); if(!_findTileSetID(testName, insertSetID) || testCount > 99) {
if(!_findTileSetID(testName, insertSetID) || testCount > 99) { name = testName;
if(testCount > 1) { break;
name = testName; }
} }
break;
} }
} //-- Create new set
//-- Create new set QSqlQuery cQuery(*_db);
QSqlQuery cQuery(*_db); cQuery.prepare("INSERT INTO TileSets("
cQuery.prepare("INSERT INTO TileSets(" "name, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, defaultSet, date"
"name, typeStr, topleftLat, topleftLon, bottomRightLat, bottomRightLon, minZoom, maxZoom, type, numTiles, defaultSet, date" ") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); cQuery.addBindValue(name);
cQuery.addBindValue(name); cQuery.addBindValue(mapType);
cQuery.addBindValue(mapType); cQuery.addBindValue(topleftLat);
cQuery.addBindValue(topleftLat); cQuery.addBindValue(topleftLon);
cQuery.addBindValue(topleftLon); cQuery.addBindValue(bottomRightLat);
cQuery.addBindValue(bottomRightLat); cQuery.addBindValue(bottomRightLon);
cQuery.addBindValue(bottomRightLon); cQuery.addBindValue(minZoom);
cQuery.addBindValue(minZoom); cQuery.addBindValue(maxZoom);
cQuery.addBindValue(maxZoom);
cQuery.addBindValue(type);
cQuery.addBindValue(numTiles);
cQuery.addBindValue(defaultSet);
cQuery.addBindValue(QDateTime::currentDateTime().toTime_t());
if(!cQuery.exec()) {
task->setError("Error adding imported tile set to database");
break;
} else {
//-- Get just created (auto-incremented) setID
insertSetID = cQuery.lastInsertId().toULongLong();
}
}
//-- Find set tiles
QSqlQuery cQuery(*_db);
QSqlQuery subQuery(*dbImport);
QString sb = QString("SELECT * FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(setID);
if(subQuery.exec(sb)) {
_db->transaction();
while(subQuery.next()) {
QString hash = subQuery.value("hash").toString();
QString format = subQuery.value("format").toString();
QByteArray img = subQuery.value("tile").toByteArray();
int type = subQuery.value("type").toInt();
//-- Save tile
cQuery.prepare("INSERT INTO Tiles(hash, format, tile, size, type, date) VALUES(?, ?, ?, ?, ?, ?)");
cQuery.addBindValue(hash);
cQuery.addBindValue(format);
cQuery.addBindValue(img);
cQuery.addBindValue(img.size());
cQuery.addBindValue(type); cQuery.addBindValue(type);
cQuery.addBindValue(numTiles);
cQuery.addBindValue(defaultSet);
cQuery.addBindValue(QDateTime::currentDateTime().toTime_t()); cQuery.addBindValue(QDateTime::currentDateTime().toTime_t());
if(cQuery.exec()) { if(!cQuery.exec()) {
quint64 importTileID = cQuery.lastInsertId().toULongLong(); task->setError("Error adding imported tile set to database");
QString s = QString("INSERT INTO SetTiles(tileID, setID) VALUES(%1, %2)").arg(importTileID).arg(insertSetID); break;
cQuery.prepare(s); } else {
cQuery.exec(); //-- Get just created (auto-incremented) setID
currentCount++; insertSetID = cQuery.lastInsertId().toULongLong();
task->setProgress((int)((double)currentCount / (double)tileCount * 100.0));
} }
} }
_db->commit(); //-- Find set tiles
//-- Update tile count QSqlQuery cQuery(*_db);
s = QString("SELECT COUNT(size) FROM Tiles A INNER JOIN SetTiles B on A.tileID = B.tileID WHERE B.setID = %1").arg(insertSetID); QSqlQuery subQuery(*dbImport);
if(cQuery.exec(s)) { QString sb = QString("SELECT * FROM Tiles WHERE tileID IN (SELECT A.tileID FROM SetTiles A JOIN SetTiles B ON A.tileID = B.tileID WHERE B.setID = %1 GROUP BY A.tileID HAVING COUNT(A.tileID) = 1)").arg(setID);
if(cQuery.next()) { if(subQuery.exec(sb)) {
quint64 count = cQuery.value(0).toULongLong(); quint64 tilesFound = 0;
s = QString("UPDATE TileSets SET numTiles = %1 WHERE setID = %2").arg(count).arg(insertSetID); quint64 tilesSaved = 0;
cQuery.exec(s); _db->transaction();
while(subQuery.next()) {
tilesFound++;
QString hash = subQuery.value("hash").toString();
QString format = subQuery.value("format").toString();
QByteArray img = subQuery.value("tile").toByteArray();
int type = subQuery.value("type").toInt();
//-- Save tile
cQuery.prepare("INSERT INTO Tiles(hash, format, tile, size, type, date) VALUES(?, ?, ?, ?, ?, ?)");
cQuery.addBindValue(hash);
cQuery.addBindValue(format);
cQuery.addBindValue(img);
cQuery.addBindValue(img.size());
cQuery.addBindValue(type);
cQuery.addBindValue(QDateTime::currentDateTime().toTime_t());
if(cQuery.exec()) {
tilesSaved++;
quint64 importTileID = cQuery.lastInsertId().toULongLong();
QString s = QString("INSERT INTO SetTiles(tileID, setID) VALUES(%1, %2)").arg(importTileID).arg(insertSetID);
cQuery.prepare(s);
cQuery.exec();
currentCount++;
if(tileCount) {
int progress = (int)((double)currentCount / (double)tileCount * 100.0);
//-- Avoid calling this if (int) progress hasn't changed.
if(lastProgress != progress) {
lastProgress = progress;
task->setProgress(progress);
}
}
}
}
_db->commit();
if(tilesSaved) {
//-- Update tile count (if any added)
s = QString("SELECT COUNT(size) FROM Tiles A INNER JOIN SetTiles B on A.tileID = B.tileID WHERE B.setID = %1").arg(insertSetID);
if(cQuery.exec(s)) {
if(cQuery.next()) {
quint64 count = cQuery.value(0).toULongLong();
s = QString("UPDATE TileSets SET numTiles = %1 WHERE setID = %2").arg(count).arg(insertSetID);
cQuery.exec(s);
}
}
}
qint64 uniqueTiles = tilesFound - tilesSaved;
if((quint64)uniqueTiles < tileCount) {
tileCount -= uniqueTiles;
} else {
tileCount = 0;
}
//-- If there was nothing new in this set, remove it.
if(!tilesSaved && !defaultSet) {
qCDebug(QGCTileCacheLog) << "No unique tiles in" << name << "Removing it.";
_deleteTileSet(insertSetID);
} }
} }
} }
} else {
task->setError("No tile set in database");
} }
} else {
task->setError("No tile set in database");
} }
delete dbImport; delete dbImport;
QSqlDatabase::removeDatabase(kExportSession); QSqlDatabase::removeDatabase(kExportSession);
if(!tileCount) {
task->setError("No unique tiles in imported database");
}
} else { } else {
task->setError("Error opening import database"); task->setError("Error opening import database");
} }
......
...@@ -76,6 +76,7 @@ private: ...@@ -76,6 +76,7 @@ private:
bool _createDB (QSqlDatabase *db, bool createDefault = true); bool _createDB (QSqlDatabase *db, bool createDefault = true);
quint64 _getDefaultTileSet (); quint64 _getDefaultTileSet ();
void _updateTotals (); void _updateTotals ();
void _deleteTileSet (qulonglong id);
signals: signals:
void updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize); void updateTotals (quint32 totaltiles, quint64 totalsize, quint32 defaulttiles, quint64 defaultsize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment