[darwinbuild-changes] [664] branches/PR-7431723/darwinup
source_changes at macosforge.org
source_changes at macosforge.org
Tue Dec 15 13:01:10 PST 2009
Revision: 664
http://trac.macosforge.org/projects/darwinbuild/changeset/664
Author: wsiegrist at apple.com
Date: 2009-12-15 13:01:09 -0800 (Tue, 15 Dec 2009)
Log Message:
-----------
Refactor the commands that take an archive as argument. Split iterate_archives into several functions so they are flexible enough to handle operations on "all" archives. Add a new archive() function that synthesises an Archive object from a sqlite row. Cleanup printing of files/lists so they look nice and lineup when asking for "all".
Modified Paths:
--------------
branches/PR-7431723/darwinup/Archive.h
branches/PR-7431723/darwinup/Depot.cpp
branches/PR-7431723/darwinup/Depot.h
branches/PR-7431723/darwinup/main.cpp
Modified: branches/PR-7431723/darwinup/Archive.h
===================================================================
--- branches/PR-7431723/darwinup/Archive.h 2009-12-14 19:30:19 UTC (rev 663)
+++ branches/PR-7431723/darwinup/Archive.h 2009-12-15 21:01:09 UTC (rev 664)
@@ -120,7 +120,7 @@
// Constructor for subclasses and Depot to use when unserializing an archive from the database.
Archive(uint64_t serial, uuid_t uuid, const char* name, const char* path, uint64_t info, time_t date_installed);
-
+
uint64_t m_serial;
uuid_t m_uuid;
char* m_name;
Modified: branches/PR-7431723/darwinup/Depot.cpp
===================================================================
--- branches/PR-7431723/darwinup/Depot.cpp 2009-12-14 19:30:19 UTC (rev 663)
+++ branches/PR-7431723/darwinup/Depot.cpp 2009-12-15 21:01:09 UTC (rev 664)
@@ -254,6 +254,25 @@
return archive;
}
+// create a new Archive from a database row
+Archive* Depot::archive(sqlite3_stmt* stmt) {
+ uuid_t uuid;
+ uint64_t serial = sqlite3_column_int64(stmt, 0);
+ const void* blob = sqlite3_column_blob(stmt, 1);
+ int blobsize = sqlite3_column_bytes(stmt, 1);
+ const unsigned char* name = sqlite3_column_text(stmt, 2);
+ uint64_t info = sqlite3_column_int64(stmt, 3);
+ time_t date_added = sqlite3_column_int(stmt, 4);
+ if (blobsize > 0) {
+ assert(blobsize == sizeof(uuid_t));
+ memcpy(uuid, blob, sizeof(uuid_t));
+ } else {
+ uuid_clear(uuid);
+ }
+ return new Archive(serial, uuid, (const char*)name, NULL, info, date_added);
+}
+
+
// Return Archive from database matching arg, which is one of:
//
// uuid (ex: 22969F32-9C4F-4370-82C8-DD3609736D8D)
@@ -283,48 +302,71 @@
return Depot::archive((archive_name_t)arg);
}
-int Depot::iterate_archives(ArchiveIteratorFunc func, void* context) {
+Archive** Depot::get_all_archives(size_t* count) {
+ extern uint32_t verbosity;
int res = 0;
+ *count = this->count_archives();
+ //fprintf(stderr, "DEBUG: get_all_archives got count = %d \n", (int)*count);
+ Archive** list = (Archive**)malloc(*count * sizeof(Archive*));
static sqlite3_stmt* stmt = NULL;
if (stmt == NULL && m_db) {
- const char* query = "SELECT serial, uuid, name, info, date_added FROM archives ORDER BY serial DESC";
+ const char* query = "SELECT serial, uuid, name, info, date_added FROM archives WHERE name != '<Rollback>' ORDER BY serial DESC";
+ if (verbosity & VERBOSE_DEBUG) {
+ query = "SELECT serial, uuid, name, info, date_added FROM archives ORDER BY serial DESC";
+ }
res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
}
if (stmt && res == 0) {
- while (res == 0) {
+ size_t i = 0;
+ while (res != SQLITE_DONE) {
res = sqlite3_step(stmt);
if (res == SQLITE_ROW) {
- res = 0;
- uuid_t uuid;
- uint64_t serial = sqlite3_column_int64(stmt, 0);
- const void* blob = sqlite3_column_blob(stmt, 1);
- int blobsize = sqlite3_column_bytes(stmt, 1);
- const unsigned char* name = sqlite3_column_text(stmt, 2);
- uint64_t info = sqlite3_column_int64(stmt, 3);
- time_t date_added = sqlite3_column_int(stmt, 4);
- if (blobsize > 0) {
- assert(blobsize == sizeof(uuid_t));
- memcpy(uuid, blob, sizeof(uuid_t));
- } else {
- uuid_clear(uuid);
- }
- Archive* archive = new Archive(serial, uuid, (const char*)name, NULL, info, date_added);
- if (archive) {
- res = func(archive, context);
- delete archive;
- } else {
- fprintf(stderr, "%s:%d: new Archive returned NULL\n", __FILE__, __LINE__);
- res = -1;
- break;
- }
- } else if (res == SQLITE_DONE) {
- res = 0;
- break;
- }
+ //fprintf(stderr, "DEBUG: making %d-th archive \n", (int)i);
+ list[i++] = this->archive(stmt);
+ //fprintf(stderr, "DEBUG: archive = %p \n", list[i-1]);
+ }
}
sqlite3_reset(stmt);
}
+ return list;
+}
+
+size_t Depot::count_archives() {
+ extern uint32_t verbosity;
+ int res = 0;
+ size_t count = 0;
+ static sqlite3_stmt* stmt = NULL;
+ if (stmt == NULL && m_db) {
+ const char* query = "SELECT count(*) FROM archives WHERE name != '<Rollback>'";
+ if (verbosity & VERBOSE_DEBUG) {
+ query = "SELECT count(*) FROM archives";
+ }
+ res = sqlite3_prepare(m_db, query, -1, &stmt, NULL);
+ if (res != 0) fprintf(stderr, "%s:%d: sqlite3_prepare: %s: %s (%d)\n", __FILE__, __LINE__, query, sqlite3_errmsg(m_db), res);
+ }
+ if (stmt && res == 0) {
+ res = sqlite3_step(stmt);
+ if (res == SQLITE_ROW) {
+ count = sqlite3_column_int64(stmt, 0);
+ }
+ sqlite3_reset(stmt);
+ }
+ return count;
+}
+
+int Depot::iterate_archives(ArchiveIteratorFunc func, void* context) {
+ int res = 0;
+ size_t count = 0;
+ Archive** list = this->get_all_archives(&count);
+ //fprintf(stderr, "DEBUG: iterate got: %p %d \n", *list, (int)count);
+ for (size_t i = 0; i < count; i++) {
+ //fprintf(stderr, "DEBUG: iterating on i = %d list[i] = %p \n", (int)i, list[i]);
+ if (list[i]) {
+ res = func(list[i], context);
+ delete list[i];
+ }
+ }
return res;
}
@@ -818,12 +860,18 @@
}
int Depot::uninstall(Archive* archive) {
+ extern uint32_t verbosity;
int res = 0;
assert(archive != NULL);
uint64_t serial = archive->serial();
if (INFO_TEST(archive->info(), ARCHIVE_INFO_ROLLBACK)) {
+ // if in debug mode, get_all_archives returns rollbacks too, so just ignore
+ if (verbosity & VERBOSE_DEBUG) {
+ fprintf(stderr, "[uninstall] skipping uninstall since archive is a rollback.\n");
+ return 0;
+ }
fprintf(stderr, "%s:%d: cannot uninstall a rollback archive.\n", __FILE__, __LINE__);
return -1;
}
@@ -888,13 +936,16 @@
int Depot::verify(Archive* archive) {
int res = 0;
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
+ list_archive(archive, stdout);
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = this->iterate_files(archive, &Depot::verify_file, NULL);
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
-int Depot::list_archive(Archive* archive, void* context) {
- extern uint32_t verbosity;
-
+int Depot::list_archive(Archive* archive, void* context) {
uint64_t serial = archive->serial();
char uuid[37];
@@ -906,10 +957,7 @@
localtime_r(&seconds, &local);
strftime(date, sizeof(date), "%F %T %Z", &local);
- if (!INFO_TEST(archive->info(), ARCHIVE_INFO_ROLLBACK) ||
- (verbosity & VERBOSE_DEBUG)) {
- fprintf((FILE*)context, "%-6llu %-36s %-23s %s\n", serial, uuid, date, archive->name());
- }
+ fprintf((FILE*)context, "%-6llu %-36s %-23s %s\n", serial, uuid, date, archive->name());
return 0;
}
@@ -931,11 +979,12 @@
int Depot::files(Archive* archive) {
int res = 0;
- fprintf(stdout, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stdout, "==================================== ======================= =================\n");
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
list_archive(archive, stdout);
- fprintf(stdout, "================================================================================\n");
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = this->iterate_files(archive, &Depot::print_file, stdout);
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
@@ -943,9 +992,9 @@
Depot* depot = (Depot*)context;
int res = 0;
list_archive(archive, stdout);
- fprintf(stdout, "================================================================================\n");
+ fprintf(stdout, "=======================================================================================\n");
if (res == 0) res = depot->iterate_files(archive, &Depot::print_file, stdout);
- fprintf(stdout, "================================================================================\n\n\n");
+ fprintf(stdout, "=======================================================================================\n\n");
return res;
}
@@ -953,8 +1002,8 @@
extern uint32_t verbosity;
verbosity = 0xFFFFFFFF; // dump is intrinsically a debug command
int res = 0;
- fprintf(stdout, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stdout, "==================================== ======================= =================\n");
+ fprintf(stdout, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stdout, "====== ==================================== ======================= =================\n");
if (res == 0) res = this->iterate_archives(&Depot::dump_archive, this);
return res;
}
@@ -1223,7 +1272,63 @@
return res;
}
+// helper to dispatch the actual command for process_archive()
+int Depot::dispatch_command(Archive* archive, const char* command) {
+ int res = 0;
+ if (strncasecmp((char*)command, "files", 5) == 0) {
+ res = this->files(archive);
+ } else if (strncasecmp((char*)command, "uninstall", 9) == 0) {
+ res = this->uninstall(archive);
+ } else if (strncasecmp((char*)command, "verify", 6) == 0) {
+ res = this->verify(archive);
+ } else {
+ fprintf(stderr, "Error: unknown command given to dispatch_command.\n");
+ }
+ if (res != 0) {
+ fprintf(stderr, "An error occurred.\n");
+ }
+ return res;
+}
+
+// perform a command on an archive specification
+int Depot::process_archive(const char* command, const char* arg) {
+ extern uint32_t verbosity;
+ int res = 0;
+ size_t count = 0;
+ Archive** list = NULL;
+
+ if (strncasecmp(arg, "all", 3) == 0) {
+ list = this->get_all_archives(&count);
+ } else {
+ // make a list of 1 Archive
+ list = (Archive**)malloc(sizeof(Archive*));
+ list[0] = this->get_archive(arg);
+ count = 1;
+ }
+
+ //fprintf(stderr, "DEBUG: count = %d \n", (int)count);
+
+ for (size_t i = 0; i < count; i++) {
+ //fprintf(stderr, "DEBUG: i = %d \n", (int)i);
+ if (!list[i]) {
+ fprintf(stderr, "Archive not found: %s\n", arg);
+ return -1;
+ }
+ if (verbosity & VERBOSE_DEBUG) {
+ char uuid[37];
+ uuid_unparse_upper(list[i]->uuid(), uuid);
+ fprintf(stderr, "Found archive: %s\n", uuid);
+ }
+ //fprintf(stderr, "DEBUG: dispatching %p %s \n", list[i], command);
+ res = this->dispatch_command(list[i], command);
+ delete list[i];
+ }
+ free(list);
+ return res;
+}
+
+
#define __SQL(callback, context, fmt) \
va_list args; \
char* errmsg; \
Modified: branches/PR-7431723/darwinup/Depot.h
===================================================================
--- branches/PR-7431723/darwinup/Depot.h 2009-12-14 19:30:19 UTC (rev 663)
+++ branches/PR-7431723/darwinup/Depot.h 2009-12-15 21:01:09 UTC (rev 664)
@@ -56,7 +56,7 @@
int initialize();
int is_initialized();
- const char* prefix();
+ const char* prefix();
const char* database_path();
const char* archives_path();
@@ -64,12 +64,17 @@
virtual int commit_transaction();
virtual int rollback_transaction();
- Archive* archive(uint64_t serial);
- Archive* archive(uuid_t uuid);
- Archive* archive(archive_name_t name);
- Archive* archive(archive_keyword_t keyword);
- Archive* get_archive(const char* arg);
+ Archive* archive(uint64_t serial);
+ Archive* archive(uuid_t uuid);
+ Archive* archive(archive_name_t name);
+ Archive* archive(archive_keyword_t keyword);
+ Archive* archive(sqlite3_stmt* stmt);
+ Archive* get_archive(const char* arg);
+ // returns a list of Archive*. Caller must free the list.
+ Archive** get_all_archives(size_t *count);
+ size_t count_archives();
+
int dump();
static int dump_archive(Archive* archive, void* context);
@@ -92,8 +97,13 @@
int iterate_files(Archive* archive, FileIteratorFunc func, void* context);
int iterate_archives(ArchiveIteratorFunc func, void* context);
- // test if the depot is currently locked
- int is_locked();
+ // processes an archive according to command
+ // arg is an archive identifier, such as serial or uuid
+ int dispatch_command(Archive* archive, const char* command);
+ int process_archive(const char* command, const char* arg);
+
+ // test if the depot is currently locked
+ int is_locked();
protected:
@@ -123,7 +133,7 @@
// Removes all archive entries which have no corresponding files entries.
int prune_archives();
-
+
File* file_superseded_by(File* file);
File* file_preceded_by(File* file);
File* file_star_eded_by(File* file, sqlite3_stmt* stmt);
Modified: branches/PR-7431723/darwinup/main.cpp
===================================================================
--- branches/PR-7431723/darwinup/main.cpp 2009-12-14 19:30:19 UTC (rev 663)
+++ branches/PR-7431723/darwinup/main.cpp 2009-12-15 21:01:09 UTC (rev 664)
@@ -154,50 +154,11 @@
} else if (argc == 1 && strcmp(argv[0], "dump") == 0) {
depot->dump();
} else if (argc == 2 && strcmp(argv[0], "files") == 0) {
- Archive* archive = depot->get_archive(argv[1]);
- if (archive) {
- res = depot->files(archive);
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else if (argc == 2 && strcmp(argv[0], "uninstall") == 0) {
- Archive* archive = depot->get_archive(argv[1]);
- if (archive) {
- if (verbosity & VERBOSE_DEBUG) {
- char uuid[37];
- uuid_unparse_upper(archive->uuid(), uuid);
- fprintf(stderr, "[uninstall] found archive: %s\n", uuid);
- }
- res = depot->uninstall(archive);
- if (res != 0) {
- fprintf(stderr, "An error occurred.\n");
- res = 1;
- }
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else if (argc == 2 && strcmp(argv[0], "verify") == 0) {
- Archive* archive = depot->get_archive(argv[1]);
- if (archive) {
- if (verbosity & VERBOSE_DEBUG) {
- char uuid[37];
- uuid_unparse_upper(archive->uuid(), uuid);
- fprintf(stderr, "[uninstall] found archive: %s\n", uuid);
- }
- res = depot->verify(archive);
- if (res != 0) {
- fprintf(stderr, "An error occurred.\n");
- res = 1;
- }
- delete archive;
- } else {
- fprintf(stderr, "Archive not found: %s\n", argv[1]);
- res = 1;
- }
+ res = depot->process_archive(argv[0], argv[1]);
} else {
usage(progname);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091215/28aae93f/attachment-0001.html>
More information about the darwinbuild-changes
mailing list