Support for SQLite metadata DB + new repomd module interface
authorTomas Mlcoch <tmlcoch@redhat.com>
Tue, 26 Jun 2012 11:16:47 +0000 (13:16 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Tue, 26 Jun 2012 11:24:46 +0000 (13:24 +0200)
src/createrepo_c.c
src/mergerepo_c.c
src/package.h
src/repomd.c
src/repomd.h

index e2c253c..0fb53fe 100644 (file)
@@ -35,6 +35,7 @@
 #include "misc.h"
 #include "cmd_parser.h"
 #include "xml_dump.h"
+#include "sqlite.h"
 
 
 #define G_LOG_DOMAIN    ((gchar*) 0)
@@ -45,6 +46,9 @@ struct UserData {
     CW_FILE *pri_f;
     CW_FILE *fil_f;
     CW_FILE *oth_f;
+    DbPrimaryStatements pri_statements;
+    DbFilelistsStatements fil_statements;
+    DbOtherStatements oth_statements;
     int changelog_limit;
     char *location_base;
     int repodir_name_len;
@@ -126,13 +130,10 @@ G_LOCK_DEFINE (LOCK_PRI);
 G_LOCK_DEFINE (LOCK_FIL);
 G_LOCK_DEFINE (LOCK_OTH);
 
-void dumper_thread(gpointer data, gpointer user_data) {
-    struct UserData *udata = (struct UserData *) user_data;
 
-//    if (udata->verbose) {
-//        printf("Processing: %s\n", data);
-//    }
+void dumper_thread(gpointer data, gpointer user_data) {
 
+    struct UserData *udata = (struct UserData *) user_data;
     struct PoolTask *task = (struct PoolTask *) data;
 
     // get location_href without leading part of path (path to repo) including '/' char
@@ -142,7 +143,7 @@ void dumper_thread(gpointer data, gpointer user_data) {
 
     // Get stat info about file
     struct stat stat_buf;
-    if (!(udata->old_metadata) || !(udata->skip_stat)) {
+    if (udata->old_metadata && !(udata->skip_stat)) {
         if (stat(task->full_path, &stat_buf) == -1) {
             g_critical("Stat() on %s: %s", task->full_path, strerror(errno));
             return;
@@ -152,11 +153,9 @@ void dumper_thread(gpointer data, gpointer user_data) {
     struct XmlStruct res;
 
     // Update stuff
-    gboolean modified_primary_xml_used = FALSE;
-    gchar *modified_primary_xml = NULL;
-
     gboolean old_used = FALSE;
-    Package *md;
+    Package *md = NULL;
+    Package *pkg = NULL;
 
     if (udata->old_metadata) {
         // We have old metadata
@@ -186,36 +185,55 @@ void dumper_thread(gpointer data, gpointer user_data) {
     }
 
     if (!old_used) {
-        res = xml_from_package_file(task->full_path, udata->checksum_type, location_href,
-                                    udata->location_base, udata->changelog_limit, NULL);
+        pkg = package_from_file(task->full_path, udata->checksum_type,
+                                location_href, udata->location_base,
+                                udata->changelog_limit, NULL);
+        if (!pkg) {
+            g_warning("Cannot read package: %s", task->full_path);
+            goto task_cleanup;
+        }
+        res = xml_dump(pkg);
     } else {
+        pkg = md;
         res = xml_dump(md);
     }
 
     // Write primary data
     G_LOCK(LOCK_PRI);
     cw_puts(udata->pri_f, (const char *) res.primary);
+    if (udata->pri_statements) {
+        add_primary_pkg_db(udata->pri_statements, pkg);
+    }
     G_UNLOCK(LOCK_PRI);
 
     // Write fielists data
     G_LOCK(LOCK_FIL);
     cw_puts(udata->fil_f, (const char *) res.filelists);
+    if (udata->fil_statements) {
+        add_filelists_pkg_db(udata->fil_statements, pkg);
+    }
     G_UNLOCK(LOCK_FIL);
 
     // Write other data
     G_LOCK(LOCK_OTH);
     cw_puts(udata->oth_f, (const char *) res.other);
+    if (udata->oth_statements) {
+        add_other_pkg_db(udata->oth_statements, pkg);
+    }
     G_UNLOCK(LOCK_OTH);
 
+
     // Clean up
+
+    if (pkg != md) {
+        package_free(pkg);
+    }
+
     free(res.primary);
     free(res.filelists);
     free(res.other);
 
-    if (modified_primary_xml_used) {
-        g_free(modified_primary_xml);
-    }
-
+task_cleanup:
     g_free(task->full_path);
     g_free(task->filename);
     g_free(task->path);
@@ -254,10 +272,10 @@ int main(int argc, char **argv) {
 
     // Dirs
 
-    gchar *in_dir   = NULL;  // path/to/repo/
-    gchar *in_repo  = NULL;  // path/to/repo/repodata/
-    gchar *out_dir  = NULL;  // path/to/out_repo/
-    gchar *out_repo = NULL;  // path/to/out_repo/repodata/
+    gchar *in_dir   = NULL;     // path/to/repo/
+    gchar *in_repo  = NULL;     // path/to/repo/repodata/
+    gchar *out_dir  = NULL;     // path/to/out_repo/
+    gchar *out_repo = NULL;     // path/to/out_repo/repodata/
     gchar *tmp_out_repo = NULL; // path/to/out_repo/.repodata/
 
     in_dir = normalize_dir_path(argv[1]);
@@ -402,26 +420,27 @@ int main(int argc, char **argv) {
 
     // Create and open new compressed files
 
-    const char *compression_suffix = NULL;
-    CompressionType used_compression = GZ_COMPRESSION;
+    const char *sqlite_compression_suffix = NULL;
+    CompressionType sqlite_compression = BZ2_COMPRESSION;
     CompressionType groupfile_compression = GZ_COMPRESSION;
     if (cmd_options->xz_compression) {
+        sqlite_compression = XZ_COMPRESSION;
         groupfile_compression = XZ_COMPRESSION;
     }
-    compression_suffix = get_suffix(used_compression);
+    sqlite_compression_suffix = get_suffix(sqlite_compression);
 
     CW_FILE *pri_cw_file;
     CW_FILE *fil_cw_file;
     CW_FILE *oth_cw_file;
 
     g_message("Temporary output repo path: %s", tmp_out_repo);
-    g_debug("Opening/Creating .xml%s files", compression_suffix);
+    g_debug("Creating .xml.gz files");
 
-    gchar *pri_xml_filename = g_strconcat(tmp_out_repo, "/primary.xml", compression_suffix, NULL);
-    gchar *fil_xml_filename = g_strconcat(tmp_out_repo, "/filelists.xml", compression_suffix, NULL);
-    gchar *oth_xml_filename = g_strconcat(tmp_out_repo, "/other.xml", compression_suffix, NULL);
+    gchar *pri_xml_filename = g_strconcat(tmp_out_repo, "/primary.xml.gz", NULL);
+    gchar *fil_xml_filename = g_strconcat(tmp_out_repo, "/filelists.xml.gz", NULL);
+    gchar *oth_xml_filename = g_strconcat(tmp_out_repo, "/other.xml.gz", NULL);
 
-    if ((pri_cw_file = cw_open(pri_xml_filename, CW_MODE_WRITE, used_compression)) == NULL) {
+    if ((pri_cw_file = cw_open(pri_xml_filename, CW_MODE_WRITE, GZ_COMPRESSION)) == NULL) {
         g_critical("Cannot open file: %s", pri_xml_filename);
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
@@ -429,7 +448,7 @@ int main(int argc, char **argv) {
         exit(1);
     }
 
-    if ((fil_cw_file = cw_open(fil_xml_filename, CW_MODE_WRITE, used_compression)) == NULL) {
+    if ((fil_cw_file = cw_open(fil_xml_filename, CW_MODE_WRITE, GZ_COMPRESSION)) == NULL) {
         g_critical("Cannot open file: %s", fil_xml_filename);
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
@@ -438,7 +457,7 @@ int main(int argc, char **argv) {
         exit(1);
     }
 
-    if ((oth_cw_file = cw_open(oth_xml_filename, CW_MODE_WRITE, used_compression)) == NULL) {
+    if ((oth_cw_file = cw_open(oth_xml_filename, CW_MODE_WRITE, GZ_COMPRESSION)) == NULL) {
         g_critical("Cannot open file: %s", oth_xml_filename);
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
@@ -449,6 +468,32 @@ int main(int argc, char **argv) {
     }
 
 
+    // Open sqlite databases
+
+    gchar *pri_db_filename = NULL;
+    gchar *fil_db_filename = NULL;
+    gchar *oth_db_filename = NULL;
+    sqlite3 *pri_db = NULL;
+    sqlite3 *fil_db = NULL;
+    sqlite3 *oth_db = NULL;
+    DbPrimaryStatements pri_statements   = NULL;
+    DbFilelistsStatements fil_statements = NULL;
+    DbOtherStatements oth_statements     = NULL;
+
+    if (!cmd_options->no_database) {
+        g_debug("Creating .xml.gz files");
+        pri_db_filename = g_strconcat(tmp_out_repo, "/primary.sqlite", NULL);
+        fil_db_filename = g_strconcat(tmp_out_repo, "/filelists.sqlite", NULL);
+        oth_db_filename = g_strconcat(tmp_out_repo, "/other.sqlite", NULL);
+        pri_db = open_primary_db(pri_db_filename, NULL);
+        fil_db = open_filelists_db(fil_db_filename, NULL);
+        oth_db = open_other_db(oth_db_filename, NULL);
+        pri_statements = prepare_primary_db_statements(pri_db, NULL);
+        fil_statements = prepare_filelists_db_statements(fil_db, NULL);
+        oth_statements = prepare_other_db_statements(oth_db, NULL);
+    }
+
+
     // Init package parser
 
     init_package_parser();
@@ -460,6 +505,9 @@ int main(int argc, char **argv) {
     user_data.pri_f             = pri_cw_file;
     user_data.fil_f             = fil_cw_file;
     user_data.oth_f             = oth_cw_file;
+    user_data.pri_statements    = pri_statements;
+    user_data.fil_statements    = fil_statements;
+    user_data.oth_statements    = oth_statements;
     user_data.changelog_limit   = cmd_options->changelog_limit;
     user_data.location_base     = cmd_options->location_base;
     user_data.checksum_type_str = cmd_options->checksum;
@@ -635,6 +683,17 @@ int main(int argc, char **argv) {
     cw_close(user_data.oth_f);
 
 
+    // Close db
+
+    destroy_primary_db_statements(user_data.pri_statements);
+    destroy_filelists_db_statements(user_data.fil_statements);
+    destroy_other_db_statements(user_data.oth_statements);
+
+    close_primary_db(pri_db, NULL);
+    close_filelists_db(fil_db, NULL);
+    close_other_db(oth_db, NULL);
+
+
     // Move files from out_repo into tmp_out_repo
 
     g_debug("Moving data from %s", out_repo);
@@ -686,39 +745,146 @@ int main(int argc, char **argv) {
     }
 
 
-    // Create repomd.xml
+    // Create repomd records for each file
 
     g_debug("Generating repomd.xml");
 
-    gchar *pri_xml_name = g_strconcat("repodata/", "primary.xml", compression_suffix, NULL);
-    gchar *fil_xml_name = g_strconcat("repodata/", "filelists.xml", compression_suffix, NULL);
-    gchar *oth_xml_name = g_strconcat("repodata/", "other.xml", compression_suffix, NULL);
-    gchar *groupfile_name = NULL;
+    RepomdRecord pri_xml_rec = new_repomdrecord("repodata/primary.xml.gz");
+    RepomdRecord fil_xml_rec = new_repomdrecord("repodata/filelists.xml.gz");
+    RepomdRecord oth_xml_rec = new_repomdrecord("repodata/other.xml.gz");
+    RepomdRecord pri_db_rec               = NULL;
+    RepomdRecord fil_db_rec               = NULL;
+    RepomdRecord oth_db_rec               = NULL;
+    RepomdRecord groupfile_rec            = NULL;
+    RepomdRecord compressed_groupfile_rec = NULL;
+
+
+    // XML
+
+    fill_missing_data(out_dir, pri_xml_rec, &(cmd_options->checksum_type));
+    fill_missing_data(out_dir, fil_xml_rec, &(cmd_options->checksum_type));
+    fill_missing_data(out_dir, oth_xml_rec, &(cmd_options->checksum_type));
+
+
+    // Groupfile
+
     if (groupfile) {
-        groupfile_name = g_strconcat("repodata/", get_filename(groupfile), NULL);
+        gchar *groupfile_name = g_strconcat("repodata/", get_filename(groupfile), NULL);
+        groupfile_rec = new_repomdrecord(groupfile_name);
+        compressed_groupfile_rec = new_repomdrecord(groupfile_name);
+
+        process_groupfile(out_dir, groupfile_rec, compressed_groupfile_rec,
+                      &(cmd_options->checksum_type), groupfile_compression);
+        g_free(groupfile_name);
     }
 
-    struct repomdResult *repomd_res = xml_repomd(out_dir, cmd_options->unique_md_filenames,
-                                                 pri_xml_name, fil_xml_name, oth_xml_name,
-                                                 NULL, NULL, NULL, groupfile_name, NULL,
-                                                 &(cmd_options->checksum_type),
-                                                 groupfile_compression);
+
+    // Sqlite db
+
+    if (!cmd_options->no_database) {
+        gchar *pri_db_name = g_strconcat("repodata/primary.sqlite", sqlite_compression_suffix, NULL);
+        gchar *fil_db_name = g_strconcat("repodata/filelists.sqlite", sqlite_compression_suffix, NULL);
+        gchar *oth_db_name = g_strconcat("repodata/other.sqlite", sqlite_compression_suffix, NULL);
+
+        gchar *tmp_pri_db_path;
+        gchar *tmp_fil_db_path;
+        gchar *tmp_oth_db_path;
+
+
+        // Open dbs again (but from the new (final) location)
+        // and insert XML checksums
+
+        tmp_pri_db_path = g_strconcat(out_dir, "repodata/primary.sqlite", NULL);
+        tmp_fil_db_path = g_strconcat(out_dir, "repodata/filelists.sqlite", NULL);
+        tmp_oth_db_path = g_strconcat(out_dir, "repodata/other.sqlite", NULL);
+
+        sqlite3_open(tmp_pri_db_path, &pri_db);
+        sqlite3_open(tmp_fil_db_path, &fil_db);
+        sqlite3_open(tmp_oth_db_path, &oth_db);
+
+        dbinfo_update(pri_db, pri_xml_rec->checksum, NULL);
+        dbinfo_update(fil_db, fil_xml_rec->checksum, NULL);
+        dbinfo_update(oth_db, oth_xml_rec->checksum, NULL);
+
+        sqlite3_close(pri_db);
+        sqlite3_close(fil_db);
+        sqlite3_close(oth_db);
+
+
+        // Compress dbs
+
+        compress_file(tmp_pri_db_path, NULL, sqlite_compression);
+        compress_file(tmp_fil_db_path, NULL, sqlite_compression);
+        compress_file(tmp_oth_db_path, NULL, sqlite_compression);
+
+        remove(tmp_pri_db_path);
+        remove(tmp_fil_db_path);
+        remove(tmp_oth_db_path);
+
+        g_free(tmp_pri_db_path);
+        g_free(tmp_fil_db_path);
+        g_free(tmp_oth_db_path);
+
+
+        // Prepare repomd records
+
+        pri_db_rec = new_repomdrecord(pri_db_name);
+        fil_db_rec = new_repomdrecord(fil_db_name);
+        oth_db_rec = new_repomdrecord(oth_db_name);
+
+        fill_missing_data(out_dir, pri_db_rec, &(cmd_options->checksum_type));
+        fill_missing_data(out_dir, fil_db_rec, &(cmd_options->checksum_type));
+        fill_missing_data(out_dir, oth_db_rec, &(cmd_options->checksum_type));
+
+        g_free(pri_db_name);
+        g_free(fil_db_name);
+        g_free(oth_db_name);
+    }
+
+
+    // Add checksums into files names
+
+    if (cmd_options->unique_md_filenames) {
+        rename_file(out_dir, pri_xml_rec);
+        rename_file(out_dir, fil_xml_rec);
+        rename_file(out_dir, oth_xml_rec);
+        rename_file(out_dir, pri_db_rec);
+        rename_file(out_dir, fil_db_rec);
+        rename_file(out_dir, oth_db_rec);
+        rename_file(out_dir, groupfile_rec);
+        rename_file(out_dir, compressed_groupfile_rec);
+    }
+
+
+    // Gen xml
+
+    char *repomd_xml = xml_repomd(out_dir, pri_xml_rec, fil_xml_rec,
+                                  oth_xml_rec, pri_db_rec, fil_db_rec,
+                                  oth_db_rec, groupfile_rec,
+                                  compressed_groupfile_rec, NULL);
     gchar *repomd_path = g_strconcat(out_repo, "repomd.xml", NULL);
 
+
+    // Write repomd.xml
+
     FILE *frepomd = fopen(repomd_path, "w");
-    if (frepomd && repomd_res->repomd_xml) {
-        fputs(repomd_res->repomd_xml, frepomd);
-        fclose(frepomd);
-    } else {
+    if (!frepomd || !repomd_xml) {
         g_critical("Generate of repomd.xml failed");
+        return 1;
     }
-
-    free_repomdresult(repomd_res);
+    fputs(repomd_xml, frepomd);
+    fclose(frepomd);
+    g_free(repomd_xml);
     g_free(repomd_path);
-    g_free(pri_xml_name);
-    g_free(fil_xml_name);
-    g_free(oth_xml_name);
-    g_free(groupfile_name);
+
+    free_repomdrecord(pri_xml_rec);
+    free_repomdrecord(fil_xml_rec);
+    free_repomdrecord(oth_xml_rec);
+    free_repomdrecord(pri_db_rec);
+    free_repomdrecord(fil_db_rec);
+    free_repomdrecord(oth_db_rec);
+    free_repomdrecord(groupfile_rec);
+    free_repomdrecord(compressed_groupfile_rec);
 
 
     // Clean up
@@ -738,6 +904,9 @@ int main(int argc, char **argv) {
     g_free(pri_xml_filename);
     g_free(fil_xml_filename);
     g_free(oth_xml_filename);
+    g_free(pri_db_filename);
+    g_free(fil_db_filename);
+    g_free(oth_db_filename);
     g_free(groupfile);
 
     free_options(cmd_options);
index 80ae940..3cdcc0e 100644 (file)
 #include "package.h"
 #include "xml_dump.h"
 #include "repomd.h"
+#include "sqlite.h"
 
 
 #define G_LOG_DOMAIN    ((gchar*) 0)
 
 #define DEFAULT_OUTPUTDIR               "merged_repo/"
-#define DEFAULT_COMPRESSION_TYPE        GZ_COMPRESSION
+#define DEFAULT_DB_COMPRESSION_TYPE             BZ2_COMPRESSION
+#define DEFAULT_GROUPFILE_COMPRESSION_TYPE      GZ_COMPRESSION
 
 
 typedef enum {
@@ -70,14 +72,16 @@ struct CmdOptions {
     char *out_repo;
     GSList *repo_list;
     GSList *arch_list;
-    CompressionType compression_type;
+    CompressionType db_compression_type;
+    CompressionType groupfile_compression_type;
     MergeMethod merge_method;
 
 };
 
 
 struct CmdOptions _cmd_options = {
-        .compression_type = GZ_COMPRESSION,
+        .db_compression_type = DEFAULT_DB_COMPRESSION_TYPE,
+        .groupfile_compression_type = DEFAULT_GROUPFILE_COMPRESSION_TYPE,
         .merge_method = MM_DEFAULT
     };
 
@@ -101,7 +105,8 @@ static GOptionEntry cmd_entries[] =
 };
 
 
-gboolean check_arguments(struct CmdOptions *options)
+gboolean
+check_arguments(struct CmdOptions *options)
 {
     int x;
     gboolean ret = TRUE;
@@ -145,11 +150,14 @@ gboolean check_arguments(struct CmdOptions *options)
     // Compress type
     if (options->compress_type) {
         if (!g_strcmp0(options->compress_type, "gz")) {
-            options->compression_type = GZ_COMPRESSION;
+            options->db_compression_type = GZ_COMPRESSION;
+            options->groupfile_compression_type = GZ_COMPRESSION;
         } else if (!g_strcmp0(options->compress_type, "bz2")) {
-            options->compression_type = BZ2_COMPRESSION;
+            options->db_compression_type = BZ2_COMPRESSION;
+            options->groupfile_compression_type = BZ2_COMPRESSION;
         } else if (!g_strcmp0(options->compress_type, "xz")) {
-            options->compression_type = XZ_COMPRESSION;
+            options->db_compression_type = XZ_COMPRESSION;
+            options->groupfile_compression_type = XZ_COMPRESSION;
         } else {
             g_critical("Compression %s not available: Please choose from: gz or bz2 or xz", options->compress_type);
             ret = FALSE;
@@ -174,7 +182,8 @@ gboolean check_arguments(struct CmdOptions *options)
 }
 
 
-struct CmdOptions *parse_arguments(int *argc, char ***argv)
+struct CmdOptions *
+parse_arguments(int *argc, char ***argv)
 {
     GError *error = NULL;
     GOptionContext *context;
@@ -195,7 +204,8 @@ struct CmdOptions *parse_arguments(int *argc, char ***argv)
 
 
 
-void free_options(struct CmdOptions *options)
+void
+free_options(struct CmdOptions *options)
 {
     g_free(options->outputdir);
     g_free(options->archlist);
@@ -224,7 +234,8 @@ void free_options(struct CmdOptions *options)
 
 
 
-void black_hole_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+void
+black_hole_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
 {
     UNUSED(log_domain);
     UNUSED(log_level);
@@ -235,7 +246,8 @@ void black_hole_log_function (const gchar *log_domain, GLogLevelFlags log_level,
 
 
 
-void free_merged_values(gpointer data)
+void
+free_merged_values(gpointer data)
 {
     GSList *element = (GSList *) data;
     for (; element; element=g_slist_next(element)) {
@@ -247,7 +259,8 @@ void free_merged_values(gpointer data)
 
 
 
-GHashTable *new_merged_metadata_hashtable()
+GHashTable *
+new_merged_metadata_hashtable()
 {
     GHashTable *hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free_merged_values); // TODO!!
     return hashtable;
@@ -255,7 +268,8 @@ GHashTable *new_merged_metadata_hashtable()
 
 
 
-void destroy_merged_metadata_hashtable(GHashTable *hashtable)
+void
+destroy_merged_metadata_hashtable(GHashTable *hashtable)
 {
     if (hashtable) {
         g_hash_table_destroy(hashtable);
@@ -269,7 +283,8 @@ void destroy_merged_metadata_hashtable(GHashTable *hashtable)
 //  0 = Package was not added
 //  1 = Package was added
 //  2 = Package replaced old package
-int add_package(Package *pkg, gchar *repopath, GHashTable *merged, GSList *arch_list,
+int
+add_package(Package *pkg, gchar *repopath, GHashTable *merged, GSList *arch_list,
                 MergeMethod merge_method, gboolean include_all)
 {
     GSList *list, *element;
@@ -395,7 +410,8 @@ int add_package(Package *pkg, gchar *repopath, GHashTable *merged, GSList *arch_
 
 
 
-long merge_repos(GHashTable *merged, GSList *repo_list, GSList *arch_list, MergeMethod merge_method,
+long
+merge_repos(GHashTable *merged, GSList *repo_list, GSList *arch_list, MergeMethod merge_method,
                  gboolean include_all, GHashTable *noarch_hashtable) {
 
     long loaded_packages = 0;
@@ -485,7 +501,9 @@ long merge_repos(GHashTable *merged, GSList *repo_list, GSList *arch_list, Merge
 
 
 
-int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *groupfile, struct CmdOptions *cmd_options)
+int
+dump_merged_metadata(GHashTable *merged_hashtable, long packages,
+                         gchar *groupfile, struct CmdOptions *cmd_options)
 {
     // Create/Open output xml files
 
@@ -493,25 +511,24 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
     CW_FILE *fil_f;
     CW_FILE *oth_f;
 
-    const char *suffix = get_suffix(cmd_options->compression_type);
-    if (!suffix) {
-        g_warning("Unknown compression_type (%d)", cmd_options->compression_type);
-        return 0;
-    }
+    const char *db_suffix = get_suffix(cmd_options->db_compression_type);
+    const char *groupfile_suffix = get_suffix(cmd_options->groupfile_compression_type);
 
-    gchar *pri_xml_filename = g_strconcat(cmd_options->out_repo, "/primary.xml", ".gz", NULL);
-    gchar *fil_xml_filename = g_strconcat(cmd_options->out_repo, "/filelists.xml", ".gz", NULL);
-    gchar *oth_xml_filename = g_strconcat(cmd_options->out_repo, "/other.xml", ".gz", NULL);
-    gchar *ui_xml_filename = NULL;
+    gchar *pri_xml_filename = g_strconcat(cmd_options->out_repo, "/primary.xml.gz", NULL);
+    gchar *fil_xml_filename = g_strconcat(cmd_options->out_repo, "/filelists.xml.gz", NULL);
+    gchar *oth_xml_filename = g_strconcat(cmd_options->out_repo, "/other.xml.gz", NULL);
+    gchar *update_info_filename = NULL;
     if (!cmd_options->noupdateinfo)
-        ui_xml_filename  = g_strconcat(cmd_options->out_repo, "/updateinfo.xml", suffix, NULL);
+        update_info_filename  = g_strconcat(cmd_options->out_repo,
+                                            "/updateinfo.xml",
+                                            groupfile_suffix, NULL);
 
     if ((pri_f = cw_open(pri_xml_filename, CW_MODE_WRITE, GZ_COMPRESSION)) == NULL) {
         g_critical("Cannot open file: %s", pri_xml_filename);
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
         g_free(oth_xml_filename);
-        g_free(ui_xml_filename);
+        g_free(update_info_filename);
         return 0;
     }
 
@@ -520,7 +537,7 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
         g_free(oth_xml_filename);
-        g_free(ui_xml_filename);
+        g_free(update_info_filename);
         cw_close(pri_f);
         return 0;
     }
@@ -530,7 +547,7 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
         g_free(pri_xml_filename);
         g_free(fil_xml_filename);
         g_free(oth_xml_filename);
-        g_free(ui_xml_filename);
+        g_free(update_info_filename);
         cw_close(fil_f);
         cw_close(pri_f);
         return 0;
@@ -547,6 +564,33 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
         "<otherdata xmlns=\""XML_OTHER_NS"\" packages=\"%d\">\n", packages);
 
 
+    // Prepare sqlite if needed
+
+    gchar *pri_db_filename;
+    gchar *fil_db_filename;
+    gchar *oth_db_filename;
+    sqlite3 *pri_db = NULL;
+    sqlite3 *fil_db = NULL;
+    sqlite3 *oth_db = NULL;
+    DbPrimaryStatements pri_statements = NULL;
+    DbFilelistsStatements fil_statements = NULL;
+    DbOtherStatements oth_statements = NULL;
+
+    if (!cmd_options->no_database) {
+        pri_db_filename = g_strconcat(cmd_options->out_repo, "/primary.sqlite", NULL);
+        fil_db_filename = g_strconcat(cmd_options->out_repo, "/filelists.sqlite", NULL);
+        oth_db_filename = g_strconcat(cmd_options->out_repo, "/other.sqlite", NULL);
+
+        pri_db = open_primary_db(pri_db_filename, NULL);
+        fil_db = open_filelists_db(fil_db_filename, NULL);
+        oth_db = open_other_db(oth_db_filename, NULL);
+
+        pri_statements = prepare_primary_db_statements(pri_db, NULL);
+        fil_statements = prepare_filelists_db_statements(fil_db, NULL);
+        oth_statements = prepare_other_db_statements(oth_db, NULL);
+    }
+
+
     // Dump hashtable
 
     GHashTableIter iter;
@@ -565,6 +609,12 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
             cw_puts(fil_f, (const char *) res.filelists);
             cw_puts(oth_f, (const char *) res.other);
 
+            if (!cmd_options->no_database) {
+                add_primary_pkg_db(pri_statements, pkg);
+                add_filelists_pkg_db(fil_statements, pkg);
+                add_other_pkg_db(oth_statements, pkg);
+            }
+
             free(res.primary);
             free(res.filelists);
             free(res.other);
@@ -591,68 +641,167 @@ int dump_merged_metadata(GHashTable *merged_hashtable, long packages, gchar *gro
 
     if (!cmd_options->noupdateinfo) {
         CW_FILE *update_info = NULL;
-        if ((update_info = cw_open(ui_xml_filename, CW_MODE_WRITE, cmd_options->compression_type))) {
+        if ((update_info = cw_open(update_info_filename, CW_MODE_WRITE, cmd_options->groupfile_compression_type))) {
             cw_puts(update_info, "<?xml version=\"1.0\"?>\n<updates></updates>\n");
             cw_close(update_info);
         } else {
-            g_warning("Cannot open file: %s", ui_xml_filename);
+            g_warning("Cannot open file: %s", update_info_filename);
         }
     }
 
 
-    // Gen repomd.xml
+    // Prepare repomd records
 
-    gchar *pri_xml_name = g_strconcat("repodata/", "primary.xml", ".gz", NULL);
-    gchar *fil_xml_name = g_strconcat("repodata/", "filelists.xml",".gz", NULL);
-    gchar *oth_xml_name = g_strconcat("repodata/", "other.xml", ".gz", NULL);
-    gchar *rel_groupfile = NULL;
-    if (groupfile)
-        rel_groupfile = g_strconcat("repodata/", get_filename(groupfile), NULL);
-    gchar *ui_xml_name = NULL;
-    if (!cmd_options->noupdateinfo)
-        ui_xml_name = g_strconcat("repodata/", "updateinfo.xml", suffix, NULL);
-
-    struct repomdResult *repomd_res = xml_repomd(cmd_options->out_dir, 1, pri_xml_name,
-                                                 fil_xml_name, oth_xml_name, NULL, NULL,
-                                                 NULL, rel_groupfile, ui_xml_name, NULL,
-                                                 cmd_options->compression_type);
-    if (repomd_res) {
-        if (repomd_res->repomd_xml) {
-            gchar *repomd_path = g_strconcat(cmd_options->out_repo, "repomd.xml", NULL);
-            FILE *frepomd = fopen(repomd_path, "w");
-            if (frepomd) {
-                fputs(repomd_res->repomd_xml, frepomd);
-                fclose(frepomd);
-            } else {
-                g_critical("Cannot open file: %s", repomd_path);
-            }
-            g_free(repomd_path);
-        } else {
-            g_critical("Generate of repomd.xml failed");
-        }
-        free_repomdresult(repomd_res);
+    char *out_dir = cmd_options->out_dir;
+
+    RepomdRecord pri_xml_rec = new_repomdrecord("repodata/primary.xml.gz");
+    RepomdRecord fil_xml_rec = new_repomdrecord("repodata/filelists.xml.gz");
+    RepomdRecord oth_xml_rec = new_repomdrecord("repodata/other.xml.gz");
+    RepomdRecord pri_db_rec               = NULL;
+    RepomdRecord fil_db_rec               = NULL;
+    RepomdRecord oth_db_rec               = NULL;
+    RepomdRecord groupfile_rec            = NULL;
+    RepomdRecord compressed_groupfile_rec = NULL;
+    RepomdRecord update_info_rec          = NULL;
+
+
+    // XML
+
+    fill_missing_data(out_dir, pri_xml_rec, NULL);
+    fill_missing_data(out_dir, fil_xml_rec, NULL);
+    fill_missing_data(out_dir, oth_xml_rec, NULL);
+
+
+    // Groupfile
+
+    if (groupfile) {
+        gchar *groupfile_name = g_strconcat("repodata/", get_filename(groupfile), NULL);
+        groupfile_rec = new_repomdrecord(groupfile_name);
+        compressed_groupfile_rec = new_repomdrecord(groupfile_name);
+
+        process_groupfile(out_dir, groupfile_rec, compressed_groupfile_rec,
+                          NULL, cmd_options->groupfile_compression_type);
+        g_free(groupfile_name);
     }
 
 
+    // Update info
+
+    if (!cmd_options->noupdateinfo) {
+        gchar *update_info_name = g_strconcat("repodata/updateinfo.xml", groupfile_suffix, NULL);
+        update_info_rec = new_repomdrecord(update_info_name);
+        fill_missing_data(out_dir, update_info_rec, NULL);
+        g_free(update_info_name);
+    }
+
+
+    // Sqlite db
+
+    if (!cmd_options->no_database) {
+        // Insert XML checksums into the dbs
+        dbinfo_update(pri_db, pri_xml_rec->checksum, NULL);
+        dbinfo_update(fil_db, fil_xml_rec->checksum, NULL);
+        dbinfo_update(oth_db, oth_xml_rec->checksum, NULL);
+
+        // Close dbs
+        destroy_primary_db_statements(pri_statements);
+        destroy_filelists_db_statements(fil_statements);
+        destroy_other_db_statements(oth_statements);
+
+        close_primary_db(pri_db, NULL);
+        close_filelists_db(fil_db, NULL);
+        close_other_db(oth_db, NULL);
+
+        // Compress dbs
+        compress_file(pri_db_filename, NULL, cmd_options->db_compression_type);
+        compress_file(fil_db_filename, NULL, cmd_options->db_compression_type);
+        compress_file(oth_db_filename, NULL, cmd_options->db_compression_type);
+
+        remove(pri_db_filename);
+        remove(fil_db_filename);
+        remove(oth_db_filename);
+
+        // Prepare repomd records
+        gchar *pri_db_name = g_strconcat("repodata/primary.sqlite", db_suffix, NULL);
+        gchar *fil_db_name = g_strconcat("repodata/filelists.sqlite", db_suffix, NULL);
+        gchar *oth_db_name = g_strconcat("repodata/other.sqlite", db_suffix, NULL);
+
+        pri_db_rec = new_repomdrecord(pri_db_name);
+        fil_db_rec = new_repomdrecord(fil_db_name);
+        oth_db_rec = new_repomdrecord(oth_db_name);
+
+        g_free(pri_db_name);
+        g_free(fil_db_name);
+        g_free(oth_db_name);
+
+        fill_missing_data(out_dir, pri_db_rec, NULL);
+        fill_missing_data(out_dir, fil_db_rec, NULL);
+        fill_missing_data(out_dir, oth_db_rec, NULL);
+    }
+
+
+    // Add checksums into files names
+
+    rename_file(out_dir, pri_xml_rec);
+    rename_file(out_dir, fil_xml_rec);
+    rename_file(out_dir, oth_xml_rec);
+    rename_file(out_dir, pri_db_rec);
+    rename_file(out_dir, fil_db_rec);
+    rename_file(out_dir, oth_db_rec);
+    rename_file(out_dir, groupfile_rec);
+    rename_file(out_dir, compressed_groupfile_rec);
+    rename_file(out_dir, update_info_rec);
+
+
+    // Gen repomd.xml content
+
+    char *repomd_xml = xml_repomd(out_dir, pri_xml_rec,
+                                  fil_xml_rec, oth_xml_rec, pri_db_rec,
+                                  fil_db_rec, oth_db_rec, groupfile_rec,
+                                  compressed_groupfile_rec, update_info_rec);
+
+    if (repomd_xml) {
+        gchar *repomd_path = g_strconcat(cmd_options->out_repo, "repomd.xml", NULL);
+        FILE *frepomd = fopen(repomd_path, "w");
+        if (frepomd) {
+            fputs(repomd_xml, frepomd);
+            fclose(frepomd);
+        } else
+            g_critical("Cannot open file: %s", repomd_path);
+        g_free(repomd_path);
+    } else
+        g_critical("Generate of repomd.xml failed");
+
+
     // Clean up
 
-    g_free(pri_xml_name);
-    g_free(fil_xml_name);
-    g_free(oth_xml_name);
-    g_free(rel_groupfile);
-    g_free(ui_xml_name);
+    g_free(repomd_xml);
+
+    free_repomdrecord(pri_xml_rec);
+    free_repomdrecord(fil_xml_rec);
+    free_repomdrecord(oth_xml_rec);
+    free_repomdrecord(pri_db_rec);
+    free_repomdrecord(fil_db_rec);
+    free_repomdrecord(oth_db_rec);
+    free_repomdrecord(groupfile_rec);
+    free_repomdrecord(compressed_groupfile_rec);
+    free_repomdrecord(update_info_rec);
 
     g_free(pri_xml_filename);
     g_free(fil_xml_filename);
     g_free(oth_xml_filename);
-    g_free(ui_xml_filename);
+    g_free(update_info_filename);
+    g_free(pri_db_filename);
+    g_free(fil_db_filename);
+    g_free(oth_db_filename);
 
     return 1;
 }
 
 
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
     // Parse arguments
 
index e68d371..5f591ef 100644 (file)
@@ -58,7 +58,7 @@ typedef struct {
  * Package
  */
 typedef struct {
-    gint64 pkgKey;              /*!< not used */
+    gint64 pkgKey;              /*!< used while inserting into sqlite db */
     char *pkgId;                /*!< package hash */
     char *name;                 /*!< name */
     char *arch;                 /*!< architecture */
index c3c9023..644290c 100644 (file)
 #define REPOMD_ERR      1
 
 
-struct repomdData {
-    const char *location_href;
-    char *checksum;
-    char *checksum_type;
-    char *checksum_open;
-    char *checksum_open_type;
-    long timestamp;
-    long size;
-    long size_open;
-    int db_ver;
-
-    GStringChunk *chunk;
-};
+typedef struct _RepomdRecord * RepomdRecord;
 
 
 typedef struct _contentStat {
@@ -70,55 +58,31 @@ typedef struct _contentStat {
 } contentStat;
 
 
-struct repomdData *new_repomddata();
-void free_repomddata(struct repomdData *);
-void free_repomdresult(struct repomdResult *);
-
-
-struct repomdData *new_repomddata()
+RepomdRecord
+new_repomdrecord(const char *path)
 {
-    struct repomdData *md = (struct repomdData *) g_malloc0(sizeof(struct repomdData));
+    RepomdRecord md = (RepomdRecord) g_malloc0(sizeof(*md));
     md->chunk = g_string_chunk_new(1024);
+    if (path)
+        md->location_href = g_string_chunk_insert(md->chunk, path);
     return md;
 }
 
 
 
-void free_repomddata(struct repomdData *md)
+void
+free_repomdrecord(RepomdRecord md)
 {
-    if (!md) {
+    if (!md)
         return;
-    }
 
     g_string_chunk_free(md->chunk);
     g_free(md);
 }
 
 
-
-void free_repomdresult(struct repomdResult *rr)
-{
-    if (!rr) {
-        return;
-    }
-
-    g_free(rr->pri_xml_location);
-    g_free(rr->fil_xml_location);
-    g_free(rr->oth_xml_location);
-    g_free(rr->pri_sqlite_location);
-    g_free(rr->fil_sqlite_location);
-    g_free(rr->oth_sqlite_location);
-    g_free(rr->groupfile_location);
-    g_free(rr->cgroupfile_location);
-    g_free(rr->update_info_location);
-    g_free(rr->repomd_xml);
-
-    g_free(rr);
-}
-
-
-
-contentStat *get_compressed_content_stat(const char *filename, ChecksumType checksum_type)
+contentStat *
+get_compressed_content_stat(const char *filename, ChecksumType checksum_type)
 {
     if (!g_file_test(filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
         return NULL;
@@ -166,6 +130,10 @@ contentStat *get_compressed_content_stat(const char *filename, ChecksumType chec
 
     do {
         readed = cw_read(cwfile, (void *) buffer, BUFFER_SIZE);
+        if (readed == CW_ERR) {
+            g_debug(MODULE"%s: Error while read compressed file: %s", __func__, filename);
+            break;
+        }
         g_checksum_update (checksum, buffer, readed);
         size += readed;
     } while (readed == BUFFER_SIZE);
@@ -190,7 +158,9 @@ contentStat *get_compressed_content_stat(const char *filename, ChecksumType chec
 
 
 
-int fill_missing_data(const char *base_path, struct repomdData *md, ChecksumType *checksum_type) {
+int
+fill_missing_data(const char *base_path, RepomdRecord md, ChecksumType *checksum_type)
+{
     if (!md || !(md->location_href) || !strlen(md->location_href)) {
         // Nothing to do
         return REPOMD_ERR;
@@ -279,8 +249,9 @@ int fill_missing_data(const char *base_path, struct repomdData *md, ChecksumType
 }
 
 
-void process_groupfile(const char *base_path, struct repomdData *groupfile,
-                       struct repomdData *cgroupfile, ChecksumType *checksum_type,
+void
+process_groupfile(const char *base_path, RepomdRecord groupfile,
+                       RepomdRecord cgroupfile, ChecksumType *checksum_type,
                        CompressionType groupfile_compression)
 {
     if (!groupfile || !(groupfile->location_href) || !strlen(groupfile->location_href) || !cgroupfile) {
@@ -398,7 +369,8 @@ void process_groupfile(const char *base_path, struct repomdData *groupfile,
 }
 
 
-void dump_data_items(xmlNodePtr root, struct repomdData *md, const xmlChar *type)
+void
+dump_data_items(xmlNodePtr root, RepomdRecord md, const xmlChar *type)
 {
     xmlNodePtr data, node;
     gchar str_buffer[STR_BUFFER_SIZE];
@@ -440,11 +412,12 @@ void dump_data_items(xmlNodePtr root, struct repomdData *md, const xmlChar *type
 }
 
 
-char *repomd_xml_dump(long revision, struct repomdData *pri_xml, struct repomdData *fil_xml,
-                      struct repomdData *oth_xml, struct repomdData *pri_sqlite,
-                      struct repomdData *fil_sqlite, struct repomdData *oth_sqlite,
-                      struct repomdData *groupfile, struct repomdData *cgroupfile,
-                      struct repomdData *update_info)
+char *
+repomd_xml_dump(long revision, RepomdRecord pri_xml, RepomdRecord fil_xml,
+                      RepomdRecord oth_xml, RepomdRecord pri_sqlite,
+                      RepomdRecord fil_sqlite, RepomdRecord oth_sqlite,
+                      RepomdRecord groupfile, RepomdRecord cgroupfile,
+                      RepomdRecord update_info)
 {
     xmlDocPtr doc;
     xmlNodePtr root;
@@ -488,7 +461,8 @@ char *repomd_xml_dump(long revision, struct repomdData *pri_xml, struct repomdDa
 }
 
 
-void rename_file(const char *base_path, struct repomdData *md)
+void
+rename_file(const char *base_path, RepomdRecord md)
 {
     if (!md || !(md->location_href) || !strlen(md->location_href)) {
         return;
@@ -542,148 +516,17 @@ void rename_file(const char *base_path, struct repomdData *md)
 }
 
 
-// groupfile is expected uncompressed!
-struct repomdResult *xml_repomd_2(const char *path, int rename_to_unique, struct repomdData *pri_xml,
-                                  struct repomdData *fil_xml, struct repomdData *oth_xml,
-                                  struct repomdData *pri_sqlite, struct repomdData *fil_sqlite,
-                                  struct repomdData *oth_sqlite, struct repomdData *groupfile,
-                                  struct repomdData *cgroupfile, struct repomdData *update_info,
-                                  ChecksumType *checksum_type, CompressionType groupfile_compression)
+gchar *
+xml_repomd(const char *path, RepomdRecord pri_xml,
+           RepomdRecord fil_xml, RepomdRecord oth_xml,
+           RepomdRecord pri_sqlite, RepomdRecord fil_sqlite,
+           RepomdRecord oth_sqlite, RepomdRecord groupfile,
+           RepomdRecord cgroupfile, RepomdRecord update_info)
 {
     if (!path) {
         return NULL;
     }
 
-    struct repomdResult *res = g_malloc(sizeof(struct repomdResult));
-
-
-    // Fill all missing stuff
-
-    fill_missing_data(path, pri_xml, checksum_type);
-    fill_missing_data(path, fil_xml, checksum_type);
-    fill_missing_data(path, oth_xml, checksum_type);
-    fill_missing_data(path, pri_sqlite, checksum_type);
-    fill_missing_data(path, fil_sqlite, checksum_type);
-    fill_missing_data(path, oth_sqlite, checksum_type);
-    fill_missing_data(path, update_info, checksum_type);
-
-    process_groupfile(path, groupfile, cgroupfile, checksum_type, groupfile_compression);
-
-
-    // Include checksum in the metadata filename
-
-    if (rename_to_unique) {
-        rename_file(path, pri_xml);
-        rename_file(path, fil_xml);
-        rename_file(path, oth_xml);
-        rename_file(path, pri_sqlite);
-        rename_file(path, fil_sqlite);
-        rename_file(path, oth_sqlite);
-        rename_file(path, groupfile);
-        rename_file(path, cgroupfile);
-        rename_file(path, update_info);
-    }
-
-
-    // Set locations in output structure
-
-    res->pri_xml_location = pri_xml ? g_strdup(pri_xml->location_href) : NULL;
-    res->fil_xml_location = fil_xml ? g_strdup(fil_xml->location_href) : NULL;
-    res->oth_xml_location = oth_xml ? g_strdup(oth_xml->location_href) : NULL;
-    res->pri_sqlite_location = pri_sqlite ? g_strdup(pri_sqlite->location_href) : NULL;
-    res->fil_sqlite_location = fil_sqlite ? g_strdup(fil_sqlite->location_href) : NULL;
-    res->oth_sqlite_location = oth_sqlite ? g_strdup(oth_sqlite->location_href) : NULL;
-    res->groupfile_location = groupfile ? g_strdup(groupfile->location_href) : NULL;
-    res->cgroupfile_location = cgroupfile ? g_strdup(cgroupfile->location_href) : NULL;
-    res->update_info_location = update_info ? g_strdup(update_info->location_href) : NULL;
-
-    // Get revision
-
     long revision = (long) time(NULL);
-
-
-    // Dump xml
-
-    res->repomd_xml = repomd_xml_dump(revision, pri_xml, fil_xml, oth_xml, pri_sqlite, fil_sqlite, oth_sqlite, groupfile, cgroupfile, update_info);
-
-    return res;
-}
-
-
-
-struct repomdResult *xml_repomd(const char *path, int rename_to_unique, const char *pri_xml,
-                                const char *fil_xml, const char *oth_xml,
-                                const char *pri_sqlite, const char *fil_sqlite,
-                                const char *oth_sqlite, const char *groupfile,
-                                const char *update_info, ChecksumType *checksum_type,
-                                CompressionType groupfile_compression)
-{
-    if (!path) {
-        return NULL;
-    }
-
-    struct repomdData *pri_xml_rd     = NULL;
-    struct repomdData *fil_xml_rd     = NULL;
-    struct repomdData *oth_xml_rd     = NULL;
-    struct repomdData *pri_sqlite_rd  = NULL;
-    struct repomdData *fil_sqlite_rd  = NULL;
-    struct repomdData *oth_sqlite_rd  = NULL;
-    struct repomdData *groupfile_rd   = NULL;
-    struct repomdData *cgroupfile_rd  = NULL;
-    struct repomdData *update_info_rd = NULL;
-
-    if (pri_xml) {
-        pri_xml_rd = new_repomddata();
-        pri_xml_rd->location_href = pri_xml;
-    }
-    if (fil_xml) {
-        fil_xml_rd = new_repomddata();
-        fil_xml_rd->location_href = fil_xml;
-    }
-    if (oth_xml) {
-        oth_xml_rd = new_repomddata();
-        oth_xml_rd->location_href = oth_xml;
-    }
-    if (pri_sqlite) {
-        pri_sqlite_rd = new_repomddata();
-        pri_sqlite_rd->location_href = pri_sqlite;
-    }
-    if (fil_sqlite) {
-        fil_sqlite_rd = new_repomddata();
-        fil_sqlite_rd->location_href = fil_sqlite;
-    }
-    if (oth_sqlite) {
-        oth_sqlite_rd = new_repomddata();
-        oth_sqlite_rd->location_href = oth_sqlite;
-    }
-    if (groupfile) {
-        groupfile_rd = new_repomddata();
-        groupfile_rd->location_href = groupfile;
-        cgroupfile_rd = new_repomddata();
-        cgroupfile_rd->location_href = groupfile;
-    }
-    if (update_info) {
-        update_info_rd = new_repomddata();
-        update_info_rd->location_href = update_info;
-    }
-
-    // Dump xml
-
-    struct repomdResult *res = xml_repomd_2(path, rename_to_unique,
-                                            pri_xml_rd, fil_xml_rd, oth_xml_rd,
-                                            pri_sqlite_rd, fil_sqlite_rd, oth_sqlite_rd,
-                                            groupfile_rd, cgroupfile_rd, update_info_rd,
-                                            checksum_type, groupfile_compression);
-
-    free_repomddata(pri_xml_rd);
-    free_repomddata(fil_xml_rd);
-    free_repomddata(oth_xml_rd);
-    free_repomddata(pri_sqlite_rd);
-    free_repomddata(fil_sqlite_rd);
-    free_repomddata(oth_sqlite_rd);
-    free_repomddata(groupfile_rd);
-    free_repomddata(cgroupfile_rd);
-    free_repomddata(update_info_rd);
-
-    return res;
+    return repomd_xml_dump(revision, pri_xml, fil_xml, oth_xml, pri_sqlite, fil_sqlite, oth_sqlite, groupfile, cgroupfile, update_info);
 }
index a3297d2..b43f2b4 100644 (file)
 /** \defgroup repomd            Repomd API.
  */
 
+/** \ingroup misc
+ * RepomdRecord object
+ */
+typedef struct _RepomdRecord * RepomdRecord;
 
-/** \ingroup repomd
- * Structure representing repomd.xml.
+/** \ingroup misc
+ * Internal representation of RepomdRecord object
  */
-struct repomdResult {
-    char *pri_xml_location;             /*!< location of primary.xml */
-    char *fil_xml_location;             /*!< location of filelists.xml */
-    char *oth_xml_location;             /*!< location of other.xml */
-    char *pri_sqlite_location;          /*!< location of primary.sqlite */
-    char *fil_sqlite_location;          /*!< location of filelists.sqlite */
-    char *oth_sqlite_location;          /*!< location of other.sqlite */
-    char *groupfile_location;           /*!< location of groupfile */
-    char *cgroupfile_location;          /*!< location of compressed groupfile */
-    char *update_info_location;         /*!< location of updateinfo.xml */
-    char *repomd_xml;                   /*!< xml representation of repomd_xml */
+struct _RepomdRecord {
+    const char *location_href;  /*!< location of the file */
+    char *checksum;             /*!< checksum of file */
+    char *checksum_type;        /*!< checksum type */
+    char *checksum_open;        /*!< checksum of uncompressed file */
+    char *checksum_open_type;   /*!< checksum type of uncompressed file*/
+    long timestamp;             /*!< mtime of the file */
+    long size;                  /*!< size of file in bytes */
+    long size_open;             /*!< size of uncompressed file in bytes */
+    int db_ver;                 /*!< version of database */
+
+    GStringChunk *chunk;        /*!< string chunk for string from this structure*/
 };
 
 /** \ingroup repomd
- * Free repomdResult.
- * @param repomdResult          struct repomdReult
+ * Creates (alloc) new RepomdRecord object
+ * @param path                  path to the compressed file
+ */
+RepomdRecord new_repomdrecord(const char *path);
+
+/** \ingroup repomd
+ * Destroy RepomdRecord object
+ * @param record                RepomdRecord object
+ */
+void free_repomdrecord(RepomdRecord record);
+
+/** \ingroup repomd
+ * Fill unfilled items in the RepomdRecord (calculate checksums,
+ * get file size before/after compression, etc.).
+ * Note: For groupfile you shoud use process_groupfile function.
+ * @param base_path             path to repo (to directory with repodata subdir)
+ * @param record                RepomdRecord object
+ * @param checksum_type         type of checksum to use
+ */
+int fill_missing_data(const char *base_path, RepomdRecord record, ChecksumType *checksum_type);
+
+/** \ingroup repomd
+ * Analogue of fill_missing_data but for groupfile.
+ * Groupfile must be set with the path to existing non compressed groupfile.
+ * Compressed group file will be created and compressed_groupfile record updated.
+ * @param base_path             path to repo (to directory with repodata subdir)
+ * @groupfile                   RepomdRecord initialized to an existing groupfile
+ * @compressed_groupfile        a RepomdRecord object that will by filled
+ * @checksum_type               type of checksums
+ * @compression                 type of compression
+ */
+void process_groupfile(const char *base_path, RepomdRecord groupfile,
+                       RepomdRecord compressed_groupfile, ChecksumType *checksum_type,
+                       CompressionType compression);
+
+/** \ingroup repomd
+ * Add a hash as prefix to the filename.
+ * @base_path                   path to repo (to directory with repodata subdir)
+ * @record                      RepomdRecord of file to be renamed
  */
-void free_repomdresult(struct repomdResult *);
+void rename_file(const char *base_path, RepomdRecord record);
 
 /** \ingroup repomd
- * Generate repomd.xml content and rename files (if rename_to_unique != 0).
+ * Generate repomd.xml content.
  * @param path                  path to repository (to the directory contains repodata/ subdir)
- * @param rename_to_unique      rename files? - insert checksum into the metadata file names (=0 do not insert, !=0 insert)
- * @param pri_xml               location of compressed primary.xml (relative towards to the path)
- * @param fil_xml               location of compressed filelists.xml (relative towards to the path)
- * @param oth_xml               location of compressed other.xml (relative towards to the path)
- * @param pri_sqlite            location of compressed primary.sqlite (relative towards to the path)
- * @param fil_sqlite            location of compressed filelists.sqlite (relative towards to the path)
- * @param oth_sqlite            location of compressed other.sqlite (relative towards to the path)
- * @param groupfile             location of groupfile (non compressed!)
- * @param update_info           location of compressed update_info
- * @param checksum_type         type of checksum
- * @return                      repomdResult
+ * @param pri_xml               RepomdRecord of primary.xml.gz (relative towards to the path param)
+ * @param fil_xml               RepomdRecord of filelists.xml.gz (relative towards to the path param)
+ * @param oth_xml               RepomdRecord of other.xml.gz (relative towards to the path param)
+ * @param pri_sqlite            RepomdRecord of primary.sqlite.* (relative towards to the path param)
+ * @param fil_sqlite            RepomdRecord of filelists.sqlite.* (relative towards to the path param)
+ * @param oth_sqlite            RepomdRecord of other.sqlite.* (relative towards to the path param)
+ * @param groupfile             RepomdRecord of *.xml (relative towards to the path param)
+ * @param cgroupfile            RepomdRecord of *.xml.* (relative towards to the path param)
+ * @param update_info           RepomdRecord of updateinfo.xml.* (relative towards to the path param)
+ * @return                      string with repomd.xml content
  */
-struct repomdResult *xml_repomd(const char *path, int rename_to_unique, const char *pri_xml,
-                                const char *fil_xml, const char *oth_xml,
-                                const char *pri_sqlite, const char *fil_sqlite,
-                                const char *oth_sqlite, const char *groupfile,
-                                const char *update_info, ChecksumType *checksum_type,
-                                CompressionType groupfile_compression);
+gchar * xml_repomd(const char *path, RepomdRecord pri_xml,
+                   RepomdRecord fil_xml, RepomdRecord oth_xml,
+                   RepomdRecord pri_sqlite, RepomdRecord fil_sqlite,
+                   RepomdRecord oth_sqlite, RepomdRecord groupfile,
+                   RepomdRecord cgroupfile, RepomdRecord update_info);
 
 #endif /* __C_CREATEREPOLIB_REPOMD_H__ */