[darwinbuild-changes] [731] branches/PR-7489777/darwinup

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 2 13:08:30 PST 2010


Revision: 731
          http://trac.macosforge.org/projects/darwinbuild/changeset/731
Author:   wsiegrist at apple.com
Date:     2010-03-02 13:08:27 -0800 (Tue, 02 Mar 2010)
Log Message:
-----------
Add custom creation sql support to Table, use it to create a unique index on files table. Do not bother testing for has_file(archive, file) when inserting to an archive, unless its a rollback, since rollback parent directory insertions are the only cause of duplicates. Use fts_parent pointer to walk up parent nodes instead of doing string manipulation.

Modified Paths:
--------------
    branches/PR-7489777/darwinup/DB.cpp
    branches/PR-7489777/darwinup/DB.h
    branches/PR-7489777/darwinup/Depot.cpp
    branches/PR-7489777/darwinup/Depot.h
    branches/PR-7489777/darwinup/Table.cpp
    branches/PR-7489777/darwinup/Table.h

Modified: branches/PR-7489777/darwinup/DB.cpp
===================================================================
--- branches/PR-7489777/darwinup/DB.cpp	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/DB.cpp	2010-03-02 21:08:27 UTC (rev 731)
@@ -32,9 +32,6 @@
 
 #include "DB.h"
 
-DarwinupDatabase::DarwinupDatabase() {
-	this->connect();
-}
 
 DarwinupDatabase::DarwinupDatabase(const char* path) : Database(path) {
 	this->connect();
@@ -64,7 +61,10 @@
 	ADD_INTEGER(m_files_table, "size");
 	ADD_BLOB(m_files_table, "digest");
 	ADD_INDEX(m_files_table, "path", TYPE_TEXT, false);
-	assert(this->add_table(this->m_files_table)==0);	
+	// custom index to protect from duplicate files
+	assert(this->m_files_table->set_custom_create("CREATE UNIQUE INDEX files_archive_path " 
+												  "ON files (archive, path);") == 0);
+	assert(this->add_table(this->m_files_table)==0);
 }
 
 int DarwinupDatabase::activate_archive(uint64_t serial) {

Modified: branches/PR-7489777/darwinup/DB.h
===================================================================
--- branches/PR-7489777/darwinup/DB.h	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/DB.h	2010-03-02 21:08:27 UTC (rev 731)
@@ -54,7 +54,6 @@
  *
  */
 struct DarwinupDatabase : Database {
-	DarwinupDatabase();
 	DarwinupDatabase(const char* path);
 	virtual ~DarwinupDatabase();
 	void init_schema();

Modified: branches/PR-7489777/darwinup/Depot.cpp
===================================================================
--- branches/PR-7489777/darwinup/Depot.cpp	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/Depot.cpp	2010-03-02 21:08:27 UTC (rev 731)
@@ -404,20 +404,19 @@
 			if ((state != ' ' && preceding_flags != FILE_INFO_IDENTICAL) ||
 				INFO_TEST(actual->info(), FILE_INFO_BASE_SYSTEM | FILE_INFO_ROLLBACK_DATA)) {
 				*rollback_files += 1;
-				IF_DEBUG("[analyze]    insert rollback\n");
-				res = this->insert(rollback, actual);
+				if (!this->has_file(rollback, actual)) {
+					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);
+				FTSENT *pent = ent->fts_parent;
+				
 				// 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);
+				while (pent && pent->fts_level >= 0) {
+					File* parent = FileFactory(rollback, pent);
+					
 					// if parent dir does not exist, we are
 					//  generating a rollback of base system
 					//  which does not have matching directories,
@@ -426,10 +425,13 @@
 						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);
+
+					if (!this->has_file(rollback, parent)) {
+						IF_DEBUG("[analyze]      adding parent to rollback: %s \n", parent->path());
+						res = this->insert(rollback, parent);
+					}
 					assert(res == 0);
-					ppath = dirname(ppath);
+					pent = pent->fts_parent;
 				}
 			}
 
@@ -989,10 +991,6 @@
 }
 
 int Depot::insert(Archive* archive, File* file) {
-	int res = 0;
-	int do_update = 0;
-	uint64_t* serial;
-	
 	// check for the destination prefix in file's path, remove if found
 	char *path, *relpath;
 	size_t prefixlen = strlen(this->prefix());
@@ -1002,31 +1000,18 @@
 	        relpath += prefixlen - 1;
 	}
 
-	if (this->has_file(archive, file)) {
-		do_update = 1;
-		res = this->m_db->get_file_serial_from_archive(archive, relpath, &serial);
-		if (!serial || !FOUND(res)) {
-			fprintf(stderr, "Error: unable to find file from archive %llu at path %s: %p %llu %d \n", 
-					archive->serial(), relpath, serial, *serial, res);
-			return 1;
-		}
-		res = m_db->update_file(*serial, archive, file->info(), file->mode(), file->uid(), file->gid(),
-									 file->digest(), relpath);
-	} else {
-		file->m_serial = m_db->insert_file(file->info(), file->mode(), file->uid(), file->gid(), 
-											file->digest(), archive, relpath);
-		if (!file->m_serial) {
-			fprintf(stderr, "Error: unable to insert file at path %s for archive %s \n", 
-					relpath, archive->name());
-			return 2;
-		}
+	file->m_serial = m_db->insert_file(file->info(), file->mode(), file->uid(), file->gid(), 
+									   file->digest(), archive, relpath);
+	if (!file->m_serial) {
+		fprintf(stderr, "Error: unable to insert file at path %s for archive %s \n", 
+				relpath, archive->name());
+		return DB_ERROR;
 	}
 
 	free(path);
-	return res;
+	return 0;
 }
 
-// XXX: cache what files we have seen in memory so we do not have to query db
 int Depot::has_file(Archive* archive, File* file) {
 	// check for the destination prefix in file's path, remove if found
 	char *path, *relpath;
@@ -1036,13 +1021,14 @@
 	if (strncmp(file->path(), this->prefix(), prefixlen) == 0) {
 		relpath += prefixlen - 1;
 	}
-	
+
 	uint64_t count = m_db->count_files(archive, relpath);
-	
+
 	free(path);
 	return count > 0;
 }
 
+
 int Depot::remove(Archive* archive) {
 	int res = 0;
 	res = m_db->delete_files(archive);

Modified: branches/PR-7489777/darwinup/Depot.h
===================================================================
--- branches/PR-7489777/darwinup/Depot.h	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/Depot.h	2010-03-02 21:08:27 UTC (rev 731)
@@ -103,9 +103,7 @@
 	// test if the depot is currently locked 
 	int is_locked();
 
-	int has_file(Archive* archive, File* file);
 
-	
 protected:
 
 	// Serialize access to the Depot via flock(2).
@@ -123,6 +121,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);
 	

Modified: branches/PR-7489777/darwinup/Table.cpp
===================================================================
--- branches/PR-7489777/darwinup/Table.cpp	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/Table.cpp	2010-03-02 21:08:27 UTC (rev 731)
@@ -48,6 +48,7 @@
 	m_results       = (uint8_t**)malloc(sizeof(uint8_t*) * m_result_max);
 	m_name          = strdup(name);
 	m_create_sql    = NULL;
+	m_custom_create_sql    = NULL;
 	m_insert_sql    = NULL;
 	m_update_sql    = NULL;
 	m_delete_sql    = NULL;
@@ -73,6 +74,7 @@
 	free(m_name);
 
 	free(m_create_sql);
+	free(m_custom_create_sql);
 	free(m_insert_sql);
 	free(m_update_sql);
 	free(m_delete_sql);
@@ -87,6 +89,11 @@
 	return m_name;
 }
 
+int Table::set_custom_create(const char* sql) {
+	this->m_custom_create_sql = strdup(sql);
+	return this->m_custom_create_sql == 0;
+}
+
 int Table::add_column(Column* c) {
 	// accumulate offsets for columns in m_columns_size
 	c->m_offset = this->m_columns_size;
@@ -433,6 +440,8 @@
 			size += strlen(m_columns[i]->create());
 			// size for create index query
 			size += 26 + 2*strlen(m_columns[i]->name()) + 2*strlen(m_name);
+			// custom sql
+			if (m_custom_create_sql) size += strlen(m_custom_create_sql);
 		}
 		
 		// create creation sql
@@ -456,6 +465,7 @@
 				free(buf);
 			}
 		}
+		if (m_custom_create_sql) strlcat(m_create_sql, m_custom_create_sql, size);
 	}
 
 	return (const char*)m_create_sql;

Modified: branches/PR-7489777/darwinup/Table.h
===================================================================
--- branches/PR-7489777/darwinup/Table.h	2010-03-02 16:44:21 UTC (rev 730)
+++ branches/PR-7489777/darwinup/Table.h	2010-03-02 21:08:27 UTC (rev 731)
@@ -45,6 +45,9 @@
 	
 	const char*    name();
 
+	// Add custom SQL to table initialization
+	int            set_custom_create(const char* sql);
+	
 	// Column handling
 	int            add_column(Column*);
 	Column*        column(uint32_t index);
@@ -105,6 +108,7 @@
 	char*          m_name;
 
 	char*          m_create_sql;
+	char*          m_custom_create_sql;
 	char*          m_insert_sql;
 	char*          m_update_sql;
 	char*          m_delete_sql;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100302/89feddba/attachment-0001.html>


More information about the darwinbuild-changes mailing list