Added build script of Debian
[qtrapids] / src / server / ServerDb.hpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Ixonos Plc   *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; version 2 of the License.               *
7  *                                                                         *
8  *   This program is distributed in the hope that it will be useful,       *
9  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
10  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
11  *   GNU General Public License for more details.                          *
12  *                                                                         *
13  *   You should have received a copy of the GNU General Public License     *
14  *   along with this program; if not, write to the                         *
15  *   Free Software Foundation, Inc.,                                       *
16  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
17  ***************************************************************************/
18 #ifndef _SERVERDB_HPP_
19 #define _SERVERDB_HPP_
20
21 #include <QDebug>
22 #include <QSettings>
23 #include <QtSql>
24 #include <QDir>
25
26 #include <qtrapids/settings.hpp>
27
28 namespace qtrapids
29 {
30
31 class ServerSettings
32 {
33
34 public:
35         ServerSettings(QSettings &settings)
36                         : settings_(settings) { }
37
38         ~ServerSettings() { }
39
40         QString getDbEngine() const {
41                 return getParamAndStore("db_engine", getDefaultDbEngine()).toString();
42         }
43
44         QString getDbName() const {
45                 QString default_db_path(QDir::home().filePath(appName() + ".sqlite"));
46                 return getParamAndStore("db", default_db_path).toString();
47         }
48
49         QString getTorrentsDir() const {
50                 QString default_dir(QDir::home().filePath(getTorrentsSubDir()));
51                 return getParamAndStore("torrents_dir", default_dir).toString();
52
53         }
54
55         static QString getTorrentsSubDir() {
56                 return QString(".") + appName();
57         }
58
59         QString getDownloadDir() const {
60                 QString default_dir(QDir::home().absolutePath());
61                 QString v = getParamAndStore("download/directory", default_dir).toString();
62                 if (!v.isEmpty()) {
63                         return v;
64                 } else {
65                         settings_.setValue("download/directory", default_dir);
66                         return default_dir;
67                 }
68         }
69
70         ports_range_t getListenPorts() const {
71
72                 ports_range_t default_ports(13131, 13132);
73                 default_ports.first = getParamAndStore("net/listen_range_begin", default_ports.first).toUInt();
74                 default_ports.second = getParamAndStore("net/listen_range_end", default_ports.second).toUInt();
75                 return default_ports;
76         }
77
78         /**
79            @todo deztructor: there is no check for option type yet
80          */
81         void setOptions(ParamsMapConst_t &options) {
82                 for (ParamsMapConstIterator_t p = options.constBegin(); p != options.constEnd(); ++p) {
83                         settings_.setValue(p.key(), p.value());
84                 }
85         }
86
87         ParamsMap_t getOptions() const {
88                 ParamsMap_t options;
89                 QStringList keys = settings_.allKeys();
90                 for (QStringList::const_iterator p = keys.begin(); p != keys.end(); ++p) {
91                         options[*p] = settings_.value(*p).toString();
92                 }
93                 return options;
94         }
95
96 private:
97
98         ServerSettings(ServerSettings const&);
99         ServerSettings& operator= (ServerSettings const&);
100
101         static inline QString appName() {
102                 return QCoreApplication::applicationName();
103         }
104
105         static QString getDefaultDbEngine() {
106                 // for (QStringListIterator p = QSqlDatabase::drivers(); p.hasNext();) {
107                 //     return p.next();
108                 // }
109                 return "QSQLITE";
110         }
111
112         QVariant getParamAndStore(QString const& name, QVariant default_value) const {
113                 return GetSettingsStoreDefault(settings_, name, default_value);
114         }
115
116         mutable QSettings &settings_;
117 };
118
119 namespace {
120
121 class DbAccessor
122 {
123 public:
124         DbAccessor(QSqlDatabase &db)
125                         : db_(db) {
126                 if (!db_.open()) {
127                         qDebug() << "cant open db";
128                 }
129         }
130
131         ~DbAccessor() {
132                 db_.close();
133         }
134
135 private:
136         QSqlDatabase &db_;
137 };
138
139 }
140
141 class ServerDb
142 {
143
144 public:
145         ServerDb(ServerSettings *settings)
146                         : db_(QSqlDatabase::addDatabase(settings->getDbEngine())) {
147                 QString db_name(settings->getDbName());
148                 db_.setDatabaseName(db_name);
149
150                 qDebug() << "opening db " << db_name;
151                 if (!db_.open()) {
152                         qDebug() << "cant open db";
153                         return;
154                 }
155                 qDebug() << "opened " << db_name;
156
157                 QSqlQuery q;
158                 if (!q.exec("create table torrents (hash varchar primary key, path varchar, savepath varchar);\n")) {
159                         qDebug() << "cant create table: " << q.lastError().text();
160                 }
161         }
162
163         ~ServerDb() {
164                 db_.close();
165         }
166
167         void addTorrent(const QString &hash, const QString &path, const QString &save_path) {
168                 DbAccessor dba(db_);
169                 QSqlQuery query_add_;
170                 query_add_.prepare("INSERT INTO torrents (hash, path, savepath) VALUES (?, ?, ?)");
171                 query_add_.bindValue(0, hash);
172                 query_add_.bindValue(1, path);
173                 query_add_.bindValue(2, save_path);
174                 if (!query_add_.exec()) {
175                         qDebug() << "cant add torrent info into db: "
176                         << query_add_.lastError().text();
177                 }
178         }
179
180         void removeTorrent(const QString &hash) {
181                 DbAccessor dba(db_);
182                 QSqlQuery query(QString("DELETE FROM torrents WHERE hash='") + hash + "'");
183                 if (!query.exec()) {
184                         qDebug() << "cant delete torrent info from db"
185                         << query.lastError().text();
186                 }
187         }
188
189 private:
190
191         ServerDb(ServerDb const&);
192         ServerDb& operator= (ServerDb const&);
193
194         QSqlDatabase db_;
195 };
196
197 class TorrentsStorage
198 {
199 public:
200
201         TorrentsStorage(ServerDb &db)
202                         : torrents_("SELECT hash, path, savepath from torrents") { }
203
204
205         bool nextTorrent(TorrentDownloadInfo &info) {
206                 if (!torrents_.next()) {
207                         return false;
208                 }
209                 info.hash = torrents_.value(0).toString();
210                 info.path = torrents_.value(1).toString();
211                 info.download_path = torrents_.value(2).toString();
212                 return true;
213         }
214
215
216 private:
217         QSqlQuery torrents_;
218 };
219
220 } // namespace qtrapids
221
222 #endif // _SERVERDB_HPP_