[yum-cvs] yum-metadata-parser sqlitecachec.py, NONE, 1.1 db.c, 1.1.1.1, 1.2 db.h, 1.1.1.1, 1.2 setup.py, 1.1.1.1, 1.2 sqlitecache.c, 1.2, 1.3 xml-parser.c, 1.2, 1.3 xml-parser.h, 1.2, 1.3 sqlitecache.py, 1.2, NONE

Tambet Ingo tambet at linux.duke.edu
Wed May 24 12:49:18 UTC 2006


Update of /home/groups/yum/cvs/yum-metadata-parser
In directory login1.linux.duke.edu:/tmp/cvs-serv32090

Modified Files:
	db.c db.h setup.py sqlitecache.c xml-parser.c xml-parser.h 
Added Files:
	sqlitecachec.py 
Removed Files:
	sqlitecache.py 
Log Message:
2006-05-24  Tambet Ingo  <tambet at ximian.com>

	* Implement the database opening correctly, just like yum does.

	* Implement raising the correct exception if something goes wrong.

	* Some small performance optimizations: Don't copy uninteresting XML
	characters to the local buffer, use typed python object initialization
	functions instead of BuildValue(), and add a dedicated string chunk to
	package ids collection instead of doing one malloc per id.

	* Rename sqlitecache.py to sqlitecachec.py


--- NEW FILE sqlitecachec.py ---
#!/usr/bin/python -tt

# 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 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.

import sqlite
import _sqlitecache

class RepodataParserSqlite:
    def __init__(self, storedir, repoid, callback=None):
		self.callback = callback

    def open_database(self, filename):
        if not filename:
            return None
        return sqlite.connect(filename)

    def getPrimary(self, location, checksum):
        """Load primary.xml.gz from an sqlite cache and update it 
           if required"""
        return self.open_database(_sqlitecache.update_primary(location,
															  checksum,
															  self.callback))

    def getFilelists(self, location, checksum):
        """Load filelist.xml.gz from an sqlite cache and update it if 
           required"""
        return self.open_database(_sqlitecache.update_filelist(location,
															   checksum,
															   self.callback))

    def getOtherdata(self, location, checksum):
        """Load other.xml.gz from an sqlite cache and update it if required"""
        return self.open_database(_sqlitecache.update_other(location,
															checksum,
															self.callback))
    

Index: db.c
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/db.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- db.c	11 May 2006 17:33:57 -0000	1.1.1.1
+++ db.c	24 May 2006 12:49:16 -0000	1.2
@@ -16,9 +16,20 @@
  */
 
 #include <string.h>
+#include <unistd.h>
 #include "db.h"
 #include "debug.h"
 
+GQuark
+yum_db_error_quark (void)
+{
+    static GQuark quark;
+
+    if (!quark)
+        quark = g_quark_from_static_string ("yum_db_error");
+
+    return quark;
+}
 
 #define ENCODED_PACKAGE_FILE_FILES 2048
 #define ENCODED_PACKAGE_FILE_TYPES 60
@@ -100,49 +111,25 @@
     return filename;
 }
 
-sqlite3 *
-yum_db_open (const char *path)
-{
-    int rc;
-    sqlite3 *db = NULL;
-
-    rc = sqlite3_open (path, &db);
-    if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not open SQL database: %s",
-               sqlite3_errmsg (db));
-        sqlite3_close (db);
-        db = NULL;
-    }
+typedef enum {
+    DB_STATUS_OK,
+    DB_STATUS_VERSION_MISMATCH,
+    DB_STATUS_CHECKSUM_MISMATCH,
+    DB_STATUS_ERROR
+} DBStatus;
 
-    sqlite3_exec (db, "PRAGMA synchronous = 0", NULL, NULL, NULL);
-
-    return db;
-}
-
-static void
-yum_db_create_dbinfo_table (sqlite3 *db)
-{
-    const char *sql;
-
-    sql = "CREATE TABLE db_info (dbversion TEXT, checksum TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
-}
-
-gboolean
-yum_db_dbinfo_fresh (sqlite3 *db, const char *checksum)
+static DBStatus
+dbinfo_status (sqlite3 *db, const char *checksum)
 {
     const char *query;
     int rc;
     sqlite3_stmt *handle = NULL;
-    gboolean fresh = FALSE;
+    DBStatus status = DB_STATUS_ERROR;
 
     query = "SELECT dbversion, checksum FROM db_info";
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
-    if (rc != SQLITE_OK) {
-        /* That's fine, maybe the table doesn't even exist (yet) */
+    if (rc != SQLITE_OK)
         goto cleanup;
-    }
 
     while ((rc = sqlite3_step (handle)) == SQLITE_ROW) {
         int dbversion;
@@ -151,15 +138,17 @@
         dbversion  = sqlite3_column_int  (handle, 0);
         dbchecksum = (const char *) sqlite3_column_text (handle, 1);
 
-        if (dbversion != YUM_SQLITE_CACHE_DBVERSION)
+        if (dbversion != YUM_SQLITE_CACHE_DBVERSION) {
             debug (DEBUG_LEVEL_INFO,
                    "Warning: cache file is version %d, we need %d, will regenerate",
                    dbversion, YUM_SQLITE_CACHE_DBVERSION);
-        else if (strcmp (checksum, dbchecksum))
+            status = DB_STATUS_VERSION_MISMATCH;
+        } else if (strcmp (checksum, dbchecksum)) {
             debug (DEBUG_LEVEL_INFO,
                    "sqlite cache needs updating, reading in metadata\n");
-        else
-            fresh = TRUE;
+            status = DB_STATUS_CHECKSUM_MISMATCH;
+        } else
+            status = DB_STATUS_OK;
 
         break;
     }
@@ -168,31 +157,117 @@
     if (handle)
         sqlite3_finalize (handle);
 
-    return fresh;
+    return status;
 }
 
-void
-yum_db_dbinfo_clear (sqlite3 *db)
+static void
+yum_db_create_dbinfo_table (sqlite3 *db, GError **err)
 {
-    sqlite3_exec (db, "DELETE FROM db_info", NULL, NULL, NULL);
+    int rc;
+    const char *sql;
+
+    sql = "CREATE TABLE db_info (dbversion TEXT, checksum TEXT)";
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create db_info table: %s",
+                     sqlite3_errmsg (db));
+    }
+}
+
+sqlite3 *
+yum_db_open (const char *path,
+             const char *checksum,
+             CreateTablesFn create_tables,
+             GError **err)
+{
+    int rc;
+    sqlite3 *db = NULL;
+    gboolean db_existed;
+
+    db_existed = g_file_test (path, G_FILE_TEST_EXISTS);
+
+    rc = sqlite3_open (path, &db);
+    if (rc == SQLITE_OK) {
+        if (db_existed) {
+            DBStatus status = dbinfo_status (db, checksum);
+
+            switch (status) {
+            case DB_STATUS_OK:
+                /* Everything is up-to-date */
+                sqlite3_close (db);
+                return NULL;
+                break;
+            case DB_STATUS_CHECKSUM_MISMATCH:
+                sqlite3_exec (db, "PRAGMA synchronous = 0", NULL, NULL, NULL);
+                sqlite3_exec (db, "DELETE FROM db_info", NULL, NULL, NULL);
+                return db;
+                break;
+            case DB_STATUS_VERSION_MISMATCH:
+            case DB_STATUS_ERROR:
+                sqlite3_close (db);
+                db = NULL;
+                break;
+            }
+        }
+    } else {
+        /* Let's try to delete it and try again,
+           maybe it's a sqlite3 version mismatch. */
+        sqlite3_close (db);
+        db = NULL;
+        unlink (path);
+    }
+
+    if (!db) {
+        rc = sqlite3_open (path, &db);
+        if (rc != SQLITE_OK) {
+            g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                         "Can not open SQL database: %s",
+                         sqlite3_errmsg (db));
+            goto cleanup;
+        }
+    }
+
+    yum_db_create_dbinfo_table (db, err);
+    if (*err)
+        goto cleanup;
+
+    create_tables (db, err);
+    if (*err)
+        goto cleanup;
+
+    sqlite3_exec (db, "PRAGMA synchronous = 0", NULL, NULL, NULL);
+
+ cleanup:
+    if (*err && db) {
+        sqlite3_close (db);
+        db = NULL;
+    }
+
+    return db;
 }
 
 void
-yum_db_dbinfo_update (sqlite3 *db, const char *checksum)
+yum_db_dbinfo_update (sqlite3 *db, const char *checksum, GError **err)
 {
+    int rc;
     char *sql;
 
     sql = g_strdup_printf
         ("INSERT INTO db_info (dbversion, checksum) VALUES (%d, '%s')",
          YUM_SQLITE_CACHE_DBVERSION, checksum);
 
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK)
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not update dbinfo table: %s",
+                     sqlite3_errmsg (db));
 
     g_free (sql);
 }
 
 GHashTable *
-yum_db_read_package_ids (sqlite3 *db)
+yum_db_read_package_ids (sqlite3 *db, GError **err)
 {
     const char *query;
     int rc;
@@ -202,9 +277,9 @@
     query = "SELECT pkgId, pkgKey FROM packages";
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_WARNING,
-               "Can not prepare SQL clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare SQL clause: %s",
+                     sqlite3_errmsg (db));
         goto cleanup;
     }
 
@@ -222,9 +297,9 @@
     }
 
     if (rc != SQLITE_DONE)
-        debug (DEBUG_LEVEL_ERROR,
-               "Error reading from SQL: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Error reading from SQL: %s",
+                     sqlite3_errmsg (db));
 
  cleanup:
     if (handle)
@@ -234,12 +309,11 @@
 }
 
 void
-yum_db_create_primary_tables (sqlite3 *db)
+yum_db_create_primary_tables (sqlite3 *db, GError **err)
 {
+    int rc;
     const char *sql;
 
-    yum_db_create_dbinfo_table (db);
-
     sql =
         "CREATE TABLE packages ("
         "  pkgKey INTEGER PRIMARY KEY,"
@@ -270,19 +344,44 @@
         "  checksum_type TEXT,"
         "  checksum_value TEXT)";
 
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create packages table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql = "CREATE INDEX packagename ON packages (name)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create packagename index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
+    
     sql = "CREATE INDEX packageId ON packages (pkgId)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create packageId index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TABLE files ("
         "  name TEXT,"
         "  type TEXT,"
         "  pkgKey TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create files table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TABLE %s ("
@@ -292,19 +391,31 @@
         "  version TEXT,"
         "  release TEXT,"
         "  pkgKey TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
 
     const char *deps[] = { "requires", "provides", "conflicts", "obsoletes", NULL };
     int i;
 
     for (i = 0; deps[i]; i++) {
         char *query = g_strdup_printf (sql, deps[i]);
-        sqlite3_exec (db, query, NULL, NULL, NULL);
+        rc = sqlite3_exec (db, query, NULL, NULL, NULL);
         g_free (query);
+
+        if (rc != SQLITE_OK) {
+            g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                         "Can not create %s table: %s",
+                         deps[i], sqlite3_errmsg (db));
+            return;
+        }
     }
 
     sql = "CREATE INDEX providesname ON provides (name)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create providesname index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TRIGGER removals AFTER DELETE ON packages"
@@ -316,11 +427,17 @@
         "    DELETE FROM obsoletes WHERE pkgKey = old.pkgKey;"
         "  END;";
 
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create removals trigger: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 }
 
 sqlite3_stmt *
-yum_db_package_prepare (sqlite3 *db)
+yum_db_package_prepare (sqlite3 *db, GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -338,9 +455,9 @@
 
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_WARNING,
-               "Can not prepare package insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare packages insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }
@@ -392,7 +509,9 @@
 }
 
 sqlite3_stmt *
-yum_db_dependency_prepare (sqlite3 *db, const char *table)
+yum_db_dependency_prepare (sqlite3 *db,
+                           const char *table,
+                           GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -406,9 +525,9 @@
     g_free (query);
 
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not prepare dependency insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare dependency insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }
@@ -441,7 +560,7 @@
 }
 
 sqlite3_stmt *
-yum_db_file_prepare (sqlite3 *db)
+yum_db_file_prepare (sqlite3 *db, GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -451,9 +570,9 @@
 
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not prepare file insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare file insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }
@@ -484,17 +603,22 @@
 }
 
 void
-yum_db_create_filelist_tables (sqlite3 *db)
+yum_db_create_filelist_tables (sqlite3 *db, GError **err)
 {
+    int rc;
     const char *sql;
 
-    yum_db_create_dbinfo_table (db);
-
     sql =
         "CREATE TABLE packages ("
         "  pkgKey INTEGER PRIMARY KEY,"
         "  pkgId TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create packages table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TABLE filelist ("
@@ -502,13 +626,31 @@
         "  dirname TEXT,"
         "  filenames TEXT,"
         "  filetypes TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create filelist table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql = "CREATE INDEX keyfile ON filelist (pkgKey)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create keyfile index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql = "CREATE INDEX pkgId ON packages (pkgId)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create pkgId index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TRIGGER remove_filelist AFTER DELETE ON packages"
@@ -516,11 +658,17 @@
         "    DELETE FROM filelist WHERE pkgKey = old.pkgKey;"
         "  END;";
 
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create remove_filelist trigger: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 }
 
 sqlite3_stmt *
-yum_db_package_ids_prepare (sqlite3 *db)
+yum_db_package_ids_prepare (sqlite3 *db, GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -529,9 +677,9 @@
     query = "INSERT INTO packages (pkgId) VALUES (?)";
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not prepare package insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare package ids insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }
@@ -557,7 +705,7 @@
 }
 
 sqlite3_stmt *
-yum_db_filelists_prepare (sqlite3 *db)
+yum_db_filelists_prepare (sqlite3 *db, GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -569,9 +717,9 @@
 
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not prepare filelists insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare filelist insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }
@@ -623,17 +771,22 @@
 }
 
 void
-yum_db_create_other_tables (sqlite3 *db)
+yum_db_create_other_tables (sqlite3 *db, GError **err)
 {
+    int rc;
     const char *sql;
 
-    yum_db_create_dbinfo_table (db);
-
     sql =
         "CREATE TABLE packages ("
         "  pkgKey INTEGER PRIMARY KEY,"
         "  pkgId TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create packages table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TABLE changelog ("
@@ -641,13 +794,31 @@
         "  author TEXT,"
         "  date TEXT,"
         "  changelog TEXT)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create changelog table: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql = "CREATE INDEX keychange ON changelog (pkgKey)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create keychange index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql = "CREATE INDEX pkgId ON packages (pkgId)";
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create pkgId index: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 
     sql =
         "CREATE TRIGGER remove_changelogs AFTER DELETE ON packages"
@@ -655,11 +826,17 @@
         "    DELETE FROM changelog WHERE pkgKey = old.pkgKey;"
         "  END;";
 
-    sqlite3_exec (db, sql, NULL, NULL, NULL);
+    rc = sqlite3_exec (db, sql, NULL, NULL, NULL);
+    if (rc != SQLITE_OK) {
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not create remove_changelogs trigger: %s",
+                     sqlite3_errmsg (db));
+        return;
+    }
 }
 
 sqlite3_stmt *
-yum_db_changelog_prepare (sqlite3 *db)
+yum_db_changelog_prepare (sqlite3 *db, GError **err)
 {
     int rc;
     sqlite3_stmt *handle = NULL;
@@ -671,9 +848,9 @@
 
     rc = sqlite3_prepare (db, query, -1, &handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_ERROR,
-               "Can not prepare changelog insertion clause: %s",
-               sqlite3_errmsg (db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare changelog insertion: %s",
+                     sqlite3_errmsg (db));
         sqlite3_finalize (handle);
         handle = NULL;
     }

Index: db.h
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/db.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- db.h	11 May 2006 17:33:57 -0000	1.1.1.1
+++ db.h	24 May 2006 12:49:16 -0000	1.2
@@ -24,32 +24,40 @@
 
 #define YUM_SQLITE_CACHE_DBVERSION 8
 
+#define YUM_DB_ERROR yum_db_error_quark()
+GQuark yum_db_error_quark (void);
+
+typedef void (*CreateTablesFn) (sqlite3 *db, GError **err);
+
 char         *yum_db_filename               (const char *prefix);
-sqlite3      *yum_db_open                   (const char *path);
+sqlite3      *yum_db_open                   (const char *path,
+                                             const char *checksum,
+                                             CreateTablesFn create_tables,
+                                             GError **err);
 
-void          yum_db_dbinfo_clear           (sqlite3 *db);
-gboolean      yum_db_dbinfo_fresh           (sqlite3 *db,
-                                             const char *checksum);
 void          yum_db_dbinfo_update          (sqlite3 *db,
-                                             const char *checksum);
+                                             const char *checksum,
+                                             GError **err);
 
-GHashTable   *yum_db_read_package_ids       (sqlite3 *db);
+GHashTable   *yum_db_read_package_ids       (sqlite3 *db, GError **err);
 
 /* Primary */
 
-void          yum_db_create_primary_tables  (sqlite3 *db);
-sqlite3_stmt *yum_db_package_prepare        (sqlite3 *db);
+void          yum_db_create_primary_tables  (sqlite3 *db, GError **err);
+sqlite3_stmt *yum_db_package_prepare        (sqlite3 *db, GError **err);
 void          yum_db_package_write          (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              Package *p);
 
-sqlite3_stmt *yum_db_dependency_prepare     (sqlite3 *db, const char *table);
+sqlite3_stmt *yum_db_dependency_prepare     (sqlite3 *db,
+                                             const char *table,
+                                             GError **err);
 void          yum_db_dependency_write       (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              gint64 pkgKey,
                                              Dependency *dep);
 
-sqlite3_stmt *yum_db_file_prepare           (sqlite3 *db);
+sqlite3_stmt *yum_db_file_prepare           (sqlite3 *db, GError **err);
 void          yum_db_file_write             (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              gint64 pkgKey,
@@ -57,20 +65,20 @@
 
 /* Filelists */
 
-void          yum_db_create_filelist_tables (sqlite3 *db);
-sqlite3_stmt *yum_db_package_ids_prepare    (sqlite3 *db);
+void          yum_db_create_filelist_tables (sqlite3 *db, GError **err);
+sqlite3_stmt *yum_db_package_ids_prepare    (sqlite3 *db, GError **err);
 void          yum_db_package_ids_write      (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              Package *p);
 
-sqlite3_stmt *yum_db_filelists_prepare      (sqlite3 *db);
+sqlite3_stmt *yum_db_filelists_prepare      (sqlite3 *db, GError **err);
 void          yum_db_filelists_write        (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              Package *p);
 
 /* Other */
-void          yum_db_create_other_tables    (sqlite3 *db);
-sqlite3_stmt *yum_db_changelog_prepare      (sqlite3 *db);
+void          yum_db_create_other_tables    (sqlite3 *db, GError **err);
+sqlite3_stmt *yum_db_changelog_prepare      (sqlite3 *db, GError **err);
 void          yum_db_changelog_write        (sqlite3 *db,
                                              sqlite3_stmt *handle,
                                              Package *p);

Index: setup.py
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/setup.py,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- setup.py	11 May 2006 17:33:57 -0000	1.1.1.1
+++ setup.py	24 May 2006 12:49:16 -0000	1.2
@@ -26,4 +26,5 @@
 setup (name = '_sqlitecache',
        version = '1.0',
        description = 'A fast YUM meta-data parser',
+	   py_modules = ['sqlitecachec'],
        ext_modules = [module])

Index: sqlitecache.c
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/sqlitecache.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- sqlitecache.c	16 May 2006 03:53:32 -0000	1.2
+++ sqlitecache.c	24 May 2006 12:49:16 -0000	1.3
@@ -22,6 +22,9 @@
 #include "db.h"
 #include "package.h"
 
+/* Make room for 2500 package ids, 40 bytes + '\0' each */
+#define PACKAGE_IDS_CHUNK 41 * 2500
+
 typedef void (*ProgressFn) (guint32 current, guint32 total, gpointer user_data);
 
 typedef struct {
@@ -33,13 +36,14 @@
     guint32 del_count;
     GHashTable *current_packages;
     GHashTable *all_packages;
+    GStringChunk *package_ids_chunk;
     GTimer *timer;
     ProgressFn progress_cb;
     gpointer user_data;
 } UpdateInfo;
 
 static void
-update_info_init (UpdateInfo *info)
+update_info_init (UpdateInfo *info, GError **err)
 {
     const char *sql;
     int rc;
@@ -47,9 +51,10 @@
     sql = "DELETE FROM packages WHERE pkgKey = ?";
     rc = sqlite3_prepare (info->db, sql, -1, &info->remove_handle, NULL);
     if (rc != SQLITE_OK) {
-        debug (DEBUG_LEVEL_WARNING,
-               "Can not prepare package removal clause: %s",
-               sqlite3_errmsg (info->db));
+        g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR,
+                     "Can not prepare changelog insertion: %s",
+                     sqlite3_errmsg (info->db));
+        sqlite3_finalize (info->remove_handle);
         return;
     }
 
@@ -57,11 +62,11 @@
     info->packages_seen = 0;
     info->add_count = 0;
     info->del_count = 0;
-    info->current_packages = yum_db_read_package_ids (info->db);
-    info->all_packages = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                (GDestroyNotify) g_free, NULL);
+    info->all_packages = g_hash_table_new (g_str_hash, g_str_equal);
+    info->package_ids_chunk = g_string_chunk_new (PACKAGE_IDS_CHUNK);
     info->timer = g_timer_new ();
     g_timer_start (info->timer);
+    info->current_packages = yum_db_read_package_ids (info->db, err);
 }
 
 static void
@@ -100,17 +105,25 @@
 }
 
 static void
-update_info_done (UpdateInfo *info)
+update_info_done (UpdateInfo *info, GError **err)
 {
-    sqlite3_finalize (info->remove_handle);
-    g_hash_table_destroy (info->current_packages);
-    g_hash_table_destroy (info->all_packages);
+    if (info->remove_handle)
+        sqlite3_finalize (info->remove_handle);
+    if (info->current_packages)
+        g_hash_table_destroy (info->current_packages);
+    if (info->all_packages)
+        g_hash_table_destroy (info->all_packages);
+    if (info->package_ids_chunk)
+        g_string_chunk_free (info->package_ids_chunk);
 
     g_timer_stop (info->timer);
-    debug (DEBUG_LEVEL_INFO,
-           "Added %d new packages, deleted %d old in %.2f seconds",
-           info->add_count, info->del_count,
-           g_timer_elapsed (info->timer, NULL));
+    if (!*err) {
+        debug (DEBUG_LEVEL_INFO,
+               "Added %d new packages, deleted %d old in %.2f seconds",
+               info->add_count, info->del_count,
+               g_timer_elapsed (info->timer, NULL));
+    }
+
     g_timer_destroy (info->timer);
 }
 
@@ -127,14 +140,24 @@
 } PackageWriterInfo;
 
 static void
-package_writer_info_init (PackageWriterInfo *info, sqlite3 *db)
+package_writer_info_init (PackageWriterInfo *info, sqlite3 *db, GError **err)
 {
-    info->pkg_handle = yum_db_package_prepare (db);
-    info->requires_handle = yum_db_dependency_prepare (db, "requires");
-    info->provides_handle = yum_db_dependency_prepare (db, "provides");
-    info->conflicts_handle = yum_db_dependency_prepare (db, "conflicts");
-    info->obsoletes_handle = yum_db_dependency_prepare (db, "obsoletes");
-    info->files_handle = yum_db_file_prepare (db);
+    info->pkg_handle = yum_db_package_prepare (db, err);
+    if (*err)
+        return;
+    info->requires_handle = yum_db_dependency_prepare (db, "requires", err);
+    if (*err)
+        return;
+    info->provides_handle = yum_db_dependency_prepare (db, "provides", err);
+    if (*err)
+        return;
+    info->conflicts_handle = yum_db_dependency_prepare (db, "conflicts", err);
+    if (*err)
+        return;
+    info->obsoletes_handle = yum_db_dependency_prepare (db, "obsoletes", err);
+    if (*err)
+        return;
+    info->files_handle = yum_db_file_prepare (db, err);
 }
 
 static void
@@ -181,7 +204,8 @@
     UpdateInfo *info = (UpdateInfo *) user_data;
 
     g_hash_table_insert (info->all_packages,
-                         g_strdup (package->pkgId),
+                         g_string_chunk_insert (info->package_ids_chunk,
+                                                package->pkgId),
                          GINT_TO_POINTER (1));
 
     if (g_hash_table_lookup (info->current_packages,
@@ -200,57 +224,73 @@
 static void
 package_writer_info_clean (PackageWriterInfo *info)
 {
-    sqlite3_finalize (info->pkg_handle);
-    sqlite3_finalize (info->requires_handle);
-    sqlite3_finalize (info->provides_handle);
-    sqlite3_finalize (info->conflicts_handle);
-    sqlite3_finalize (info->obsoletes_handle);
-    sqlite3_finalize (info->files_handle);
+    if (info->pkg_handle)
+        sqlite3_finalize (info->pkg_handle);
+    if (info->requires_handle)
+        sqlite3_finalize (info->requires_handle);
+    if (info->provides_handle)
+        sqlite3_finalize (info->provides_handle);
+    if (info->conflicts_handle)
+        sqlite3_finalize (info->conflicts_handle);
+    if (info->obsoletes_handle)
+        sqlite3_finalize (info->obsoletes_handle);
+    if (info->files_handle)
+        sqlite3_finalize (info->files_handle);
 }
 
 static char *
 update_primary (const char *md_filename,
                 const char *checksum,
                 ProgressFn progress_cb,
-                gpointer user_data)
+                gpointer user_data,
+                GError **err)
 {
     PackageWriterInfo info;
     UpdateInfo *update_info = &info.update_info;
     char *db_filename;
 
     db_filename = yum_db_filename (md_filename);
-    update_info->db = yum_db_open (db_filename);
+    update_info->db = yum_db_open (db_filename, checksum,
+                                   yum_db_create_primary_tables,
+                                   err);
 
-    if (!update_info->db) {
-        g_free (db_filename);
-        return NULL;
-    }
+    if (*err != NULL)
+        goto cleanup;
 
-    if (yum_db_dbinfo_fresh (update_info->db, checksum)) {
-        sqlite3_close (update_info->db);
+    if (!update_info->db)
         return db_filename;
-    }
 
-    yum_db_create_primary_tables (update_info->db);
-    yum_db_dbinfo_clear (update_info->db);
+    update_info_init (update_info, err);
+    if (*err)
+        goto cleanup;
 
-    update_info_init (update_info);
     update_info->progress_cb = progress_cb;
     update_info->user_data = user_data;
-    package_writer_info_init (&info, update_info->db);
+    package_writer_info_init (&info, update_info->db, err);
+    if (*err)
+        goto cleanup;
 
     sqlite3_exec (update_info->db, "BEGIN", NULL, NULL, NULL);
-    yum_xml_parse_primary (md_filename, count_cb, add_package, &info);
+    yum_xml_parse_primary (md_filename, count_cb, add_package, &info, err);
+    if (*err)
+        goto cleanup;
     sqlite3_exec (update_info->db, "COMMIT", NULL, NULL, NULL);
 
-    package_writer_info_clean (&info);
-
     update_info_remove_old_entries (update_info);
-    update_info_done (update_info);
 
-    yum_db_dbinfo_update (update_info->db, checksum);
+    yum_db_dbinfo_update (update_info->db, checksum, err);
 
-    sqlite3_close (update_info->db);
+ cleanup:
+    package_writer_info_clean (&info);
+    update_info_done (update_info, err);
+
+    if (update_info->db)
+        sqlite3_close (update_info->db);
+
+    if (*err) {
+        g_free (db_filename);
+        db_filename = NULL;
+    }
 
     return db_filename;
 }
@@ -270,7 +310,8 @@
     UpdateInfo *update_info = &info->update_info;
 
     g_hash_table_insert (update_info->all_packages,
-                         g_strdup (p->pkgId),
+                         g_string_chunk_insert (update_info->package_ids_chunk,
+                                                p->pkgId),
                          GINT_TO_POINTER (1));
 
     if (g_hash_table_lookup (update_info->current_packages,
@@ -291,50 +332,64 @@
 update_filelist (const char *md_filename,
                  const char *checksum,
                  ProgressFn progress_cb,
-                 gpointer user_data)
+                 gpointer user_data,
+                 GError **err)
 {
     FileListInfo info;
     UpdateInfo *update_info = &info.update_info;
     char *db_filename;
 
     db_filename = yum_db_filename (md_filename);
-    update_info->db = yum_db_open (db_filename);
+    update_info->db = yum_db_open (db_filename, checksum,
+                                   yum_db_create_filelist_tables,
+                                   err);
 
-    if (!update_info->db) {
-        g_free (db_filename);
-        return NULL;
-    }
+    if (*err)
+        goto cleanup;
 
-    if (yum_db_dbinfo_fresh (update_info->db, checksum)) {
-        sqlite3_close (update_info->db);
+    if (!update_info->db)
         return db_filename;
-    }
-
-    yum_db_create_filelist_tables (update_info->db);
-    yum_db_dbinfo_clear (update_info->db);
 
-    update_info_init (update_info);
+    update_info_init (update_info, err);
+    if (*err)
+        goto cleanup;
     update_info->progress_cb = progress_cb;
     update_info->user_data = user_data;
-    info.pkg_handle = yum_db_package_ids_prepare (update_info->db);
-    info.file_handle = yum_db_filelists_prepare (update_info->db);
+    info.pkg_handle = yum_db_package_ids_prepare (update_info->db, err);
+    if (*err)
+        goto cleanup;
+
+    info.file_handle = yum_db_filelists_prepare (update_info->db, err);
+    if (*err)
+        goto cleanup;
 
     sqlite3_exec (update_info->db, "BEGIN", NULL, NULL, NULL);
     yum_xml_parse_filelists (md_filename,
                              count_cb,
                              update_filelist_cb,
-                             &info);
+                             &info,
+                             err);
+    if (*err)
+        goto cleanup;
     sqlite3_exec (update_info->db, "COMMIT", NULL, NULL, NULL);
 
-    sqlite3_finalize (info.pkg_handle);
-    sqlite3_finalize (info.file_handle);
-
     update_info_remove_old_entries (update_info);
-    update_info_done (update_info);
+    yum_db_dbinfo_update (update_info->db, checksum, err);
 
-    yum_db_dbinfo_update (update_info->db, checksum);
+ cleanup:
+    update_info_done (update_info, err);
 
-    sqlite3_close (update_info->db);
+    if (info.pkg_handle)
+        sqlite3_finalize (info.pkg_handle);
+    if (info.file_handle)
+        sqlite3_finalize (info.file_handle);
+    if (update_info->db)
+        sqlite3_close (update_info->db);
+
+    if (*err) {
+        g_free (db_filename);
+        db_filename = NULL;
+    }
 
     return db_filename;
 }
@@ -354,7 +409,8 @@
     UpdateInfo *update_info = &info->update_info;
 
     g_hash_table_insert (update_info->all_packages,
-                         g_strdup (p->pkgId),
+                         g_string_chunk_insert (update_info->package_ids_chunk,
+                                                p->pkgId),
                          GINT_TO_POINTER (1));
 
     if (g_hash_table_lookup (update_info->current_packages,
@@ -375,50 +431,64 @@
 update_other (const char *md_filename,
               const char *checksum,
               ProgressFn progress_cb,
-              gpointer user_data)
+              gpointer user_data,
+              GError **err)
 {
     UpdateOtherInfo info;
     UpdateInfo *update_info = &info.update_info;
     char *db_filename;
 
     db_filename = yum_db_filename (md_filename);
-    update_info->db = yum_db_open (db_filename);
+    update_info->db = yum_db_open (db_filename, checksum,
+                                   yum_db_create_other_tables,
+                                   err);
 
-    if (!update_info->db) {
-        g_free (db_filename);
-        return NULL;
-    }
+    if (*err)
+        goto cleanup;
 
-    if (yum_db_dbinfo_fresh (update_info->db, checksum)) {
-        sqlite3_close (update_info->db);
+    if (!update_info->db)
         return db_filename;
-    }
-
-    yum_db_create_other_tables (update_info->db);
-    yum_db_dbinfo_clear (update_info->db);
 
-    update_info_init (update_info);
+    update_info_init (update_info, err);
+    if (*err)
+        goto cleanup;
     update_info->progress_cb = progress_cb;
     update_info->user_data = user_data;
-    info.pkg_handle = yum_db_package_ids_prepare (update_info->db);
-    info.changelog_handle = yum_db_changelog_prepare (update_info->db);
+    info.pkg_handle = yum_db_package_ids_prepare (update_info->db, err);
+    if (*err)
+        goto cleanup;
+
+    info.changelog_handle = yum_db_changelog_prepare (update_info->db, err);
+    if (*err)
+        goto cleanup;
 
     sqlite3_exec (update_info->db, "BEGIN", NULL, NULL, NULL);
     yum_xml_parse_other (md_filename,
                          count_cb,
                          update_other_cb,
-                         &info);
+                         &info,
+                         err);
+    if (*err)
+        goto cleanup;
     sqlite3_exec (update_info->db, "COMMIT", NULL, NULL, NULL);
 
-    sqlite3_finalize (info.pkg_handle);
-    sqlite3_finalize (info.changelog_handle);
-
     update_info_remove_old_entries (update_info);
-    update_info_done (update_info);
+    yum_db_dbinfo_update (update_info->db, checksum, err);
 
-    yum_db_dbinfo_update (update_info->db, checksum);
+ cleanup:
+    update_info_done (update_info, err);
 
-    sqlite3_close (update_info->db);
+    if (info.pkg_handle)
+        sqlite3_finalize (info.pkg_handle);
+    if (info.changelog_handle)
+        sqlite3_finalize (info.changelog_handle);
+    if (update_info->db)
+        sqlite3_close (update_info->db);
+
+    if (*err) {
+        g_free (db_filename);
+        db_filename = NULL;
+    }
 
     return db_filename;
 }
@@ -460,15 +530,17 @@
 
 static void
 progress_cb (guint32 current, guint32 total, gpointer user_data)
-{
+    {
     PyObject *progress = (PyObject *) user_data;
-    PyObject *arglist;
+    PyObject *args;
     PyObject *result;
 
-    arglist = Py_BuildValue ("(ii)", current, total);
-    result = PyEval_CallObject (progress, arglist);
-    Py_DECREF (arglist);
+    args = PyTuple_New (2);
+    PyTuple_SET_ITEM (args, 0, PyInt_FromLong (current));
+    PyTuple_SET_ITEM (args, 1, PyInt_FromLong (total));
 
+    result = PyEval_CallObject (progress, args);
+    Py_DECREF (args);
     Py_XDECREF (result);
 }
 
@@ -478,13 +550,15 @@
           gpointer user_data)
 {
     PyObject *callback = (PyObject *) user_data;
-    PyObject *arglist;
+    PyObject *args;
     PyObject *result;
 
-    arglist = Py_BuildValue ("(is)", level, message);
-    result = PyEval_CallObject (callback, arglist);
-    Py_DECREF (arglist);
+    args = PyTuple_New (2);
+    PyTuple_SET_ITEM (args, 0, PyInt_FromLong (level));
+    PyTuple_SET_ITEM (args, 1, PyString_FromString (message));
 
+    result = PyEval_CallObject (callback, args);
+    Py_DECREF (args);
     Py_XDECREF (result);
 }
 
@@ -497,7 +571,8 @@
     PyObject *progress = NULL;
     int log_id = 0;
     char *db_filename;
-    PyObject *ret;
+    PyObject *ret = NULL;
+    GError *err = NULL;
 
     if (!py_parse_args (args, &md_filename, &checksum, &log, &progress))
         return NULL;
@@ -508,17 +583,18 @@
     db_filename = update_primary (md_filename,
                                   checksum,
                                   progress != NULL ? progress_cb : NULL,
-                                  progress);
+                                  progress,
+                                  &err);
 
     if (log_id)
         debug_remove_handler (log_id);
 
     if (db_filename) {
-        ret = Py_BuildValue ("s", db_filename);
+        ret = PyString_FromString (db_filename);
         g_free (db_filename);
     } else {
-        Py_INCREF (Py_None);
-        ret = Py_None;
+        PyErr_SetString (PyExc_TypeError, err->message);
+        g_error_free (err);
     }
 
     return ret;
@@ -533,7 +609,8 @@
     PyObject *progress = NULL;
     int log_id = 0;
     char *db_filename;
-    PyObject *ret;
+    PyObject *ret = NULL;
+    GError *err = NULL;
 
     if (!py_parse_args (args, &md_filename, &checksum, &log, &progress))
         return NULL;
@@ -544,17 +621,18 @@
     db_filename = update_filelist (md_filename,
                                    checksum,
                                    progress != NULL ? progress_cb : NULL,
-                                   progress);
+                                   progress,
+                                   &err);
 
     if (log_id)
         debug_remove_handler (log_id);
 
     if (db_filename) {
-        ret = Py_BuildValue ("s", db_filename);
+        ret = PyString_FromString (db_filename);
         g_free (db_filename);
     } else {
-        Py_INCREF (Py_None);
-        ret = Py_None;
+        PyErr_SetString (PyExc_TypeError, err->message);
+        g_error_free (err);
     }
 
     return ret;
@@ -569,7 +647,8 @@
     PyObject *progress = NULL;
     int log_id = 0;
     char *db_filename;
-    PyObject *ret;
+    PyObject *ret = NULL;
+    GError *err = NULL;
 
     if (!py_parse_args (args, &md_filename, &checksum, &log, &progress))
         return NULL;
@@ -580,17 +659,18 @@
     db_filename = update_other (md_filename,
                                 checksum,
                                 progress != NULL ? progress_cb : NULL,
-                                progress);
+                                progress,
+                                &err);
 
     if (log_id)
         debug_remove_handler (log_id);
 
     if (db_filename) {
-        ret = Py_BuildValue ("s", db_filename);
+        ret = PyString_FromString (db_filename);
         g_free (db_filename);
     } else {
-        Py_INCREF (Py_None);
-        ret = Py_None;
+        PyErr_SetString (PyExc_TypeError, err->message);
+        g_error_free (err);
     }
 
     return ret;

Index: xml-parser.c
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/xml-parser.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- xml-parser.c	16 May 2006 03:53:32 -0000	1.2
+++ xml-parser.c	24 May 2006 12:49:16 -0000	1.3
@@ -27,6 +27,17 @@
 
 #define PACKAGE_FIELD_SIZE 1024
 
+GQuark
+yum_parser_error_quark (void)
+{
+    static GQuark quark;
+
+    if (!quark)
+        quark = g_quark_from_static_string ("yum_parser_error");
+
+    return quark;
+}
+
 static guint32
 string_to_guint32_with_default (const char *n, guint32 def)
 {
@@ -50,6 +61,7 @@
 typedef struct {
     xmlParserCtxt *xml_context;
     PrimarySAXContextState state;
+    GError **error;
     CountFn count_fn;
     PackageFn package_fn;
     gpointer user_data;
@@ -58,6 +70,7 @@
     GSList **current_dep_list;
     PackageFile *current_file;
 
+    gboolean want_text;
     GString *text_buffer;
 } PrimarySAXContext;
 
@@ -104,6 +117,8 @@
 
     g_assert (p != NULL);
 
+    ctx->want_text = TRUE;
+
     if (!strcmp (name, "format")) {
         ctx->state = PRIMARY_PARSER_FORMAT;
     }
@@ -313,12 +328,13 @@
     g_assert (p != NULL);
 
     if (!strcmp (name, "package")) {
-        if (ctx->package_fn)
+        if (ctx->package_fn && !*ctx->error)
             ctx->package_fn (p, ctx->user_data);
 
         package_free (p);
         ctx->current_package = NULL;
 
+        ctx->want_text = FALSE;
         ctx->state = PRIMARY_PARSER_TOPLEVEL;
     }
 
@@ -437,7 +453,8 @@
 {
     PrimarySAXContext *ctx = (PrimarySAXContext *) data;
 
-    g_string_append_len (ctx->text_buffer, ch, len);
+    if (ctx->want_text)
+        g_string_append_len (ctx->text_buffer, ch, len);
 }
 
 static void
@@ -458,13 +475,15 @@
 static void
 primary_sax_error (void *data, const char *msg, ...)
 {
+    PrimarySAXContext *ctx = (PrimarySAXContext *) data;
     va_list args;
     char *tmp;
 
     va_start (args, msg);
 
     tmp = g_strdup_vprintf (msg, args);
-    debug (DEBUG_LEVEL_ERROR, "* SAX Error: %s", tmp);
+    g_set_error (ctx->error, YUM_PARSER_ERROR, YUM_PARSER_ERROR,
+                 "Parsing primary.xml error: %s", tmp);
     g_free (tmp);
 
     va_end (args);
@@ -501,18 +520,21 @@
 yum_xml_parse_primary (const char *filename,
                        CountFn count_callback,
                        PackageFn package_callback,
-                       gpointer user_data)
+                       gpointer user_data,
+                       GError **err)
 {
     PrimarySAXContext ctx;
     int rc;
 
     ctx.state = PRIMARY_PARSER_TOPLEVEL;
+    ctx.error = err;
     ctx.count_fn = count_callback;
     ctx.package_fn = package_callback;
     ctx.user_data = user_data;
     ctx.current_package = NULL;
     ctx.current_dep_list = NULL;
     ctx.current_file = NULL;
+    ctx.want_text = FALSE;
     ctx.text_buffer = g_string_sized_new (PACKAGE_FIELD_SIZE);
 
     xmlSubstituteEntitiesDefault (1);
@@ -537,6 +559,7 @@
 typedef struct {
     xmlParserCtxt *xml_context;
     FilelistSAXContextState state;
+    GError **error;
     CountFn count_fn;
     PackageFn package_fn;
     gpointer user_data;
@@ -544,6 +567,7 @@
     Package *current_package;
     PackageFile *current_file;
 
+    gboolean want_text;
     GString *text_buffer;
 } FilelistSAXContext;
 
@@ -607,6 +631,8 @@
 
     g_assert (p != NULL);
 
+    ctx->want_text = TRUE;
+
     if (!strcmp (name, "version")) {
         for (i = 0; attrs && attrs[i]; i++) {
             attr = attrs[i];
@@ -662,8 +688,10 @@
 
     g_assert (p != NULL);
 
+    ctx->want_text = FALSE;
+
     if (!strcmp (name, "package")) {
-        if (ctx->package_fn)
+        if (ctx->package_fn && !*ctx->error)
             ctx->package_fn (p, ctx->user_data);
 
         package_free (p);
@@ -711,7 +739,8 @@
 {
     FilelistSAXContext *ctx = (FilelistSAXContext *) data;
 
-    g_string_append_len (ctx->text_buffer, ch, len);
+    if (ctx->want_text)
+        g_string_append_len (ctx->text_buffer, ch, len);
 }
 
 static void
@@ -732,13 +761,15 @@
 static void
 filelist_sax_error (void *data, const char *msg, ...)
 {
+    PrimarySAXContext *ctx = (PrimarySAXContext *) data;
     va_list args;
     char *tmp;
 
     va_start (args, msg);
 
     tmp = g_strdup_vprintf (msg, args);
-    debug (DEBUG_LEVEL_ERROR, "* SAX Error: %s", tmp);
+    g_set_error (ctx->error, YUM_PARSER_ERROR, YUM_PARSER_ERROR,
+                 "Parsing filelists.xml error: %s", tmp);
     g_free (tmp);
 
     va_end (args);
@@ -775,17 +806,20 @@
 yum_xml_parse_filelists (const char *filename,
                          CountFn count_callback,
                          PackageFn package_callback,
-                         gpointer user_data)
+                         gpointer user_data,
+                         GError **err)
 {
     FilelistSAXContext ctx;
     int rc;
 
     ctx.state = FILELIST_PARSER_TOPLEVEL;
+    ctx.error = err;
     ctx.count_fn = count_callback;
     ctx.package_fn = package_callback;
     ctx.user_data = user_data;
     ctx.current_package = NULL;
     ctx.current_file = NULL;
+    ctx.want_text = FALSE;
     ctx.text_buffer = g_string_sized_new (PACKAGE_FIELD_SIZE);
 
     xmlSubstituteEntitiesDefault (1);
@@ -812,6 +846,7 @@
 typedef struct {
     xmlParserCtxt *xml_context;
     OtherSAXContextState state;
+    GError **error;
     CountFn count_fn;
     PackageFn package_fn;
     gpointer user_data;
@@ -819,6 +854,7 @@
     Package *current_package;
     ChangelogEntry *current_entry;
 
+    gboolean want_text;
     GString *text_buffer;
 } OtherSAXContext;
 
@@ -882,6 +918,8 @@
 
     g_assert (p != NULL);
 
+    ctx->want_text = TRUE;
+
     if (!strcmp (name, "version")) {
         for (i = 0; attrs && attrs[i]; i++) {
             attr = attrs[i];
@@ -940,12 +978,14 @@
 
     g_assert (p != NULL);
 
+    ctx->want_text = FALSE;
+
     if (!strcmp (name, "package")) {
 
         if (p->changelogs)
             p->changelogs = g_slist_reverse (p->changelogs);
 
-        if (ctx->package_fn)
+        if (ctx->package_fn && !*ctx->error)
             ctx->package_fn (p, ctx->user_data);
 
         package_free (p);
@@ -991,7 +1031,8 @@
 {
     OtherSAXContext *ctx = (OtherSAXContext *) data;
 
-    g_string_append_len (ctx->text_buffer, ch, len);
+    if (ctx->want_text)
+        g_string_append_len (ctx->text_buffer, ch, len);
 }
 
 static void
@@ -1012,13 +1053,15 @@
 static void
 other_sax_error (void *data, const char *msg, ...)
 {
+    PrimarySAXContext *ctx = (PrimarySAXContext *) data;
     va_list args;
     char *tmp;
 
     va_start (args, msg);
 
     tmp = g_strdup_vprintf (msg, args);
-    debug (DEBUG_LEVEL_ERROR, "* SAX Error: %s", tmp);
+    g_set_error (ctx->error, YUM_PARSER_ERROR, YUM_PARSER_ERROR,
+                 "Parsing other.xml error: %s", tmp);
     g_free (tmp);
 
     va_end (args);
@@ -1055,17 +1098,20 @@
 yum_xml_parse_other (const char *filename,
                      CountFn count_callback,
                      PackageFn package_callback,
-                     gpointer user_data)
+                     gpointer user_data,
+                     GError **err)
 {
     OtherSAXContext ctx;
     int rc;
 
     ctx.state = OTHER_PARSER_TOPLEVEL;
+    ctx.error = err;
     ctx.count_fn = count_callback;
     ctx.package_fn = package_callback;
     ctx.user_data = user_data;
     ctx.current_package = NULL;
     ctx.current_entry = NULL;
+    ctx.want_text = FALSE;
     ctx.text_buffer = g_string_sized_new (PACKAGE_FIELD_SIZE);
 
     xmlSubstituteEntitiesDefault (1);

Index: xml-parser.h
===================================================================
RCS file: /home/groups/yum/cvs/yum-metadata-parser/xml-parser.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- xml-parser.h	16 May 2006 03:53:32 -0000	1.2
+++ xml-parser.h	24 May 2006 12:49:16 -0000	1.3
@@ -22,21 +22,27 @@
 
 typedef void (*CountFn) (guint32 count, gpointer data);
 
+#define YUM_PARSER_ERROR yum_parser_error_quark()
+GQuark yum_parser_error_quark (void);
+
 void
 yum_xml_parse_primary (const char *filename,
                        CountFn count_callback,
                        PackageFn package_callback,
-                       gpointer user_data);
+                       gpointer user_data,
+                       GError **err);
 
 void
 yum_xml_parse_filelists (const char *filename,
                          CountFn count_callback,
                          PackageFn package_callback,
-                         gpointer user_data);
+                         gpointer user_data,
+                         GError **err);
 
 void yum_xml_parse_other (const char *filename,
                           CountFn count_callback,
                           PackageFn package_callback,
-                          gpointer user_data);
+                          gpointer user_data,
+                          GError **err);
 
 #endif /* __YUM_XML_PARSER_H__ */

--- sqlitecache.py DELETED ---




More information about the Yum-cvs-commits mailing list