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