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

source_changes at macosforge.org source_changes at macosforge.org
Tue Feb 2 09:17:51 PST 2010


Revision: 685
          http://trac.macosforge.org/projects/darwinbuild/changeset/685
Author:   wsiegrist at apple.com
Date:     2010-02-02 09:17:49 -0800 (Tue, 02 Feb 2010)
Log Message:
-----------
Schema creation fully implemented

Modified Paths:
--------------
    branches/PR-7489777/darwinup/Column.cpp
    branches/PR-7489777/darwinup/Column.h
    branches/PR-7489777/darwinup/Database.cpp
    branches/PR-7489777/darwinup/Database.h
    branches/PR-7489777/darwinup/Table.cpp
    branches/PR-7489777/darwinup/Table.h
    branches/PR-7489777/darwinup/Utils.h
    branches/PR-7489777/darwinup/main.cpp

Modified: branches/PR-7489777/darwinup/Column.cpp
===================================================================
--- branches/PR-7489777/darwinup/Column.cpp	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Column.cpp	2010-02-02 17:17:49 UTC (rev 685)
@@ -104,11 +104,17 @@
 	return m_is_unique;
 }
 
+/**
+ * Returns string of sql.
+ * Columns will deallocate the string in dtor.
+ *
+ */
 const char* Column::create() {
 	if (!m_create_sql) {
-		asprintf(&m_create_sql, " %s %s %s %s ", m_name, this->typestr(),
-				(this->is_pk() ? "PRIMARY KEY AUTOINCREMENT" : ""),
-				(this->is_unique() ? "UNIQUE" : ""));
+		asprintf(&m_create_sql, "%s %s%s%s", m_name, this->typestr(),
+				(this->is_pk() ? " PRIMARY KEY AUTOINCREMENT" : ""),
+				(this->is_unique() ? " UNIQUE" : ""));
 	}
+	IF_DEBUG("[COLUMN] create(): %s \n", m_create_sql);
 	return (const char*)m_create_sql;
 }

Modified: branches/PR-7489777/darwinup/Column.h
===================================================================
--- branches/PR-7489777/darwinup/Column.h	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Column.h	2010-02-02 17:17:49 UTC (rev 685)
@@ -30,10 +30,13 @@
  * @APPLE_BSD_LICENSE_HEADER_END@
  */
 
+#ifndef _COLUMNS_H
+#define _COLUMNS_H
+
 #include <stdint.h>
 #include <sqlite3.h>
+#include "Utils.h"
 
-
 struct Column {
 	Column();
 	Column(const char* name, uint32_t type);
@@ -44,6 +47,7 @@
 	const int      type();
 	const char*    typestr();
 	const char*    create();
+	const char*    index();
 	
 	const bool     is_index();
 	const bool     is_pk();
@@ -58,3 +62,5 @@
 	bool           m_is_unique;
 	
 };
+
+#endif

Modified: branches/PR-7489777/darwinup/Database.cpp
===================================================================
--- branches/PR-7489777/darwinup/Database.cpp	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Database.cpp	2010-02-02 17:17:49 UTC (rev 685)
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 #include "Database.h"
 
+
 Database::Database() {
 	// XXX: make the initial allocation for 2 to tailor to darwinup usage
 	m_table_max = 1;
@@ -43,6 +44,8 @@
 	m_tables = (Table**)malloc(sizeof(Table*) * m_table_max);
 	m_db = NULL;	
 	m_path = NULL;
+	m_error_size = 1024;
+	m_error = (char*)malloc(m_error_size);
 }
 
 Database::Database(const char* path) {
@@ -54,6 +57,8 @@
 	if (!m_path) {
 		fprintf(stderr, "Error: ran out of memory when constructing database object.\n");
 	}
+	m_error_size = 1024;
+	m_error = (char*)malloc(m_error_size);
 }
 
 Database::~Database() {
@@ -62,15 +67,24 @@
 	}
 	free(m_tables);
 	free(m_path);
+	free(m_error);
 }
 
+void Database::init_schema() {
+	// do nothing... children should implement this
+}
 
 const char* Database::path() {
 	return m_path;
 }
 
+const char* Database::error() {
+	return m_error;
+}
+
 bool Database::connect() {
 	int res = 0;
+	this->init_schema();
 	res = sqlite3_open(m_path, &m_db);
 	if (res) {
 		sqlite3_close(m_db);
@@ -78,6 +92,9 @@
 		fprintf(stderr, "Error: unable to connect to database at: %s \n", m_path);
 		return false;
 	}	
+	if (this->empty()) {
+		assert(this->create_tables());
+	}	
 	return true;	
 }
 
@@ -103,7 +120,61 @@
 }
 
 
+bool Database::empty() {
+	if (!m_tables[0]) {
+		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;
+}
 
+bool Database::create_tables() {
+	int res = SQLITE_OK;
+	for (uint32_t i=0; i<m_table_count; i++) {
+		IF_DEBUG("[DATABASE] creating table #%u \n", i);
+		res = this->sql(m_tables[i]->create());
+		if (res!=SQLITE_OK) {
+			fprintf(stderr, "Error: sql error trying to create table: %s: %s\n", 
+					m_tables[i]->name(), m_error);
+			return false;
+		}
+	}
+	return res==SQLITE_OK;
+}
+
+
+#define __SQL(callback, context, fmt) \
+    va_list args; \
+    va_start(args, fmt); \
+    char* error; \
+    if (this->m_db) { \
+        char *query = sqlite3_vmprintf(fmt, args); \
+        IF_DEBUG("[DATABASE] SQL: %s \n", query); \
+        res = sqlite3_exec(this->m_db, query, callback, context, &error); \
+        sqlite3_free(query); \
+    } else { \
+        fprintf(stderr, "Error: database not open.\n"); \
+        res = SQLITE_ERROR; \
+    } \
+    va_end(args);
+
+int Database::sql(const char* fmt, ...) {
+	int res = 0;
+	__SQL(NULL, NULL, fmt);
+	if (error) {
+		strlcpy(m_error, error, m_error_size);
+		sqlite3_free(error);
+	}
+	IF_DEBUG("[DATABASE] __SQL set res = %d \n", res);
+	return res;
+}
+
+#undef __SQL
+
+
 /**
  *
  * Darwinup database abstraction. This class is responsible
@@ -113,20 +184,18 @@
  *
  */
 DarwinupDatabase::DarwinupDatabase() {
-	m_path = strdup("");
-	this->init();
+	this->connect();
 }
 
-DarwinupDatabase::DarwinupDatabase(const char* path) {
-	m_path = strdup(path);
-	this->init();
+DarwinupDatabase::DarwinupDatabase(const char* path) : Database(path) {
+	this->connect();
 }
 
 DarwinupDatabase::~DarwinupDatabase() {
-	// Database (parent) automatically deallocates schema objects
+	// parent automatically deallocates schema objects
 }
 
-void DarwinupDatabase::init() {
+void DarwinupDatabase::init_schema() {
 	Table* archives = new Table("archives");
 	//                                                                   index  pk     unique
 	assert(archives->add_column(new Column("serial",     SQLITE_INTEGER, false, true,  false)));
@@ -135,7 +204,7 @@
 	assert(archives->add_column(new Column("date_added", SQLITE_INTEGER)));
 	assert(archives->add_column(new Column("active",     SQLITE_INTEGER)));
 	assert(archives->add_column(new Column("info",       SQLITE_INTEGER)));
-	assert(add_table(archives));
+	assert(this->add_table(archives));
 	
 	Table* files = new Table("files");
 	//                                                                   index  pk     unique
@@ -147,6 +216,6 @@
 	assert(files->add_column(new Column("gid",     SQLITE_INTEGER)));
 	assert(files->add_column(new Column("size",    SQLITE_INTEGER)));
 	assert(files->add_column(new Column("digest",  SQLITE_BLOB)));
-	assert(files->add_column(new Column("path",    SQLITE3_TEXT)));
-	assert(add_table(files));	
+	assert(files->add_column(new Column("path",    SQLITE3_TEXT,         true,  false, false)));
+	assert(this->add_table(files));	
 }

Modified: branches/PR-7489777/darwinup/Database.h
===================================================================
--- branches/PR-7489777/darwinup/Database.h	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Database.h	2010-02-02 17:17:49 UTC (rev 685)
@@ -30,6 +30,10 @@
  * @APPLE_BSD_LICENSE_HEADER_END@
  */
 
+#ifndef _DATABASE_H
+#define _DATABASE_H
+
+
 #include <stdint.h>
 #include <sqlite3.h>
 #include "Table.h"
@@ -44,7 +48,9 @@
 	Database(const char* path);
 	virtual ~Database();
 
+	virtual void init_schema();
 	const char* path();
+	const char* error();
 	bool connect();
 	bool connect(const char* path);
 	
@@ -67,14 +73,20 @@
 	
 protected:
 	
-	bool sql(const char* query, ...);
+	bool empty();
+	bool create_tables();
+	int sql(const char* fmt, ...);
 	
 	char*         m_path;
 	sqlite3*      m_db;
+
 	Table**       m_tables;
 	uint32_t      m_table_count;
 	uint32_t      m_table_max;
 
+	char*         m_error;
+	size_t        m_error_size;
+	
 };
 
 
@@ -91,6 +103,7 @@
 	DarwinupDatabase();
 	DarwinupDatabase(const char* path);
 	virtual ~DarwinupDatabase();
-	void init();
+	void init_schema();
 };
 
+#endif

Modified: branches/PR-7489777/darwinup/Table.cpp
===================================================================
--- branches/PR-7489777/darwinup/Table.cpp	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Table.cpp	2010-02-02 17:17:49 UTC (rev 685)
@@ -85,25 +85,58 @@
 	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;
+}
 
-const char* Table::create() {
+char* Table::create() {
 	if (!m_create_sql) {
+		uint32_t i = 0;
+
+		// size of "create table ( );" plus table name, plus 1 for each column to separate
+		size_t size = strlen(m_name) + 22 + m_column_count;
+		for (i=0; i<m_column_count; i++) {		
+			// size for column spec
+			size += strlen(m_columns[i]->create());
+			// size for create index query
+			size += 26 + 2*strlen(m_columns[i]->name()) + 2*strlen(m_name);
+		}
+				
+		// create creation sql
+		m_create_sql = (char*)malloc(size);
+		strlcpy(m_create_sql, "CREATE TABLE ", size);
+		strlcat(m_create_sql, m_name, size);
+		strlcat(m_create_sql, " (", size);
 		// get creation sql for each column
-		const char* cols[m_column_count];
-		const char* indexes[m_column_count];
-		for (uint32_t i=0; i<m_column_count; i++) {
-			cols[i] = m_columns[i]->create();
-			// get creation sql for any indexes
+		for (i=0; i<m_column_count; i++) {
+			if (i) strlcat(m_create_sql, ", ", size); // comma separate after 0th column
+			strlcat(m_create_sql, m_columns[i]->create(), size);
+		}
+		strlcat(m_create_sql, "); ", size);
+
+		for (i=0; i<m_column_count; i++) {
 			if (m_columns[i]->is_index()) {
-				indexes[i] = m_columns[i]->create();
-			} else {
-				indexes[i] = NULL;
-			}			
+				char* buf;
+				asprintf(&buf, "CREATE INDEX %s_%s ON %s (%s);", 
+						 m_name, m_columns[i]->name(), m_name, m_columns[i]->name());
+				strlcat(m_create_sql, buf, size);
+				free(buf);
+			}
 		}
-
-		asprintf(&m_create_sql, "CREATE TABLE %s ( );", m_name);
 	}
 	
+	IF_DEBUG("[TABLE] create(): %s \n", m_create_sql);
+		
 	return m_create_sql;
 }
 

Modified: branches/PR-7489777/darwinup/Table.h
===================================================================
--- branches/PR-7489777/darwinup/Table.h	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Table.h	2010-02-02 17:17:49 UTC (rev 685)
@@ -30,6 +30,10 @@
  * @APPLE_BSD_LICENSE_HEADER_END@
  */
 
+#ifndef _TABLE_H
+#define _TABLE_H
+
+
 #include <stdint.h>
 #include <sqlite3.h>
 #include "Column.h"
@@ -44,16 +48,16 @@
 	bool           add_column(Column*);
 	
 	// return SQL statements for this table
-	const char*    create();  
-	const char*    drop();    
-	const char*    count(const char* where);
-	const char*    select(const char* where);
-	const char*    select_column(const char* column, const char* where);		
-	const char*    update(const char* set, const char* where, uint32_t &count);
-	const char*    del(const char* where, uint32_t &count);
-	const char*    insert(const char* columns, const char* values);
-
+	char*    create();  
+	char*    drop();    
+	char*    count(const char* where);
+	char*    select(const char* where);
+	char*    select_column(const char* column, const char* where);		
+	char*    update(const char* set, const char* where, uint32_t &count);
+	char*    del(const char* where, uint32_t &count);
+	char*    insert(const char* columns, const char* values);
 	
+	
 protected:
 		
 	char*          m_name;
@@ -62,3 +66,5 @@
 	uint32_t       m_column_count;
 	uint32_t       m_column_max;
 };
+
+#endif

Modified: branches/PR-7489777/darwinup/Utils.h
===================================================================
--- branches/PR-7489777/darwinup/Utils.h	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/Utils.h	2010-02-02 17:17:49 UTC (rev 685)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_BSD_LICENSE_HEADER_START@
  *
@@ -30,6 +30,9 @@
  * @APPLE_BSD_LICENSE_HEADER_END@
  */
 
+#ifndef _UTILS_H
+#define _UTILS_H
+
 #include <stdint.h>
 #include <sys/types.h>
 #include <fts.h>
@@ -63,3 +66,4 @@
 inline int INFO_SET(uint32_t word, uint32_t flag) { return (word | flag); }
 inline int INFO_CLR(uint32_t word, uint32_t flag) { return (word & (~flag)); }
 
+#endif

Modified: branches/PR-7489777/darwinup/main.cpp
===================================================================
--- branches/PR-7489777/darwinup/main.cpp	2010-02-01 18:08:17 UTC (rev 684)
+++ branches/PR-7489777/darwinup/main.cpp	2010-02-02 17:17:49 UTC (rev 685)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_BSD_LICENSE_HEADER_START@
  *
@@ -33,6 +33,7 @@
 #include "Archive.h"
 #include "Depot.h"
 #include "Utils.h"
+#include "Database.h"
 
 #include <libgen.h>
 #include <stdio.h>
@@ -138,6 +139,8 @@
 		exit(2);
 	}
 	
+	DarwinupDatabase testdb = DarwinupDatabase("/.DarwinDepot/Database-V200");
+	
 	if (argc == 2 && strcmp(argv[0], "install") == 0) {
 		char uuid[37];
 		Archive* archive = ArchiveFactory(argv[1], depot->downloads_path());
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100202/3b66105d/attachment-0001.html>


More information about the darwinbuild-changes mailing list