- Make the container function use iterators (thanks ma)
[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   int queryNumericAttribute( const data::RecordId &record_id,
118                                  const std::string &klass,
119                                  const std::string &name )
120   {
121     sqlite3_connection con((_dbdir + "zypp.db").asString().c_str());
122     return queryNumericAttributeInternal( con, record_id, klass, name);
123   }
124
125 private:
126
127   int queryNumericAttributeInternal( sqlite3_connection &con,
128                                      const data::RecordId &record_id,
129                                      const std::string &klass,
130                                      const std::string &name )
131   {
132     con.executenonquery("BEGIN;");
133     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;");
134
135     cmd.bind(":rid", record_id);
136
137     cmd.bind(":tclass", klass);
138     cmd.bind(":tname", name);
139
140     return cmd.executeint();
141   }
142   
143   TranslatedText queryTranslatedStringAttributeInternal( sqlite3_connection &con,
144                                                          const data::RecordId &record_id,
145                                                          const std::string &klass,
146                                                          const std::string &name )
147   {
148     //con.executenonquery("PRAGMA cache_size=8000;");
149     con.executenonquery("BEGIN;");
150     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;");
151
152     cmd.bind(":rid", record_id);
153     cmd.bind(":lclass", "lang");
154
155     cmd.bind(":tclass", klass);
156     cmd.bind(":tname", name);
157
158     TranslatedText result;
159     sqlite3_reader reader = cmd.executereader();
160     while(reader.read())
161     {
162       result.setText( reader.getstring(0), Locale( reader.getstring(1) ) );
163     }
164     return result;
165   }
166
167   std::string queryStringAttributeInternal( sqlite3_connection &con,
168                                             const data::RecordId &record_id,
169                                             const std::string &klass,
170                                             const std::string &name )
171   {
172     return queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name);
173   }
174
175   std::string queryStringAttributeTranslationInternal( sqlite3_connection &con,
176                                                        const data::RecordId &record_id,
177                                                        const Locale &locale,
178                                                        const std::string &klass,
179                                                        const std::string &name )
180   {
181     //con.executenonquery("PRAGMA cache_size=8000;");
182     con.executenonquery("BEGIN;");
183     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;");
184
185     cmd.bind(":rid", record_id);
186     cmd.bind(":lclass", "lang");
187     if (locale == Locale() )
188       cmd.bind(":lname", "none");
189     else
190       cmd.bind(":lname", locale.code());
191
192     cmd.bind(":tclass", klass);
193     cmd.bind(":tname", name);
194
195     return cmd.executestring();
196   }
197 };
198
199 //////////////////////////////////////////////////////////////////////////////
200 // FORWARD TO IMPLEMENTATION
201 //////////////////////////////////////////////////////////////////////////////
202
203 ResolvableQuery::ResolvableQuery( const Pathname &dbdir)
204   : _pimpl(new Impl(dbdir))
205 {
206 }
207
208 //////////////////////////////////////////////////////////////////////////////
209
210 void ResolvableQuery::query( const data::RecordId &id, ProcessResolvable fnc  )
211 {
212   _pimpl->query(id, fnc);
213 }
214
215 //////////////////////////////////////////////////////////////////////////////
216
217 void ResolvableQuery::query( const std::string &s, ProcessResolvable fnc  )
218 {
219   _pimpl->query(s, fnc);
220 }
221
222 //////////////////////////////////////////////////////////////////////////////
223
224 int ResolvableQuery::queryNumericAttribute( const data::RecordId &record_id,
225                                             const std::string &klass,
226                                             const std::string &name )
227 {
228   return _pimpl->queryNumericAttribute(record_id, klass, name);
229 }
230
231 bool ResolvableQuery::queryBooleanAttribute( const data::RecordId &record_id,
232                                              const std::string &klass,
233                                              const std::string &name )
234 {
235   return _pimpl->queryNumericAttribute(record_id, klass, name);
236 }
237
238
239 std::string ResolvableQuery::queryStringAttribute( const data::RecordId &record_id,
240                                                    const std::string &klass,
241                                                    const std::string &name )
242 {
243   return _pimpl->queryStringAttribute(record_id, klass, name);
244 }
245
246 //////////////////////////////////////////////////////////////////////////////
247
248 std::string ResolvableQuery::queryStringAttributeTranslation( const data::RecordId &record_id,
249                                                               const Locale &locale,
250                                                               const std::string &klass,
251                                                               const std::string &name )
252 {
253   return _pimpl->queryStringAttributeTranslation(record_id, locale, klass, name);
254 }
255
256 //////////////////////////////////////////////////////////////////////////////
257
258 TranslatedText ResolvableQuery::queryTranslatedStringAttribute( const data::RecordId &record_id,
259                                                                 const std::string &klass,
260                                                                 const std::string &name )
261 {
262   return _pimpl->queryTranslatedStringAttribute(record_id, klass, name);
263 }
264
265 //////////////////////////////////////////////////////////////////////////////
266
267 } } // namespace zypp::cache