- add messages
[platform/upstream/libzypp.git] / zypp / cache / ResolvableQuery.cc
1 #include <iterator>
2 #include <algorithm>
3
4 #include "zypp/cache/CacheTypes.h"
5 #include "zypp/cache/ResolvableQuery.h"
6 #include "zypp/Package.h"
7 #include "zypp/cache/sqlite3x/sqlite3x.hpp"
8
9 using namespace sqlite3x;
10 using namespace std;
11
12 namespace zypp { namespace cache {
13
14
15 struct ResolvableQuery::Impl
16 {
17   Pathname _dbdir;
18   string _fields;
19   CacheTypes _type_cache;
20   
21   Impl( const Pathname &dbdir)
22   : _dbdir(dbdir)
23     , _type_cache(dbdir)
24   {
25     _fields = "id, name, version, release, epoch, arch, kind, installed_size, archive_size, install_only, build_time, install_time, repository_id";
26   }
27
28   ~Impl()
29   {
30   }
31
32   data::ResObject_Ptr fromRow( sqlite3_reader &reader )
33   {
34     data::ResObject_Ptr ptr (new data::ResObject);
35
36     ptr->name = reader.getstring(1);
37     ptr->edition = Edition( reader.getstring(2), reader.getstring(3), reader.getint(4));
38     ptr->arch = _type_cache.archFor(reader.getint(5));
39
40     // TODO get the rest of the data
41
42     return ptr;
43   }
44
45   
46   void query( const data::RecordId &id,
47                   ProcessResolvable fnc )
48   {
49     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
50     //con.executenonquery("PRAGMA cache_size=8000;");
51     con.executenonquery("BEGIN;");
52     sqlite3_command cmd( con, "select " + _fields + " from resolvables where id=:id;");
53     cmd.bind(":id", id);
54     sqlite3_reader reader = cmd.executereader();
55     while(reader.read())
56     {
57       fnc( id, fromRow(reader) );
58     }
59     con.executenonquery("COMMIT;");
60   }
61
62
63   void query( const std::string &s,
64               ProcessResolvable fnc  )
65   {  
66     
67     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
68     //con.executenonquery("PRAGMA cache_size=8000;");
69     con.executenonquery("BEGIN;");
70     sqlite3_command cmd( con, "select " + _fields + " from resolvables where name like '%:name%';");
71     cmd.bind(":name", s);
72     sqlite3_reader reader = cmd.executereader();
73     while(reader.read())
74     {
75       fnc( reader.getint64(0), fromRow(reader) );
76     }
77     con.executenonquery("COMMIT;");
78   }
79
80
81   std::string queryStringAttribute( const data::RecordId &record_id,
82                                     const std::string &klass,
83                                     const std::string &name,
84                                     const std::string &default_value )
85   {
86     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
87     
88     string value;
89     try {
90       value = queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name);
91     }
92     catch ( const Exception &e )
93     {
94       ZYPP_CAUGHT(e);
95       return default_value;
96     }
97     
98     return value;
99   }
100
101
102   std::string queryStringAttributeTranslation( const data::RecordId &record_id,
103                                                const Locale &locale,
104                                                const std::string &klass,
105                                                const std::string &name,
106                                                const std::string &default_value )
107   {
108     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
109     string value;
110     try {
111       value = queryStringAttributeTranslationInternal( con, record_id, locale, klass, name );
112     }
113     catch ( const Exception &e )
114     {
115       ZYPP_CAUGHT(e);
116       return default_value;
117     }
118     return value;
119   }
120
121
122   TranslatedText queryTranslatedStringAttribute( const data::RecordId &record_id,
123                                                  const std::string &klass,
124                                                  const std::string &name,
125                                                  const TranslatedText &default_value )
126   {
127     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
128     TranslatedText value;
129     try {
130       value = queryTranslatedStringAttributeInternal( con, record_id, klass, name );
131     }
132     catch ( const Exception &e )
133     {
134       ZYPP_CAUGHT(e);
135       return default_value;
136     }
137     return value;
138   }
139
140
141   bool queryBooleanAttribute( const data::RecordId &record_id,
142                               const std::string &klass,
143                               const std::string &name,
144                               bool default_value )
145   {
146     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
147     bool value;
148     try {
149       value = queryNumericAttributeInternal( con, record_id, klass, name);
150     }
151     catch ( const Exception &e )
152     {
153       ZYPP_CAUGHT(e);
154       return default_value;
155     }
156     return value;
157   }
158       
159   int queryNumericAttribute( const data::RecordId &record_id,
160                              const std::string &klass,
161                              const std::string &name,
162                              int default_value )
163   {
164     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
165     int n;
166     try {
167       n = queryNumericAttributeInternal( con, record_id, klass, name);
168     }
169     catch ( const Exception &e )
170     {
171       ZYPP_CAUGHT(e);
172       return default_value;
173     }
174     return n;
175   }
176
177 private:
178
179   int queryNumericAttributeInternal( sqlite3_connection &con,
180                                      const data::RecordId &record_id,
181                                      const std::string &klass,
182                                      const std::string &name )
183   {
184     con.executenonquery("BEGIN;");
185     sqlite3_command cmd( con, "select a.value from numeric_attributes a,types t where a.weak_resolvable_id=:rid and a.attr_id=t.id and t.class=:tclass and t.name=:tname;");
186
187     cmd.bind(":rid", record_id);
188
189     cmd.bind(":tclass", klass);
190     cmd.bind(":tname", name);
191
192     return cmd.executeint();
193   }
194   
195   TranslatedText queryTranslatedStringAttributeInternal( sqlite3_connection &con,
196                                                          const data::RecordId &record_id,
197                                                          const std::string &klass,
198                                                          const std::string &name )
199   {
200     //con.executenonquery("PRAGMA cache_size=8000;");
201     con.executenonquery("BEGIN;");
202     sqlite3_command cmd( con, "select a.text, l.name from text_attributes a,types l,types t where a.weak_resolvable_id=:rid and a.lang_id=l.id and a.attr_id=t.id and l.class=:lclass and t.class=:tclass and t.name=:tname;");
203
204     cmd.bind(":rid", record_id);
205     cmd.bind(":lclass", "lang");
206
207     cmd.bind(":tclass", klass);
208     cmd.bind(":tname", name);
209
210     TranslatedText result;
211     sqlite3_reader reader = cmd.executereader();
212     while(reader.read())
213     {
214       result.setText( reader.getstring(0), Locale( reader.getstring(1) ) );
215     }
216     return result;
217   }
218
219   std::string queryStringAttributeInternal( sqlite3_connection &con,
220                                             const data::RecordId &record_id,
221                                             const std::string &klass,
222                                             const std::string &name )
223   {
224     return queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name);
225   }
226
227   std::string queryStringAttributeTranslationInternal( sqlite3_connection &con,
228                                                        const data::RecordId &record_id,
229                                                        const Locale &locale,
230                                                        const std::string &klass,
231                                                        const std::string &name )
232   {
233     //con.executenonquery("PRAGMA cache_size=8000;");
234     con.executenonquery("BEGIN;");
235     sqlite3_command cmd( con, "select a.text from text_attributes a,types l,types t where a.weak_resolvable_id=:rid and a.lang_id=l.id and a.attr_id=t.id and l.class=:lclass and l.name=:lname and t.class=:tclass and t.name=:tname;");
236
237     cmd.bind(":rid", record_id);
238     cmd.bind(":lclass", "lang");
239     if (locale == Locale() )
240       cmd.bind(":lname", "none");
241     else
242       cmd.bind(":lname", locale.code());
243
244     cmd.bind(":tclass", klass);
245     cmd.bind(":tname", name);
246
247     return cmd.executestring();
248   }
249 };
250
251 //////////////////////////////////////////////////////////////////////////////
252 // FORWARD TO IMPLEMENTATION
253 //////////////////////////////////////////////////////////////////////////////
254
255 ResolvableQuery::ResolvableQuery( const Pathname &dbdir)
256   : _pimpl(new Impl(dbdir))
257 {
258 }
259
260 //////////////////////////////////////////////////////////////////////////////
261
262 void ResolvableQuery::query( const data::RecordId &id, ProcessResolvable fnc  )
263 {
264   _pimpl->query(id, fnc);
265 }
266
267 //////////////////////////////////////////////////////////////////////////////
268
269 void ResolvableQuery::query( const std::string &s, ProcessResolvable fnc  )
270 {
271   _pimpl->query(s, fnc);
272 }
273
274 //////////////////////////////////////////////////////////////////////////////
275
276 int ResolvableQuery::queryNumericAttribute( const data::RecordId &record_id,
277                                             const std::string &klass,
278                                             const std::string &name,
279                                             int default_value )
280 {
281   return _pimpl->queryNumericAttribute(record_id, klass, name, default_value);
282 }
283
284 bool ResolvableQuery::queryBooleanAttribute( const data::RecordId &record_id,
285                                              const std::string &klass,
286                                              const std::string &name,
287                                              bool default_value )
288 {
289   return _pimpl->queryNumericAttribute(record_id, klass, name, default_value);
290 }
291
292
293 std::string ResolvableQuery::queryStringAttribute( const data::RecordId &record_id,
294                                                    const std::string &klass,
295                                                    const std::string &name,
296                                                    const std::string &default_value )
297 {
298   return _pimpl->queryStringAttribute(record_id, klass, name, default_value);
299 }
300
301 //////////////////////////////////////////////////////////////////////////////
302
303 std::string ResolvableQuery::queryStringAttributeTranslation( const data::RecordId &record_id,
304                                                               const Locale &locale,
305                                                               const std::string &klass,
306                                                               const std::string &name,
307                                                               const std::string &default_value )
308 {
309   return _pimpl->queryStringAttributeTranslation(record_id, locale, klass, name, default_value );
310 }
311
312 //////////////////////////////////////////////////////////////////////////////
313
314 TranslatedText ResolvableQuery::queryTranslatedStringAttribute( const data::RecordId &record_id,
315                                                                 const std::string &klass,
316                                                                 const std::string &name,
317                                                                 const TranslatedText &default_value )
318 {
319   return _pimpl->queryTranslatedStringAttribute(record_id, klass, name, default_value );
320 }
321
322 //////////////////////////////////////////////////////////////////////////////
323
324 } } // namespace zypp::cache