dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
pureimagecache.cpp
Go to the documentation of this file.
1 
13 /*
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, see <http://www.gnu.org/licenses/>
26 */
27 #include "pureimagecache.h"
28 #include <QDateTime>
29 #include <QSettings>
30 //#define DEBUG_PUREIMAGECACHE
31 namespace core {
32  qlonglong PureImageCache::ConnCounter=0;
33 
35  {
36 
37  }
38 
39  void PureImageCache::setGtileCache(const QString &value)
40  {
41  lock.lockForWrite();
42  gtilecache=value;
43  QDir d;
44  if(!d.exists(gtilecache))
45  {
46  d.mkdir(gtilecache);
47 #ifdef DEBUG_PUREIMAGECACHE
48  qDebug()<<"Create Cache directory";
49 #endif //DEBUG_PUREIMAGECACHE
50  }
51  {
52  QString db=gtilecache+"Data.qmdb";
53  if(!QFileInfo(db).exists())
54  {
55 #ifdef DEBUG_PUREIMAGECACHE
56  qDebug()<<"Try to create EmptyDB";
57 #endif //DEBUG_PUREIMAGECACHE
58  CreateEmptyDB(db);
59  }
60  }
61  lock.unlock();
62  }
64  {
65  return gtilecache;
66  }
67 
68 
69  bool PureImageCache::CreateEmptyDB(const QString &file)
70  {
71  {
72 #ifdef DEBUG_PUREIMAGECACHE
73  qDebug()<<"Create database at!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:"<<file;
74 #endif //DEBUG_PUREIMAGECACHE
75  QFileInfo File(file);
76  QDir dir=File.absoluteDir();
77  QString path=dir.absolutePath();
78  QString filename=File.fileName();
79  if(File.exists())
80  QFile(filename).remove();
81  if(!dir.exists())
82  {
83 #ifdef DEBUG_PUREIMAGECACHE
84  qDebug()<<"CreateEmptyDB: Cache path doesn't exist, try to create";
85 #endif //DEBUG_PUREIMAGECACHE
86  if(!dir.mkpath(path))
87  {
88 #ifdef DEBUG_PUREIMAGECACHE
89  qDebug()<<"CreateEmptyDB: Could not create path";
90 #endif //DEBUG_PUREIMAGECACHE
91  return false;
92  }
93  }
94  QSqlDatabase db;
95 
96  db = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("CreateConn"));
97  db.setDatabaseName(file);
98  if (!db.open())
99  {
100 #ifdef DEBUG_PUREIMAGECACHE
101  qDebug()<<"CreateEmptyDB: Unable to create database";
102 #endif //DEBUG_PUREIMAGECACHE
103 
104  return false;
105  }
106  QSqlQuery query(db);
107  query.exec("CREATE TABLE IF NOT EXISTS Tiles (id INTEGER NOT NULL PRIMARY KEY, X INTEGER NOT NULL, Y INTEGER NOT NULL, Zoom INTEGER NOT NULL, Type INTEGER NOT NULL,Date TEXT)");
108  if(query.numRowsAffected()==-1)
109  {
110 #ifdef DEBUG_PUREIMAGECACHE
111  qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
112 #endif //DEBUG_PUREIMAGECACHE
113  db.close();
114  return false;
115  }
116  query.exec("CREATE TABLE IF NOT EXISTS TilesData (id INTEGER NOT NULL PRIMARY KEY CONSTRAINT fk_Tiles_id REFERENCES Tiles(id) ON DELETE CASCADE, Tile BLOB NULL)");
117  if(query.numRowsAffected()==-1)
118  {
119 #ifdef DEBUG_PUREIMAGECACHE
120  qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
121 #endif //DEBUG_PUREIMAGECACHE
122  db.close();
123  return false;
124  }
125  query.exec(
126  "CREATE TRIGGER fki_TilesData_id_Tiles_id "
127  "BEFORE INSERT ON [TilesData] "
128  "FOR EACH ROW BEGIN "
129  "SELECT RAISE(ROLLBACK, 'insert on table TilesData violates foreign key constraint fki_TilesData_id_Tiles_id') "
130  "WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; "
131  "END");
132  if(query.numRowsAffected()==-1)
133  {
134 #ifdef DEBUG_PUREIMAGECACHE
135  qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
136 #endif //DEBUG_PUREIMAGECACHE
137  db.close();
138  return false;
139  }
140  query.exec(
141  "CREATE TRIGGER fku_TilesData_id_Tiles_id "
142  "BEFORE UPDATE ON [TilesData] "
143  "FOR EACH ROW BEGIN "
144  "SELECT RAISE(ROLLBACK, 'update on table TilesData violates foreign key constraint fku_TilesData_id_Tiles_id') "
145  "WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; "
146  "END");
147  if(query.numRowsAffected()==-1)
148  {
149 #ifdef DEBUG_PUREIMAGECACHE
150  qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
151 #endif //DEBUG_PUREIMAGECACHE
152  db.close();
153  return false;
154  }
155  query.exec(
156  "CREATE TRIGGER fkdc_TilesData_id_Tiles_id "
157  "BEFORE DELETE ON Tiles "
158  "FOR EACH ROW BEGIN "
159  "DELETE FROM TilesData WHERE TilesData.id = OLD.id; "
160  "END");
161  if(query.numRowsAffected()==-1)
162  {
163 #ifdef DEBUG_PUREIMAGECACHE
164  qDebug()<<"CreateEmptyDB: "<<query.lastError().driverText();
165 #endif //DEBUG_PUREIMAGECACHE
166  db.close();
167  return false;
168  }
169  db.close();
170  }
171  QSqlDatabase::removeDatabase(QLatin1String("CreateConn"));
172  return true;
173  }
174  bool PureImageCache::PutImageToCache(const QByteArray &tile, const MapType::Types &type,const Point &pos,const int &zoom)
175  {
176  if(gtilecache.isEmpty()|gtilecache.isNull())
177  return false;
178  lock.lockForRead();
179 #ifdef DEBUG_PUREIMAGECACHE
180  qDebug()<<"PutImageToCache Start:";//<<pos;
181 #endif //DEBUG_PUREIMAGECACHE
182  Mcounter.lock();
183  qlonglong id=++ConnCounter;
184  Mcounter.unlock();
185  {
186  QSqlDatabase cn;
187  cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
188  QString db=gtilecache+"Data.qmdb";
189  cn.setDatabaseName(db);
190  cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
191  if(cn.open())
192  {
193  {
194  QSqlQuery query(cn);
195  query.prepare("INSERT INTO Tiles(X, Y, Zoom, Type,Date) VALUES(?, ?, ?, ?,?)");
196  query.addBindValue(pos.X());
197  query.addBindValue(pos.Y());
198  query.addBindValue(zoom);
199 
200  query.addBindValue((int)type);
201  query.addBindValue(QDateTime::currentDateTime().toString());
202  query.exec();
203  }
204  {
205  QSqlQuery query(cn);
206  query.prepare("INSERT INTO TilesData(id, Tile) VALUES((SELECT last_insert_rowid()), ?)");
207  query.addBindValue(tile);
208  query.exec();
209  }
210  cn.close();
211  }
212  }
213  QSqlDatabase::removeDatabase(QString::number(id));
214  lock.unlock();
215  return true;
216  }
217  QByteArray PureImageCache::GetImageFromCache(MapType::Types type, Point pos, int zoom)
218  {
219  lock.lockForRead();
220  QByteArray ar;
221  if(gtilecache.isEmpty()|gtilecache.isNull())
222  return ar;
223  QString dir=gtilecache;
224  Mcounter.lock();
225  qlonglong id=++ConnCounter;
226  Mcounter.unlock();
227 #ifdef DEBUG_PUREIMAGECACHE
228  qDebug()<<"Cache dir="<<dir<<" Try to GET:"<<pos.X()+","+pos.Y();
229 #endif //DEBUG_PUREIMAGECACHE
230 
231  {
232  QString db=dir+"Data.qmdb";
233  {
234  QSqlDatabase cn;
235 
236  cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
237 
238  cn.setDatabaseName(db);
239  cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
240  if(cn.open())
241  {
242  {
243  QSqlQuery query(cn);
244  query.exec(QString("SELECT Tile FROM TilesData WHERE id = (SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4)").arg(pos.X()).arg(pos.Y()).arg(zoom).arg((int) type));
245  query.next();
246  if(query.isValid())
247  {
248  ar=query.value(0).toByteArray();
249  }
250  }
251  cn.close();
252  }
253  }
254  }
255  QSqlDatabase::removeDatabase(QString::number(id));
256  lock.unlock();
257  return ar;
258  }
259  void PureImageCache::deleteOlderTiles(int const& days)
260  {
261  if(gtilecache.isEmpty()|gtilecache.isNull())
262  return;
263  QList<long> add;
264  bool ret=true;
265  QString dir=gtilecache;
266  {
267  QString db=dir+"Data.qmdb";
268  ret=QFileInfo(db).exists();
269  if(ret)
270  {
271  QSqlDatabase cn;
272  Mcounter.lock();
273  qlonglong id=++ConnCounter;
274  Mcounter.unlock();
275  cn = QSqlDatabase::addDatabase("QSQLITE",QString::number(id));
276  cn.setDatabaseName(db);
277  cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
278  if(cn.open())
279  {
280  {
281  QSqlQuery query(cn);
282  query.exec(QString("SELECT id, X, Y, Zoom, Type, Date FROM Tiles"));
283  while(query.next())
284  {
285  if(QDateTime::fromString(query.value(5).toString()).daysTo(QDateTime::currentDateTime())>days)
286  add.append(query.value(0).toLongLong());
287  }
288  foreach(long i,add)
289  {
290  query.exec(QString("DELETE FROM Tiles WHERE id = %1;").arg(i));
291  }
292  }
293 
294  cn.close();
295  }
296  QSqlDatabase::removeDatabase(QString::number(id));
297  }
298  }
299  }
300  // PureImageCache::ExportMapDataToDB("C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data.qmdb","C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data2.qmdb");
301  bool PureImageCache::ExportMapDataToDB(QString sourceFile, QString destFile)
302  {
303  bool ret=true;
304  QList<long> add;
305  if(!QFileInfo(destFile).exists())
306  {
307 #ifdef DEBUG_PUREIMAGECACHE
308  qDebug()<<"Try to create EmptyDB";
309 #endif //DEBUG_PUREIMAGECACHE
310  ret=CreateEmptyDB(destFile);
311  }
312  if(!ret) return false;
313  QSqlDatabase ca = QSqlDatabase::addDatabase("QSQLITE","ca");
314  ca.setDatabaseName(sourceFile);
315 
316  if(ca.open())
317  {
318  QSqlDatabase cb = QSqlDatabase::addDatabase("QSQLITE","cb");
319  cb.setDatabaseName(destFile);
320  if(cb.open())
321  {
322  QSqlQuery queryb(cb);
323  queryb.exec(QString("ATTACH DATABASE \"%1\" AS Source").arg(sourceFile));
324  QSqlQuery querya(ca);
325  querya.exec("SELECT id, X, Y, Zoom, Type, Date FROM Tiles");
326  while(querya.next())
327  {
328  long id=querya.value(0).toLongLong();
329  queryb.exec(QString("SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4;").arg(querya.value(1).toLongLong()).arg(querya.value(2).toLongLong()).arg(querya.value(3).toLongLong()).arg(querya.value(4).toLongLong()));
330  if(!queryb.next())
331  {
332  add.append(id);
333  }
334 
335  }
336  long f;
337  foreach(f,add)
338  {
339  queryb.exec(QString("INSERT INTO Tiles(X, Y, Zoom, Type, Date) SELECT X, Y, Zoom, Type, Date FROM Source.Tiles WHERE id=%1").arg(f));
340  queryb.exec(QString("INSERT INTO TilesData(id, Tile) Values((SELECT last_insert_rowid()), (SELECT Tile FROM Source.TilesData WHERE id=%1))").arg(f));
341  }
342  add.clear();
343  ca.close();
344  cb.close();
345 
346  }
347  else return false;
348  }
349  else return false;
350  QSqlDatabase::removeDatabase("ca");
351  QSqlDatabase::removeDatabase("cb");
352  return true;
353 
354  }
355 
356 }
qint64 X() const
Definition: point.h:51
QByteArray GetImageFromCache(MapType::Types type, core::Point pos, int zoom)
static bool CreateEmptyDB(const QString &file)
for i
Definition: OPPlots.m:140
T * query(Aggregate *obj)
Definition: aggregate.h:85
Parse log file
void setGtileCache(const QString &value)
void deleteOlderTiles(int const &days)
Definition: icore.h:39
static bool ExportMapDataToDB(QString sourceFile, QString destFile)
bool PutImageToCache(const QByteArray &tile, const MapType::Types &type, const core::Point &pos, const int &zoom)
qint64 Y() const
Definition: point.h:52