[packagekit] packagekit: Branch 'master' - 19 commits
Richard Hughes
hughsient at kemper.freedesktop.org
Wed Oct 10 15:04:22 PDT 2007
TODO | 2
backends/apt/Makefile.am | 9
backends/apt/apt-build-db.cpp | 283 ++++++++++++++++
backends/apt/helpers/.gitignore | 2
backends/apt/helpers/Makefile.am | 16
backends/apt/helpers/aptBackend.py | 53 +++
backends/apt/helpers/refresh-cache.py | 22 +
backends/apt/pk-backend-apt.cpp | 580 +--------------------------------
backends/apt/pk-backend-apt.h | 30 +
backends/apt/python-backend-common.cpp | 38 ++
backends/apt/python-backend-common.h | 27 +
backends/apt/sqlite-pkg-cache.cpp | 227 ++++++++++++
backends/apt/sqlite-pkg-cache.h | 39 ++
configure.ac | 1
libpackagekit/pk-client.c | 77 ++++
python/pk-frontend-test.py | 6
src/pk-backend.c | 6
17 files changed, 859 insertions(+), 559 deletions(-)
New commits:
diff-tree 58b32e8a981ff098a989a9187637649a69c4ded1 (from 48f727193d0129293e8e5e7709e521d2809316dc)
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Oct 10 23:01:08 2007 +0100
check the private tid before we compare to silence lots of warnings
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 48a93a8..fe8a0e0 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -225,12 +225,21 @@ pk_client_finished_cb (DBusGProxy *prox
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
exit = pk_exit_enum_from_text (exit_text);
pk_debug ("emit finished %i, %i", exit, runtime);
+
+ /* only this instance is finished, and do it before the signal so we can reset */
+ client->priv->is_finished = TRUE;
+
g_signal_emit (client , signals [PK_CLIENT_FINISHED], 0, exit, runtime);
}
- client->priv->is_finished = TRUE;
}
/**
@@ -245,6 +254,12 @@ pk_client_percentage_changed_cb (DBusGPr
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit percentage-changed %i", percentage);
g_signal_emit (client , signals [PK_CLIENT_PERCENTAGE_CHANGED], 0, percentage);
@@ -263,6 +278,12 @@ pk_client_sub_percentage_changed_cb (DBu
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit sub-percentage-changed %i", percentage);
g_signal_emit (client, signals [PK_CLIENT_SUB_PERCENTAGE_CHANGED], 0, percentage);
@@ -280,6 +301,12 @@ pk_client_no_percentage_updates_cb (DBus
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit no-percentage-updates");
g_signal_emit (client , signals [PK_CLIENT_NO_PERCENTAGE_UPDATES], 0);
@@ -300,6 +327,12 @@ pk_client_transaction_status_changed_cb
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
status = pk_status_enum_from_text (status_text);
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit transaction-status-changed %i", status);
@@ -323,6 +356,12 @@ pk_client_package_cb (DBusGProxy *prox
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit package %s, %s, %s", info_text, package_id, summary);
info = pk_info_enum_from_text (info_text);
@@ -364,6 +403,12 @@ pk_client_transaction_cb (DBusGProxy *pr
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
role = pk_role_enum_from_text (role_text);
pk_debug ("emitting transaction %s, %s, %i, %s, %i, %s", old_tid, timespec, succeeded, role_text, duration, data);
@@ -388,6 +433,12 @@ pk_client_update_detail_cb (DBusGProxy
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit update-detail %s, %s, %s, %s, %s, %s",
package_id, updates, obsoletes, url, restart, update_text);
@@ -415,6 +466,12 @@ pk_client_description_cb (DBusGProxy *p
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
group = pk_group_enum_from_text (group_text);
pk_debug ("emit description %s, %s, %i, %s, %s, %ld, %s",
@@ -435,6 +492,12 @@ pk_client_repo_signature_required_cb (DB
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
pk_debug ("emit repo_signature_required tid:%s, %s, %s, %s, %s, %s, %s",
tid, repository_name, key_url, key_userid, key_id, key_timestamp, type_text);
@@ -457,6 +520,12 @@ pk_client_error_code_cb (DBusGProxy *pr
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
code = pk_error_enum_from_text (code_text);
pk_debug ("emit error-code %i, %s", code, details);
@@ -478,6 +547,12 @@ pk_client_require_restart_cb (DBusGProxy
g_return_if_fail (client != NULL);
g_return_if_fail (PK_IS_CLIENT (client));
+ /* check to see if we have been assigned yet */
+ if (client->priv->tid == NULL) {
+ pk_debug ("ignoring tid:%s as we are not yet assigned", tid);
+ return;
+ }
+
if (pk_transaction_id_equal (tid, client->priv->tid) == TRUE) {
restart = pk_restart_enum_from_text (restart_text);
pk_debug ("emit require-restart %i, %s", restart, details);
diff-tree 48f727193d0129293e8e5e7709e521d2809316dc (from cbc060b6d6012ebf28690c2620a6c180025822c6)
Author: Ken VanDine <ken at vandine.org>
Date: Wed Oct 10 16:30:38 2007 -0400
Added a blocker
diff --git a/TODO b/TODO
index 29a27f7..70e8b9e 100644
--- a/TODO
+++ b/TODO
@@ -14,6 +14,7 @@ RepoSetData(s=rid,s=data,s=value)
*** pk-application (client) ***
Use an icons for installed and not-installed rather than tickboxes
Refresh the query list after an install or remove (means saving the query and re-issuing)
+** RELEASE BLOCKER **
*** Client library has to be able to re_issue ***
Need to save PkRole
diff-tree cbc060b6d6012ebf28690c2620a6c180025822c6 (from c62bd856cf9796a028c11ccca0588dc924ad943b)
Author: Ken VanDine <ken at vandine.org>
Date: Wed Oct 10 16:29:57 2007 -0400
Removed a blocker from TODO
diff --git a/TODO b/TODO
index a9f534c..29a27f7 100644
--- a/TODO
+++ b/TODO
@@ -2,7 +2,6 @@ Order of no particular importance:
*** pk-update-icon (client) ***
* Don't re-run get-updates when selecting "Show updates" from the update icon, just populate it with the previous results.
-NOTE: RELEASE BLOCKER
*** Add new callback for status ***
TimeRemaining()
diff-tree c62bd856cf9796a028c11ccca0588dc924ad943b (from ee658a84df7ffc982e5b0091a49ac8513b0ca99b)
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Oct 10 20:23:59 2007 +0100
remove some trailing whitespace in toms patch
diff --git a/backends/apt/apt-build-db.cpp b/backends/apt/apt-build-db.cpp
index 54fe28a..894b70b 100644
--- a/backends/apt/apt-build-db.cpp
+++ b/backends/apt/apt-build-db.cpp
@@ -64,13 +64,13 @@ void apt_build_db(PkBackend * backend, s
g_strfreev(items);
continue;
}
-
+
/* warning: nasty hack with g_strjoinv */
temp = items[len-2];
items[len-2] = NULL;
parsed_name = g_strjoinv("_",items);
items[len-2] = temp;
-
+
if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
{
gchar * repo = NULL, *fullname;
@@ -155,9 +155,9 @@ void apt_build_db(PkBackend * backend, s
parsed_name = g_strjoinv("_",items);
items[len-1] = temp;
}
-
+
pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
-
+
repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
if (repo == NULL)
{
@@ -261,7 +261,7 @@ void apt_build_db(PkBackend * backend, s
}
if (next == NULL)
break;
- begin = next;
+ begin = next;
}
res = sqlite3_exec(db,"commit",NULL,NULL,NULL);
if (res!=SQLITE_OK)
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index 14c3ea7..369801d 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -7,7 +7,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -82,7 +82,7 @@ sqlite_search_packages_thread (PkBackend
sqlite3_stmt *package = NULL;
g_strdelimit(st->search," ",'%');
-
+
if (st->depth == SEARCH_NAME)
sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
else if (st->depth == SEARCH_DETAILS)
@@ -92,7 +92,7 @@ sqlite_search_packages_thread (PkBackend
pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type");
goto end_search_packages;
}
-
+
pk_debug("statement is '%s'",sel);
res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
g_free(sel);
diff-tree ee658a84df7ffc982e5b0091a49ac8513b0ca99b (from bb2a7b0b47d8b152f778798ac3cfe06f28ebae21)
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Oct 10 20:21:52 2007 +0100
Top is the APT dude. I share none of the credit
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index 0e3d7d7..2b72d65 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -130,7 +130,7 @@ static void backend_search_file(PkBacken
extern "C" PK_BACKEND_OPTIONS (
"APT", /* description */
"0.0.1", /* version */
- "Richard Hughes <richard at hughsie.com>, Tom Parker <palfrey at tevp.net>", /* author */
+ "Tom Parker <palfrey at tevp.net>", /* author */
backend_initialize, /* initalize */
NULL, /* destroy */
backend_get_groups, /* get_groups */
diff-tree bb2a7b0b47d8b152f778798ac3cfe06f28ebae21 (from a4a73837d340069f3128962125b38555d5010d42)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:09:50 2007 +0200
sqlite-pkg-cache listed as under GPLv2 only
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index f71c54f..14c3ea7 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -6,9 +6,8 @@
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
+ * the Free Software Foundation; version 2 of the License.
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
diff-tree a4a73837d340069f3128962125b38555d5010d42 (from b5b570785fcbe6a0bfdb0079d5f4b8c215468840)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:08:42 2007 +0200
Add "depends" call to pk-frontend-test.py
diff --git a/python/pk-frontend-test.py b/python/pk-frontend-test.py
index 40bd9a7..4761b4f 100755
--- a/python/pk-frontend-test.py
+++ b/python/pk-frontend-test.py
@@ -68,6 +68,12 @@ def desc(*args):
raise PackageKitTransactionFailure
return p.GetDescription(args[0][0])
+def depends(*args):
+ if len(args)!=1 or len(args[0])!=1:
+ print "depends only takes single arg"
+ raise PackageKitTransactionFailure
+ return p.GetDepends(args[0][0])
+
def refresh_cache(*args):
if len(args)>0 and len(args[0])>0:
print "refresh_cache doesn't take args"
diff-tree b5b570785fcbe6a0bfdb0079d5f4b8c215468840 (from 50713c3aac3a164ee8163262a4e666a5d34634d6)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:06:59 2007 +0200
Clear up name vs. detail searching in sqlite cache
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index 1475715..f71c54f 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -74,6 +74,7 @@ sqlite_search_packages_thread (PkBackend
{
search_task *st = (search_task *) data;
int res;
+ gchar *sel;
pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
pk_backend_no_percentage_updates(backend);
@@ -82,7 +83,17 @@ sqlite_search_packages_thread (PkBackend
sqlite3_stmt *package = NULL;
g_strdelimit(st->search," ",'%');
- gchar *sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
+
+ if (st->depth == SEARCH_NAME)
+ sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
+ else if (st->depth == SEARCH_DETAILS)
+ sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%' or short_desc like '%%%s%%' or long_desc like '%%%s%%'",st->search, st->search, st->search);
+ else
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Unknown search task type");
+ goto end_search_packages;
+ }
+
pk_debug("statement is '%s'",sel);
res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
g_free(sel);
@@ -106,6 +117,7 @@ sqlite_search_packages_thread (PkBackend
g_assert(0);
}
+ end_search_packages:
g_free(st->search);
g_free(st);
diff-tree 50713c3aac3a164ee8163262a4e666a5d34634d6 (from faa3d44b653b6ea36251891b2753f16967f093e9)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:05:01 2007 +0200
Add backend "must be older" file for sqlite rebuilding
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index 67a80aa..0e3d7d7 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -47,11 +47,20 @@ static void backend_initialize(PkBackend
{
if (!inited)
{
+ gchar *apt_fname = NULL;
if (pkgInitConfig(*_config) == false)
pk_debug("pkginitconfig was false");
if (pkgInitSystem(*_config, _system) == false)
pk_debug("pkginitsystem was false");
- sqlite_init_cache(backend, APT_DB, apt_build_db);
+
+ apt_fname = g_strconcat(
+ _config->Find("Dir").c_str(),
+ _config->Find("Dir::Cache").c_str(),
+ _config->Find("Dir::Cache::pkgcache").c_str(),
+ NULL);
+
+ sqlite_init_cache(backend, APT_DB, apt_fname, apt_build_db);
+ g_free(apt_fname);
inited = TRUE;
}
}
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index 1205676..1475715 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -21,6 +21,7 @@
#include <sqlite3.h>
#include <glib.h>
+#include <glib/gstdio.h>
#include "sqlite-pkg-cache.h"
static sqlite3 *db = NULL;
@@ -36,27 +37,35 @@ struct search_task {
};
void
-sqlite_init_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *))
+sqlite_init_cache(PkBackend *backend, const char* dbname, const char *compare_fname, void (*build_db)(PkBackend *, sqlite3 *))
{
- gint ret;
+ int ret;
+ struct stat st;
+ time_t db_age;
ret = sqlite3_open (dbname, &db);
ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
g_assert(ret == SQLITE_OK);
- ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
- if (ret == SQLITE_ERROR)
- {
- ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it!
- //g_assert(ret == SQLITE_OK);
- pk_debug("wiped db");
- ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
- g_assert(ret == SQLITE_OK);
- build_db(backend,db);
+ g_stat(dbname, &st);
+ db_age = st.st_mtime;
+ g_stat(compare_fname, &st);
+ if (db_age>=st.st_mtime)
+ {
+ ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
+ if (ret != SQLITE_ERROR)
+ return;
+ }
+ ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it!
+ //g_assert(ret == SQLITE_OK);
+ pk_debug("wiped db");
+ ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
+ g_assert(ret == SQLITE_OK);
+
+ build_db(backend,db);
- sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL);
- sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL);
- }
+ sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL);
+ sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL);
}
// sqlite_search_packages_thread
diff --git a/backends/apt/sqlite-pkg-cache.h b/backends/apt/sqlite-pkg-cache.h
index 0cbadcd..68f5287 100644
--- a/backends/apt/sqlite-pkg-cache.h
+++ b/backends/apt/sqlite-pkg-cache.h
@@ -30,7 +30,7 @@ typedef enum {
#include <pk-backend.h>
-void sqlite_init_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *db));
+void sqlite_init_cache(PkBackend *backend, const char* dbname, const char* compare_fname, void (*build_db)(PkBackend *, sqlite3 *db));
void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func);
diff-tree faa3d44b653b6ea36251891b2753f16967f093e9 (from a635bb191b5a90bc14578adc3f264452d90ab601)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:02:47 2007 +0200
Add common python spawner
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 1c33f10..05dcc43 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS = helpers
plugindir = @PK_PLUGIN_DIR@
plugin_LTLIBRARIES = libpk_backend_apt.la
libpk_backend_apt_la_INCLUDES = $(APT_CFLAGS) $(SQLITE_CFLAGS)
-libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp sqlite-pkg-cache.cpp apt-build-db.cpp
+libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp sqlite-pkg-cache.cpp apt-build-db.cpp python-backend-common.cpp
libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@ $(APT_LIBS) $(SQLITE_LIBS)
libpk_backend_apt_la_LDFLAGS = -module -avoid-version
libpk_backend_apt_la_CXXFLAGS = @PK_PLUGIN_CFLAGS@ -DDATABASEDIR=\""$(PK_DB_DIR)"\"
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index 29d7ec8..67a80aa 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -37,6 +37,7 @@
#include "pk-backend-apt.h"
#include "sqlite-pkg-cache.h"
+#include "python-backend-common.h"
static gboolean inited = FALSE;
@@ -83,22 +84,6 @@ backend_get_filters (PkBackend *backend,
-1);
}
-/**
- * backend_refresh_cache:
- **/
-static void backend_refresh_cache(PkBackend * backend, gboolean force)
-{
- /* check network state */
- if (pk_backend_network_is_online(backend) == FALSE)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
- pk_backend_finished(backend);
- return;
- }
-
- pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
-}
-
static gboolean backend_search_file_thread (PkBackend *backend, gpointer data)
{
//search_task *st = (search_task*)data;
@@ -149,7 +134,7 @@ extern "C" PK_BACKEND_OPTIONS (
NULL, /* get_updates */
NULL, /* install_package */
NULL, /* install_name */
- backend_refresh_cache, /* refresh_cache */
+ python_refresh_cache, /* refresh_cache */
NULL, /* remove_package */
NULL, /* resolve */
NULL, /* rollback */
diff --git a/backends/apt/python-backend-common.cpp b/backends/apt/python-backend-common.cpp
new file mode 100644
index 0000000..cfc82c7
--- /dev/null
+++ b/backends/apt/python-backend-common.cpp
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <pk-backend.h>
+
+/**
+ * python_refresh_cache:
+ **/
+void python_refresh_cache(PkBackend * backend, gboolean force)
+{
+ /* check network state */
+ if (pk_backend_network_is_online(backend) == FALSE)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline");
+ pk_backend_finished(backend);
+ return;
+ }
+
+ pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
+}
+
diff --git a/backends/apt/python-backend-common.h b/backends/apt/python-backend-common.h
new file mode 100644
index 0000000..a7573cf
--- /dev/null
+++ b/backends/apt/python-backend-common.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PYTHON_BACKEND_COMMON_H
+#define PYTHON_BACKEND_COMMON_H
+
+void python_refresh_cache(PkBackend * backend, gboolean force);
+
+#endif
+
diff-tree a635bb191b5a90bc14578adc3f264452d90ab601 (from af8de100f4ca9ac8edb8e85b071c90808e61ab19)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 17:56:12 2007 +0200
Minor sqlite-pkg-cache fixes
- Default package type is "unknown"
- Drop packages before rebuild
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index 03c672d..1205676 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -39,24 +39,23 @@ void
sqlite_init_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *))
{
gint ret;
- sqlite3_stmt *complete;
ret = sqlite3_open (dbname, &db);
ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
g_assert(ret == SQLITE_OK);
- sqlite3_prepare_v2("create table params (name text primary key, value integer)", -1, &complete, NULL)
ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
- g_assert(ret == SQLITE_OK);
if (ret == SQLITE_ERROR)
{
- sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
- build_db(backend,db);
- }
- else
- {
- /*ret = sqlite3_exec(db,"delete from packages",NULL,NULL,NULL); // clear it!
+ ret = sqlite3_exec(db,"drop table packages",NULL,NULL,NULL); // wipe it!
+ //g_assert(ret == SQLITE_OK);
+ pk_debug("wiped db");
+ ret = sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
g_assert(ret == SQLITE_OK);
- pk_debug("wiped db");*/
+
+ build_db(backend,db);
+
+ sqlite3_exec(db,"create table params (name text primary key, value integer)", NULL, NULL, NULL);
+ sqlite3_exec(db,"insert into params values ('build_complete',1)", NULL, NULL, NULL);
}
}
@@ -87,7 +86,7 @@ sqlite_search_packages_thread (PkBackend
(const gchar*)sqlite3_column_text(package,1),
(const gchar*)sqlite3_column_text(package,2),
(const gchar*)sqlite3_column_text(package,3));
- pk_backend_package(backend, FALSE, pid, (const gchar*)sqlite3_column_text(package,4));
+ pk_backend_package(backend, PK_INFO_ENUM_UNKNOWN, pid, (const gchar*)sqlite3_column_text(package,4));
g_free(pid);
if (res==SQLITE_ROW)
res = sqlite3_step(package);
diff-tree af8de100f4ca9ac8edb8e85b071c90808e61ab19 (from b923087aa63b879fd5dd075f0b5756925b934cf0)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 17:52:16 2007 +0200
Look for local as well as global backend helpers
diff --git a/src/pk-backend.c b/src/pk-backend.c
index fa43869..242c5cc 100644
--- a/src/pk-backend.c
+++ b/src/pk-backend.c
@@ -487,7 +487,11 @@ pk_backend_spawn_helper_internal (PkBack
gchar *command;
/* build script */
- filename = g_build_filename (DATADIR, "PackageKit", "helpers", backend->priv->name, script, NULL);
+ filename = g_build_filename ("..", "backends", backend->priv->name, "helpers", script, NULL);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) {
+ g_free (filename);
+ filename = g_build_filename (DATADIR, "PackageKit", "helpers", backend->priv->name, script, NULL);
+ }
pk_debug ("using spawn filename %s", filename);
if (argument != NULL) {
diff-tree b923087aa63b879fd5dd075f0b5756925b934cf0 (from 75b824ca71130c2d37e2a3e192fd80be19f2b540)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:09:24 2007 +0200
Add sqlite_get_description
Drop old libapt-based description grabbing in favour of a new and
improved sqlite-cache based one.
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index d08fd33..29d7ec8 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -23,40 +23,25 @@
#include <gmodule.h>
#include <glib.h>
#include <glib/gprintf.h>
+
+#include <math.h>
#include <string.h>
+
#include <pk-backend.h>
#include <pk-debug.h>
#include <pk-package-id.h>
#include "config.h"
-#include <apt-pkg/pkgcachegen.h>
-#include <apt-pkg/pkgcache.h>
-#include <apt-pkg/cachefile.h>
-#include <apt-pkg/progress.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/init.h>
-#include <apt-pkg/pkgrecords.h>
-#include <apt-pkg/sourcelist.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/acquire.h>
-#include <apt-pkg/acquire-item.h>
-
-#include <string.h>
-#include <math.h>
#include "pk-backend-apt.h"
#include "sqlite-pkg-cache.h"
-static pkgCacheFile *fileCache = NULL;
-static pkgSourceList *SrcList = 0;
static gboolean inited = FALSE;
#define APT_DB DATABASEDIR "/apt.db"
-struct desc_task {
- PkPackageId *pi;
-};
-
static void backend_initialize(PkBackend *backend)
{
if (!inited)
@@ -65,38 +50,11 @@ static void backend_initialize(PkBackend
pk_debug("pkginitconfig was false");
if (pkgInitSystem(*_config, _system) == false)
pk_debug("pkginitsystem was false");
- init_sqlite_cache(backend, APT_DB, apt_build_db);
+ sqlite_init_cache(backend, APT_DB, apt_build_db);
inited = TRUE;
}
}
-static pkgCacheFile *getCache(PkBackend *backend)
-{
- if (fileCache == NULL)
- {
- MMap *Map = 0;
- OpTextProgress Prog;
- // Open the cache file
- SrcList = new pkgSourceList;
- SrcList->ReadMainList();
-
- // Generate it and map it
- pkgMakeStatusCache(*SrcList, Prog, &Map, true);
-
- fileCache = new pkgCacheFile();
-
- if (fileCache->Open(Prog, FALSE) == FALSE)
- {
- pk_debug("I need more privelges");
- fileCache->Close();
- fileCache = NULL;
- }
- else
- pk_debug("cache inited");
- }
- return fileCache;
-}
-
/**
* backend_get_groups:
*/
@@ -141,121 +99,6 @@ static void backend_refresh_cache(PkBack
pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
}
-static GHashTable *PackageRecord(PkBackend *backend, pkgCache::VerIterator V)
-{
- GHashTable *ret = NULL;
-
- pkgCache & pkgCache = *(getCache(backend));
- // Find an appropriate file
- pkgCache::VerFileIterator Vf = V.FileList();
- for (; Vf.end() == false; Vf++)
- {
- if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0)
- break;
- if (Vf.end() == true)
- Vf = V.FileList();
- }
-
- // Check and load the package list file
- pkgCache::PkgFileIterator I = Vf.File();
- if (I.IsOk() == false)
- return NULL;
-
- FileFd PkgF(I.FileName(),FileFd::ReadOnly);
- if (_error->PendingError() == true)
- return NULL;
-
- // Read the record
- char *Buffer = new char[pkgCache.HeaderP->MaxVerFileSize+1];
- Buffer[V.FileList()->Size] = '\0';
- if (PkgF.Seek(V.FileList()->Offset) == false ||
- PkgF.Read(Buffer,V.FileList()->Size) == false)
- {
- delete [] Buffer;
- return NULL;
- }
- //pk_debug("buffer: '%s'\n",Buffer);
- ret = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
- gchar ** lines = g_strsplit(Buffer,"\n",-1);
- guint i;
- for (i=0;i<g_strv_length(lines);i++)
- {
- gchar ** parts = g_strsplit_set(lines[i],": ",2);
- if (g_strv_length(parts)>1)
- {
- //pk_debug("entry = '%s' : '%s'",parts[0],parts[1]);
- if (parts[0][0]=='\0')
- {
- gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
- g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
- //pk_debug("new entry = '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
- g_free(oldval);
- }
- else
- g_hash_table_insert(ret,g_strdup(parts[0]),g_strdup(parts[1]));
- }
- g_strfreev(parts);
- }
- g_strfreev(lines);
- return ret;
-
-}
-
-// backend_get_description_thread
-static gboolean backend_get_description_thread (PkBackend *backend, gpointer data)
-{
- desc_task *dt = (desc_task *) data;
-
- pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
- pk_backend_no_percentage_updates(backend);
-
- pk_debug("finding %s", dt->pi->name);
- pkgCache & pkgCache = *(getCache(backend));
- pkgDepCache::Policy Plcy;
-
- // Map versions that we want to write out onto the VerList array.
- for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
- {
- if (strcmp(dt->pi->name, P.Name())!=0)
- continue;
-
- // Find the proper version to use.
- pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
- GHashTable *pkg = PackageRecord(backend,V);
- pk_backend_description(backend,dt->pi->name,
- "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)g_hash_table_lookup(pkg,"Description"),"");
- g_hash_table_unref(pkg);
- }
- return NULL;
-}
-
-/**
- * backend_get_description:
- */
-static void
-backend_get_description (PkBackend *backend, const gchar *package_id)
-{
- g_return_if_fail (backend != NULL);
- desc_task *data = g_new(struct desc_task, 1);
- if (data == NULL)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_OOM, "Failed to allocate memory for search task");
- pk_backend_finished(backend);
- return;
- }
-
- data->pi = pk_package_id_new_from_string(package_id);
- if (data->pi == NULL)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
- pk_backend_finished(backend);
- return;
- }
-
- pk_backend_thread_helper (backend, backend_get_description_thread, data);
- return;
-}
-
static gboolean backend_search_file_thread (PkBackend *backend, gpointer data)
{
//search_task *st = (search_task*)data;
@@ -300,7 +143,7 @@ extern "C" PK_BACKEND_OPTIONS (
backend_get_filters, /* get_filters */
NULL, /* cancel */
NULL, /* get_depends */
- backend_get_description, /* get_description */
+ sqlite_get_description, /* get_description */
NULL, /* get_requires */
NULL, /* get_update_detail */
NULL, /* get_updates */
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
index 5e90f8e..03c672d 100644
--- a/backends/apt/sqlite-pkg-cache.cpp
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -25,35 +25,44 @@
static sqlite3 *db = NULL;
+struct desc_task {
+ PkPackageId *pi;
+};
+
struct search_task {
gchar *search;
gchar *filter;
SearchDepth depth;
};
-void init_sqlite_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *))
+void
+sqlite_init_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *))
{
gint ret;
- char *errmsg = NULL;
+ sqlite3_stmt *complete;
+
ret = sqlite3_open (dbname, &db);
ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
g_assert(ret == SQLITE_OK);
- sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,&errmsg);
- if (errmsg == NULL) // success, ergo didn't exist
+ sqlite3_prepare_v2("create table params (name text primary key, value integer)", -1, &complete, NULL)
+ ret = sqlite3_exec(db, "select value from params where name = 'build_complete'", NULL, NULL, NULL);
+ g_assert(ret == SQLITE_OK);
+ if (ret == SQLITE_ERROR)
{
+ sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,NULL);
build_db(backend,db);
}
else
{
- sqlite3_free(errmsg);
/*ret = sqlite3_exec(db,"delete from packages",NULL,NULL,NULL); // clear it!
g_assert(ret == SQLITE_OK);
pk_debug("wiped db");*/
}
}
-// backend_search_packages_thread
-gboolean backend_search_packages_thread (PkBackend *backend, gpointer data)
+// sqlite_search_packages_thread
+static gboolean
+sqlite_search_packages_thread (PkBackend *backend, gpointer data)
{
search_task *st = (search_task *) data;
int res;
@@ -118,21 +127,82 @@ backend_search_common(PkBackend * backen
}
/**
- * backend_search_details:
+ * sqlite_search_details:
*/
void
sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
{
- backend_search_common(backend, filter, search, SEARCH_DETAILS, backend_search_packages_thread);
+ backend_search_common(backend, filter, search, SEARCH_DETAILS, sqlite_search_packages_thread);
}
/**
- * backend_search_name:
+ * sqlite_search_name:
*/
void
sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
{
- backend_search_common(backend, filter, search, SEARCH_NAME, backend_search_packages_thread);
+ backend_search_common(backend, filter, search, SEARCH_NAME, sqlite_search_packages_thread);
+}
+
+// sqlite_get_description_thread
+static gboolean sqlite_get_description_thread (PkBackend *backend, gpointer data)
+{
+ desc_task *dt = (desc_task *) data;
+ int res;
+
+ pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
+ pk_backend_no_percentage_updates(backend);
+
+ pk_debug("finding %s", dt->pi->name);
+
+ sqlite3_stmt *package = NULL;
+ gchar *sel = g_strdup_printf("select long_desc from packages where name = '%s' and version = '%s' and repo = '%s'",dt->pi->name,dt->pi->version,dt->pi->data);
+ pk_debug("statement is '%s'",sel);
+ res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
+ g_free(sel);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
+ res = sqlite3_step(package);
+ pk_backend_description(backend,dt->pi->name, "unknown", PK_GROUP_ENUM_OTHER,(const gchar*)sqlite3_column_text(package,0),"",0,"");
+ res = sqlite3_step(package);
+ if (res==SQLITE_ROW)
+ pk_error("multiple matches for that package!");
+ if (res!=SQLITE_DONE)
+ {
+ pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
+ g_assert(0);
+ }
+
+ g_free(dt);
+
+ return TRUE;
+}
+
+/**
+ * sqlite_get_description:
+ */
+void
+sqlite_get_description (PkBackend *backend, const gchar *package_id)
+{
+ g_return_if_fail (backend != NULL);
+ desc_task *data = g_new(struct desc_task, 1);
+ if (data == NULL)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_OOM, "Failed to allocate memory for search task");
+ pk_backend_finished(backend);
+ return;
+ }
+
+ data->pi = pk_package_id_new_from_string(package_id);
+ if (data->pi == NULL)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
+ pk_backend_finished(backend);
+ return;
+ }
+
+ pk_backend_thread_helper (backend, sqlite_get_description_thread, data);
+ return;
}
diff --git a/backends/apt/sqlite-pkg-cache.h b/backends/apt/sqlite-pkg-cache.h
index 99511bf..0cbadcd 100644
--- a/backends/apt/sqlite-pkg-cache.h
+++ b/backends/apt/sqlite-pkg-cache.h
@@ -30,9 +30,10 @@ typedef enum {
#include <pk-backend.h>
-void init_sqlite_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *db));
+void sqlite_init_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *db));
void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func);
+void sqlite_get_description (PkBackend *backend, const gchar *package_id);
#endif
diff-tree 75b824ca71130c2d37e2a3e192fd80be19f2b540 (from a2ed6f5baffd0a2e0053bbada29c64fc3ba8d071)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 17:58:11 2007 +0200
Move to python refresh-cache for apt backend
Given the lack of caching for the internal apt pointers between
tasks, we're not gaining anything from a copy&paste of the
internal apt update code, and so it's easier to just do callouts
into python for the cache refresh.
This also means we need a backends/apt/helpers folder, and the
config changes for that
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 82f364b..1c33f10 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -1,3 +1,4 @@
+SUBDIRS = helpers
plugindir = @PK_PLUGIN_DIR@
plugin_LTLIBRARIES = libpk_backend_apt.la
libpk_backend_apt_la_INCLUDES = $(APT_CFLAGS) $(SQLITE_CFLAGS)
diff --git a/backends/apt/helpers/.gitignore b/backends/apt/helpers/.gitignore
new file mode 100644
index 0000000..d18402d
--- /dev/null
+++ b/backends/apt/helpers/.gitignore
@@ -0,0 +1,2 @@
+*.pyc
+.*.swp
diff --git a/backends/apt/helpers/Makefile.am b/backends/apt/helpers/Makefile.am
new file mode 100644
index 0000000..c14397e
--- /dev/null
+++ b/backends/apt/helpers/Makefile.am
@@ -0,0 +1,16 @@
+
+helperdir = $(datadir)/PackageKit/helpers/apt
+
+NULL =
+
+dist_helper_DATA = \
+ refresh-cache.py \
+ aptBackend.py \
+ $(NULL)
+
+install-data-hook:
+ chmod a+rx $(DESTDIR)$(helperdir)/*.py
+
+clean-local :
+ rm -f *~
+
diff --git a/backends/apt/helpers/aptBackend.py b/backends/apt/helpers/aptBackend.py
new file mode 100644
index 0000000..b2ca5cc
--- /dev/null
+++ b/backends/apt/helpers/aptBackend.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+
+from packagekit.backend import *
+import apt
+
+class PackageKitProgress(apt.progress.OpProgress, apt.progress.FetchProgress):
+ def __init__(self, backend):
+ self.backend = backend
+
+ # OpProgress callbacks
+ def update(self, percent):
+ self.backend.percentage(percent)
+
+ def done(self):
+ self.backend.percentage(50.0)
+
+ # FetchProgress callbacks
+ def pulse(self):
+ apt.progress.FetchProgress.pulse(self)
+ self.backend.percentage(self.percent)
+
+ def stop(self):
+ print "self.inc (stop)"
+ self.backend.percentage(100)
+
+ def mediaChange(self, medium, drive):
+ self.backend.error(ERROR_INTERNAL_ERROR, "Needed to do a medium change!")
+
+class PackageKitAptBackend(PackageKitBaseBackend):
+ def refresh_cache(self):
+ '''
+ Implement the {backend}-refresh_cache functionality
+ '''
+ self.percentage(0)
+ pkp = PackageKitProgress(self)
+ cache = apt.Cache(pkp)
+ if cache.update(pkp) == False:
+ self.error(ERROR_INTERNAL_ERROR,"Fetch failure")
+
diff --git a/backends/apt/helpers/refresh-cache.py b/backends/apt/helpers/refresh-cache.py
new file mode 100755
index 0000000..5feb6e5
--- /dev/null
+++ b/backends/apt/helpers/refresh-cache.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+#
+# Apt refresh-cache handler. Modified from the yum handler
+#
+# Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+# Copyright (C) 2007 Red Hat Inc, Seth Vidal <skvidal at fedoraproject.org>
+# Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+#
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+import sys
+
+from aptBackend import PackageKitAptBackend
+
+backend = PackageKitAptBackend(sys.argv[1:])
+backend.refresh_cache()
+sys.exit(0)
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index f4955c9..d08fd33 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -97,144 +97,6 @@ static pkgCacheFile *getCache(PkBackend
return fileCache;
}
-class UpdatePercentage:public pkgAcquireStatus
-{
- double old;
- PkBackend *backend;
-
- public:
- UpdatePercentage(PkBackend *tk)
- {
- old = -1;
- backend = tk;
- }
-
- virtual bool MediaChange(string Media,string Drive)
- {
- pk_debug("PANIC!: we don't handle mediachange");
- return FALSE;
- }
-
- virtual bool Pulse(pkgAcquire *Owner)
- {
- pkgAcquireStatus::Pulse(Owner);
- double percent = double(CurrentBytes*100.0)/double(TotalBytes);
- if (old!=percent)
- {
- pk_backend_change_percentage(backend,(guint)percent);
- pk_backend_change_sub_percentage(backend,((guint)(percent*100.0))%100);
- old = percent;
- }
- return true;
- }
-};
-
-// backend_refresh_cache_thread - Update the package lists
-// Swiped from apt-get's update mode
-static gboolean backend_refresh_cache_thread (PkBackend *backend, gpointer data)
-{
- pkgCacheFile *Cache;
- bool Failed = false;
- bool TransientNetworkFailure = false;
- OpTextProgress Prog;
-
- /* easy as that */
- pk_backend_change_status(backend, PK_STATUS_ENUM_REFRESH_CACHE);
-
- Cache = getCache(backend);
-
- // Get the source list
- pkgSourceList List;
- if (List.ReadMainList() == false)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failure reading lists");
- return FALSE;
- }
-
- // Lock the list directory
- FileFd Lock;
- if (_config->FindB("Debug::NoLocking", false) == false)
- {
- Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
- if (_error->PendingError() == true)
- {
- _error->DumpErrors();
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Unable to lock the list directory");
- return FALSE;
- }
- }
-
- // Create the download object
- UpdatePercentage *Stat = new UpdatePercentage(backend);
- pkgAcquire Fetcher(Stat);
-
- // Populate it with the source selection
- if (List.GetIndexes(&Fetcher) == false)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failed to populate the source selection");
- goto do_update_clean;
- }
-
- // Run it
- if (Fetcher.Run() == pkgAcquire::Failed)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failed to run the fetcher");
- goto do_update_clean;
- }
-
- for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
- {
- if ((*I)->Status == pkgAcquire::Item::StatDone)
- continue;
-
- (*I)->Finished();
-
- fprintf(stderr, "Failed to fetch %s %s\n", (*I)->DescURI().c_str(), (*I)->ErrorText.c_str());
-
- if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
- {
- TransientNetworkFailure = true;
- continue;
- }
-
- Failed = true;
- }
-
- // Clean out any old list files
- if (!TransientNetworkFailure && _config->FindB("APT::Get::List-Cleanup", true) == true)
- {
- if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
- Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failed to clean out any old list files");
- goto do_update_clean;
- }
- }
-
- // Prepare the cache.
- Cache = getCache(backend);
- if (Cache->BuildCaches(Prog,false) == false)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failed to prepare the cache");
- goto do_update_clean;
- }
-
- if (TransientNetworkFailure == true)
- pk_debug("Some index files failed to download, they have been ignored, or old ones used instead.");
- else if (Failed == true)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Generic Error");
- goto do_update_clean;
- }
-
- delete Stat;
- return TRUE;
-
- do_update_clean:
- delete Stat;
- return FALSE;
-}
-
/**
* backend_get_groups:
*/
@@ -276,7 +138,7 @@ static void backend_refresh_cache(PkBack
return;
}
- pk_backend_thread_helper(backend, backend_refresh_cache_thread, NULL);
+ pk_backend_spawn_helper (backend, "refresh-cache.py", NULL);
}
static GHashTable *PackageRecord(PkBackend *backend, pkgCache::VerIterator V)
diff --git a/configure.ac b/configure.ac
index f945914..833c748 100644
--- a/configure.ac
+++ b/configure.ac
@@ -368,6 +368,7 @@ docs/Makefile
backends/Makefile
backends/alpm/Makefile
backends/apt/Makefile
+backends/apt/helpers/Makefile
backends/box/Makefile
backends/box/helpers/Makefile
backends/conary/Makefile
diff-tree a2ed6f5baffd0a2e0053bbada29c64fc3ba8d071 (from 8ae7eeb02211070c10b4a39577ec0cebf695c202)
Author: Tom Parker <palfrey at tevp.net>
Date: Thu Sep 27 20:39:13 2007 +0200
Handle full descriptions in apt sqlite builder
diff --git a/backends/apt/apt-build-db.cpp b/backends/apt/apt-build-db.cpp
index 602f5a6..54fe28a 100644
--- a/backends/apt/apt-build-db.cpp
+++ b/backends/apt/apt-build-db.cpp
@@ -203,6 +203,14 @@ void apt_build_db(PkBackend * backend, s
{
if (haspk)
{
+ if (description!=NULL)
+ {
+ res=sqlite3_bind_text(package,FIELD_LONG,description,-1,SQLITE_TRANSIENT);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during description bind: %s", sqlite3_errmsg(db));
+ g_free(description);
+ description = NULL;
+ }
res = sqlite3_step(package);
if (res!=SQLITE_DONE)
pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
@@ -214,10 +222,14 @@ void apt_build_db(PkBackend * backend, s
}
else if (begin[0]==' ')
{
- /*gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
- g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
- //pk_debug("new entry = '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
- g_free(oldval);*/
+ if (description == NULL)
+ description = g_strdup(&begin[1]);
+ else
+ {
+ gchar *oldval = description;
+ description = g_strconcat(oldval, "\n",&begin[1],NULL);
+ g_free(oldval);
+ }
}
else
{
diff-tree 8ae7eeb02211070c10b4a39577ec0cebf695c202 (from ac4809e980c5d4fa587c14050c85a07ee9ad9958)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 19:08:15 2007 +0200
Cleanup variable usage in apt_build_db
apt_build_db now specifies variables earlier on in a C-style
way vs. the earlier use of C++-style mid-function declarations
Also, the deprecated "version" and "description" regexes are
removed, and the insert statement is generated earlier.
Plus fix potential build_apt_db crash
diff --git a/backends/apt/apt-build-db.cpp b/backends/apt/apt-build-db.cpp
index 8b46002..602f5a6 100644
--- a/backends/apt/apt-build-db.cpp
+++ b/backends/apt/apt-build-db.cpp
@@ -32,9 +32,11 @@ void apt_build_db(PkBackend * backend, s
gchar *contents = NULL;
gchar *sdir;
const gchar *fname;
- GRegex *origin, *suite, *version, *description;
+ GRegex *origin, *suite;
GDir *dir;
GHashTable *releases;
+ int res;
+ sqlite3_stmt *package = NULL;
pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
pk_backend_no_percentage_updates(backend);
@@ -51,9 +53,6 @@ void apt_build_db(PkBackend * backend, s
origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
- version = g_regex_new("^Version: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
- description = g_regex_new("^Description: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
-
releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
while ((fname = g_dir_read_name(dir))!=NULL)
{
@@ -117,6 +116,11 @@ void apt_build_db(PkBackend * backend, s
/* and then we need to do this again, but this time we're looking for the packages */
dir = g_dir_open(sdir,0,&error);
+ res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
+ else
+ pk_debug("insert prepare ok for %p",package);
while ((fname = g_dir_read_name(dir))!=NULL)
{
gchar** items = g_strsplit(fname,"_",-1);
@@ -130,8 +134,12 @@ void apt_build_db(PkBackend * backend, s
if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
{
const gchar *repo;
- gchar *temp, *parsed_name;
- gchar *fullname;
+ gchar *temp=NULL, *parsed_name=NULL;
+ gchar *fullname= NULL;
+ gchar *begin=NULL, *next=NULL, *description = NULL;
+ glong count = 0;
+ gboolean haspk = FALSE;
+
/* warning: nasty hack with g_strjoinv */
if (g_str_has_prefix(items[len-2],"binary-"))
{
@@ -168,21 +176,19 @@ void apt_build_db(PkBackend * backend, s
pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
goto search_task_cleanup;
}
- gchar *begin = contents, *next;
- glong count = 0;
+ /*else
+ pk_debug("loaded");*/
- sqlite3_stmt *package = NULL;
- int res;
- res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
- if (res!=SQLITE_OK)
- pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
- res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_STATIC);
+ res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_TRANSIENT);
if (res!=SQLITE_OK)
pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
+ /*else
+ pk_debug("repo bind ok");*/
- gboolean haspk = FALSE;
+ res = sqlite3_exec(db,"begin",NULL,NULL,NULL);
+ g_assert(res == SQLITE_OK);
- sqlite3_exec(db,"begin",NULL,NULL,NULL);
+ begin = contents;
while (true)
{
@@ -221,7 +227,6 @@ void apt_build_db(PkBackend * backend, s
colon+=2;
/*if (strlen(colon)>3000)
pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
- //typedef enum {FIELD_PKG=0,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
//pk_debug("entry = '%s','%s'",begin,colon);
if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
{
@@ -246,11 +251,17 @@ void apt_build_db(PkBackend * backend, s
break;
begin = next;
}
- sqlite3_exec(db,"commit",NULL,NULL,NULL);
+ res = sqlite3_exec(db,"commit",NULL,NULL,NULL);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during commit: %s", sqlite3_errmsg(db));
+ res = sqlite3_clear_bindings(package);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during clear: %s", sqlite3_errmsg(db));
g_free(contents);
contents = NULL;
}
}
+ sqlite3_finalize(package);
search_task_cleanup:
g_dir_close(dir);
diff-tree ac4809e980c5d4fa587c14050c85a07ee9ad9958 (from f95e81b62827cee1a59041e859c5cd0449bdd771)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Oct 10 17:56:43 2007 +0200
Separate all of the sqlite caching from apt stuff
The apt backend is now separated into 5 files (vs. 2 before)
- sqlite-pkg-cache.{cc,h}
Generic sqlite cache searching and initialisation
Can possibly be folded into the PackageKit core at some
point in the future.
- apt-build-db.cc
Apt-specific sqlite cache builder
- pk-backend-apt.{cc,h}
Everything else
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 622f703..82f364b 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -1,8 +1,8 @@
plugindir = @PK_PLUGIN_DIR@
plugin_LTLIBRARIES = libpk_backend_apt.la
-libpk_backend_apt_la_INCLUDES = $(APT_CFLAGS)
-libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp
-libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@ $(APT_LIBS)
+libpk_backend_apt_la_INCLUDES = $(APT_CFLAGS) $(SQLITE_CFLAGS)
+libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp sqlite-pkg-cache.cpp apt-build-db.cpp
+libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@ $(APT_LIBS) $(SQLITE_LIBS)
libpk_backend_apt_la_LDFLAGS = -module -avoid-version
libpk_backend_apt_la_CXXFLAGS = @PK_PLUGIN_CFLAGS@ -DDATABASEDIR=\""$(PK_DB_DIR)"\"
diff --git a/backends/apt/apt-build-db.cpp b/backends/apt/apt-build-db.cpp
new file mode 100644
index 0000000..8b46002
--- /dev/null
+++ b/backends/apt/apt-build-db.cpp
@@ -0,0 +1,260 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "pk-backend-apt.h"
+#include <apt-pkg/configuration.h>
+#include <sqlite3.h>
+
+typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
+
+void apt_build_db(PkBackend * backend, sqlite3 *db)
+{
+ GMatchInfo *match_info;
+ GError *error = NULL;
+ gchar *contents = NULL;
+ gchar *sdir;
+ const gchar *fname;
+ GRegex *origin, *suite, *version, *description;
+ GDir *dir;
+ GHashTable *releases;
+
+ pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
+ pk_backend_no_percentage_updates(backend);
+
+ sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
+ dir = g_dir_open(sdir,0,&error);
+ if (error!=NULL)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir);
+ g_error_free(error);
+ goto search_task_cleanup;
+ }
+
+ origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+ suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+
+ version = g_regex_new("^Version: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+ description = g_regex_new("^Description: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+
+ releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
+ while ((fname = g_dir_read_name(dir))!=NULL)
+ {
+ gchar *temp, *parsed_name;
+ gchar** items = g_strsplit(fname,"_",-1);
+ guint len = g_strv_length(items);
+ if(len<=3) // minimum is <source>_<type>_<group>
+ {
+ g_strfreev(items);
+ continue;
+ }
+
+ /* warning: nasty hack with g_strjoinv */
+ temp = items[len-2];
+ items[len-2] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-2] = temp;
+
+ if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
+ {
+ gchar * repo = NULL, *fullname;
+ fullname = g_build_filename(sdir,fname,NULL);
+ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+ goto search_task_cleanup;
+ }
+ g_free(fullname);
+
+ g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info);
+ if (!g_match_info_matches(match_info))
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname);
+ goto search_task_cleanup;
+ }
+ repo = g_match_info_fetch (match_info, 1);
+
+ g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info);
+ if (g_match_info_matches(match_info))
+ {
+ temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL);
+ g_free(repo);
+ repo = temp;
+ }
+
+ temp = parsed_name;
+ parsed_name = g_strconcat(temp,"_",items[len-2],NULL);
+ g_free(temp);
+
+ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+ g_hash_table_insert(releases, parsed_name, repo);
+ g_free(contents);
+ contents = NULL;
+ }
+ else
+ g_free(parsed_name);
+ g_strfreev(items);
+ }
+ g_dir_close(dir);
+
+ /* and then we need to do this again, but this time we're looking for the packages */
+ dir = g_dir_open(sdir,0,&error);
+ while ((fname = g_dir_read_name(dir))!=NULL)
+ {
+ gchar** items = g_strsplit(fname,"_",-1);
+ guint len = g_strv_length(items);
+ if(len<=3) // minimum is <source>_<type>_<group>
+ {
+ g_strfreev(items);
+ continue;
+ }
+
+ if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
+ {
+ const gchar *repo;
+ gchar *temp, *parsed_name;
+ gchar *fullname;
+ /* warning: nasty hack with g_strjoinv */
+ if (g_str_has_prefix(items[len-2],"binary-"))
+ {
+ temp = items[len-3];
+ items[len-3] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-3] = temp;
+ }
+ else
+ {
+ temp = items[len-1];
+ items[len-1] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-1] = temp;
+ }
+
+ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+ repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
+ if (repo == NULL)
+ {
+ pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name);
+ repo = g_strdup("unknown");
+ //g_assert(0);
+ }
+ else
+ pk_debug("repo for %s is %s",parsed_name,repo);
+ g_free(parsed_name);
+
+ fullname = g_build_filename(sdir,fname,NULL);
+ pk_debug("loading %s",fullname);
+ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+ goto search_task_cleanup;
+ }
+ gchar *begin = contents, *next;
+ glong count = 0;
+
+ sqlite3_stmt *package = NULL;
+ int res;
+ res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
+ res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_STATIC);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
+
+ gboolean haspk = FALSE;
+
+ sqlite3_exec(db,"begin",NULL,NULL,NULL);
+
+ while (true)
+ {
+ next = strstr(begin,"\n");
+ if (next!=NULL)
+ {
+ next[0] = '\0';
+ next++;
+ }
+
+ if (begin[0]=='\0')
+ {
+ if (haspk)
+ {
+ res = sqlite3_step(package);
+ if (res!=SQLITE_DONE)
+ pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
+ sqlite3_reset(package);
+ //pk_debug("added package");
+ haspk = FALSE;
+ }
+ //g_assert(0);
+ }
+ else if (begin[0]==' ')
+ {
+ /*gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
+ g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
+ //pk_debug("new entry = '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
+ g_free(oldval);*/
+ }
+ else
+ {
+ gchar *colon = strchr(begin,':');
+ g_assert(colon!=NULL);
+ colon[0] = '\0';
+ colon+=2;
+ /*if (strlen(colon)>3000)
+ pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
+ //typedef enum {FIELD_PKG=0,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
+ //pk_debug("entry = '%s','%s'",begin,colon);
+ if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
+ {
+ res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC);
+ haspk = TRUE;
+ count++;
+ if (count%1000==0)
+ pk_debug("Package %ld (%s)",count,colon);
+ }
+ else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db));
+ }
+ if (next == NULL)
+ break;
+ begin = next;
+ }
+ sqlite3_exec(db,"commit",NULL,NULL,NULL);
+ g_free(contents);
+ contents = NULL;
+ }
+ }
+
+search_task_cleanup:
+ g_dir_close(dir);
+ g_free(sdir);
+ g_free(contents);
+}
+
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index ca08bae..f4955c9 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -1,6 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
*
* Licensed under the GNU General Public License Version 2
*
@@ -42,300 +43,29 @@
#include <string.h>
#include <math.h>
-#include <sqlite3.h>
+
+#include "pk-backend-apt.h"
+#include "sqlite-pkg-cache.h"
static pkgCacheFile *fileCache = NULL;
static pkgSourceList *SrcList = 0;
static gboolean inited = FALSE;
-static sqlite3 *db = NULL;
#define APT_DB DATABASEDIR "/apt.db"
-typedef enum {
- SEARCH_NAME = 1,
- SEARCH_DETAILS,
- SEARCH_FILE
-} SearchDepth;
-
-struct search_task {
- gchar *search;
- gchar *filter;
- SearchDepth depth;
-};
-
struct desc_task {
PkPackageId *pi;
};
-#ifdef APT_PKG_RPM
-typedef pkgCache::VerFile AptCompFile;
-#elif defined(APT_PKG_DEB)
-typedef pkgCache::DescFile AptCompFile;
-#else
-#error Need either rpm or deb defined
-#endif
-
-typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
-
-static void build_db(PkBackend * backend)
-{
- GMatchInfo *match_info;
- GError *error = NULL;
- gchar *contents = NULL;
- gchar *sdir;
- const gchar *fname;
- GRegex *origin, *suite, *version, *description;
- GDir *dir;
- GHashTable *releases;
-
- pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
- pk_backend_no_percentage_updates(backend);
-
- sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
- dir = g_dir_open(sdir,0,&error);
- if (error!=NULL)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir);
- g_error_free(error);
- goto search_task_cleanup;
- }
-
- origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
- suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
-
- version = g_regex_new("^Version: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
- description = g_regex_new("^Description: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
-
- releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
- while ((fname = g_dir_read_name(dir))!=NULL)
- {
- gchar *temp, *parsed_name;
- gchar** items = g_strsplit(fname,"_",-1);
- guint len = g_strv_length(items);
- if(len<=3) // minimum is <source>_<type>_<group>
- {
- g_strfreev(items);
- continue;
- }
-
- /* warning: nasty hack with g_strjoinv */
- temp = items[len-2];
- items[len-2] = NULL;
- parsed_name = g_strjoinv("_",items);
- items[len-2] = temp;
-
- if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
- {
- gchar * repo = NULL, *fullname;
- fullname = g_build_filename(sdir,fname,NULL);
- if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
- goto search_task_cleanup;
- }
- g_free(fullname);
-
- g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info);
- if (!g_match_info_matches(match_info))
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname);
- goto search_task_cleanup;
- }
- repo = g_match_info_fetch (match_info, 1);
-
- g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info);
- if (g_match_info_matches(match_info))
- {
- temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL);
- g_free(repo);
- repo = temp;
- }
-
- temp = parsed_name;
- parsed_name = g_strconcat(temp,"_",items[len-2],NULL);
- g_free(temp);
-
- pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
-
- g_hash_table_insert(releases, parsed_name, repo);
- g_free(contents);
- contents = NULL;
- }
- else
- g_free(parsed_name);
- g_strfreev(items);
- }
- g_dir_close(dir);
-
- /* and then we need to do this again, but this time we're looking for the packages */
- dir = g_dir_open(sdir,0,&error);
- while ((fname = g_dir_read_name(dir))!=NULL)
- {
- gchar** items = g_strsplit(fname,"_",-1);
- guint len = g_strv_length(items);
- if(len<=3) // minimum is <source>_<type>_<group>
- {
- g_strfreev(items);
- continue;
- }
-
- if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
- {
- const gchar *repo;
- gchar *temp, *parsed_name;
- gchar *fullname;
- /* warning: nasty hack with g_strjoinv */
- if (g_str_has_prefix(items[len-2],"binary-"))
- {
- temp = items[len-3];
- items[len-3] = NULL;
- parsed_name = g_strjoinv("_",items);
- items[len-3] = temp;
- }
- else
- {
- temp = items[len-1];
- items[len-1] = NULL;
- parsed_name = g_strjoinv("_",items);
- items[len-1] = temp;
- }
-
- pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
-
- repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
- if (repo == NULL)
- {
- pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name);
- repo = g_strdup("unknown");
- //g_assert(0);
- }
- else
- pk_debug("repo for %s is %s",parsed_name,repo);
- g_free(parsed_name);
-
- fullname = g_build_filename(sdir,fname,NULL);
- pk_debug("loading %s",fullname);
- if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
- goto search_task_cleanup;
- }
- gchar *begin = contents, *next;
- glong count = 0;
-
- sqlite3_stmt *package = NULL;
- int res;
- res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
- if (res!=SQLITE_OK)
- pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
- res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_STATIC);
- if (res!=SQLITE_OK)
- pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
-
- gboolean haspk = FALSE;
-
- sqlite3_exec(db,"begin",NULL,NULL,NULL);
-
- while (true)
- {
- next = strstr(begin,"\n");
- if (next!=NULL)
- {
- next[0] = '\0';
- next++;
- }
-
- if (begin[0]=='\0')
- {
- if (haspk)
- {
- res = sqlite3_step(package);
- if (res!=SQLITE_DONE)
- pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
- sqlite3_reset(package);
- //pk_debug("added package");
- haspk = FALSE;
- }
- //g_assert(0);
- }
- else if (begin[0]==' ')
- {
- /*gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
- g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
- //pk_debug("new entry = '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
- g_free(oldval);*/
- }
- else
- {
- gchar *colon = strchr(begin,':');
- g_assert(colon!=NULL);
- colon[0] = '\0';
- colon+=2;
- /*if (strlen(colon)>3000)
- pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
- //typedef enum {FIELD_PKG=0,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
- //pk_debug("entry = '%s','%s'",begin,colon);
- if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
- {
- res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC);
- haspk = TRUE;
- count++;
- if (count%1000==0)
- pk_debug("Package %ld (%s)",count,colon);
- }
- else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0)
- res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC);
- else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0)
- res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC);
- else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0)
- res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC);
- else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0)
- res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC);
- if (res!=SQLITE_OK)
- pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db));
- }
- if (next == NULL)
- break;
- begin = next;
- }
- sqlite3_exec(db,"commit",NULL,NULL,NULL);
- g_free(contents);
- contents = NULL;
- }
- }
-
-search_task_cleanup:
- g_dir_close(dir);
- g_free(sdir);
- g_free(contents);
-}
-
-static void init(PkBackend *backend)
+static void backend_initialize(PkBackend *backend)
{
if (!inited)
{
- gint ret;
- char *errmsg = NULL;
if (pkgInitConfig(*_config) == false)
pk_debug("pkginitconfig was false");
if (pkgInitSystem(*_config, _system) == false)
pk_debug("pkginitsystem was false");
- ret = sqlite3_open (APT_DB, &db);
- ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
- g_assert(ret == SQLITE_OK);
- //sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,&errmsg);
- sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string)",NULL,NULL,&errmsg);
- if (errmsg == NULL) // success, ergo didn't exist
- {
- build_db(backend);
- }
- else
- {
- sqlite3_free(errmsg);
- /*ret = sqlite3_exec(db,"delete from packages",NULL,NULL,NULL); // clear it!
- g_assert(ret == SQLITE_OK);
- pk_debug("wiped db");*/
- }
+ init_sqlite_cache(backend, APT_DB, apt_build_db);
inited = TRUE;
}
}
@@ -346,7 +76,6 @@ static pkgCacheFile *getCache(PkBackend
{
MMap *Map = 0;
OpTextProgress Prog;
- init(backend);
// Open the cache file
SrcList = new pkgSourceList;
SrcList->ReadMainList();
@@ -550,73 +279,6 @@ static void backend_refresh_cache(PkBack
pk_backend_thread_helper(backend, backend_refresh_cache_thread, NULL);
}
-// backend_search_packages_thread
-// Swiped from apt-cache's search mode
-static gboolean backend_search_packages_thread (PkBackend *backend, gpointer data)
-{
- search_task *st = (search_task *) data;
- int res;
-
- init(backend);
- pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
- pk_backend_no_percentage_updates(backend);
-
- pk_debug("finding %s", st->search);
-
- sqlite3_stmt *package = NULL;
- g_strdelimit(st->search," ",'%');
- gchar *sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
- pk_debug("statement is '%s'",sel);
- res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
- g_free(sel);
- if (res!=SQLITE_OK)
- pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
- res = sqlite3_step(package);
- while (res == SQLITE_ROW)
- {
- gchar *pid = pk_package_id_build((const gchar*)sqlite3_column_text(package,0),
- (const gchar*)sqlite3_column_text(package,1),
- (const gchar*)sqlite3_column_text(package,2),
- (const gchar*)sqlite3_column_text(package,3));
- pk_backend_package(backend, FALSE, pid, (const gchar*)sqlite3_column_text(package,4));
- g_free(pid);
- if (res==SQLITE_ROW)
- res = sqlite3_step(package);
- }
- if (res!=SQLITE_DONE)
- {
- pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
- g_assert(0);
- }
-
- g_free(st->search);
- g_free(st);
-
- return TRUE;
-}
-
-/**
- * backend_search_common
- **/
-static void
-backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func)
-{
- g_return_if_fail (backend != NULL);
- search_task *data = g_new(struct search_task, 1);
- if (data == NULL)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_OOM, "Failed to allocate memory for search task");
- pk_backend_finished(backend);
- }
- else
- {
- data->search = g_strdup(search);
- data->filter = g_strdup(filter);
- data->depth = which;
- pk_backend_thread_helper (backend, func, data);
- }
-}
-
static GHashTable *PackageRecord(PkBackend *backend, pkgCache::VerIterator V)
{
GHashTable *ret = NULL;
@@ -732,24 +394,6 @@ backend_get_description (PkBackend *back
return;
}
-/**
- * backend_search_details:
- */
-static void
-backend_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
-{
- backend_search_common(backend, filter, search, SEARCH_DETAILS, backend_search_packages_thread);
-}
-
-/**
- * backend_search_name:
- */
-static void
-backend_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
-{
- backend_search_common(backend, filter, search, SEARCH_NAME, backend_search_packages_thread);
-}
-
static gboolean backend_search_file_thread (PkBackend *backend, gpointer data)
{
//search_task *st = (search_task*)data;
@@ -787,8 +431,8 @@ static void backend_search_file(PkBacken
extern "C" PK_BACKEND_OPTIONS (
"APT", /* description */
"0.0.1", /* version */
- "Richard Hughes <richard at hughsie.com>", /* author */
- NULL, /* initalize */
+ "Richard Hughes <richard at hughsie.com>, Tom Parker <palfrey at tevp.net>", /* author */
+ backend_initialize, /* initalize */
NULL, /* destroy */
backend_get_groups, /* get_groups */
backend_get_filters, /* get_filters */
@@ -804,10 +448,10 @@ extern "C" PK_BACKEND_OPTIONS (
NULL, /* remove_package */
NULL, /* resolve */
NULL, /* rollback */
- backend_search_details, /* search_details */
+ sqlite_search_details, /* search_details */
backend_search_file, /* search_file */
NULL, /* search_group */
- backend_search_name, /* search_name */
+ sqlite_search_name, /* search_name */
NULL, /* update_package */
NULL /* update_system */
);
diff --git a/backends/apt/pk-backend-apt.h b/backends/apt/pk-backend-apt.h
new file mode 100644
index 0000000..ff67654
--- /dev/null
+++ b/backends/apt/pk-backend-apt.h
@@ -0,0 +1,30 @@
+#ifndef PK_BACKEND_APT
+#define PK_BACKEND_APT
+
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <sqlite3.h>
+#include <pk-backend.h>
+
+void apt_build_db(PkBackend * backend, sqlite3 *db);
+
+#endif
diff --git a/backends/apt/sqlite-pkg-cache.cpp b/backends/apt/sqlite-pkg-cache.cpp
new file mode 100644
index 0000000..5e90f8e
--- /dev/null
+++ b/backends/apt/sqlite-pkg-cache.cpp
@@ -0,0 +1,138 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <sqlite3.h>
+#include <glib.h>
+#include "sqlite-pkg-cache.h"
+
+static sqlite3 *db = NULL;
+
+struct search_task {
+ gchar *search;
+ gchar *filter;
+ SearchDepth depth;
+};
+
+void init_sqlite_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *))
+{
+ gint ret;
+ char *errmsg = NULL;
+ ret = sqlite3_open (dbname, &db);
+ ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
+ g_assert(ret == SQLITE_OK);
+ sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,&errmsg);
+ if (errmsg == NULL) // success, ergo didn't exist
+ {
+ build_db(backend,db);
+ }
+ else
+ {
+ sqlite3_free(errmsg);
+ /*ret = sqlite3_exec(db,"delete from packages",NULL,NULL,NULL); // clear it!
+ g_assert(ret == SQLITE_OK);
+ pk_debug("wiped db");*/
+ }
+}
+
+// backend_search_packages_thread
+gboolean backend_search_packages_thread (PkBackend *backend, gpointer data)
+{
+ search_task *st = (search_task *) data;
+ int res;
+
+ pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
+ pk_backend_no_percentage_updates(backend);
+
+ pk_debug("finding %s", st->search);
+
+ sqlite3_stmt *package = NULL;
+ g_strdelimit(st->search," ",'%');
+ gchar *sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
+ pk_debug("statement is '%s'",sel);
+ res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
+ g_free(sel);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
+ res = sqlite3_step(package);
+ while (res == SQLITE_ROW)
+ {
+ gchar *pid = pk_package_id_build((const gchar*)sqlite3_column_text(package,0),
+ (const gchar*)sqlite3_column_text(package,1),
+ (const gchar*)sqlite3_column_text(package,2),
+ (const gchar*)sqlite3_column_text(package,3));
+ pk_backend_package(backend, FALSE, pid, (const gchar*)sqlite3_column_text(package,4));
+ g_free(pid);
+ if (res==SQLITE_ROW)
+ res = sqlite3_step(package);
+ }
+ if (res!=SQLITE_DONE)
+ {
+ pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
+ g_assert(0);
+ }
+
+ g_free(st->search);
+ g_free(st);
+
+ return TRUE;
+}
+
+/**
+ * backend_search_common
+ **/
+void
+backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func)
+{
+ g_return_if_fail (backend != NULL);
+ search_task *data = g_new(struct search_task, 1);
+ if (data == NULL)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_OOM, "Failed to allocate memory for search task");
+ pk_backend_finished(backend);
+ }
+ else
+ {
+ data->search = g_strdup(search);
+ data->filter = g_strdup(filter);
+ data->depth = which;
+ pk_backend_thread_helper (backend, func, data);
+ }
+}
+
+/**
+ * backend_search_details:
+ */
+void
+sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+ backend_search_common(backend, filter, search, SEARCH_DETAILS, backend_search_packages_thread);
+}
+
+/**
+ * backend_search_name:
+ */
+void
+sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search)
+{
+ backend_search_common(backend, filter, search, SEARCH_NAME, backend_search_packages_thread);
+}
+
+
diff --git a/backends/apt/sqlite-pkg-cache.h b/backends/apt/sqlite-pkg-cache.h
new file mode 100644
index 0000000..99511bf
--- /dev/null
+++ b/backends/apt/sqlite-pkg-cache.h
@@ -0,0 +1,38 @@
+#ifndef SQLITE_PKT_CACHE
+#define SQLITE_PKT_CACHE
+
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+typedef enum {
+ SEARCH_NAME = 1,
+ SEARCH_DETAILS,
+ SEARCH_FILE
+} SearchDepth;
+
+#include <pk-backend.h>
+
+void init_sqlite_cache(PkBackend *backend, const char* dbname, void (*build_db)(PkBackend *, sqlite3 *db));
+void sqlite_search_details (PkBackend *backend, const gchar *filter, const gchar *search);
+void sqlite_search_name (PkBackend *backend, const gchar *filter, const gchar *search);
+void backend_search_common(PkBackend * backend, const gchar * filter, const gchar * search, SearchDepth which, PkBackendThreadFunc func);
+
+#endif
diff-tree f95e81b62827cee1a59041e859c5cd0449bdd771 (from ea5c533ec4822e6a22a3d63ed25adc825b926c41)
Author: Tom Parker <palfrey at tevp.net>
Date: Wed Sep 26 16:43:42 2007 +0200
Let " " in searches match random characters
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index 3c47611..ca08bae 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -564,6 +564,7 @@ static gboolean backend_search_packages_
pk_debug("finding %s", st->search);
sqlite3_stmt *package = NULL;
+ g_strdelimit(st->search," ",'%');
gchar *sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
pk_debug("statement is '%s'",sel);
res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
diff-tree ea5c533ec4822e6a22a3d63ed25adc825b926c41 (from 2e71cf2378e950a692277e82ee41c3fa431fb317)
Author: Tom Parker <palfrey at tevp.net>
Date: Thu Sep 27 15:51:32 2007 +0200
First work with sqlite caching backend for APT
APT backend now automagically builds a db containing all the
packages on first run, and then does the searches in that.
TODO: rebuild on changes, non-name searches
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index aab967b..622f703 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -4,5 +4,5 @@ libpk_backend_apt_la_INCLUDES = $(APT_CF
libpk_backend_apt_la_SOURCES = pk-backend-apt.cpp
libpk_backend_apt_la_LIBADD = @PK_PLUGIN_LIBS@ $(APT_LIBS)
libpk_backend_apt_la_LDFLAGS = -module -avoid-version
-libpk_backend_apt_la_CXXFLAGS = @PK_PLUGIN_CFLAGS@
+libpk_backend_apt_la_CXXFLAGS = @PK_PLUGIN_CFLAGS@ -DDATABASEDIR=\""$(PK_DB_DIR)"\"
diff --git a/backends/apt/pk-backend-apt.cpp b/backends/apt/pk-backend-apt.cpp
index 7f8d823..3c47611 100644
--- a/backends/apt/pk-backend-apt.cpp
+++ b/backends/apt/pk-backend-apt.cpp
@@ -21,6 +21,7 @@
#include <gmodule.h>
#include <glib.h>
+#include <glib/gprintf.h>
#include <string.h>
#include <pk-backend.h>
#include <pk-debug.h>
@@ -39,12 +40,16 @@
#include <apt-pkg/acquire.h>
#include <apt-pkg/acquire-item.h>
-#include <regex.h>
#include <string.h>
#include <math.h>
+#include <sqlite3.h>
static pkgCacheFile *fileCache = NULL;
-pkgSourceList *SrcList = 0;
+static pkgSourceList *SrcList = 0;
+static gboolean inited = FALSE;
+static sqlite3 *db = NULL;
+
+#define APT_DB DATABASEDIR "/apt.db"
typedef enum {
SEARCH_NAME = 1,
@@ -70,27 +75,278 @@ typedef pkgCache::DescFile AptCompFile;
#error Need either rpm or deb defined
#endif
-struct ExDescFile {
- AptCompFile *Df;
- const char *verstr;
- const char *arch;
- gboolean installed;
- gboolean available;
- char *repo;
- bool NameMatch;
-};
+typedef enum {FIELD_PKG=1,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
+
+static void build_db(PkBackend * backend)
+{
+ GMatchInfo *match_info;
+ GError *error = NULL;
+ gchar *contents = NULL;
+ gchar *sdir;
+ const gchar *fname;
+ GRegex *origin, *suite, *version, *description;
+ GDir *dir;
+ GHashTable *releases;
+
+ pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
+ pk_backend_no_percentage_updates(backend);
+
+ sdir = g_build_filename(_config->Find("Dir").c_str(),_config->Find("Dir::State").c_str(),_config->Find("Dir::State::lists").c_str(), NULL);
+ dir = g_dir_open(sdir,0,&error);
+ if (error!=NULL)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "can't open %s",dir);
+ g_error_free(error);
+ goto search_task_cleanup;
+ }
+
+ origin = g_regex_new("^Origin: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+ suite = g_regex_new("^Suite: (\\S+)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+
+ version = g_regex_new("^Version: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+ description = g_regex_new("^Description: (.*)",(GRegexCompileFlags)(G_REGEX_CASELESS|G_REGEX_OPTIMIZE|G_REGEX_MULTILINE),(GRegexMatchFlags)0,NULL);
+ releases = g_hash_table_new_full(g_str_hash,g_str_equal,g_free,g_free);
+ while ((fname = g_dir_read_name(dir))!=NULL)
+ {
+ gchar *temp, *parsed_name;
+ gchar** items = g_strsplit(fname,"_",-1);
+ guint len = g_strv_length(items);
+ if(len<=3) // minimum is <source>_<type>_<group>
+ {
+ g_strfreev(items);
+ continue;
+ }
+
+ /* warning: nasty hack with g_strjoinv */
+ temp = items[len-2];
+ items[len-2] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-2] = temp;
+
+ if (g_ascii_strcasecmp(items[len-1],"Release")==0 && g_ascii_strcasecmp(items[len-2],"source")!=0)
+ {
+ gchar * repo = NULL, *fullname;
+ fullname = g_build_filename(sdir,fname,NULL);
+ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+ goto search_task_cleanup;
+ }
+ g_free(fullname);
+
+ g_regex_match (origin, contents, (GRegexMatchFlags)0, &match_info);
+ if (!g_match_info_matches(match_info))
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "origin regex failure in %s",fname);
+ goto search_task_cleanup;
+ }
+ repo = g_match_info_fetch (match_info, 1);
+
+ g_regex_match (suite, contents, (GRegexMatchFlags)0, &match_info);
+ if (g_match_info_matches(match_info))
+ {
+ temp = g_strconcat(repo,"/",g_match_info_fetch (match_info, 1),NULL);
+ g_free(repo);
+ repo = temp;
+ }
+
+ temp = parsed_name;
+ parsed_name = g_strconcat(temp,"_",items[len-2],NULL);
+ g_free(temp);
+
+ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+ g_hash_table_insert(releases, parsed_name, repo);
+ g_free(contents);
+ contents = NULL;
+ }
+ else
+ g_free(parsed_name);
+ g_strfreev(items);
+ }
+ g_dir_close(dir);
+
+ /* and then we need to do this again, but this time we're looking for the packages */
+ dir = g_dir_open(sdir,0,&error);
+ while ((fname = g_dir_read_name(dir))!=NULL)
+ {
+ gchar** items = g_strsplit(fname,"_",-1);
+ guint len = g_strv_length(items);
+ if(len<=3) // minimum is <source>_<type>_<group>
+ {
+ g_strfreev(items);
+ continue;
+ }
+
+ if (g_ascii_strcasecmp(items[len-1],"Packages")==0)
+ {
+ const gchar *repo;
+ gchar *temp, *parsed_name;
+ gchar *fullname;
+ /* warning: nasty hack with g_strjoinv */
+ if (g_str_has_prefix(items[len-2],"binary-"))
+ {
+ temp = items[len-3];
+ items[len-3] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-3] = temp;
+ }
+ else
+ {
+ temp = items[len-1];
+ items[len-1] = NULL;
+ parsed_name = g_strjoinv("_",items);
+ items[len-1] = temp;
+ }
+
+ pk_debug("type is %s, group is %s, parsed_name is %s",items[len-2],items[len-1],parsed_name);
+
+ repo = (const gchar *)g_hash_table_lookup(releases,parsed_name);
+ if (repo == NULL)
+ {
+ pk_debug("Can't find repo for %s, marking as \"unknown\"",parsed_name);
+ repo = g_strdup("unknown");
+ //g_assert(0);
+ }
+ else
+ pk_debug("repo for %s is %s",parsed_name,repo);
+ g_free(parsed_name);
+
+ fullname = g_build_filename(sdir,fname,NULL);
+ pk_debug("loading %s",fullname);
+ if (g_file_get_contents(fullname,&contents,NULL,NULL) == FALSE)
+ {
+ pk_backend_error_code(backend, PK_ERROR_ENUM_INTERNAL_ERROR, "error loading %s",fullname);
+ goto search_task_cleanup;
+ }
+ gchar *begin = contents, *next;
+ glong count = 0;
+
+ sqlite3_stmt *package = NULL;
+ int res;
+ res = sqlite3_prepare_v2(db, "insert or replace into packages values (?,?,?,?,?,?,?)", -1, &package, NULL);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during insert prepare: %s", sqlite3_errmsg(db));
+ res = sqlite3_bind_text(package,FIELD_REPO,repo,-1,SQLITE_STATIC);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during repo bind: %s", sqlite3_errmsg(db));
+
+ gboolean haspk = FALSE;
+
+ sqlite3_exec(db,"begin",NULL,NULL,NULL);
+
+ while (true)
+ {
+ next = strstr(begin,"\n");
+ if (next!=NULL)
+ {
+ next[0] = '\0';
+ next++;
+ }
+
+ if (begin[0]=='\0')
+ {
+ if (haspk)
+ {
+ res = sqlite3_step(package);
+ if (res!=SQLITE_DONE)
+ pk_error("sqlite error during step: %s", sqlite3_errmsg(db));
+ sqlite3_reset(package);
+ //pk_debug("added package");
+ haspk = FALSE;
+ }
+ //g_assert(0);
+ }
+ else if (begin[0]==' ')
+ {
+ /*gchar *oldval = g_strdup((const gchar*)g_hash_table_lookup(ret,"Description"));
+ g_hash_table_insert(ret,g_strdup("Description"),g_strconcat(oldval, "\n",parts[1],NULL));
+ //pk_debug("new entry = '%s'",(const gchar*)g_hash_table_lookup(ret,"Description"));
+ g_free(oldval);*/
+ }
+ else
+ {
+ gchar *colon = strchr(begin,':');
+ g_assert(colon!=NULL);
+ colon[0] = '\0';
+ colon+=2;
+ /*if (strlen(colon)>3000)
+ pk_error("strlen(colon) = %d\ncolon = %s",strlen(colon),colon);*/
+ //typedef enum {FIELD_PKG=0,FIELD_VER,FIELD_DEPS,FIELD_ARCH,FIELD_SHORT,FIELD_LONG,FIELD_REPO} Fields;
+ //pk_debug("entry = '%s','%s'",begin,colon);
+ if (begin[0] == 'P' && g_strcasecmp("Package",begin)==0)
+ {
+ res=sqlite3_bind_text(package,FIELD_PKG,colon,-1,SQLITE_STATIC);
+ haspk = TRUE;
+ count++;
+ if (count%1000==0)
+ pk_debug("Package %ld (%s)",count,colon);
+ }
+ else if (begin[0] == 'V' && g_strcasecmp("Version",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_VER,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'D' && g_strcasecmp("Depends",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_DEPS,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'A' && g_strcasecmp("Architecture",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_ARCH,colon,-1,SQLITE_STATIC);
+ else if (begin[0] == 'D' && g_strcasecmp("Description",begin)==0)
+ res=sqlite3_bind_text(package,FIELD_SHORT,colon,-1,SQLITE_STATIC);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during %s bind: %s", begin, sqlite3_errmsg(db));
+ }
+ if (next == NULL)
+ break;
+ begin = next;
+ }
+ sqlite3_exec(db,"commit",NULL,NULL,NULL);
+ g_free(contents);
+ contents = NULL;
+ }
+ }
+
+search_task_cleanup:
+ g_dir_close(dir);
+ g_free(sdir);
+ g_free(contents);
+}
-static pkgCacheFile *getCache()
+static void init(PkBackend *backend)
{
- if (fileCache == NULL)
+ if (!inited)
{
- MMap *Map = 0;
- OpTextProgress Prog;
+ gint ret;
+ char *errmsg = NULL;
if (pkgInitConfig(*_config) == false)
pk_debug("pkginitconfig was false");
if (pkgInitSystem(*_config, _system) == false)
pk_debug("pkginitsystem was false");
+ ret = sqlite3_open (APT_DB, &db);
+ ret = sqlite3_exec(db,"PRAGMA synchronous = OFF",NULL,NULL,NULL);
+ g_assert(ret == SQLITE_OK);
+ //sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string, primary key(name,version,arch,repo))",NULL,NULL,&errmsg);
+ sqlite3_exec(db,"create table packages (name text, version text, deps text, arch text, short_desc text, long_desc text, repo string)",NULL,NULL,&errmsg);
+ if (errmsg == NULL) // success, ergo didn't exist
+ {
+ build_db(backend);
+ }
+ else
+ {
+ sqlite3_free(errmsg);
+ /*ret = sqlite3_exec(db,"delete from packages",NULL,NULL,NULL); // clear it!
+ g_assert(ret == SQLITE_OK);
+ pk_debug("wiped db");*/
+ }
+ inited = TRUE;
+ }
+}
+
+static pkgCacheFile *getCache(PkBackend *backend)
+{
+ if (fileCache == NULL)
+ {
+ MMap *Map = 0;
+ OpTextProgress Prog;
+ init(backend);
// Open the cache file
SrcList = new pkgSourceList;
SrcList->ReadMainList();
@@ -156,7 +412,7 @@ static gboolean backend_refresh_cache_th
/* easy as that */
pk_backend_change_status(backend, PK_STATUS_ENUM_REFRESH_CACHE);
- Cache = getCache();
+ Cache = getCache(backend);
// Get the source list
pkgSourceList List;
@@ -227,7 +483,7 @@ static gboolean backend_refresh_cache_th
}
// Prepare the cache.
- Cache = getCache();
+ Cache = getCache(backend);
if (Cache->BuildCaches(Prog,false) == false)
{
pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "Failed to prepare the cache");
@@ -294,168 +550,44 @@ static void backend_refresh_cache(PkBack
pk_backend_thread_helper(backend, backend_refresh_cache_thread, NULL);
}
-// LocalitySort - Sort a version list by package file locality /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static int LocalityCompare(const void *a, const void *b)
-{
- pkgCache::VerFile *A = *(pkgCache::VerFile **)a;
- pkgCache::VerFile *B = *(pkgCache::VerFile **)b;
-
- if (A == 0 && B == 0)
- return 0;
- if (A == 0)
- return 1;
- if (B == 0)
- return -1;
-
- if (A->File == B->File)
- return A->Offset - B->Offset;
- return A->File - B->File;
-}
-
-static void LocalitySort(AptCompFile **begin,
- unsigned long Count,size_t Size)
-{
- qsort(begin,Count,Size,LocalityCompare);
-}
-
-static gboolean buildExDesc(ExDescFile *DFList, unsigned int pid, pkgCache::VerIterator V)
-{
- // Find the proper version to use.
- DFList[pid].available = false;
- if (V.end() == false)
- {
- #ifdef APT_PKG_RPM
- DFList[pid].Df = V.FileList();
- #else
- DFList[pid].Df = V.DescriptionList().FileList();
- #endif
- DFList[pid].verstr = V.VerStr();
- DFList[pid].arch = V.Arch();
- for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++)
- {
- // Locate the associated index files so we can derive a description
- pkgIndexFile *Indx;
- bool hasLocal = _system->FindIndex(VF.File(),Indx);
- if (SrcList->FindIndex(VF.File(),Indx) == false && !hasLocal)
- {
- pk_debug("Cache is out of sync, can't x-ref a package file");
- break;
- }
- gchar** items = g_strsplit_set(Indx->Describe(true).c_str()," \t",-1);
- DFList[pid].repo = g_strdup(items[1]); // should be in format like "http://ftp.nl.debian.org unstable/main Packages"
- DFList[pid].installed = hasLocal;
- g_strfreev(items);
- DFList[pid].available = true;
- if (hasLocal)
- break;
- }
- }
- return DFList[pid].available;
-}
-
// backend_search_packages_thread
// Swiped from apt-cache's search mode
static gboolean backend_search_packages_thread (PkBackend *backend, gpointer data)
{
search_task *st = (search_task *) data;
- ExDescFile *DFList = NULL;
+ int res;
+ init(backend);
pk_backend_change_status(backend, PK_STATUS_ENUM_QUERY);
pk_backend_no_percentage_updates(backend);
pk_debug("finding %s", st->search);
- pkgCache & pkgCache = *(getCache());
- pkgDepCache::Policy Plcy;
- // Create the text record parser
- pkgRecords Recs(pkgCache);
- // Compile the regex pattern
- regex_t *Pattern = new regex_t;
- memset(Pattern, 0, sizeof(*Pattern));
- if (regcomp(Pattern, st->search, REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
- {
- pk_backend_error_code(backend, PK_ERROR_ENUM_UNKNOWN, "regex compilation error");
- goto search_task_cleanup;
+ sqlite3_stmt *package = NULL;
+ gchar *sel = g_strdup_printf("select name,version,arch,repo,short_desc from packages where name like '%%%s%%'",st->search);
+ pk_debug("statement is '%s'",sel);
+ res = sqlite3_prepare_v2(db,sel, -1, &package, NULL);
+ g_free(sel);
+ if (res!=SQLITE_OK)
+ pk_error("sqlite error during select prepare: %s", sqlite3_errmsg(db));
+ res = sqlite3_step(package);
+ while (res == SQLITE_ROW)
+ {
+ gchar *pid = pk_package_id_build((const gchar*)sqlite3_column_text(package,0),
+ (const gchar*)sqlite3_column_text(package,1),
+ (const gchar*)sqlite3_column_text(package,2),
+ (const gchar*)sqlite3_column_text(package,3));
+ pk_backend_package(backend, FALSE, pid, (const gchar*)sqlite3_column_text(package,4));
+ g_free(pid);
+ if (res==SQLITE_ROW)
+ res = sqlite3_step(package);
}
-
- DFList = new ExDescFile[pkgCache.HeaderP->PackageCount + 1];
- memset(DFList, 0, sizeof(*DFList) * pkgCache.HeaderP->PackageCount + 1);
-
- // Map versions that we want to write out onto the VerList array.
- for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
+ if (res!=SQLITE_DONE)
{
- DFList[P->ID].NameMatch = true;
- if (regexec(Pattern, P.Name(), 0, 0, 0) == 0)
- DFList[P->ID].NameMatch &= true;
- else
- DFList[P->ID].NameMatch = false;
-
- // Doing names only, drop any that dont match..
- if (st->depth == SEARCH_NAME && DFList[P->ID].NameMatch == false)
- continue;
-
- // Find the proper version to use.
- pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
- buildExDesc(DFList, P->ID, V);
- }
-
- // Include all the packages that provide matching names too
- for (pkgCache::PkgIterator P = pkgCache.PkgBegin(); P.end() == false; P++)
- {
- if (DFList[P->ID].NameMatch == false)
- continue;
-
- for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; Prv++)
- {
- pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
- if (buildExDesc(DFList, Prv.OwnerPkg()->ID, V))
- DFList[Prv.OwnerPkg()->ID].NameMatch = true;
- }
+ pk_debug("sqlite error during step (%d): %s", res, sqlite3_errmsg(db));
+ g_assert(0);
}
- LocalitySort(&DFList->Df, pkgCache.HeaderP->PackageCount, sizeof(*DFList));
-
- // Iterate over all the version records and check them
- for (ExDescFile * J = DFList; J->Df != 0; J++)
- {
-#ifdef APT_PKG_RPM
- pkgRecords::Parser & P = Recs.Lookup(pkgCache::VerFileIterator(pkgCache, J->Df));
-#else
- pkgRecords::Parser & P = Recs.Lookup(pkgCache::DescFileIterator(pkgCache, J->Df));
-#endif
-
- gboolean Match = true;
- if (J->NameMatch == false)
- {
- string LongDesc = P.LongDesc();
- if (regexec(Pattern, LongDesc.c_str(), 0, 0, 0) == 0)
- Match = true;
- else
- Match = false;
- }
-
- if (Match == true)// && pk_backend_filter_package_name(backend,P.Name().c_str()))
- {
- gchar *pid = pk_package_id_build(P.Name().c_str(),J->verstr,J->arch,J->repo);
- PkInfoEnum info;
- if (J->installed)
- info = PK_INFO_ENUM_INSTALLED;
- else
- info = PK_INFO_ENUM_AVAILABLE;
- pk_backend_package(backend, info, pid, P.ShortDesc().c_str());
- g_free(pid);
- }
- }
-
-search_task_cleanup:
- for (ExDescFile * J = DFList; J->Df != 0; J++)
- {
- g_free(J->repo);
- }
- delete[]DFList;
- regfree(Pattern);
g_free(st->search);
g_free(st);
@@ -484,11 +616,11 @@ backend_search_common(PkBackend * backen
}
}
-static GHashTable *PackageRecord(pkgCache::VerIterator V)
+static GHashTable *PackageRecord(PkBackend *backend, pkgCache::VerIterator V)
{
GHashTable *ret = NULL;
- pkgCache & pkgCache = *(getCache());
+ pkgCache & pkgCache = *(getCache(backend));
// Find an appropriate file
pkgCache::VerFileIterator Vf = V.FileList();
for (; Vf.end() == false; Vf++)
@@ -553,7 +685,7 @@ static gboolean backend_get_description_
pk_backend_no_percentage_updates(backend);
pk_debug("finding %s", dt->pi->name);
- pkgCache & pkgCache = *(getCache());
+ pkgCache & pkgCache = *(getCache(backend));
pkgDepCache::Policy Plcy;
// Map versions that we want to write out onto the VerList array.
@@ -564,7 +696,7 @@ static gboolean backend_get_description_
// Find the proper version to use.
pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
- GHashTable *pkg = PackageRecord(V);
+ GHashTable *pkg = PackageRecord(backend,V);
pk_backend_description(backend,dt->pi->name,
"unknown", PK_GROUP_ENUM_OTHER,(const gchar*)g_hash_table_lookup(pkg,"Description"),"");
g_hash_table_unref(pkg);
More information about the PackageKit
mailing list