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