00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "datenbank.h"
00025 #include <iostream>
00026 #include <QSqlIndex>
00027 #include <QSqlQuery>
00028 #include <QVariant>
00029 #include <QSqlError>
00030
00031 const QString CONNECTION_NAME = "imageTagger_SQLITE_database_connection";
00032
00037 Datenbank::Datenbank(const QString &db_path) {
00038 m_db = QSqlDatabase::addDatabase("QSQLITE", CONNECTION_NAME);
00039 m_db.setHostName("localhost");
00040 m_db.setDatabaseName(db_path+"/imageTagger.db");
00041 if(!m_db.open()) {
00042 std::cerr << "Kann Datenbank nicht öffnen" << std::endl;
00043 }
00044 if(m_db.primaryIndex("bild").isEmpty()) {
00045 createDatabase();
00046 }
00047 }
00048
00049 Datenbank::~Datenbank() {
00050 m_db.close();
00051 }
00052
00056 void Datenbank::createDatabase() {
00057 QString query;
00058 query = "CREATE TABLE bild ("
00059 "bildid INTEGER PRIMARY KEY,"
00060 "name TEXT UNIQUE ON CONFLICT IGNORE)";
00061 QSqlQuery(query, m_db).exec();
00062 query = "CREATE TABLE tags ("
00063 "bildid INTEGER NOT NULL,"
00064 "tag TEXT NOT NULL)";
00065 QSqlQuery(query, m_db).exec();
00066 query = "CREATE INDEX idxBildName "
00067 "ON bild (name)";
00068 QSqlQuery(query, m_db).exec();
00069 query = "CREATE INDEX idxTags "
00070 "ON tags (tag)";
00071 QSqlQuery(query, m_db).exec();
00072 }
00073
00079 QStringList Datenbank::getTags(const QString &bild) const {
00080 QStringList ret;
00081 QSqlQuery qry(m_db);
00082
00083 qry.prepare("SELECT tags.tag "
00084 "FROM tags,bild "
00085 "WHERE tags.bildid=bild.bildid "
00086 "AND bild.name=?");
00087 qry.bindValue(0, bild);
00088 if(!qry.exec())
00089 std::cerr << "Datenbankfehler: \n"
00090 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00091 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00092 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00093 while(qry.next()) {
00094 ret.append(qry.value(0).toString());
00095 }
00096 return ret;
00097 }
00098
00108 void Datenbank::writeTags(const QString &bild, const QStringList &taglist) const {
00109 QSqlQuery qry(m_db);
00110
00111 qry.prepare("INSERT INTO bild "
00112 "(name) "
00113 "VALUES (?)");
00114 qry.bindValue(0, bild);
00115 if(!qry.exec())
00116 std::cerr << "Datenbankfehler: \n"
00117 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00118 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00119 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00120
00121 qry.prepare("SELECT bild.bildid "
00122 "FROM bild "
00123 "WHERE bild.name=?");
00124 qry.bindValue(0, bild);
00125 if(!qry.exec())
00126 std::cerr << "Datenbankfehler: \n"
00127 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00128 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00129 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00130 qry.first();
00131 int uid = qry.value(0).toInt();
00132
00133 qry.prepare("DELETE FROM tags "
00134 "WHERE tags.bildid=?");
00135 qry.bindValue(0, uid);
00136 if(!qry.exec())
00137 std::cerr << "Datenbankfehler: \n"
00138 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00139 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00140 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00141
00142 QStringList::const_iterator it;
00143 for(it = taglist.begin();
00144 taglist.end() != it;
00145 it++) {
00146 qry.prepare("INSERT INTO tags "
00147 "(bildid, tag) "
00148 "VALUES (?, ?)");
00149 qry.bindValue(0, uid);
00150 qry.bindValue(1, *it);
00151 if(!qry.exec())
00152 std::cerr << "Datenbankfehler: \n"
00153 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00154 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00155 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00156 }
00157 }
00158
00165 QStringList Datenbank::findByTag(const QString &tag) const {
00166 QStringList ret;
00167 QSqlQuery qry(m_db);
00168
00169 qry.prepare("SELECT bild.name "
00170 "FROM tags,bild "
00171 "WHERE tags.bildid=bild.bildid "
00172 "AND tags.tag=?");
00173 qry.bindValue(0, tag);
00174 if(!qry.exec())
00175 std::cerr << "Datenbankfehler: \n"
00176 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00177 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00178 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00179 while(qry.next()) {
00180 ret.append(qry.value(0).toString());
00181 }
00182 return ret;
00183 }
00184
00192 QStringList Datenbank::findByTagList(const QStringList &mustHave, const QStringList& notHave) const {
00193 QStringList ret;
00194 QSqlQuery qry(m_db);
00195 int i;
00196
00197 if(0 == mustHave.size() && 0 == notHave.size())
00198 return getAllImages();
00199
00200 QString queryString = "SELECT bild.name FROM bild",
00201 tempString = "";
00202 for(i=0; i<mustHave.size(); i++) {
00203 queryString += ",tags AS T" + QString::number(i);
00204 if(0 != i)
00205 tempString += " AND";
00206 tempString += " T" + QString::number(i) + ".tag=? AND T" +
00207 QString::number(i) + ".bildid=bild.bildid";
00208 }
00209
00210 queryString += " WHERE" + tempString;
00211
00212 if(0 != notHave.size()) {
00213 if(0 != mustHave.size()) {
00214 queryString += " AND";
00215 }
00216 queryString += " bild.bildid NOT IN"
00217 " ( SELECT DISTINCT bildid"
00218 " FROM tags WHERE"
00219 " tag IN"
00220 " ( ?";
00221
00222
00223
00224 for(i=1; i<notHave.size(); i++) {
00225 queryString += ",?";
00226 }
00227 queryString += " )"
00228 ")";
00229 }
00230 qry.prepare(queryString);
00231 int ct;
00232 for(i=0, ct=0; i<mustHave.size(); i++, ct++) {
00233 qry.bindValue(ct, mustHave[ct]);
00234
00235 }
00236 for(i=0; i<notHave.size(); i++, ct++) {
00237 qry.bindValue(ct, notHave[i]);
00238
00239 }
00240 if(!qry.exec())
00241 std::cerr << "Datenbankfehler: \n"
00242 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00243 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00244 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00245 while(qry.next()) {
00246 ret.append(qry.value(0).toString());
00247 }
00248 return ret;
00249 }
00250
00256 QStringList Datenbank::getAllTags() const {
00257 QStringList ret;
00258 QSqlQuery qry(m_db);
00259 qry.prepare("SELECT DISTINCT tags.tag "
00260 "FROM tags");
00261 if(!qry.exec())
00262 std::cerr << "Datenbankfehler: \n"
00263 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00264 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00265 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00266 while(qry.next()) {
00267 ret.append(qry.value(0).toString());
00268 }
00269 return ret;
00270 }
00271
00278 QStringList Datenbank::getAllImages() const {
00279 QStringList ret;
00280 QSqlQuery qry(m_db);
00281 qry.prepare("SELECT bild.name "
00282 "FROM bild");
00283 if(!qry.exec())
00284 std::cerr << "Datenbankfehler: \n"
00285 << "Query: " << qry.lastQuery().toUtf8().constData() << '\n'
00286 << qry.lastError().databaseText().toUtf8().constData() << '\n'
00287 << qry.lastError().driverText().toUtf8().constData() << std::endl;
00288 while(qry.next()) {
00289 ret.append(qry.value(0).toString());
00290 }
00291 return ret;
00292 }