OSDN Git Service

0d6074ce9d14e7a6806cbf34a64b95ca78d9c9e3
[wordring-tm/wordring-tm.git] / proxy / tmdatabase.h
1 #ifndef TMDATABASE_H
2 #define TMDATABASE_H
3
4 #include "tmsocket.h"
5 #include "tmtext.h"
6
7 #include <QObject>
8 #include <QPointer>
9 #include <QSqlDatabase>
10 #include <QSqlQuery>
11
12 #include <QMap>
13 #include <QPair>
14 #include <QJsonArray>
15 #include <QTime>
16
17 #include <QThread>
18
19 #include <memory>
20 #include <functional>
21
22 #define TMDATABASE_ROOT_PATH_KEY "Database/root"
23
24 QT_BEGIN_NAMESPACE
25 QT_END_NAMESPACE
26
27 class Settings;
28
29 namespace TM
30 {
31
32 class Service;
33
34 class DatabaseBase
35 {
36 protected:
37         bool open(char const *message);
38         QSqlQuery prepare(char const *sql, char const *message = nullptr);
39         bool exec(QSqlQuery &query, char const *message = nullptr);
40         QSqlQuery exec(char const *sql, char const *message = nullptr);
41         void error(QString message, QSqlQuery *query = nullptr);
42
43 protected:
44         QSqlDatabase m_database;
45         QString m_database_name;
46 };
47
48 /*!
49  * \brief サイトに番号を振るためのクラスです。
50  */
51 class SiteDatabase : public DatabaseBase
52 {
53 public:
54         typedef std::unique_ptr<SiteDatabase> pointer;
55
56 private:
57         SiteDatabase(Settings *settings);
58 public:
59         ~SiteDatabase();
60         quint32 site_id(QString domain);
61
62 private:
63         quint32 find_site_id(QString host_name);
64         void insert_site(QString host_name);
65         QString find_site_name(int site_id);
66
67 public:
68         static pointer create(Settings *settings);
69
70 private:
71         QSqlQuery m_find_site_id;
72         QSqlQuery m_insert_site;
73
74         QMap<QString, quint32> m_cache;
75         int m_cache_limit;
76 };
77
78 /*!
79  * \brief 単語に番号を振るためのクラスです。
80  */
81 class WordDatabase : public DatabaseBase
82 {
83 public:
84         typedef std::shared_ptr<WordDatabase> pointer;
85
86 private:
87         WordDatabase(Settings *settings, QString name);
88 public:
89         ~WordDatabase();
90
91         int word_id(QString word);
92
93 private:
94         int find_word_id(QString word);
95         void insert_word(QString word);
96
97 public:
98         static pointer create(Settings *settings, QString name);
99
100 private:
101         QSqlQuery m_find_word_id;
102         QSqlQuery m_insert_word;
103
104         QMap<QString, int> m_cache;
105         int m_cache_limit;
106 };
107
108 class SentenceDatabase : public DatabaseBase
109 {
110 public:
111         typedef std::shared_ptr<SentenceDatabase> pointer;
112         typedef QList<sentence_data_type> sentences_data_type;
113
114 private:
115         SentenceDatabase(Settings *settings, int site_id, QString name);
116 public:
117         ~SentenceDatabase();
118
119         quint32 find_sentence_id(QString sentence);
120         quint32 find_sentence_id_with_context(
121                         QString sentence, quint32 previous_crc, quint32 next_crc);
122
123         bool find_sentence_by_crc(
124                         quint32 crc, QString *tsentence, QJsonArray *json = nullptr);
125
126         sentence_data_type find_sentence(quint32 sentence_id);
127         sentence_data_type find_sentence_by_source_id(int source_id);
128
129         void insert(sentence_data_type const &sentence_data);
130         void update(sentence_data_type const &sentence_data);
131         void remove(quint32 source_id);
132
133 private:
134         sentence_data_type stuff_value(QSqlQuery *query);
135
136 public:
137         static pointer create(Settings *settings, int site_id, QString name);
138
139 private:
140         QSqlQuery m_find_sentence_id;
141         QSqlQuery m_find_sentence_id_with_context;
142         QSqlQuery m_find_sentence;
143         QSqlQuery m_find_sentence_by_crc;
144         QSqlQuery m_find_sentence_by_source_id;
145         QSqlQuery m_insert_sentence;
146         QSqlQuery m_update_sentence;
147         QSqlQuery m_delete_sentence;
148 };
149
150 struct index_data_type
151 {
152         index_data_type();
153
154         quint32 index_id;
155         quint32 word_id; /*!< 単語ID */
156         QSet<quint32> source_ids; /*!< 原文IDの集合 */
157         bool is_stop_word;
158 };
159
160 /*!
161  * \brief 原文の単語IDと訳文のIDを結びつけるクラスです。
162  */
163 class IndexDatabase : public DatabaseBase
164 {
165 public:
166         typedef std::shared_ptr<IndexDatabase> pointer;
167
168 private:
169         IndexDatabase(Settings *settings, QString dbname);
170
171 public:
172         QSet<quint32> find_index(quint32 word_id);
173         void insert_index(quint32 word_id, quint32 source_id);
174         void remove_index(quint32 word_id, quint32 source_id);
175
176 public:
177         static pointer create(Settings *settings, QString dbname);
178
179 private:
180         QSqlQuery m_find_index;
181         QSqlQuery m_insert_index;
182         QSqlQuery m_update_index;
183         QSqlQuery m_remove_index;
184
185         int m_index_limit;
186 };
187
188 class Database : public QObject
189 {
190         Q_OBJECT
191 public:
192         typedef std::function<void(sentence_data_type)> sentence_callback;
193
194 public:
195         Database(Settings *settings, Service *service);
196         ~Database();
197
198 signals:
199
200 public slots:
201         void setup();
202
203         void open_word_database(int code, QString name);
204
205         quint32 find_site_id(QString host_name);
206
207         void find_sentence(sentence_data_type source,
208                                            TextSentence::weak_pointer token);
209         void insert_sentence(sentence_data_type source, sentence_data_type target,
210                                                  TextSentence::weak_pointer token);
211         void remove_sentence(sentence_data_type sdata,
212                                                  sentence_data_type tdata);
213
214         void find_candidates(sentence_data_type source,
215                                                 TextSentence::weak_pointer token);
216
217 private:
218         QString find_language_name(int code) const;
219
220         int find_word_id(int code, QString word);
221         WordDatabase::pointer find_word_database(int code);
222
223         IndexDatabase::pointer find_index_database(
224                                                                         quint32 site_id, int scode, int tcode);
225
226         SentenceDatabase::pointer find_sentence_database(quint32 site_id, int code);
227
228 private:
229         Settings *m_settings;
230         Service *m_service;
231
232         QMap<int, QString> m_language_map; /*!< 言語コード、言語名 */
233
234         SiteDatabase::pointer m_site_database;
235         QMap<int, WordDatabase::pointer> m_word_databases; /*!< 言語コード, 単語データベース */
236
237         /*! QPair<サイトID、言語コード>、文データベース */
238         QMap<QPair<quint32, int>, SentenceDatabase::pointer> m_sentence_databases;
239         int m_sentence_cache_limit; /*!< 文データベース接続の最大値 */
240
241         QMap<QString, IndexDatabase::pointer> m_index_databases;
242         int m_index_cache_limit;
243 };
244
245 } // namespace TM
246
247 #endif // TMDATABASE_H