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

source_changes at macosforge.org source_changes at macosforge.org
Thu Feb 4 17:53:19 PST 2010


Revision: 690
          http://trac.macosforge.org/projects/darwinbuild/changeset/690
Author:   wsiegrist at apple.com
Date:     2010-02-04 17:53:18 -0800 (Thu, 04 Feb 2010)
Log Message:
-----------
Most of the support we need for Depot::has_file

Modified Paths:
--------------
    branches/PR-7489777/darwinup/DB.cpp
    branches/PR-7489777/darwinup/DB.h
    branches/PR-7489777/darwinup/Database.cpp
    branches/PR-7489777/darwinup/Database.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
    branches/PR-7489777/darwinup/main.cpp

Modified: branches/PR-7489777/darwinup/DB.cpp
===================================================================
--- branches/PR-7489777/darwinup/DB.cpp	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/DB.cpp	2010-02-05 01:53:18 UTC (rev 690)
@@ -150,4 +150,19 @@
 	return this->last_insert_id();
 }
 
+uint64_t DarwinupDatabase::count_files(Archive* archive, const char* path) {
 
+	bool res = false;
+	uint64_t c = 1234;
+	res = this->count("count_files",
+					  (void**)&c,
+					  this->m_files_table,
+					  2,                              // number of where conditions
+					  this->m_files_table->column(1), // archive
+					  (uint64_t)archive->serial(),
+					  this->m_files_table->column(8), // path
+					  path);
+	fprintf(stderr, "COUNT: Database::count() gave us %llu\n", c);
+	return c;
+}
+

Modified: branches/PR-7489777/darwinup/DB.h
===================================================================
--- branches/PR-7489777/darwinup/DB.h	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/DB.h	2010-02-05 01:53:18 UTC (rev 690)
@@ -57,6 +57,8 @@
 	virtual ~DarwinupDatabase();
 	void init_schema();
 	
+	uint64_t count_files(Archive* archive, const char* path);
+	
 	// inserts into tables, returns serial from primary key
 	uint64_t insert_archive(uuid_t uuid, uint32_t info, const char* name, time_t date);
 	bool update_file(Archive* archive, const char* path, uint32_t info, mode_t mode, 

Modified: branches/PR-7489777/darwinup/Database.cpp
===================================================================
--- branches/PR-7489777/darwinup/Database.cpp	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Database.cpp	2010-02-05 01:53:18 UTC (rev 690)
@@ -170,10 +170,10 @@
 		fprintf(stderr, "Error: Database has not had a schema initialized.\n");
 		return false;
 	}
-	char* sqlstr = m_tables[0]->count(NULL);
-	int res = this->sql(sqlstr);
-	free(sqlstr);
-	return res!=SQLITE_OK;
+	sqlite3_stmt* stmt = m_tables[0]->count(m_db);
+	int res = sqlite3_step(stmt);
+	sqlite3_finalize(stmt);
+	return res!=SQLITE_ROW;
 }
 
 bool Database::create_tables() {
@@ -295,46 +295,63 @@
 	return res;
 }
 
+#define __get_stmt(expr) \
+	sqlite3_stmt* stmt; \
+	char* key = strdup(name); \
+	cache_get_and_retain(m_statement_cache, key, (void**)&stmt); \
+	if (!stmt) { \
+		fprintf(stderr, "DEBUG: generating query for %s \n", key); \
+		va_list args; \
+		va_start(args, count); \
+		stmt = expr; \
+		va_end(args); \
+		cache_set_and_retain(m_statement_cache, key, stmt, sizeof(stmt)); \
+	} else { \
+		fprintf(stderr, "DEBUG: found query for %s in cache: %p \n", key, stmt); \
+		fprintf(stderr, "DEBUG: query is: %s \n", sqlite3_sql(stmt)); \
+	} \
+	free(key);
 
+#define __step_and_store(stmt, type, output) \
+    res = sqlite3_step(stmt); \
+    if (res == SQLITE_ROW) { \
+	    switch(type) { \
+		    case TYPE_INTEGER: \
+				fprintf(stderr, "DEBUG: step and store : integer\n"); \
+			    *(uint64_t*)output = sqlite3_column_int64(stmt, 0); \
+				fprintf(stderr, "DEBUG: step and store : %llu\n", *(uint64_t*)output); \
+			    break; \
+		    case TYPE_TEXT: \
+				fprintf(stderr, "DEBUG: step and store : text\n"); \
+			    *(const unsigned char**)output = sqlite3_column_text(stmt, 0); \
+				fprintf(stderr, "DEBUG: step and store : %s\n", *(char**)output); \
+			    break; \
+    		case TYPE_BLOB: \
+				fprintf(stderr, "DEBUG: step and store : blob\n"); \
+	    		*(const void**)output = sqlite3_column_blob(stmt, 0); \
+		    	break; \
+    	} \
+    } \
+    sqlite3_reset(stmt); \
+	cache_release_value(m_statement_cache, &stmt);
+
+bool Database::count(const char* name, void** output, Table* table, uint32_t count, ...) {
+	__get_stmt(table->count(m_db, count, args))
+	int res = SQLITE_OK;
+	uint32_t param = 1;
+	__bind_va_columns(count);
+	int type = TYPE_INTEGER;
+	__step_and_store(stmt, type, output)
+	return output != NULL;
+}
+
 bool Database::get_value(const char* name, void** output, Table* table, Column* value_column, 
 						 uint32_t count, ...) {
-	sqlite3_stmt* stmt;
-	char* key = strdup(name);
-	cache_get_and_retain(m_statement_cache, key, (void**)&stmt);
-	if (!stmt) {
-		// did not have stmt cached, so we need to generate it
-		fprintf(stderr, "DEBUG: get_value is generating query for %s \n", key);
-		va_list args;
-		va_start(args, count);
-		stmt = table->get_value(m_db, value_column, count, args);
-		va_end(args);
-		cache_set_and_retain(m_statement_cache, key, stmt, sizeof(stmt));
-	} else {
-		fprintf(stderr, "DEBUG: found get_value query for %s in cache: %p \n", key, stmt);
-		fprintf(stderr, "DEBUG: query is: %s \n", sqlite3_sql(stmt));
-	}
-	
+	__get_stmt(table->get_value(m_db, value_column, count, args));
 	int res = SQLITE_OK;
 	uint32_t param = 1;
 	__bind_va_columns(count);
-	
-	res = sqlite3_step(stmt);
-	if (res == SQLITE_ROW) {
-		switch(value_column->type()) {
-			case TYPE_INTEGER:
-				*(uint64_t*)output = sqlite3_column_int64(stmt, 0);
-				break;
-			case TYPE_TEXT:
-				*(const unsigned char**)output = sqlite3_column_text(stmt, 0);
-				break;
-			case TYPE_BLOB:
-				*(const void**)output = sqlite3_column_blob(stmt, 0);
-				break;
-		}
-	}
-	sqlite3_reset(stmt);
-	cache_release_value(m_statement_cache, &stmt);
-	free(key);
+	__step_and_store(stmt, value_column->type(), output)
 	return output != NULL;
 }
 

Modified: branches/PR-7489777/darwinup/Database.h
===================================================================
--- branches/PR-7489777/darwinup/Database.h	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Database.h	2010-02-05 01:53:18 UTC (rev 690)
@@ -83,15 +83,10 @@
 	const char* get_row(Table* table, const char* where);
 	const char* get_column(Table* table, Column* column, const char* where);
 	const char* get_all(Table* table, const char* where);
-	
-	uint32_t count(Table* table, const char* where);
-	
+		
 	bool del(Table* table, const char* where, uint32_t &count);
 	
-	bool get_value(void* value, Table* table, Column* value_column, ...);
 	
-	
-	
 	/**
 	 * SELECT statement caching and execution
 	 *
@@ -102,6 +97,7 @@
 	 *  everything else are Column*,value pairs for making a WHERE clause
 	 *
 	 */
+	bool count(const char* name, void** output, Table* table, uint32_t count, ...);
 	bool get_value(const char* name, void** output, Table* table, Column* value_column, uint32_t count, ...);
 
 	

Modified: branches/PR-7489777/darwinup/Depot.cpp
===================================================================
--- branches/PR-7489777/darwinup/Depot.cpp	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Depot.cpp	2010-02-05 01:53:18 UTC (rev 690)
@@ -1229,8 +1229,9 @@
 }
 
 int Depot::insert(Archive* archive, File* file) {
-	int res = 0;
+	bool res = true;
 	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());
@@ -1240,49 +1241,24 @@
 	        relpath += prefixlen - 1;
 	}
 
-	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=?";
+		res = m_db2->update_file(archive, relpath, file->info(), file->mode(), file->uid(), file->gid(),
+								 file->digest());		
 	} 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_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());
-		if (res == 0) res = sqlite3_bind_int(stmt, i++, file->gid());
-		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) {
-			// 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);
+		file->m_serial = m_db2->insert_file(file->info(), file->mode(), file->uid(), file->gid(), 
+								 file->digest(), archive, relpath);
+		if (!file->m_serial) {
+			fprintf(stderr, "%s:%d: Could not add file to database: %s (%d)\n", 
+					__FILE__, __LINE__, sqlite3_errmsg(m_db), res);
 		}
-		sqlite3_reset(stmt);
 	}
+
 	free(path);
 	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());
@@ -1292,26 +1268,10 @@
 		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);
-	}
+	uint64_t count = m_db2->count_files(archive, relpath);
+	
+	fprintf(stderr, "COUNT=%llu\n", count);
+	
 	free(path);
 	return count > 0;
 }

Modified: branches/PR-7489777/darwinup/Depot.h
===================================================================
--- branches/PR-7489777/darwinup/Depot.h	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Depot.h	2010-02-05 01:53:18 UTC (rev 690)
@@ -110,6 +110,8 @@
 	// 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).
@@ -127,8 +129,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-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Table.cpp	2010-02-05 01:53:18 UTC (rev 690)
@@ -92,19 +92,6 @@
 	return true;
 }
 
-char* Table::count(const char* where) {
-	IF_DEBUG("[TABLE] entering count of %s with where: %s \n", m_name, where);
-	char* buf;
-	if (where) {
-		IF_DEBUG("[TABLE] counting %s with where %s \n", m_name, where);
-		asprintf(&buf, "SELECT count(*) FROM %s %s ;", m_name, where);
-	} else {
-		IF_DEBUG("[TABLE] counting %s \n", m_name);
-		asprintf(&buf, "SELECT count(*) FROM %s ;", m_name);
-	}
-	IF_DEBUG("[TABLE] count() returning: %s \n", buf);
-	return buf;
-}
 
 char* Table::create() {
 	if (!m_create_sql) {
@@ -147,7 +134,15 @@
 	return m_create_sql;
 }
 
-#define __check_size \
+#define __alloc_stmt_query \
+	size_t size = 256; \
+	size_t used = 0; \
+	char* query = (char*)malloc(size); \
+	sqlite3_stmt* stmt = (sqlite3_stmt*)malloc(sizeof(sqlite3_stmt*));
+
+
+#define __check_and_cat(text) \
+	used = strlcat(query, text, size); \
     if (used >= size-1) { \
         size *= 4; \
         query = (char*)realloc(query, size); \
@@ -155,48 +150,83 @@
 			fprintf(stderr, "Error: ran out of memory!\n"); \
             return NULL; \
         } \
+        used = strlcat(query, text, size); \
     }
 
-sqlite3_stmt* Table::get_value(sqlite3* db, Column* value_column, uint32_t count, va_list args) {
-	size_t size = 256;
-	size_t used = 0;
-	char* query = (char*)malloc(size);
+#define __where_va_columns \
+	char tmpstr[256]; \
+	int len; \
+	for (uint32_t i=0; i < count; i++) { \
+		Column* col = va_arg(args, Column*); \
+		va_arg(args, void*); \
+		len = snprintf(tmpstr, 256, " AND %s=?", col->name()); \
+		if (len >= 255) { \
+			fprintf(stderr, "Error: column name is too big (limit: 248): %s\n", col->name()); \
+			return NULL; \
+		} \
+		used = strlcat(query, tmpstr, size); \
+		if (used >= size-1) { \
+			size *= 4; \
+			query = (char*)realloc(query, size); \
+			if (!query) { \
+				fprintf(stderr, "Error: ran out of memory!\n"); \
+				return NULL; \
+			} \
+			used = strlcat(query, tmpstr, size); \
+		} \
+	}
+
+#define __prepare_stmt \
+	int res = sqlite3_prepare_v2(db, query, size, &stmt, NULL); \
+	free(query); \
+	if (res != SQLITE_OK) { \
+		fprintf(stderr, "Error: unable to prepare statement.\n"); \
+		return NULL; \
+	}
+
+
+sqlite3_stmt* Table::count(sqlite3* db) {
+	IF_DEBUG("[TABLE] entering count of %s \n", m_name);
 	sqlite3_stmt* stmt = (sqlite3_stmt*)malloc(sizeof(sqlite3_stmt*));
+	char* query;
+	int size = asprintf(&query, "SELECT count(*) FROM %s ;", m_name) + 1;
+	__prepare_stmt;
+	return stmt;
+}
+
+sqlite3_stmt* Table::count(sqlite3* db, uint32_t count, va_list args) {
+	__alloc_stmt_query;
+	strlcpy(query, "SELECT count(*) FROM ", size);
+	__check_and_cat(m_name);
+	__check_and_cat(" WHERE 1");
 	
+	__where_va_columns;
+	
+	strlcat(query, ";", size);
+	
+	IF_DEBUG("[TABLE] count query: %s \n", query);
+
+	__prepare_stmt;
+
+	return stmt;	
+}
+
+sqlite3_stmt* Table::get_value(sqlite3* db, Column* value_column, uint32_t count, va_list args) {
+	__alloc_stmt_query;
 	strlcpy(query, "SELECT ", size);
-	used = strlcat(query, value_column->name(), size);
-	__check_size;
-	used = strlcat(query, " FROM ", size);
-	__check_size;
-	used = strlcat(query, m_name, size);
-	__check_size;
-	used = strlcat(query, " WHERE 1", size);
-	__check_size;
+	__check_and_cat(value_column->name());
+	__check_and_cat(" FROM ");
+	__check_and_cat(m_name);
+	__check_and_cat(" WHERE 1");
 
-	char tmpstr[256];
-	int len;
-	for (uint32_t i=0; i < count; i++) {
-		Column* col = va_arg(args, Column*);
-		va_arg(args, void*); // pop off the value which we do not need this time around
-		len = snprintf(tmpstr, 256, " AND %s=?", col->name()); 
-		if (len >= 255) {
-			fprintf(stderr, "Error: column name is too big (limit: 248): %s\n", col->name());
-			return NULL;
-		}
-		used = strlcat(query, tmpstr, size);
-		__check_size;
-	}
+	__where_va_columns;
+	
 	strlcat(query, ";", size);
 
 	IF_DEBUG("[TABLE] get_value query: %s \n", query);
 
-	int res = sqlite3_prepare_v2(db, query, size, &stmt, NULL);
-	free(query);
-	if (res != SQLITE_OK) {
-		fprintf(stderr, "Error: unable to prepare statement for get_value.\n");
-		return NULL;
-	}
-
+	__prepare_stmt;
+	
 	return stmt;
 }
 

Modified: branches/PR-7489777/darwinup/Table.h
===================================================================
--- branches/PR-7489777/darwinup/Table.h	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/Table.h	2010-02-05 01:53:18 UTC (rev 690)
@@ -52,11 +52,12 @@
 	// return SQL statements for this table
 	char*    create();  
 	char*    drop();    
-	char*    count(const char* where);
 	char*    select(const char* where);
 	char*    select_column(const char* column, const char* where);		
 	char*    del(const char* where, uint32_t &count);
 
+	sqlite3_stmt*    count(sqlite3* db);
+	sqlite3_stmt*    count(sqlite3* db, uint32_t count, va_list args);
 	sqlite3_stmt*    get_value(sqlite3* db, Column* value_column, uint32_t count, va_list args);
 	sqlite3_stmt*    insert(sqlite3* db);
 	sqlite3_stmt*    update(sqlite3* db);

Modified: branches/PR-7489777/darwinup/main.cpp
===================================================================
--- branches/PR-7489777/darwinup/main.cpp	2010-02-04 23:44:08 UTC (rev 689)
+++ branches/PR-7489777/darwinup/main.cpp	2010-02-05 01:53:18 UTC (rev 690)
@@ -154,9 +154,17 @@
 	testdb->insert_file(1, 2, 3, 4, f->digest(), a, mypath);
 	testdb->update_file(a, mypath, 5, 6, 7, 8, f->digest());
 	testdb->update_file(a, mypath, 6, 7, 8, 9, f->digest());
-	testdb->update_file(a, mypath, 7, 8, 9, 0, f->digest());
-	testdb->update_file(a, mypath, 8, 9, 0, 1, f->digest());
-	testdb->update_file(a, mypath, 9, 0, 1, 2, f->digest());
+
+	if (depot->has_file(a, f)) {
+		fprintf(stderr, "HASFILE: true\n");
+	}
+	if (depot->has_file(a, f)) {
+		fprintf(stderr, "HASFILE: true\n");
+	}
+	if (depot->has_file(a, f)) {
+		fprintf(stderr, "HASFILE: true\n");
+	}
+	
 	exit(0);
 	// XXX
 	
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100204/fc5ba8cd/attachment-0001.html>


More information about the darwinbuild-changes mailing list