📄 sqlitecache.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License, * version 2, as published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307, USA. */#include <Python.h>#include "xml-parser.h"#include "db.h"#include "package.h"/* Make room for 2500 package ids, 40 bytes + '\0' each */#define PACKAGE_IDS_CHUNK 41 * 2500typedef struct _UpdateInfo UpdateInfo;typedef void (*InfoInitFn) (UpdateInfo *update_info, sqlite3 *db, GError **err);typedef void (*InfoCleanFn) (UpdateInfo *update_info);typedef void (*XmlParseFn) (const char *filename, CountFn count_callback, PackageFn package_callback, gpointer user_data, GError **err);typedef void (*WriteDbPackageFn) (UpdateInfo *update_info, Package *package);struct _UpdateInfo { sqlite3 *db; sqlite3_stmt *remove_handle; guint32 count_from_md; guint32 packages_seen; guint32 add_count; guint32 del_count; GHashTable *current_packages; GHashTable *all_packages; GStringChunk *package_ids_chunk; GTimer *timer; gpointer python_callback; InfoInitFn info_init; InfoCleanFn info_clean; CreateTablesFn create_tables; WriteDbPackageFn write_package; XmlParseFn xml_parse; gpointer user_data;};static voidupdate_info_init (UpdateInfo *info, GError **err){ const char *sql; int rc; sql = "DELETE FROM packages WHERE pkgKey = ?"; rc = sqlite3_prepare (info->db, sql, -1, &info->remove_handle, NULL); if (rc != SQLITE_OK) { 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; } info->count_from_md = 0; info->packages_seen = 0; info->add_count = 0; info->del_count = 0; 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 voidremove_entry (gpointer key, gpointer value, gpointer user_data){ UpdateInfo *info = (UpdateInfo *) user_data; if (g_hash_table_lookup (info->all_packages, key) == NULL) { int rc; sqlite3_bind_int (info->remove_handle, 1, GPOINTER_TO_INT (value)); rc = sqlite3_step (info->remove_handle); sqlite3_reset (info->remove_handle); if (rc != SQLITE_DONE) g_warning ("Error removing package from SQL: %s", sqlite3_errmsg (info->db)); info->del_count++; }}static voidupdate_info_remove_old_entries (UpdateInfo *info){ g_hash_table_foreach (info->current_packages, remove_entry, info);}static voidcount_cb (guint32 count, gpointer user_data){ UpdateInfo *info = (UpdateInfo *) user_data; info->count_from_md = count;}static voidupdate_info_done (UpdateInfo *info, GError **err){ 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); if (!*err) { g_message ("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);}/* Primary */typedef struct { UpdateInfo update_info; sqlite3_stmt *pkg_handle; sqlite3_stmt *requires_handle; sqlite3_stmt *provides_handle; sqlite3_stmt *conflicts_handle; sqlite3_stmt *obsoletes_handle; sqlite3_stmt *files_handle;} PackageWriterInfo;static voidpackage_writer_info_init (UpdateInfo *update_info, sqlite3 *db, GError **err){ PackageWriterInfo *info = (PackageWriterInfo *) update_info; 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 voidwrite_deps (sqlite3 *db, sqlite3_stmt *handle, gint64 pkgKey, GSList *deps){ GSList *iter; for (iter = deps; iter; iter = iter->next) yum_db_dependency_write (db, handle, pkgKey, (Dependency *) iter->data, FALSE);}static voidwrite_requirements (sqlite3 *db, sqlite3_stmt *handle, gint64 pkgKey, GSList *deps){ GSList *iter; for (iter = deps; iter; iter = iter->next) yum_db_dependency_write (db, handle, pkgKey, (Dependency *) iter->data, TRUE);}static voidwrite_files (sqlite3 *db, sqlite3_stmt *handle, Package *pkg){ GSList *iter; for (iter = pkg->files; iter; iter = iter->next) yum_db_file_write (db, handle, pkg->pkgKey, (PackageFile *) iter->data);}static voidwrite_package_to_db (UpdateInfo *update_info, Package *package){ PackageWriterInfo *info = (PackageWriterInfo *) update_info; yum_db_package_write (update_info->db, info->pkg_handle, package); write_requirements (update_info->db, info->requires_handle, package->pkgKey, package->requires); write_deps (update_info->db, info->provides_handle, package->pkgKey, package->provides); write_deps (update_info->db, info->conflicts_handle, package->pkgKey, package->conflicts); write_deps (update_info->db, info->obsoletes_handle, package->pkgKey, package->obsoletes); write_files (update_info->db, info->files_handle, package);}static voidpackage_writer_info_clean (UpdateInfo *update_info){ PackageWriterInfo *info = (PackageWriterInfo *) update_info; 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);}/* Filelists */typedef struct { UpdateInfo update_info; sqlite3_stmt *pkg_handle; sqlite3_stmt *file_handle;} FileListInfo;static voidupdate_filelist_info_init (UpdateInfo *update_info, sqlite3 *db, GError **err){ FileListInfo *info = (FileListInfo *) update_info; info->pkg_handle = yum_db_package_ids_prepare (db, err); if (*err) return; info->file_handle = yum_db_filelists_prepare (db, err);}static voidupdate_filelist_info_clean (UpdateInfo *update_info){ FileListInfo *info = (FileListInfo *) update_info; if (info->pkg_handle) sqlite3_finalize (info->pkg_handle); if (info->file_handle) sqlite3_finalize (info->file_handle);}static voidwrite_filelist_package_to_db (UpdateInfo *update_info, Package *package){ FileListInfo *info = (FileListInfo *) update_info; yum_db_package_ids_write (update_info->db, info->pkg_handle, package); yum_db_filelists_write (update_info->db, info->file_handle, package);}/* Other */typedef struct { UpdateInfo update_info; sqlite3_stmt *pkg_handle; sqlite3_stmt *changelog_handle;} UpdateOtherInfo;static voidupdate_other_info_init (UpdateInfo *update_info, sqlite3 *db, GError **err){ UpdateOtherInfo *info = (UpdateOtherInfo *) update_info; info->pkg_handle = yum_db_package_ids_prepare (db, err); if (*err) return; info->changelog_handle = yum_db_changelog_prepare (db, err);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -