[darwinbuild-changes] [671] branches/PR-7482850/darwinup

source_changes at macosforge.org source_changes at macosforge.org
Mon Dec 21 11:04:40 PST 2009


Revision: 671
          http://trac.macosforge.org/projects/darwinbuild/changeset/671
Author:   wsiegrist at apple.com
Date:     2009-12-21 11:04:39 -0800 (Mon, 21 Dec 2009)
Log Message:
-----------
Add parent directories when saving user modifications in a rollback. Make Depot::insert use UPDATE as needed to avoid duplicates in the files table.

Modified Paths:
--------------
    branches/PR-7482850/darwinup/Depot.cpp
    branches/PR-7482850/darwinup/Depot.h

Modified: branches/PR-7482850/darwinup/Depot.cpp
===================================================================
--- branches/PR-7482850/darwinup/Depot.cpp	2009-12-18 01:29:26 UTC (rev 670)
+++ branches/PR-7482850/darwinup/Depot.cpp	2009-12-21 19:04:39 UTC (rev 671)
@@ -316,7 +316,6 @@
 	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) {
@@ -332,9 +331,7 @@
 		while (res != SQLITE_DONE) {
 			res = sqlite3_step(stmt);
 			if (res == SQLITE_ROW) {
-				//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);
@@ -369,9 +366,7 @@
 	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];
@@ -558,6 +553,30 @@
 				IF_DEBUG("[analyze]    insert rollback\n");
 				res = this->insert(rollback, actual);
 				assert(res == 0);
+				// need to save parent directories as well
+				char *ppath;
+				char *pathbuf;
+				pathbuf = strdup(actual->path());
+				ppath = dirname(pathbuf);
+				free(pathbuf);
+				// while we have a valid path that is below the prefix
+				while (ppath 
+					   && strncmp(ppath, this->prefix(), strlen(this->prefix())) == 0
+					   && strncmp(ppath, this->prefix(), strlen(ppath)) > 0) {
+					File* parent = FileFactory(ppath);
+					// if parent dir does not exist, we are
+					//  generating a rollback of base system
+					//  which does not have matching directories,
+					//  so we can just move on.
+					if (!parent) {
+						IF_DEBUG("[analyze]      parent path not found, skipping parents\n");
+						break;
+					}
+					IF_DEBUG("[analyze]      adding parent to rollback: %s \n", parent->path());
+					res = this->insert(rollback, parent);
+					assert(res == 0);
+					ppath = dirname(ppath);
+				}
 			}
 
 			fprintf(stderr, "%c %s\n", state, file->path());
@@ -1227,7 +1246,7 @@
 
 int Depot::insert(Archive* archive, File* file) {
 	int res = 0;
-
+	int do_update = 0;
 	// check for the destination prefix in file's path, remove if found
 	char *path, *relpath;
 	size_t prefixlen = strlen(this->prefix());
@@ -1237,15 +1256,21 @@
 	        relpath += prefixlen - 1;
 	}
 
-	static sqlite3_stmt* stmt = NULL;
-	if (stmt == NULL && m_db) {
-		const char* query = "INSERT INTO files (archive, info, mode, uid, gid, digest, path) VALUES (?, ?, ?, ?, ?, ?, ?)";
+	const char* query = NULL;
+	if (this->has_file(archive, file)) {
+		do_update = 1;
+		IF_DEBUG("archive(%llu) already has %s, updating instead \n", archive->serial(), relpath);
+		query = "UPDATE files SET info=?, mode=?, uid=?, gid=?, digest=? WHERE archive=? and path=?";
+	} else {
+		query = "INSERT INTO files (info, mode, uid, gid, digest, archive, path) VALUES (?, ?, ?, ?, ?, ?, ?)";	
+	}
+	sqlite3_stmt* stmt = NULL;
+	if (m_db) {
 		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) {
 		int i = 1;
-		if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
 		if (res == 0) res = sqlite3_bind_int(stmt, i++, file->info());
 		if (res == 0) res = sqlite3_bind_int(stmt, i++, file->mode());
 		if (res == 0) res = sqlite3_bind_int(stmt, i++, file->uid());
@@ -1253,10 +1278,14 @@
 		Digest* dig = file->digest();
 		if (res == 0 && dig) res = sqlite3_bind_blob(stmt, i++, dig->data(), dig->size(), SQLITE_STATIC);
 		else if (res == 0) res = sqlite3_bind_blob(stmt, i++, NULL, 0, SQLITE_STATIC);
+		if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
 		if (res == 0) res = sqlite3_bind_text(stmt, i++, relpath, -1, SQLITE_STATIC);
 		if (res == 0) res = sqlite3_step(stmt);
 		if (res == SQLITE_DONE) {
-			file->m_serial = (uint64_t)sqlite3_last_insert_rowid(m_db);
+			// if we did an insert, update the file serial
+			if (!do_update) {
+				file->m_serial = (uint64_t)sqlite3_last_insert_rowid(m_db);
+			}
 			res = 0;
 		} else {
 			fprintf(stderr, "%s:%d: Could not add file to database: %s (%d)\n", __FILE__, __LINE__, sqlite3_errmsg(m_db), res);
@@ -1267,6 +1296,42 @@
 	return res;
 }
 
+int Depot::has_file(Archive* archive, File* file) {
+	int res = 0;
+	size_t count = 0;
+	// check for the destination prefix in file's path, remove if found
+	char *path, *relpath;
+	size_t prefixlen = strlen(this->prefix());
+	asprintf(&path, "%s", file->path());
+	relpath = path;
+	if (strncmp(file->path(), this->prefix(), prefixlen) == 0) {
+		relpath += prefixlen - 1;
+	}
+	
+	static sqlite3_stmt* stmt = NULL;
+	if (stmt == NULL && m_db) {
+		const char* query = "SELECT count(*) FROM files WHERE archive=? and path=?";
+		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) {
+		int i = 1;
+		if (res == 0) res = sqlite3_bind_int64(stmt, i++, archive->serial());
+		if (res == 0) res = sqlite3_bind_text(stmt, i++, relpath, -1, SQLITE_STATIC);
+		if (res == 0) res = sqlite3_step(stmt);
+		if (res == SQLITE_ROW) {
+			count = sqlite3_column_int64(stmt, 0);
+			IF_DEBUG("has_file(%llu, %s) got count = %u \n", archive->serial(), relpath, (unsigned int)count);
+		} else {
+			res = -1;
+			fprintf(stderr, "%s:%d: Could not query for file in archive: %s (%d)\n", __FILE__, __LINE__, sqlite3_errmsg(m_db), res);
+		}
+		sqlite3_reset(stmt);
+	}
+	free(path);
+	return count > 0;
+}
+
 int Depot::remove(Archive* archive) {
 	int res = 0;
 	uint64_t serial = archive->serial();
@@ -1317,10 +1382,7 @@
 		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;
@@ -1330,7 +1392,6 @@
 			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];
 	} 

Modified: branches/PR-7482850/darwinup/Depot.h
===================================================================
--- branches/PR-7482850/darwinup/Depot.h	2009-12-18 01:29:26 UTC (rev 670)
+++ branches/PR-7482850/darwinup/Depot.h	2009-12-21 19:04:39 UTC (rev 671)
@@ -123,6 +123,8 @@
 	// If the File already has a serial number, it cannot be inserted.
 	int insert(Archive* archive, File* file);
 
+	int has_file(Archive* archive, File* file);
+	
 	// Removes an Archive from the database.
 	int remove(Archive* archive);
 	
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20091221/8ccda2e7/attachment.html>


More information about the darwinbuild-changes mailing list