7 #ifndef EPT_DEBTAGS_SERIALIZER_H
8 #define EPT_DEBTAGS_SERIALIZER_H
12 #include <tagcoll/patch.h>
13 #include <wibble/mixin.h>
19 template<
typename OUT>
20 class IntToPkg :
public wibble::mixin::OutputIterator< IntToPkg<OUT> >
28 : pkgid(pkgid), voc(voc), out(out) {}
30 template<
typename ITEMS,
typename TAGS>
33 std::set<std::string> ritems;
36 for (
typename ITEMS::const_iterator i = data.first.begin();
37 i != data.first.end(); ++i)
39 std::string pkg = pkgid.
byID(*i);
44 for (
typename TAGS::const_iterator i = data.second.begin();
45 i != data.second.end(); ++i)
52 if (!ritems.empty() && !rtags.empty())
54 *out = make_pair(ritems, rtags);
61 template<
typename OUT>
67 template<
typename OUT>
68 class StringToInt :
public wibble::mixin::OutputIterator< StringToInt<OUT> >
76 : pkgid(pkgid), voc(voc), out(out) {}
78 template<
typename ITEMS,
typename TAGS>
84 for (
typename ITEMS::const_iterator i = data.first.begin();
85 i != data.first.end(); ++i)
92 for (
typename TAGS::const_iterator i = data.second.begin();
93 i != data.second.end(); ++i)
100 if (!ritems.empty() && !rtags.empty())
102 *out = make_pair(ritems, rtags);
110 template<
typename OUT>
116 template<
typename OUT>
117 class StringToPkg :
public wibble::mixin::OutputIterator< StringToPkg<OUT> >
125 : pkgid(pkgid), voc(voc), out(out) {}
127 template<
typename ITEMS,
typename TAGS>
130 std::set<std::string> ritems;
133 for (
typename ITEMS::const_iterator i = data.first.begin();
134 i != data.first.end(); ++i)
137 if (pkgid.
byName(*i) == -1)
142 for (
typename TAGS::const_iterator i = data.second.begin();
143 i != data.second.end(); ++i)
150 if (!ritems.empty() && !rtags.empty())
152 *out = make_pair(ritems, rtags);
160 template<
typename OUT>
166 template<
typename OUT>
167 class PkgToString :
public wibble::mixin::OutputIterator< PkgToString<OUT> >
173 template<
typename ITEMS,
typename TAGS>
176 std::set<std::string> stags;
177 for (
typename TAGS::const_iterator i = data.second.begin();
178 i != data.second.end(); ++i)
180 stags.insert(i->fullname());
181 *out = make_pair(data.first, stags);
187 template<
typename OUT>
193 template<
typename OUT>
202 : pkgid(pkgid), voc(voc), out(out) {}
206 int id = pkgid.
byName(patch.item);
210 tagcoll::Patch<int, int> res(
id);
211 for (std::set<std::string>::const_iterator i = patch.added.begin();
212 i != patch.added.end(); ++i)
218 for (std::set<std::string>::const_iterator i = patch.removed.begin();
219 i != patch.removed.end(); ++i)
223 res.remove(tag.
id());
231 template<
typename OUT>
237 template<
typename OUT>
246 : pkgid(pkgid), voc(voc), out(out) {}
250 std::string name = pkgid.
byID(patch.item);
254 tagcoll::Patch<std::string, std::string> res(name);
255 for (std::set<int>::const_iterator i = patch.added.begin();
256 i != patch.added.end(); ++i)
262 for (std::set<int>::const_iterator i = patch.removed.begin();
263 i != patch.removed.end(); ++i)
275 template<
typename OUT>
284 template<
typename OUT>
285 class ToInt :
public wibble::mixin::OutputIterator< ToInt<OUT> >
289 ToInt(
const OUT& out) : out(out) {}
291 template<
typename ITEMS,
typename TAGS>
292 ToInt<OUT>& operator=(
const std::pair<ITEMS, TAGS>& data)
294 std::set<int> iitems;
296 for (
typename ITEMS::const_iterator i = data.first.begin();
297 i != data.first.end(); ++i)
299 iitems.insert(i->ondiskId());
300 for (
typename TAGS::const_iterator i = data.second.begin();
301 i != data.second.end(); ++i)
303 itags.insert(i->id());
304 *out = make_pair(iitems, itags);
310 template<
typename OUT>
311 ToInt<OUT> toInt(
const OUT& out)
313 return ToInt<OUT>(out);
316 template<
typename ITEMCONV,
typename TAGCONV,
typename OUT>
317 class Converter :
public wibble::mixin::OutputIterator< Converter<ITEMCONV, TAGCONV, OUT> >
324 Converter(
const ITEMCONV& itemconv,
const TAGCONV& tagconv,
const OUT& out)
325 : itemconv(itemconv), tagconv(tagconv), out(out) {}
327 template<
typename ITEMS,
typename TAGS>
328 Converter<ITEMCONV, TAGCONV, OUT>& operator=(
const std::pair<ITEMS, TAGS>& data)
330 *out = make_pair(itemconv(data.first), tagconv(data.second));
336 template<
typename ITEMCONV,
typename TAGCONV,
typename OUT>
337 Converter<ITEMCONV, TAGCONV, OUT> converter(
const ITEMCONV& itemconv,
const TAGCONV& tagconv,
const OUT& out)
339 return Converter<ITEMCONV, TAGCONV, OUT>(itemconv, tagconv, out);
343 template<
typename OUT>
344 class PatchToString :
public wibble::mixin::OutputIterator< PatchToString<OUT> >
349 PatchToString(
const OUT& out) : out(out) {}
351 template<
typename PKG,
typename TAG>
352 PatchToString<OUT>& operator=(
const tagcoll::Patch<PKG, TAG>& patch)
354 if (!patch.item.valid())
357 tagcoll::Patch<std::string, std::string> res(patch.item.name());
358 for (
typename std::set<TAG>::const_iterator i = patch.added.begin();
359 i != patch.added.end(); ++i)
361 res.add(i->fullname());
362 for (
typename std::set<TAG>::const_iterator i = patch.removed.begin();
363 i != patch.removed.end(); ++i)
365 res.remove(i->fullname());
372 template<
typename OUT>
373 PatchToString<OUT> patchToString(
const OUT& out)
375 return PatchToString<OUT>(out);
389 struct coll_traits< ept::cache::debtags::DebtagsIndex >
391 typedef ept::cache::Package<> item_type;
392 typedef ept::cache::debtags::Tag tag_type;
393 typedef std::set< ept::cache::Package<> > itemset_type;
394 typedef std::set<ept::cache::debtags::Tag> tagset_type;
408 class FacetIntConverter :
public Implementation<FacetIntConverter>,
409 public Tagcoll::Converter<aptFront::cache::entity::Facet, int>,
410 public Tagcoll::Converter<int, aptFront::cache::entity::Facet>
412 typedef aptFront::cache::entity::Facet Facet;
413 typedef Tagcoll::OpSet<aptFront::cache::entity::Facet> FacetSet;
414 typedef Tagcoll::OpSet<int> IntSet;
416 virtual int operator()(
const aptFront::cache::entity::Facet& item)
const;
417 virtual aptFront::cache::entity::Facet operator()(
const int& item)
const;
419 virtual IntSet operator()(
const FacetSet& item)
const
420 {
return Tagcoll::Converter<Facet, int>::operator()(item); }
421 virtual FacetSet operator()(
const IntSet& item)
const
422 {
return Tagcoll::Converter<int, Facet>::operator()(item); }
424 static std::string componentName();
430 class FacetStringConverter :
public Implementation<FacetStringConverter>,
431 public Tagcoll::Converter<aptFront::cache::entity::Facet, std::string>,
432 public Tagcoll::Converter<std::string, aptFront::cache::entity::Facet>
434 typedef aptFront::cache::entity::Facet Facet;
435 typedef Tagcoll::OpSet<aptFront::cache::entity::Facet> FacetSet;
436 typedef Tagcoll::OpSet<std::string> StringSet;
438 virtual std::string operator()(
const aptFront::cache::entity::Facet& item)
const;
439 virtual aptFront::cache::entity::Facet operator()(
const std::string& item)
const;
441 virtual StringSet operator()(
const FacetSet& item)
const
442 {
return Tagcoll::Converter<Facet, std::string>::operator()(item); }
443 virtual FacetSet operator()(
const StringSet& item)
const
444 {
return Tagcoll::Converter<std::string, Facet>::operator()(item); }
446 static std::string componentName();
452 class TagIntConverter :
public Implementation<TagIntConverter>,
453 public Tagcoll::Converter<aptFront::cache::entity::Tag, int>,
454 public Tagcoll::Converter<int, aptFront::cache::entity::Tag>
456 typedef aptFront::cache::entity::Tag Tag;
457 typedef Tagcoll::OpSet<aptFront::cache::entity::Tag> TagSet;
458 typedef Tagcoll::OpSet<int> IntSet;
460 virtual int operator()(
const aptFront::cache::entity::Tag& item)
const;
461 virtual aptFront::cache::entity::Tag operator()(
const int& item)
const;
463 virtual IntSet operator()(
const TagSet& item)
const
464 {
return Tagcoll::Converter<Tag, int>::operator()(item); }
465 virtual TagSet operator()(
const IntSet& item)
const
466 {
return Tagcoll::Converter<int, Tag>::operator()(item); }
468 static std::string componentName();
474 class TagStringConverter :
public Implementation<TagStringConverter>,
475 public Tagcoll::Converter<aptFront::cache::entity::Tag, std::string>,
476 public Tagcoll::Converter<std::string, aptFront::cache::entity::Tag>
478 typedef aptFront::cache::entity::Tag Tag;
479 typedef Tagcoll::OpSet<aptFront::cache::entity::Tag> TagSet;
480 typedef Tagcoll::OpSet<std::string> StringSet;
482 virtual std::string operator()(
const Tag& item)
const;
483 virtual Tag operator()(
const std::string& item)
const;
485 virtual StringSet operator()(
const TagSet& item)
const
486 {
return Tagcoll::Converter<Tag, std::string>::operator()(item); }
487 virtual TagSet operator()(
const StringSet& item)
const
488 {
return Tagcoll::Converter<std::string, Tag>::operator()(item); }
490 TagSet parseTagList(
const std::string& str)
const;
492 static std::string componentName();
498 class PackageIntConverter :
public Implementation<PackageIntConverter>,
499 public Tagcoll::Converter<aptFront::cache::entity::Package, int>,
500 public Tagcoll::Converter<int, aptFront::cache::entity::Package>
503 typedef Tagcoll::OpSet<aptFront::cache::entity::Package> PackageSet;
504 typedef Tagcoll::OpSet<int> IntSet;
506 virtual int operator()(
const Package& item)
const;
507 virtual Package operator()(
const int& item)
const;
509 virtual IntSet operator()(
const PackageSet& item)
const
510 {
return Tagcoll::Converter<Package, int>::operator()(item); }
511 virtual PackageSet operator()(
const IntSet& item)
const
512 {
return Tagcoll::Converter<int, Package>::operator()(item); }
514 static std::string componentName();
520 class PackageStringConverter :
public Implementation<PackageStringConverter>,
521 public Tagcoll::Converter<aptFront::cache::entity::Package, std::string>,
522 public Tagcoll::Converter<std::string, aptFront::cache::entity::Package>
525 typedef Tagcoll::OpSet<aptFront::cache::entity::Package> PackageSet;
526 typedef Tagcoll::OpSet<std::string> StringSet;
528 virtual std::string operator()(
const Package& item)
const;
529 virtual Package operator()(
const std::string& item)
const;
531 virtual StringSet operator()(
const PackageSet& item)
const
532 {
return Tagcoll::Converter<Package, std::string>::operator()(item); }
533 virtual PackageSet operator()(
const StringSet& item)
const
534 {
return Tagcoll::Converter<std::string, Package>::operator()(item); }
536 static std::string componentName();
556 #ifndef EPT_CACHE_DEBTAGS_SERIALIZER_TCC
557 #define EPT_CACHE_DEBTAGS_SERIALIZER_TCC
559 #include <ept/cache/debtags/serializer.h>
561 #include <ept/cache/debtags/pkgidx.h>
562 #include <ept/cache/debtags/vocabulary.h>
563 #include <ept/cache/package.h>
575 string FacetIntConverter::componentName() {
return "FacetIntConverter"; }
577 int FacetIntConverter::operator()(
const aptFront::cache::entity::Facet& item)
const
579 if (!item.valid())
return -1;
582 aptFront::cache::entity::Facet FacetIntConverter::operator()(
const int& item)
const
584 return cache().tags().facetByID(item);
587 string FacetStringConverter::componentName() {
return "FacetStringConverter"; }
589 std::string FacetStringConverter::operator()(
const aptFront::cache::entity::Facet& item)
const
591 if (!item.valid())
return string();
594 aptFront::cache::entity::Facet FacetStringConverter::operator()(
const std::string& item)
const
596 return cache().tags().facetByName(item);
599 string TagIntConverter::componentName() {
return "TagIntConverter"; }
601 int TagIntConverter::operator()(
const aptFront::cache::entity::Tag& item)
const
603 if (!item.valid())
return -1;
606 aptFront::cache::entity::Tag TagIntConverter::operator()(
const int& item)
const
608 return cache().tags().tagByID(item);
611 string TagStringConverter::componentName() {
return "TagStringConverter"; }
613 std::string TagStringConverter::operator()(
const aptFront::cache::entity::Tag& item)
const
615 if (!item.valid())
return string();
616 return item.fullname();
618 aptFront::cache::entity::Tag TagStringConverter::operator()(
const std::string& item)
const
620 return cache().tags().tagByName(item);
623 Tagcoll::OpSet<entity::Tag> TagStringConverter::parseTagList(
const std::string& str)
const
626 return Tagcoll::OpSet<entity::Tag>();
628 size_t i = str.find(
", ");
629 if (i == string::npos)
632 if (str[str.size() - 1] ==
'}')
635 Tagcoll::OpSet<entity::Tag> res;
636 size_t begin = str.find(
'{');
637 if (begin == string::npos)
639 string prefix(str, 0, begin);
642 while ((end = str.find(
',', begin)) != string::npos)
644 res += (*this)(prefix + str.substr(begin, end-begin));
647 res += (*this)(prefix + str.substr(begin, str.size() - 1 - begin));
650 entity::Tag t = (*this)(str);
652 return Tagcoll::OpSet<entity::Tag>() + t;
654 return Tagcoll::OpSet<entity::Tag>();
657 return parseTagList(
string(str, 0, i)) + parseTagList(
string(str, i+2));
661 string PackageIntConverter::componentName() {
return "PackageIntConverter"; }
665 if (!item.valid())
return -1;
670 PkgIdx& p = cache().pkgidx();
671 return cache().packages().packageByName(
string(p.name(item), p.size(item)));
674 string PackageStringConverter::componentName() {
return "PackageStringConverter"; }
678 if (!item.valid())
return string();
683 return cache().packages().packageByName(item);
693 #ifdef COMPILE_TESTSUITE
696 #include "test-utils.h"
699 using namespace aptFront::cache;
700 using namespace component;
701 using namespace debtags;
704 struct cache_component_debtags_serializer_shar {
705 cache_component_debtags_serializer_shar () {
708 debtags::fetchNewData();
709 c.open( Cache::OpenDefault |
710 Cache::OpenReadOnly | Cache::OpenDebtags );
715 throw warning(
"debtags init failed, cancelling" );
717 ~cache_component_debtags_serializer_shar() {
724 TESTGRP( cache_component_debtags_serializer );
726 using namespace Tagcoll;
728 template<>
template<>
733 PackageStringConverter& psc = c.packagestringconverter();
748 ensure_equals(psc(p),
"debtags");
749 ensure_equals(psc(p1),
"debtags");
750 ensure_equals(psc(p), psc(p1));
754 Tagcoll::OpSet<entity::Package> pkgs;
755 pkgs += c.packages().packageByName(
"debtags" );
756 pkgs += c.packages().packageByName(
"tagcoll" );
759 ensure_equals (pkgs.size(), 3u);
760 ensure_equals (psc(pkgs).size(), 2u);
761 ensure (psc(pkgs).contains(
"debtags"));
762 ensure (psc(pkgs).contains(
"tagcoll"));
767 Tagcoll::OpSet<std::string> pkgs;
770 pkgs +=
"Slartibartsfart";
772 ensure_equals (pkgs.size(), 3u);
773 ensure_equals (psc(pkgs).size(), 2u);
774 ensure (psc(pkgs).contains(psc(
"debtags")));
775 ensure (psc(pkgs).contains(psc(
"tagcoll")));
783 return out << pkg.name();
785 return out <<
"(invalid package)";
789 template<>
template<>
792 PackageStringConverter& psc = c.packagestringconverter();
793 for (component::Aggregator::iterator i = c.packages().packagesBegin();
794 i != c.packages().packagesEnd(); ++i)
797 ensure_equals(*i, psc(psc(*i)));
799 cerr <<
"Note: exception thrown during processing[string] of package " << i->name(
string(
"(invalid package)")) << endl;
804 PackageIntConverter& pic = c.packageintconverter();
805 for (component::Aggregator::iterator i = c.packages().packagesBegin();
806 i != c.packages().packagesEnd(); ++i)
809 ensure_equals(*i, pic(pic(*i)));
811 cerr <<
"Note: exception thrown during processing[int] of package " << i->name(
string(
"(invalid package)")) << endl;
818 template<>
template<>
821 typedef Tagcoll::OpSet<entity::Facet> FacetSet;
823 FacetStringConverter& fsc = c.facetstringconverter();
824 FacetSet allFacets(c.tags().facets());
825 for (FacetSet::const_iterator i = allFacets.begin(); i != allFacets.end(); i++)
828 ensure_equals(*i, fsc(fsc(*i)));
830 cerr <<
"Note: exception thrown during processing[string] of facet " << i->name() << endl;
835 FacetIntConverter& fic = c.facetintconverter();
836 for (FacetSet::const_iterator i = allFacets.begin(); i != allFacets.end(); i++)
839 ensure_equals(*i, fic(fic(*i)));
841 cerr <<
"Note: exception thrown during processing[int] of facet " << i->name() << endl;
848 template<>
template<>
851 typedef Tagcoll::OpSet<entity::Tag> TagSet;
853 TagStringConverter& tsc = c.tagstringconverter();
854 TagSet allTags(c.tags().tags());
855 for (TagSet::const_iterator i = allTags.begin(); i != allTags.end(); i++)
858 ensure_equals(*i, tsc(tsc(*i)));
860 cerr <<
"Note: exception thrown during processing[string] of tag " << i->fullname() << endl;
865 TagIntConverter& tic = c.tagintconverter();
866 for (TagSet::const_iterator i = allTags.begin(); i != allTags.end(); i++)
869 ensure_equals(*i, tic(tic(*i)));
871 cerr <<
"Note: exception thrown during processing[int] of tag " << i->fullname() << endl;
878 template<>
template<>
881 TagStringConverter& tsc = c.tagstringconverter();
882 OpSet<entity::Tag> ts;
885 ensure(tsc(
"accessibility::TODO") != entity::Tag());
886 ensure(tsc(
"role::sw:devel-lib") != entity::Tag());
887 ensure(tsc(
"x11::xserver") != entity::Tag());
888 ensure(tsc(
"antani") == entity::Tag());
889 ensure(tsc(
"blinda") == entity::Tag());
890 ensure(tsc(
"supercazzola") == entity::Tag());
892 ts = tsc.parseTagList(
"role::sw:devel-lib");
893 ensure_equals(ts.size(), 1u);
894 ensure(ts.contains(tsc(
"role::sw:devel-lib")));
896 ts = tsc.parseTagList(
"accessibility::TODO, x11::xserver, role::sw:devel-lib");
897 ensure_equals(ts.size(), 3u);
898 ensure(ts.contains(tsc(
"accessibility::TODO")));
899 ensure(ts.contains(tsc(
"role::sw:devel-lib")));
900 ensure(ts.contains(tsc(
"x11::xserver")));
902 ts = tsc.parseTagList(
"antani");
903 ensure_equals(ts.size(), 0u);
905 ts = tsc.parseTagList(
"antani, blinda, supercazzola");
906 ensure_equals(ts.size(), 0u);
908 ts = tsc.parseTagList(
"antani, x11::xserver, blinda");
909 ensure_equals(ts.size(), 1u);
910 ensure(ts.contains(tsc(
"x11::xserver")));
914 template<>
template<>
917 TagStringConverter& tsc = c.tagstringconverter();
918 OpSet<entity::Tag> ts;
921 ensure(tsc(
"role::TODO") != entity::Tag());
922 ensure(tsc(
"role::sw:server") != entity::Tag());
923 ensure(tsc(
"role::aux:dummy") != entity::Tag());
924 ensure(tsc(
"role::sw:amusement") != entity::Tag());
925 ensure(tsc(
"role::sw:server{}") == entity::Tag());
926 ensure(tsc(
"role::{}") == entity::Tag());
927 ensure(tsc(
"role::{") == entity::Tag());
928 ensure(tsc(
"role::}") == entity::Tag());
930 ts = tsc.parseTagList(
"role::{TODO,sw:server,aux:dummy,sw:amusement}");
931 ensure_equals(ts.size(), 4u);
932 ensure(ts.contains(tsc(
"role::TODO")));
933 ensure(ts.contains(tsc(
"role::sw:server")));
934 ensure(ts.contains(tsc(
"role::aux:dummy")));
935 ensure(ts.contains(tsc(
"role::sw:amusement")));
937 ts = tsc.parseTagList(
"role::{TODO,aux:dummy}, role::sw:{server,amusement}");
938 ensure_equals(ts.size(), 4u);
939 ensure(ts.contains(tsc(
"role::TODO")));
940 ensure(ts.contains(tsc(
"role::sw:server")));
941 ensure(ts.contains(tsc(
"role::aux:dummy")));
942 ensure(ts.contains(tsc(
"role::sw:amusement")));