- get rid of internal forced instanciation, not needed.
[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   {
85     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
86     return queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name);
87   }
88
89
90   std::string queryStringAttributeTranslation( const data::RecordId &record_id,
91                                                const Locale &locale,
92                                                const std::string &klass,
93                                                const std::string &name )
94   {
95     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
96     return queryStringAttributeTranslationInternal( con, record_id, locale, klass, name );
97   }
98
99
100   TranslatedText queryTranslatedStringAttribute( const data::RecordId &record_id,
101                                                  const std::string &klass,
102                                                  const std::string &name )
103   {
104     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
105     return queryTranslatedStringAttributeInternal( con, record_id, klass, name );
106   }
107
108
109   bool queryBooleanAttribute( const data::RecordId &record_id,
110                                         const std::string &klass,
111                                         const std::string &name )
112   {
113     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
114     return ( queryNumericAttributeInternal( con, record_id, klass, name) != 0 );
115   }
116       
117   template <class _Container> _Container 
118   queryStringContainerAttribute( const data::RecordId &record_id,
119                                  const std::string &klass,
120                                  const std::string &name )
121   {
122     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
123     string all = queryStringAttributeInternal( con, record_id, klass, name);
124     _Container words;
125     
126     //
127     str::split( all, std::inserter(words, words.begin()) );
128     return words;
129   }
130   
131   
132   int queryNumericAttribute( const data::RecordId &record_id,
133                                  const std::string &klass,
134                                  const std::string &name )
135   {
136     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
137     return queryNumericAttributeInternal( con, record_id, klass, name);
138   }
139
140 private:
141
142   int queryNumericAttributeInternal( sqlite3_connection &con,
143                                      const data::RecordId &record_id,
144                                      const std::string &klass,
145                                      const std::string &name )
146   {
147     con.executenonquery("BEGIN;");
148     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;");
149
150     cmd.bind(":rid", record_id);
151
152     cmd.bind(":tclass", klass);
153     cmd.bind(":tname", name);
154
155     return cmd.executeint();
156   }
157   
158   TranslatedText queryTranslatedStringAttributeInternal( sqlite3_connection &con,
159                                                          const data::RecordId &record_id,
160                                                          const std::string &klass,
161                                                          const std::string &name )
162   {
163     //con.executenonquery("PRAGMA cache_size=8000;");
164     con.executenonquery("BEGIN;");
165     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;");
166
167     cmd.bind(":rid", record_id);
168     cmd.bind(":lclass", "lang");
169
170     cmd.bind(":tclass", klass);
171     cmd.bind(":tname", name);
172
173     TranslatedText result;
174     sqlite3_reader reader = cmd.executereader();
175     while(reader.read())
176     {
177       result.setText( reader.getstring(0), Locale( reader.getstring(1) ) );
178     }
179     return result;
180   }
181
182   std::string queryStringAttributeInternal( sqlite3_connection &con,
183                                             const data::RecordId &record_id,
184                                             const std::string &klass,
185                                             const std::string &name )
186   {
187     return queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name);
188   }
189
190   std::string queryStringAttributeTranslationInternal( sqlite3_connection &con,
191                                                        const data::RecordId &record_id,
192                                                        const Locale &locale,
193                                                        const std::string &klass,
194                                                        const std::string &name )
195   {
196     //con.executenonquery("PRAGMA cache_size=8000;");
197     con.executenonquery("BEGIN;");
198     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;");
199
200     cmd.bind(":rid", record_id);
201     cmd.bind(":lclass", "lang");
202     if (locale == Locale() )
203       cmd.bind(":lname", "none");
204     else
205       cmd.bind(":lname", locale.code());
206
207     cmd.bind(":tclass", klass);
208     cmd.bind(":tname", name);
209
210     return cmd.executestring();
211   }
212 };
213
214 //////////////////////////////////////////////////////////////////////////////
215 // FORWARD TO IMPLEMENTATION
216 //////////////////////////////////////////////////////////////////////////////
217
218 ResolvableQuery::ResolvableQuery( const Pathname &dbdir)
219   : _pimpl(new Impl(dbdir))
220 {
221 }
222
223 //////////////////////////////////////////////////////////////////////////////
224
225 void ResolvableQuery::query( const data::RecordId &id, ProcessResolvable fnc  )
226 {
227   _pimpl->query(id, fnc);
228 }
229
230 //////////////////////////////////////////////////////////////////////////////
231
232 void ResolvableQuery::query( const std::string &s, ProcessResolvable fnc  )
233 {
234   _pimpl->query(s, fnc);
235 }
236
237 //////////////////////////////////////////////////////////////////////////////
238
239 int ResolvableQuery::queryNumericAttribute( const data::RecordId &record_id,
240                                             const std::string &klass,
241                                             const std::string &name )
242 {
243   return _pimpl->queryNumericAttribute(record_id, klass, name);
244 }
245
246 bool ResolvableQuery::queryBooleanAttribute( const data::RecordId &record_id,
247                                              const std::string &klass,
248                                              const std::string &name )
249 {
250   return _pimpl->queryNumericAttribute(record_id, klass, name);
251 }
252
253
254 std::string ResolvableQuery::queryStringAttribute( const data::RecordId &record_id,
255                                                    const std::string &klass,
256                                                    const std::string &name )
257 {
258   return _pimpl->queryStringAttribute(record_id, klass, name);
259 }
260
261 //////////////////////////////////////////////////////////////////////////////
262
263 std::string ResolvableQuery::queryStringAttributeTranslation( const data::RecordId &record_id,
264                                                               const Locale &locale,
265                                                               const std::string &klass,
266                                                               const std::string &name )
267 {
268   return _pimpl->queryStringAttributeTranslation(record_id, locale, klass, name);
269 }
270
271 //////////////////////////////////////////////////////////////////////////////
272
273 TranslatedText ResolvableQuery::queryTranslatedStringAttribute( const data::RecordId &record_id,
274                                                                 const std::string &klass,
275                                                                 const std::string &name )
276 {
277   return _pimpl->queryTranslatedStringAttribute(record_id, klass, name);
278 }
279
280 template<class _Container>
281 _Container ResolvableQuery::queryStringContainerAttribute( const data::RecordId &record_id,
282                                                            const std::string &klass,
283                                                            const std::string &name )
284 {
285   return _pimpl->queryStringContainerAttribute<_Container>(record_id, klass, name);
286 }
287
288 template
289 std::set<std::string> ResolvableQuery::queryStringContainerAttribute( const data::RecordId &record_id,
290                                                                       const std::string &klass,
291                                                                       const std::string &name );
292
293 template
294 std::list<std::string> ResolvableQuery::queryStringContainerAttribute( const data::RecordId &record_id,
295                                                                        const std::string &klass,
296                                                                        const std::string &name );
297
298 template
299 Package::Keywords ResolvableQuery::queryStringContainerAttribute( const data::RecordId &record_id,
300                                                                   const std::string &klass,
301                                                                   const std::string &name );
302
303 //////////////////////////////////////////////////////////////////////////////
304
305 } } // namespace zypp::cache