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"
10 using namespace sqlite3x;
14 typedef shared_ptr<sqlite3_command> sqlite3_command_ptr;
16 namespace zypp { namespace cache {
18 struct ResolvableQuery::Impl
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 sqlite3_command_ptr _cmd_disk_usage;
29 Impl( const Pathname &dbdir)
33 _con.open((dbdir + "zypp.db").asString().c_str());
34 _con.executenonquery("PRAGMA cache_size=8000;");
36 _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;") );
39 _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;"));
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;"));
43 _cmd_disk_usage.reset( new sqlite3_command( _con, "select d.name,du.size,du.files from resolvable_disk_usage du,dir_names d where du.resolvable_id=:rid and du.dir_name_id=d.id;"));
45 MIL << "Creating Resolvable query impl" << endl;
46 // 0 1 2 3 4 5 6 7 8 9 10 11 12
47 _fields = "id, name, version, release, epoch, arch, kind, installed_size, archive_size, install_only, build_time, install_time, repository_id";
52 MIL << "Destroying Resolvable query impl" << endl;
56 // convert regex ? and * operators to sql _ and % respectively
57 // example: regex2sql( "*foo?bar*" ) => "%foo_bar%"
58 std::string regex2sql( const std::string & s)
62 for (it = sql.begin(); it != sql.end(); ++it)
64 if (*it == '*') *it = '%';
65 else if (*it == '?') *it = '_';
70 data::ResObject_Ptr fromRow( sqlite3_reader &reader )
72 data::ResObject_Ptr ptr (new data::ResObject);
74 // see _fields definition above for the getXXX() numbers
76 ptr->name = reader.getstring(1);
77 ptr->edition = Edition( reader.getstring(2), reader.getstring(3), reader.getint(4));
78 ptr->arch = _type_cache.archFor(reader.getint(5));
79 ptr->kind = _type_cache.kindFor( reader.getint(6) );
80 ptr->repository = reader.getint( 12 );
82 // TODO get the rest of the data
88 void query( const data::RecordId &id,
89 ProcessResolvable fnc )
91 sqlite3_command cmd( _con, "select " + _fields + " from resolvables where id=:id;");
93 sqlite3_reader reader = cmd.executereader();
96 fnc( id, fromRow(reader) );
101 void query( const std::string &s,
102 ProcessResolvable fnc )
105 sqlite3_command cmd( _con, "select " + _fields + " from resolvables where name like :name;");
106 cmd.bind( ":name", regex2sql( s ) );
107 sqlite3_reader reader = cmd.executereader();
110 fnc( reader.getint64(0), fromRow(reader) );
115 std::string queryStringAttribute( const data::RecordId &record_id,
116 const std::string &klass,
117 const std::string &name,
118 const std::string &default_value )
121 return queryStringAttributeTranslationInternal( _con, record_id, Locale(), klass, name, default_value);
125 std::string queryStringAttributeTranslation( const data::RecordId &record_id,
126 const Locale &locale,
127 const std::string &klass,
128 const std::string &name,
129 const std::string &default_value )
131 return queryStringAttributeTranslationInternal( _con, record_id, locale, klass, name, default_value );
135 TranslatedText queryTranslatedStringAttribute( const data::RecordId &record_id,
136 const std::string &klass,
137 const std::string &name,
138 const TranslatedText &default_value )
140 return queryTranslatedStringAttributeInternal( _con, record_id, klass, name, default_value );
144 bool queryBooleanAttribute( const data::RecordId &record_id,
145 const std::string &klass,
146 const std::string &name,
149 return ( queryNumericAttributeInternal( _con, record_id, klass, name, default_value) > 0 );
152 int queryNumericAttribute( const data::RecordId &record_id,
153 const std::string &klass,
154 const std::string &name,
157 return queryNumericAttributeInternal( _con, record_id, klass, name, default_value);
160 void queryDiskUsage( const data::RecordId &record_id, DiskUsage &du )
162 _cmd_disk_usage->bind(":rid", record_id);
163 sqlite3_reader reader = _cmd_disk_usage->executereader();
165 while ( reader.read() )
167 DiskUsage::Entry entry(reader.getstring(0),
174 std::string queryRepositoryAlias( const data::RecordId &repo_id )
177 sqlite3_command cmd( _con, "select alias from repositories where id=:id;" );
178 cmd.bind( ":id", repo_id );
179 sqlite3_reader reader = cmd.executereader();
180 while( reader.read() )
182 alias = reader.getstring( 0 );
188 void iterateResolvablesByKind( zypp::Resolvable::Kind kind, ProcessResolvable fnc )
190 sqlite3_command cmd( _con, "select " + _fields + " from resolvables where kind=:kind;");
191 data::RecordId kind_id = _type_cache.idForKind( kind );
192 cmd.bind(":kind", kind_id);
193 sqlite3_reader reader = cmd.executereader();
196 fnc( reader.getint64(0), fromRow(reader) );
200 void iterateResolvablesByKindsAndStrings( const std::vector<zypp::Resolvable::Kind> & kinds,
201 const std::vector<std::string> &strings, int flags, ProcessResolvable fnc )
203 std::string sqlcmd( "SELECT " + _fields + " FROM resolvables WHERE (" );
204 std::vector<std::string>::const_iterator it_s;
205 for (it_s = strings.begin(); it_s != strings.end(); ++it_s)
207 std::string s( *it_s );
209 if (it_s != strings.begin())
212 //FIXME: Implement MATCH_RESSUMM and MATCH_RESDESC
215 if (flags & MATCH_WILDCARDS == 0)
224 if (flags & MATCH_LEADING)
226 if (flags & MATCH_TRAILING)
233 sqlcmd += ") AND kind IN (";
235 std::vector<zypp::Resolvable::Kind>::const_iterator it_k;
236 for (it_k = kinds.begin(); it_k != kinds.end(); ++it_k)
238 if (it_k != kinds.begin())
241 snprintf( idbuf, 15, "%d", (int)(_type_cache.idForKind( *it_k )) );
244 sqlite3_command cmd( _con, sqlcmd + ")");
246 sqlite3_reader reader = cmd.executereader();
249 fnc( reader.getint64(0), fromRow(reader) );
255 int queryNumericAttributeInternal( sqlite3_connection &con,
256 const data::RecordId &record_id,
257 const std::string &klass,
258 const std::string &name,
261 //con.executenonquery("BEGIN;");
262 _cmd_attr_num->bind(":rid", record_id);
264 _cmd_attr_num->bind(":tclass", klass);
265 _cmd_attr_num->bind(":tname", name);
267 sqlite3_reader reader = _cmd_attr_num->executereader();
269 return reader.getint(0);
271 return default_value;
274 TranslatedText queryTranslatedStringAttributeInternal( sqlite3_connection &con,
275 const data::RecordId &record_id,
276 const std::string &klass,
277 const std::string &name,
278 const TranslatedText &default_value )
280 //con.executenonquery("PRAGMA cache_size=8000;");
281 //con.executenonquery("BEGIN;");
283 _cmd_attr_tstr->bind(":rid", record_id);
284 _cmd_attr_tstr->bind(":lclass", "lang");
286 _cmd_attr_tstr->bind(":tclass", klass);
287 _cmd_attr_tstr->bind(":tname", name);
289 TranslatedText result;
290 sqlite3_reader reader = _cmd_attr_tstr->executereader();
295 result.setText( reader.getstring(0), Locale( reader.getstring(1) ) );
302 return default_value;
305 std::string queryStringAttributeInternal( sqlite3_connection &con,
306 const data::RecordId &record_id,
307 const std::string &klass,
308 const std::string &name,
309 const std::string &default_value )
311 return queryStringAttributeTranslationInternal( con, record_id, Locale(), klass, name, default_value );
314 std::string queryStringAttributeTranslationInternal( sqlite3_connection &con,
315 const data::RecordId &record_id,
316 const Locale &locale,
317 const std::string &klass,
318 const std::string &name,
319 const std::string &default_value )
321 //con.executenonquery("BEGIN;");
322 _cmd_attr_str->bind(":rid", record_id);
323 _cmd_attr_str->bind(":lclass", "lang");
324 if (locale == Locale() )
325 _cmd_attr_str->bind(":lname", "none");
327 _cmd_attr_str->bind(":lname", locale.code());
329 _cmd_attr_str->bind(":tclass", klass);
330 _cmd_attr_str->bind(":tname", name);
332 sqlite3_reader reader = _cmd_attr_str->executereader();
335 return reader.getstring(0);
337 return default_value;
341 //////////////////////////////////////////////////////////////////////////////
342 // FORWARD TO IMPLEMENTATION
343 //////////////////////////////////////////////////////////////////////////////
345 ResolvableQuery::ResolvableQuery( const Pathname &dbdir)
346 : _pimpl(new Impl(dbdir))
348 //MIL << "Creating Resolvable query" << endl;
351 ResolvableQuery::~ResolvableQuery()
353 //MIL << "Destroying Resolvable query" << endl;
356 //////////////////////////////////////////////////////////////////////////////
358 void ResolvableQuery::query( const data::RecordId &id, ProcessResolvable fnc )
360 _pimpl->query(id, fnc);
363 //////////////////////////////////////////////////////////////////////////////
365 void ResolvableQuery::query( const std::string &s, ProcessResolvable fnc )
367 _pimpl->query(s, fnc);
370 //////////////////////////////////////////////////////////////////////////////
372 int ResolvableQuery::queryNumericAttribute( const data::RecordId &record_id,
373 const std::string &klass,
374 const std::string &name,
377 return _pimpl->queryNumericAttribute(record_id, klass, name, default_value);
380 bool ResolvableQuery::queryBooleanAttribute( const data::RecordId &record_id,
381 const std::string &klass,
382 const std::string &name,
385 return _pimpl->queryNumericAttribute(record_id, klass, name, default_value);
389 std::string ResolvableQuery::queryStringAttribute( const data::RecordId &record_id,
390 const std::string &klass,
391 const std::string &name,
392 const std::string &default_value )
394 return _pimpl->queryStringAttribute(record_id, klass, name, default_value);
397 //////////////////////////////////////////////////////////////////////////////
399 std::string ResolvableQuery::queryStringAttributeTranslation( const data::RecordId &record_id,
400 const Locale &locale,
401 const std::string &klass,
402 const std::string &name,
403 const std::string &default_value )
405 return _pimpl->queryStringAttributeTranslation(record_id, locale, klass, name, default_value );
408 //////////////////////////////////////////////////////////////////////////////
410 TranslatedText ResolvableQuery::queryTranslatedStringAttribute( const data::RecordId &record_id,
411 const std::string &klass,
412 const std::string &name,
413 const TranslatedText &default_value )
415 return _pimpl->queryTranslatedStringAttribute(record_id, klass, name, default_value );
418 void ResolvableQuery::queryDiskUsage( const data::RecordId &record_id, DiskUsage &du )
420 _pimpl->queryDiskUsage(record_id, du);
423 std::string ResolvableQuery::queryRepositoryAlias( const data::RecordId &repo_id )
425 return _pimpl->queryRepositoryAlias( repo_id );
428 void ResolvableQuery::iterateResolvablesByKind( zypp::Resolvable::Kind kind, ProcessResolvable fnc )
430 return _pimpl->iterateResolvablesByKind( kind, fnc );
433 void ResolvableQuery::iterateResolvablesByKindsAndStrings( const std::vector<zypp::Resolvable::Kind> & kinds,
434 const std::vector<std::string> &strings, int flags, ProcessResolvable fnc )
436 _pimpl->iterateResolvablesByKindsAndStrings( kinds, strings, flags, fnc );
438 //////////////////////////////////////////////////////////////////////////////
440 } } // namespace zypp::cache