- Added rate limit preferences to DBus client/server implementation
[qtrapids] / src / server / ServerDb.hpp
1 #ifndef _SERVERDB_HPP_
2 #define _SERVERDB_HPP_
3
4 #include <QDebug>
5 #include <QSettings>
6 #include <QtSql>
7 #include <QDir>
8
9 #include <qtrapids/settings.hpp>
10
11 namespace qtrapids
12 {
13
14 class ServerSettings
15 {
16
17 public:
18         ServerSettings(QSettings &settings)
19                         : settings_(settings) { }
20
21         ~ServerSettings() { }
22
23         QString getDbEngine() const {
24                 return getParamAndStore("db_engine", getDefaultDbEngine()).toString();
25         }
26
27         QString getDbName() const {
28                 QString default_db_path(QDir::home().filePath(appName() + ".sqlite"));
29                 return getParamAndStore("db", default_db_path).toString();
30         }
31
32         QString getTorrentsDir() const {
33                 QString default_dir(QDir::home().filePath(getTorrentsSubDir()));
34                 return getParamAndStore("torrents_dir", default_dir).toString();
35
36         }
37
38         static QString getTorrentsSubDir() {
39                 return QString(".") + appName();
40         }
41
42         QString getDownloadDir() const {
43                 QString default_dir(QDir::home().absolutePath());
44                 QString v = getParamAndStore("download/directory", default_dir).toString();
45                 if (!v.isEmpty()) {
46                         return v;
47                 } else {
48                         settings_.setValue("download/directory", default_dir);
49                         return default_dir;
50                 }
51         }
52
53         ports_range_t getListenPorts() const {
54
55                 ports_range_t default_ports(13131, 13132);
56                 default_ports.first = getParamAndStore("net/listen_range_begin", default_ports.first).toUInt();
57                 default_ports.second = getParamAndStore("net/listen_range_end", default_ports.second).toUInt();
58                 return default_ports;
59         }
60
61         /**
62            @todo deztructor: there is no check for option type yet
63          */
64         void setOptions(ParamsMapConst_t &options) {
65                 for (ParamsMapConstIterator_t p = options.constBegin(); p != options.constEnd(); ++p) {
66                         settings_.setValue(p.key(), p.value());
67                 }
68         }
69
70         ParamsMap_t getOptions() const {
71                 ParamsMap_t options;
72                 QStringList keys = settings_.allKeys();
73                 for (QStringList::const_iterator p = keys.begin(); p != keys.end(); ++p) {
74                         options[*p] = settings_.value(*p).toString();
75                 }
76                 return options;
77         }
78
79 private:
80
81         ServerSettings(ServerSettings const&);
82         ServerSettings& operator= (ServerSettings const&);
83
84         static inline QString appName() {
85                 return QCoreApplication::applicationName();
86         }
87
88         static QString getDefaultDbEngine() {
89                 // for (QStringListIterator p = QSqlDatabase::drivers(); p.hasNext();) {
90                 //     return p.next();
91                 // }
92                 return "QSQLITE";
93         }
94
95         QVariant getParamAndStore(QString const& name, QVariant default_value) const {
96                 return GetSettingsStoreDefault(settings_, name, default_value);
97         }
98
99         mutable QSettings &settings_;
100 };
101
102 namespace {
103
104 class DbAccessor
105 {
106 public:
107         DbAccessor(QSqlDatabase &db)
108                         : db_(db) {
109                 if (!db_.open()) {
110                         qDebug() << "cant open db";
111                 }
112         }
113
114         ~DbAccessor() {
115                 db_.close();
116         }
117
118 private:
119         QSqlDatabase &db_;
120 };
121
122 }
123
124 class ServerDb
125 {
126
127 public:
128         ServerDb(ServerSettings *settings)
129                         : db_(QSqlDatabase::addDatabase(settings->getDbEngine())) {
130                 QString db_name(settings->getDbName());
131                 db_.setDatabaseName(db_name);
132
133                 qDebug() << "opening db " << db_name;
134                 if (!db_.open()) {
135                         qDebug() << "cant open db";
136                         return;
137                 }
138                 qDebug() << "opened " << db_name;
139
140                 QSqlQuery q;
141                 if (!q.exec("create table torrents (hash varchar primary key, path varchar, savepath varchar);\n")) {
142                         qDebug() << "cant create table: " << q.lastError().text();
143                 }
144         }
145
146         ~ServerDb() {
147                 db_.close();
148         }
149
150         void addTorrent(const QString &hash, const QString &path, const QString &save_path) {
151                 DbAccessor dba(db_);
152                 QSqlQuery query_add_;
153                 query_add_.prepare("INSERT INTO torrents (hash, path, savepath) VALUES (?, ?, ?)");
154                 query_add_.bindValue(0, hash);
155                 query_add_.bindValue(1, path);
156                 query_add_.bindValue(2, save_path);
157                 if (!query_add_.exec()) {
158                         qDebug() << "cant add torrent info into db: "
159                         << query_add_.lastError().text();
160                 }
161         }
162
163         void removeTorrent(const QString &hash) {
164                 DbAccessor dba(db_);
165                 QSqlQuery query(QString("DELETE FROM torrents WHERE hash='") + hash + "'");
166                 if (!query.exec()) {
167                         qDebug() << "cant delete torrent info from db"
168                         << query.lastError().text();
169                 }
170         }
171
172 private:
173
174         ServerDb(ServerDb const&);
175         ServerDb& operator= (ServerDb const&);
176
177         QSqlDatabase db_;
178 };
179
180 class TorrentsStorage
181 {
182 public:
183
184         TorrentsStorage(ServerDb &db)
185                         : torrents_("SELECT hash, path, savepath from torrents") { }
186
187
188         bool nextTorrent(TorrentDownloadInfo &info) {
189                 if (!torrents_.next()) {
190                         return false;
191                 }
192                 info.hash = torrents_.value(0).toString();
193                 info.path = torrents_.value(1).toString();
194                 info.download_path = torrents_.value(2).toString();
195                 return true;
196         }
197
198
199 private:
200         QSqlQuery torrents_;
201 };
202
203 } // namespace qtrapids
204
205 #endif // _SERVERDB_HPP_