summaryrefslogtreecommitdiff
path: root/gentoobrowse-api/service/maintenance/ebuildMetaProcessor.cpp
blob: 1085b70a944ca690c468715762d4c880b86c880b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "ebuildMetaProcessor.h"
#include <modifycommand.h>
#include <boost/filesystem/operations.hpp>
#include <glibmm/regex.h>
#include "fileUtils.h"
#include "xmlUtils.h"
#include "dbUtils.h"
#include <sql/maintenance/ebuildInsert.sql.h>
#include <sql/maintenance/ebuildUpdate.sql.h>
#include <sql/maintenance/ebuildDelete.sql.h>

namespace U = Gentoo::Utils;
using namespace Gentoo::Utils::File;

static Glib::RefPtr<Glib::Regex> packageVersion = Glib::Regex::create("^(.+)-([0-9].*)$");

namespace Gentoo {
	namespace Service {
		class EbuildCacheParser : public U::MemMap {
			public:
				typedef std::pair<const char *, const char *> Range;
				typedef std::map<std::string, const Range> KVs;

				EbuildCacheParser(const boost::filesystem::path & p) :
					U::MemMap(p)
				{
					const char * chardata = (const char *)this->data;
					while (const char * eq = strchr(chardata, '=')) {
						if (const char * nl = strchr(eq + 1, '\n')) {
							kvs.insert({ std::string(chardata, eq), { eq + 1, nl } });
							chardata = nl + 1;
						}
						else {
							kvs.insert({ std::string(chardata, eq), { eq + 1, (const char *)this->data + st.st_size } });
							return;
						}
					}
				}

				boost::optional<Glib::ustring> get(const std::string & key) const
				{
					auto kvi = kvs.find(key);
					if (kvi == kvs.end()) {
						return boost::optional<Glib::ustring>();
					}
					return Glib::ustring(kvi->second.first, kvi->second.second);
				}

			private:
				KVs kvs;
		};

		const int EbuildMetaProcessor::FILETYPEID = 1;

		void
		EbuildMetaProcessor::created(DB::Connection * dbc, const boost::filesystem::path & fn, const boost::filesystem::path & path) const
		{
			Glib::MatchInfo matches;
			const Glib::ustring pv = (fn / 4).string();
			if (packageVersion->match(pv, matches)) {
				auto m = dbc->modify(sql::maintenance::ebuildInsert::sql);
				EbuildCacheParser ecp(path);
				m->bindParamS(0, matches.fetch(2));
				m->bindParamS(1, matches.fetch(2));
				Utils::Database::bindOptionalsS(m, 2, { ecp.get("SLOT") });
				Utils::Database::bindOptionalsS(m, 3, { ecp.get("LICENSE") });
				m->bindParamT(4, boost::posix_time::from_time_t(ecp.getStat().st_mtim.tv_sec));
				m->bindParamS(5, (fn / 0).string()); // repo
				m->bindParamS(6, (fn / 3).string()); // category
				m->bindParamS(7, matches.fetch(1)); // package
				m->execute();
			}
		}

		void
		EbuildMetaProcessor::modified(DB::Connection * dbc, const boost::filesystem::path & fn, const boost::filesystem::path & path) const
		{
			Glib::MatchInfo matches;
			const Glib::ustring pv = (fn / 4).string();
			if (packageVersion->match(pv, matches)) {
				auto m = dbc->modify(sql::maintenance::ebuildUpdate::sql);
				EbuildCacheParser ecp(path);
				Utils::Database::bindOptionalsS(m, 0, { ecp.get("SLOT") });
				Utils::Database::bindOptionalsS(m, 1, { ecp.get("LICENSE") });
				m->bindParamT(2, boost::posix_time::from_time_t(ecp.getStat().st_mtim.tv_sec));
				m->bindParamS(3, (fn / 0).string()); // repo
				m->bindParamS(4, (fn / 3).string()); // category
				m->bindParamS(5, matches.fetch(1)); // package
				m->bindParamS(6, matches.fetch(2)); // version
				m->execute();
			}
		}

		void
		EbuildMetaProcessor::deleted(DB::Connection * dbc, const boost::filesystem::path & fn) const
		{
			auto m = dbc->modify(sql::maintenance::ebuildDelete::sql);
			m->bindParamS(0, (fn / 0).string());
			m->bindParamS(1, (fn / 3).string());
			m->bindParamS(2, (fn / 4).string());
			m->execute();
		}
	}
}