commit f6f39622d01a03c10fe1c32d997cc73b91fb6b0e Author: James Antill Date: Fri Feb 29 14:10:54 2008 -0500 Initial normalization of the primary sqlite file diff --git a/db.c b/db.c index d2b51d6..fa7072e 100644 --- a/db.c +++ b/db.c @@ -311,29 +311,53 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) { int rc; const char *sql; - + const char *vsql; + +#define YUM_DB__CREATE_ID_TABLE(x) \ + sql = "CREATE TABLE id_" x " (" x "_id INTEGER PRIMARY KEY, " x " 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 id_" x " table: %s", \ + sqlite3_errmsg (db)); \ + return; \ + } + YUM_DB__CREATE_ID_TABLE("pkgId"); + YUM_DB__CREATE_ID_TABLE("name"); + YUM_DB__CREATE_ID_TABLE("arch"); + YUM_DB__CREATE_ID_TABLE("summary"); + YUM_DB__CREATE_ID_TABLE("description"); + YUM_DB__CREATE_ID_TABLE("url"); + YUM_DB__CREATE_ID_TABLE("rpm_license"); + YUM_DB__CREATE_ID_TABLE("rpm_vendor"); + YUM_DB__CREATE_ID_TABLE("rpm_group"); + YUM_DB__CREATE_ID_TABLE("rpm_buildhost"); + YUM_DB__CREATE_ID_TABLE("rpm_sourcerpm"); + YUM_DB__CREATE_ID_TABLE("rpm_packager"); +#undef YUM_DB__CREATE_ID_TABLE + sql = - "CREATE TABLE packages (" + "CREATE TABLE packages_raw (" " pkgKey INTEGER PRIMARY KEY," - " pkgId TEXT," - " name TEXT," - " arch TEXT," + " pkgId_id INTEGER," + " name_id INTEGER," + " arch_id INTEGER," " version TEXT," " epoch TEXT," " release TEXT," - " summary TEXT," - " description TEXT," - " url TEXT," + " summary_id INTEGER," + " description_id INTEGER," + " url_id INTEGER," " time_file INTEGER," " time_build INTEGER," - " rpm_license TEXT," - " rpm_vendor TEXT," - " rpm_group TEXT," - " rpm_buildhost TEXT," - " rpm_sourcerpm TEXT," + " rpm_license_id INTEGER," + " rpm_vendor_id INTEGER," + " rpm_group_id INTEGER," + " rpm_buildhost_id INTEGER," + " rpm_sourcerpm_id INTEGER," " rpm_header_start INTEGER," " rpm_header_end INTEGER," - " rpm_packager TEXT," + " rpm_packager_id INTEGER," " size_package INTEGER," " size_installed INTEGER," " size_archive INTEGER," @@ -344,32 +368,99 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) 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", + "Can not create packages_raw table: %s", + sqlite3_errmsg (db)); + return; + } + + sql = + "CREATE VIEW packages AS " + " SELECT pkgKey," + " pkgId," + " name," + " arch," + " version," + " epoch," + " release," + " summary," + " description," + " url," + " time_file," + " time_build," + " rpm_license," + " rpm_vendor," + " rpm_group," + " rpm_buildhost," + " rpm_sourcerpm," + " rpm_header_start," + " rpm_header_end," + " rpm_packager," + " size_package," + " size_installed," + " size_archive," + " location_href," + " location_base," + " checksum_type" + " FROM ((((((((((((packages_raw " + " JOIN id_pkgId USING(pkgId_id))" + " JOIN id_name USING(name_id))" + " JOIN id_summary USING(summary_id))" + " JOIN id_description USING(description_id))" + " JOIN id_url USING(url_id))" + " JOIN id_rpm_group USING(rpm_group_id))" + " JOIN id_rpm_vendor USING(rpm_vendor_id))" + " JOIN id_rpm_packager USING(rpm_packager_id))" + " JOIN id_rpm_license USING(rpm_license_id))" + " JOIN id_arch USING(arch_id))" + " JOIN id_rpm_sourcerpm USING(rpm_sourcerpm_id))" + " JOIN id_rpm_buildhost USING(rpm_buildhost_id))"; + 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 view: %s", sqlite3_errmsg (db)); return; } - sql = "CREATE INDEX packagename ON packages (name)"; + sql = "CREATE INDEX idx_id_pkgId ON id_pkgId (pkgId)"; 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", + "Can not create idx_id_pkgId index: %s", sqlite3_errmsg (db)); return; } - - sql = "CREATE INDEX packageId ON packages (pkgId)"; + + sql = "CREATE INDEX idx_packages_raw_pkgId_id ON packages_raw (pkgId_id)"; 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", + "Can not create idx_packages_raw_pkgId_id index: %s", sqlite3_errmsg (db)); return; } + sql = "CREATE INDEX idx_id_name_name ON id_name (name)"; + 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 idx_id_name_name index: %s", + sqlite3_errmsg (db)); + return; + } + + sql = "CREATE INDEX idx_packages_raw_name_id ON packages_raw (name_id)"; + 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 idx_packages_raw_name_id index: %s", + sqlite3_errmsg (db)); + return; + } + sql = "CREATE TABLE files (" - " name TEXT," + " name TEXT," /* note file.name != packages.name */ " type TEXT," " pkgKey INTEGER)"; rc = sqlite3_exec (db, sql, NULL, NULL, NULL); @@ -380,43 +471,58 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) return; } - sql = "CREATE INDEX filenames ON files (name)"; + sql = "CREATE INDEX idx_files_name ON files (name)"; 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 filenames index: %s", + "Can not create idx_files_name index: %s", sqlite3_errmsg (db)); return; } sql = - "CREATE TABLE %s (" - " name TEXT," + "CREATE TABLE %s_raw (" + " name_id INTEGER," " flags TEXT," " epoch TEXT," " version TEXT," " release TEXT," " pkgKey INTEGER %s)"; + vsql = + "CREATE VIEW %s AS " + " SELECT name," + " flags," + " epoch," + " version," + " release," + " pkgKey %s FROM %s_raw JOIN id_name USING(name_id)"; const char *deps[] = { "requires", "provides", "conflicts", "obsoletes", NULL }; int i; - const char *pkgindexsql = "CREATE INDEX pkg%s on %s (pkgKey)"; - const char *nameindexsql = "CREATE INDEX %sname ON %s (name)"; + const char *pkgindexsql = ("CREATE INDEX idx_%s_raw_pkgKey ON %s_raw" + " (pkgKey)"); + const char *nameindexsql = ("CREATE INDEX idx_%s_raw_name_id ON %s_raw" + " (name_id)"); for (i = 0; deps[i]; i++) { - const char *prereq; + const char *prereq = ""; + const char *vprereq = ""; char *query; if (!strcmp(deps[i], "requires")) { - prereq = ", pre BOOLEAN DEFAULT FALSE"; - } else - prereq = ""; + prereq = ", pre BOOLEAN DEFAULT FALSE"; + vprereq = ", pre"; + } query = g_strdup_printf (sql, deps[i], prereq); rc = sqlite3_exec (db, query, NULL, NULL, NULL); g_free (query); + query = g_strdup_printf (vsql, deps[i], vprereq, deps[i]); + 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", @@ -430,7 +536,7 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) if (rc != SQLITE_OK) { g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR, - "Can not create index on %s table: %s", + "Can not create idx_%s_pkgKey index: %s", deps[i], sqlite3_errmsg (db)); return; } @@ -440,7 +546,7 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) rc = sqlite3_exec (db, query, NULL, NULL, NULL); if (rc != SQLITE_OK) { g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR, - "Can not create %sname index: %s", + "Can not create idx_%s_name_id index: %s", deps[i], sqlite3_errmsg (db)); return; } @@ -449,13 +555,13 @@ yum_db_create_primary_tables (sqlite3 *db, GError **err) } sql = - "CREATE TRIGGER removals AFTER DELETE ON packages" + "CREATE TRIGGER removals AFTER DELETE ON packages_raw" " BEGIN" " DELETE FROM files WHERE pkgKey = old.pkgKey;" - " DELETE FROM requires WHERE pkgKey = old.pkgKey;" - " DELETE FROM provides WHERE pkgKey = old.pkgKey;" - " DELETE FROM conflicts WHERE pkgKey = old.pkgKey;" - " DELETE FROM obsoletes WHERE pkgKey = old.pkgKey;" + " DELETE FROM requires_raw WHERE pkgKey = old.pkgKey;" + " DELETE FROM provides_raw WHERE pkgKey = old.pkgKey;" + " DELETE FROM conflicts_raw WHERE pkgKey = old.pkgKey;" + " DELETE FROM obsoletes_raw WHERE pkgKey = old.pkgKey;" " END;"; rc = sqlite3_exec (db, sql, NULL, NULL, NULL); @@ -475,11 +581,14 @@ yum_db_package_prepare (sqlite3 *db, GError **err) const char *query; query = - "INSERT INTO packages (" - " pkgId, name, arch, version, epoch, release, summary, description," - " url, time_file, time_build, rpm_license, rpm_vendor, rpm_group," - " rpm_buildhost, rpm_sourcerpm, rpm_header_start, rpm_header_end," - " rpm_packager, size_package, size_installed, size_archive," + "INSERT INTO packages_raw (" + " pkgId_id, name_id, arch_id, version, epoch, release, " + " summary_id, description_id, " + " url_id, time_file, time_build, " + " rpm_license_id, rpm_vendor_id, rpm_group_id, " + " rpm_buildhost_id, rpm_sourcerpm_id, " + " rpm_header_start, rpm_header_end," + " rpm_packager_id, size_package, size_installed, size_archive," " location_href, location_base, checksum_type) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," " ?, ?, ?, ?, ?, ?, ?)"; @@ -487,7 +596,7 @@ yum_db_package_prepare (sqlite3 *db, GError **err) rc = sqlite3_prepare (db, query, -1, &handle, NULL); if (rc != SQLITE_OK) { g_set_error (err, YUM_DB_ERROR, YUM_DB_ERROR, - "Can not prepare packages insertion: %s", + "Can not prepare packages_raw insertion: %s", sqlite3_errmsg (db)); sqlite3_finalize (handle); handle = NULL; @@ -496,30 +605,104 @@ yum_db_package_prepare (sqlite3 *db, GError **err) return handle; } +static int yum_db__map_id (sqlite3 *db, const char *sql, const char *isql, + const char *text, gint64 *ret) +{ + sqlite3_stmt *id_handle = NULL; + int rc; + + rc = sqlite3_prepare (db, sql, -1, &id_handle, NULL); + if (rc != SQLITE_OK) + goto sql_err; + sqlite3_bind_text (id_handle, 1, text, -1, SQLITE_STATIC); + + rc = sqlite3_step (id_handle); + if (rc == SQLITE_ROW) /* got an id for value */ + *ret = sqlite3_column_int (id_handle, 0); + else + { /* insert new value, and get id */ + sqlite3_finalize (id_handle); + + rc = sqlite3_prepare (db, isql, -1, &id_handle, NULL); + if (rc != SQLITE_OK) + goto sql_err; + + sqlite3_bind_text (id_handle, 1, text, -1, SQLITE_STATIC); + rc = sqlite3_step (id_handle); + if (rc != SQLITE_DONE) + goto sql_err; + + *ret = sqlite3_last_insert_rowid (db); + } + + sqlite3_finalize (id_handle); + + return (1); + + sql_err: + sqlite3_finalize (id_handle); + + return (0); +} + +/* used in yum_db_package_write() and yum_db_dependency_prepare() */ +#define YUM_DB__MAP_ID(x, data) \ + sql = "SELECT " #x "_id FROM id_" #x " WHERE " #x " = ?"; \ + isql = "INSERT INTO id_" #x " (" #x ") VALUES (?)"; \ + if (!yum_db__map_id(db, sql, isql, (data)-> x, & x ## _id)) \ + goto sql_err + void yum_db_package_write (sqlite3 *db, sqlite3_stmt *handle, Package *p) { int rc; - - sqlite3_bind_text (handle, 1, p->pkgId, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 2, p->name, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 3, p->arch, -1, SQLITE_STATIC); + const char *sql = NULL; + const char *isql = NULL; + gint64 pkgId_id = 0; + gint64 name_id = 0; + gint64 arch_id = 0; + gint64 summary_id = 0; + gint64 description_id = 0; + gint64 url_id = 0; + gint64 rpm_license_id = 0; + gint64 rpm_vendor_id = 0; + gint64 rpm_group_id = 0; + gint64 rpm_buildhost_id = 0; + gint64 rpm_sourcerpm_id = 0; + gint64 rpm_packager_id = 0; + + YUM_DB__MAP_ID(pkgId, p); + YUM_DB__MAP_ID(name, p); + YUM_DB__MAP_ID(arch, p); + YUM_DB__MAP_ID(summary, p); + YUM_DB__MAP_ID(description, p); + YUM_DB__MAP_ID(url, p); + YUM_DB__MAP_ID(rpm_license, p); + YUM_DB__MAP_ID(rpm_vendor, p); + YUM_DB__MAP_ID(rpm_group, p); + YUM_DB__MAP_ID(rpm_buildhost, p); + YUM_DB__MAP_ID(rpm_sourcerpm, p); + YUM_DB__MAP_ID(rpm_packager, p); + + sqlite3_bind_int (handle, 1, pkgId_id); + sqlite3_bind_int (handle, 2, name_id); + sqlite3_bind_int (handle, 3, arch_id); sqlite3_bind_text (handle, 4, p->version, -1, SQLITE_STATIC); sqlite3_bind_text (handle, 5, p->epoch, -1, SQLITE_STATIC); sqlite3_bind_text (handle, 6, p->release, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 7, p->summary, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 8, p->description, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 9, p->url, -1, SQLITE_STATIC); + sqlite3_bind_int (handle, 7, summary_id); + sqlite3_bind_int (handle, 8, description_id); + sqlite3_bind_int (handle, 9, url_id); sqlite3_bind_int (handle, 10, p->time_file); sqlite3_bind_int (handle, 11, p->time_build); - sqlite3_bind_text (handle, 12, p->rpm_license, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 13, p->rpm_vendor, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 14, p->rpm_group, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 15, p->rpm_buildhost, -1, SQLITE_STATIC); - sqlite3_bind_text (handle, 16, p->rpm_sourcerpm, -1, SQLITE_STATIC); + sqlite3_bind_int (handle, 12, rpm_license_id); + sqlite3_bind_int (handle, 13, rpm_vendor_id); + sqlite3_bind_int (handle, 14, rpm_group_id); + sqlite3_bind_int (handle, 15, rpm_buildhost_id); + sqlite3_bind_int (handle, 16, rpm_sourcerpm_id); sqlite3_bind_int (handle, 17, p->rpm_header_start); sqlite3_bind_int (handle, 18, p->rpm_header_end); - sqlite3_bind_text (handle, 19, p->rpm_packager, -1, SQLITE_STATIC); + sqlite3_bind_int (handle, 19, rpm_packager_id); sqlite3_bind_int (handle, 20, p->size_package); sqlite3_bind_int (handle, 21, p->size_installed); sqlite3_bind_int (handle, 22, p->size_archive); @@ -531,6 +714,7 @@ yum_db_package_write (sqlite3 *db, sqlite3_stmt *handle, Package *p) sqlite3_reset (handle); if (rc != SQLITE_DONE) { + sql_err: g_critical ("Error adding package to SQL: %s", sqlite3_errmsg (db)); } else @@ -555,8 +739,8 @@ yum_db_dependency_prepare (sqlite3 *db, } query = g_strdup_printf - ("INSERT INTO %s (name, flags, epoch, version, release, pkgKey%s) " - "VALUES (?, ?, ?, ?, ?, ?%s)", table, pre_name, pre_value); + ("INSERT INTO %s_raw (name_id, flags, epoch, version, release, pkgKey%s) " + "VALUES (?, ?, ?, ?, ?, ?%s)", table, pre_name, pre_value); rc = sqlite3_prepare (db, query, -1, &handle, NULL); g_free (query); @@ -580,8 +764,13 @@ yum_db_dependency_write (sqlite3 *db, gboolean isRequirement) { int rc; + const char *sql = NULL; + const char *isql = NULL; + gint64 name_id = 0; - sqlite3_bind_text (handle, 1, dep->name, -1, SQLITE_STATIC); + YUM_DB__MAP_ID(name, dep); + + sqlite3_bind_int (handle, 1, name_id); sqlite3_bind_text (handle, 2, dep->flags, -1, SQLITE_STATIC); sqlite3_bind_text (handle, 3, dep->epoch, -1, SQLITE_STATIC); sqlite3_bind_text (handle, 4, dep->version, -1, SQLITE_STATIC); @@ -599,10 +788,14 @@ yum_db_dependency_write (sqlite3 *db, sqlite3_reset (handle); if (rc != SQLITE_DONE) + { + sql_err: g_critical ("Error adding dependency to SQL: %s", sqlite3_errmsg (db)); + } } + sqlite3_stmt * yum_db_file_prepare (sqlite3 *db, GError **err) { diff --git a/sqlitecache.c b/sqlitecache.c index bc20b56..f21c9e1 100644 --- a/sqlitecache.c +++ b/sqlitecache.c @@ -65,6 +65,11 @@ update_info_init (UpdateInfo *info, GError **err) const char *sql; int rc; + + /* FIXME: MASSIVE hack, tmp */ + if (info->create_tables == yum_db_create_primary_tables) + sql = "DELETE FROM packages_raw WHERE pkgKey = ?"; + else sql = "DELETE FROM packages WHERE pkgKey = ?"; rc = sqlite3_prepare (info->db, sql, -1, &info->remove_handle, NULL); if (rc != SQLITE_OK) {