[darwinbuild-changes] [686] branches/PR-7489777

source_changes at macosforge.org source_changes at macosforge.org
Wed Feb 3 10:26:15 PST 2010


Revision: 686
          http://trac.macosforge.org/projects/darwinbuild/changeset/686
Author:   wsiegrist at apple.com
Date:     2010-02-03 10:26:14 -0800 (Wed, 03 Feb 2010)
Log Message:
-----------
Database::insert implemented. Split out darwinup extension of Database class to DB.{cpp,h}.

Modified Paths:
--------------
    branches/PR-7489777/darwinbuild.xcodeproj/project.pbxproj
    branches/PR-7489777/darwinup/Archive.h
    branches/PR-7489777/darwinup/Column.cpp
    branches/PR-7489777/darwinup/Database.cpp
    branches/PR-7489777/darwinup/Database.h
    branches/PR-7489777/darwinup/Digest.h
    branches/PR-7489777/darwinup/Table.cpp
    branches/PR-7489777/darwinup/Table.h
    branches/PR-7489777/darwinup/main.cpp

Added Paths:
-----------
    branches/PR-7489777/darwinup/DB.cpp
    branches/PR-7489777/darwinup/DB.h

Modified: branches/PR-7489777/darwinbuild.xcodeproj/project.pbxproj
===================================================================
--- branches/PR-7489777/darwinbuild.xcodeproj/project.pbxproj	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinbuild.xcodeproj/project.pbxproj	2010-02-03 18:26:14 UTC (rev 686)
@@ -163,6 +163,7 @@
 		72C86C9F109745BC00C66E90 /* Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72C86BE610965E4F00C66E90 /* Utils.cpp */; };
 		72C86CE210974CC800C66E90 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C86CE110974CC700C66E90 /* libcrypto.dylib */; };
 		72C86CE410974CC800C66E90 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C86CE310974CC800C66E90 /* libsqlite3.dylib */; };
+		DF12E2821119E2B0007587C1 /* DB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF12E2811119E2B0007587C1 /* DB.cpp */; };
 		DFC9772D11138F9400CAE084 /* Column.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC9772711138F9400CAE084 /* Column.cpp */; };
 		DFC9772E11138F9400CAE084 /* Database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC9772911138F9400CAE084 /* Database.cpp */; };
 		DFC9772F11138F9400CAE084 /* Table.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFC9772B11138F9400CAE084 /* Table.cpp */; };
@@ -744,6 +745,8 @@
 		72C86CDD10974C3A00C66E90 /* libredo_prebinding.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libredo_prebinding.a; path = /usr/local/lib/libredo_prebinding.a; sourceTree = "<absolute>"; };
 		72C86CE110974CC700C66E90 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = /usr/lib/libcrypto.dylib; sourceTree = "<absolute>"; };
 		72C86CE310974CC800C66E90 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = /usr/lib/libsqlite3.dylib; sourceTree = "<absolute>"; };
+		DF12E2801119E2B0007587C1 /* DB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DB.h; path = darwinup/DB.h; sourceTree = "<group>"; };
+		DF12E2811119E2B0007587C1 /* DB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DB.cpp; path = darwinup/DB.cpp; sourceTree = "<group>"; };
 		DFC9772711138F9400CAE084 /* Column.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Column.cpp; path = darwinup/Column.cpp; sourceTree = "<group>"; };
 		DFC9772811138F9400CAE084 /* Column.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Column.h; path = darwinup/Column.h; sourceTree = "<group>"; };
 		DFC9772911138F9400CAE084 /* Database.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Database.cpp; path = darwinup/Database.cpp; sourceTree = "<group>"; };
@@ -1035,6 +1038,8 @@
 				72C86BE510965E4F00C66E90 /* SerialSet.h */,
 				72C86BE610965E4F00C66E90 /* Utils.cpp */,
 				72C86BE710965E4F00C66E90 /* Utils.h */,
+				DF12E2801119E2B0007587C1 /* DB.h */,
+				DF12E2811119E2B0007587C1 /* DB.cpp */,
 			);
 			name = darwinup;
 			sourceTree = "<group>";
@@ -2176,6 +2181,7 @@
 				DFC9772D11138F9400CAE084 /* Column.cpp in Sources */,
 				DFC9772E11138F9400CAE084 /* Database.cpp in Sources */,
 				DFC9772F11138F9400CAE084 /* Table.cpp in Sources */,
+				DF12E2821119E2B0007587C1 /* DB.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: branches/PR-7489777/darwinup/Archive.h
===================================================================
--- branches/PR-7489777/darwinup/Archive.h	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Archive.h	2010-02-03 18:26:14 UTC (rev 686)
@@ -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 _ARCHIVE_H
+#define _ARCHIVE_H
+
 #include <stdint.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -301,3 +304,6 @@
 	ZipArchive(const char* path);
 	virtual int extract(const char* destdir);
 };
+
+#endif
+

Modified: branches/PR-7489777/darwinup/Column.cpp
===================================================================
--- branches/PR-7489777/darwinup/Column.cpp	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Column.cpp	2010-02-03 18:26:14 UTC (rev 686)
@@ -115,6 +115,5 @@
 				(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;
 }

Added: branches/PR-7489777/darwinup/DB.cpp
===================================================================
--- branches/PR-7489777/darwinup/DB.cpp	                        (rev 0)
+++ branches/PR-7489777/darwinup/DB.cpp	2010-02-03 18:26:14 UTC (rev 686)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_BSD_LICENSE_HEADER_START@
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @APPLE_BSD_LICENSE_HEADER_END@
+ */
+
+#include "DB.h"
+
+
+DarwinupDatabase::DarwinupDatabase() {
+	this->connect();
+}
+
+DarwinupDatabase::DarwinupDatabase(const char* path) : Database(path) {
+	this->connect();
+}
+
+DarwinupDatabase::~DarwinupDatabase() {
+	// parent automatically deallocates schema objects
+}
+
+void DarwinupDatabase::init_schema() {
+	this->m_archives_table = new Table("archives");
+	//                                                                           index  pk     unique
+	assert(m_archives_table->add_column(new Column("serial",     TYPE_INTEGER,   false, true,  false)));
+	assert(m_archives_table->add_column(new Column("uuid",       TYPE_BLOB,      true,  false, true)));
+	assert(m_archives_table->add_column(new Column("name",       TYPE_TEXT)));
+	assert(m_archives_table->add_column(new Column("date_added", TYPE_INTEGER)));
+	assert(m_archives_table->add_column(new Column("active",     TYPE_INTEGER)));
+	assert(m_archives_table->add_column(new Column("info",       TYPE_INTEGER)));
+	assert(this->add_table(this->m_archives_table));
+	
+	this->m_files_table = new Table("files");
+	//                                                                           index  pk     unique
+	assert(m_files_table->add_column(new Column("serial",  TYPE_INTEGER,         false, true,  false)));
+	assert(m_files_table->add_column(new Column("archive", TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("info",    TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("mode",    TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("uid",     TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("gid",     TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("size",    TYPE_INTEGER)));
+	assert(m_files_table->add_column(new Column("digest",  TYPE_BLOB)));
+	assert(m_files_table->add_column(new Column("path",    TYPE_TEXT,            true,  false, false)));
+	assert(this->add_table(this->m_files_table));	
+}
+
+
+uint64_t DarwinupDatabase::insert_file(uint32_t info, mode_t mode, uid_t uid, gid_t gid, 
+									   Digest* digest, Archive* archive, const char* path) {
+	
+	// must provide arguments in the same order as calls to add_column
+	// blobs need 2 args, the data and the size
+	// Database::insert() requires uint64_t integers
+	bool res = this->insert(this->m_files_table,
+							archive->serial(),
+							(uint64_t)info,
+							(uint64_t)mode,
+							(uint64_t)uid,
+							(uint64_t)gid,
+							(uint64_t)0, 
+							(uint8_t*)(digest ? digest->data() : NULL), 
+							(uint32_t)(digest ? digest->size() : 0), 
+							path);
+	if (!res) {
+		fprintf(stderr, "Error: unable to insert file at %s: %s \n",
+				path, this->error());
+		return 0;
+	}
+	
+	return this->last_insert_id();
+}
+
+

Added: branches/PR-7489777/darwinup/DB.h
===================================================================
--- branches/PR-7489777/darwinup/DB.h	                        (rev 0)
+++ branches/PR-7489777/darwinup/DB.h	2010-02-03 18:26:14 UTC (rev 686)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_BSD_LICENSE_HEADER_START@
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @APPLE_BSD_LICENSE_HEADER_END@
+ */
+
+#ifndef _DB_H
+#define _DB_H
+
+#include <stdint.h>
+#include <assert.h>
+#include "Database.h"
+#include "Table.h"
+#include "Archive.h"
+#include "Digest.h"
+
+
+/**
+ *
+ * Darwinup database abstraction. This class is responsible
+ *  for generating the Table and Column objects that make
+ *  up the darwinup database schema, but the parent handles
+ *  deallocation. 
+ *
+ */
+struct DarwinupDatabase : Database {
+	DarwinupDatabase();
+	DarwinupDatabase(const char* path);
+	virtual ~DarwinupDatabase();
+	void init_schema();
+	
+	// inserts into file table, returns serial from primary key
+	uint64_t insert_file(uint32_t info, mode_t mode, uid_t uid, gid_t gid, 
+						 Digest* digest, Archive* archive, const char* path);
+	
+protected:
+	
+	Table*        m_archives_table;
+	Table*        m_files_table;
+	
+};
+
+#endif
+

Modified: branches/PR-7489777/darwinup/Database.cpp
===================================================================
--- branches/PR-7489777/darwinup/Database.cpp	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Database.cpp	2010-02-03 18:26:14 UTC (rev 686)
@@ -33,9 +33,16 @@
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include "Database.h"
 
+/**
+ * sqlite3_trace callback for debugging
+ */
+void dbtrace(void* context, const char* sql) {
+	fprintf(stderr, "[TRACE] %s \n", sql);
+}
 
 Database::Database() {
 	// XXX: make the initial allocation for 2 to tailor to darwinup usage
@@ -146,6 +153,14 @@
 }
 
 
+bool Database::update(Table* table, Column* column, const char* value, const char* where, 
+					  uint32_t &count) {
+	// not implemented
+	assert(false);
+	return false;
+}
+
+
 #define __SQL(callback, context, fmt) \
     va_list args; \
     va_start(args, fmt); \
@@ -176,46 +191,76 @@
 
 
 /**
+ * Given a table and an arg list in the same order as table->add_column() calls,
+ * binds and executes a sql insertion. The Table is responsible for preparing the
+ * statement in Table::insert()
  *
- * Darwinup database abstraction. This class is responsible
- *  for generating the Table and Column objects that make
- *  up the darwinup database schema, but the parent handles
- *  deallocation.
+ * All integer args must be cast to uint64_t
+ * All blob columns must provide 2 args in the list. The first arg is a uint8_t* of data
+ * and then the uint32_t value for size of the data. 
  *
  */
-DarwinupDatabase::DarwinupDatabase() {
-	this->connect();
-}
+bool Database::insert(Table* table, ...) {
+	int res = SQLITE_OK;
+	va_list args;
+	va_start(args, table);
 
-DarwinupDatabase::DarwinupDatabase(const char* path) : Database(path) {
-	this->connect();
+	// get the prepared statement
+	sqlite3_stmt* stmt = table->insert(m_db);
+	if (!stmt) {
+		fprintf(stderr, "Error: %s table gave a NULL statement when trying to insert.\n", table->name());
+		return false;
+	}
+	
+	uint32_t param = 1; // counter to track placeholders in sql statement
+	
+	for (uint32_t i=0; i<table->column_count(); i++) {
+		Column* col = table->column(i);
+		
+		// primary keys do not get inserted
+		if (col->is_pk()) continue;
+
+		// temp variable for blob columns
+		uint8_t* bdata = NULL;
+		uint32_t bsize = 0;
+		
+		switch(col->type()) {
+			case SQLITE_INTEGER:
+				res = sqlite3_bind_int64(stmt, param++, va_arg(args, uint64_t));
+				break;
+			case SQLITE_TEXT:
+				res = sqlite3_bind_text(stmt, param++, va_arg(args, char*), -1, SQLITE_STATIC);
+				break;
+			case SQLITE_BLOB:
+				bdata = va_arg(args, uint8_t*);
+				bsize = va_arg(args, uint32_t);
+				res = sqlite3_bind_blob(stmt, param++, 
+										bdata, 
+										bsize, 
+										SQLITE_STATIC);
+				break;
+				
+		}
+		if (res != SQLITE_OK) {
+			fprintf(stderr, "Error: failed to bind parameter #%d with column #%d of type %d when inserting "
+					        "to table %s \n",
+					param, i, col->type(), table->name());
+			return false;
+		}
+	}
+
+	sqlite3_trace(m_db, dbtrace, NULL);
+	
+	res = sqlite3_step(stmt);
+	if (res == SQLITE_DONE) res = SQLITE_OK;
+	sqlite3_reset(stmt);
+	
+	va_end(args);
+	return res == SQLITE_OK;
 }
 
-DarwinupDatabase::~DarwinupDatabase() {
-	// parent automatically deallocates schema objects
+uint64_t Database::last_insert_id() {
+	return (uint64_t)sqlite3_last_insert_rowid(m_db);
 }
 
-void DarwinupDatabase::init_schema() {
-	Table* archives = new Table("archives");
-	//                                                                   index  pk     unique
-	assert(archives->add_column(new Column("serial",     SQLITE_INTEGER, false, true,  false)));
-	assert(archives->add_column(new Column("uuid",       SQLITE_BLOB,    true,  false, true)));
-	assert(archives->add_column(new Column("name",       SQLITE3_TEXT)));
-	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(this->add_table(archives));
-	
-	Table* files = new Table("files");
-	//                                                                   index  pk     unique
-	assert(files->add_column(new Column("serial",  SQLITE_INTEGER,       false, true,  false)));
-	assert(files->add_column(new Column("archive", SQLITE_INTEGER)));
-	assert(files->add_column(new Column("info",    SQLITE_INTEGER)));
-	assert(files->add_column(new Column("mode",    SQLITE_INTEGER)));
-	assert(files->add_column(new Column("uid",     SQLITE_INTEGER)));
-	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,         true,  false, false)));
-	assert(this->add_table(files));	
-}
+

Modified: branches/PR-7489777/darwinup/Database.h
===================================================================
--- branches/PR-7489777/darwinup/Database.h	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Database.h	2010-02-03 18:26:14 UTC (rev 686)
@@ -37,6 +37,8 @@
 #include <stdint.h>
 #include <sqlite3.h>
 #include "Table.h"
+#include "Digest.h"
+#include "Archive.h"
 
 /**
  * 
@@ -48,62 +50,55 @@
 	Database(const char* path);
 	virtual ~Database();
 
+	static const int TYPE_INTEGER = SQLITE_INTEGER;
+	static const int TYPE_TEXT    = SQLITE3_TEXT;
+	static const int TYPE_BLOB    = SQLITE_BLOB;
+	
 	virtual void init_schema();
 	const char* path();
 	const char* error();
 	bool connect();
 	bool connect(const char* path);
 	
-	const char* get_value(const char* table, const char* column, const char* where);
-	const char* get_row(const char* table, const char* where);
-	const char* get_column(const char* table, const char* column, const char* where);
-	const char* get_all(const char* table, const char* where);
+	uint64_t last_insert_id();
 	
-	uint32_t count(const char* table, const char* where);
+	const char* get_value(Table* table, Column* column, const char* where);
+	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);
 	
-	bool update(const char* table, const char* set, const char* where, uint32_t &count);
-	bool del(const char* table, const char* where, uint32_t &count);
-	bool insert(const char* table, const char* columns, const char* values);
+	uint32_t count(Table* table, const char* where);
 	
+	bool update(Table* table, Column* column, const char* value, const char* where,
+				uint32_t &count);
+	bool del(Table* table, const char* where, uint32_t &count);
+	bool insert(Table* table, ...);
+	
 	bool begin_transaction();
 	bool rollback_transaction();
 	bool commit_transaction();
-
+	
 	bool add_table(Table*);
 	
+
 protected:
 	
 	bool empty();
 	bool create_tables();
 	int sql(const char* fmt, ...);
 	
-	char*         m_path;
-	sqlite3*      m_db;
+	char*            m_path;
+	sqlite3*         m_db;
 
-	Table**       m_tables;
-	uint32_t      m_table_count;
-	uint32_t      m_table_max;
+	Table**          m_tables;
+	uint32_t         m_table_count;
+	uint32_t         m_table_max;
 
-	char*         m_error;
-	size_t        m_error_size;
+	char*            m_error;
+	size_t           m_error_size;
 	
+	sqlite3_stmt**   m_statements;
+	
 };
 
-
-
-/**
- *
- * Darwinup database abstraction. This class is responsible
- *  for generating the Table and Column objects that make
- *  up the darwinup database schema, but the parent handles
- *  deallocation. 
- *
- */
-struct DarwinupDatabase : Database {
-	DarwinupDatabase();
-	DarwinupDatabase(const char* path);
-	virtual ~DarwinupDatabase();
-	void init_schema();
-};
-
 #endif

Modified: branches/PR-7489777/darwinup/Digest.h
===================================================================
--- branches/PR-7489777/darwinup/Digest.h	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Digest.h	2010-02-03 18:26:14 UTC (rev 686)
@@ -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 _DIGEST_H
+#define _DIGEST_H
+
 #include <sys/types.h>
 #include <stdint.h>
 #include <openssl/evp.h>
@@ -132,3 +135,6 @@
 	// The target is obtained via readlink(2).
 	SHA1DigestSymlink(const char* filename);
 };
+
+#endif
+

Modified: branches/PR-7489777/darwinup/Table.cpp
===================================================================
--- branches/PR-7489777/darwinup/Table.cpp	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Table.cpp	2010-02-03 18:26:14 UTC (rev 686)
@@ -59,6 +59,8 @@
 	free(m_columns);
 	free(m_name);
 	free(m_create_sql);
+	free(m_insert_sql);
+	sqlite3_finalize(m_prepared_insert);
 }
 
 
@@ -141,4 +143,67 @@
 }
 
 
+sqlite3_stmt* Table::insert(sqlite3* db) {
+	// we only need to prepare once, return if we already have it
+	if (m_prepared_insert) return m_prepared_insert;
+	
+	uint32_t i = 0;
+	bool comma = false;  // flag we set to start adding commas
+	
+	// calculate the length of the sql statement
+	size_t size = 27 + 5*m_column_count;
+	for (i=0; i<m_column_count; i++) {
+		size += strlen(m_columns[i]->name());
+	}
+	
+	// generate the sql query
+	m_insert_sql = (char*)malloc(size);
+	strlcpy(m_insert_sql, "INSERT INTO ", size);
+	strlcat(m_insert_sql, m_name, size);
+	strlcat(m_insert_sql, " (", size);
+	for (i=0; i<m_column_count; i++) {
+		// comma separate after 0th column
+		if (comma) strlcat(m_insert_sql, ", ", size);
+		// primary keys do not get inserted
+		if (!m_columns[i]->is_pk()) {
+			strlcat(m_insert_sql, m_columns[i]->name(), size);
+			comma = true;
+		}
+	}
+	comma = false;
+	strlcat(m_insert_sql, ") VALUES (", size);
+	for (i=0; i<m_column_count; i++) {
+		// comma separate after 0th column
+		if (comma) strlcat(m_insert_sql, ", ", size); 
+		// primary keys do not get inserted
+		if (!m_columns[i]->is_pk()) {
+			strlcat(m_insert_sql, "?", size);
+			comma = true;
+		}
+	}
+	strlcat(m_insert_sql, ");", size);
+	
+	IF_DEBUG("[TABLE] prepared insert: %s \n", m_insert_sql);
+	
+	// prepare
+	int res = sqlite3_prepare_v2(db, m_insert_sql, strlen(m_insert_sql), &m_prepared_insert, NULL);
+	if (res != SQLITE_OK) {
+		fprintf(stderr, "Error: unable to prepare insert statement for table: %s \n", m_name);
+		return NULL;
+	}
+	return m_prepared_insert;
+}
 
+
+Column* Table::column(uint32_t index) {
+	if (index < m_column_count) {
+		return this->m_columns[index];
+	} else {
+		return NULL;
+	}
+}
+
+uint32_t Table::column_count() {
+	return this->m_column_count;
+}
+

Modified: branches/PR-7489777/darwinup/Table.h
===================================================================
--- branches/PR-7489777/darwinup/Table.h	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/Table.h	2010-02-03 18:26:14 UTC (rev 686)
@@ -45,8 +45,10 @@
 	
 	const char*    name();
 	const Column** columns();
+	Column*        column(uint32_t index);
+	uint32_t       column_count();
 	bool           add_column(Column*);
-	
+		
 	// return SQL statements for this table
 	char*    create();  
 	char*    drop();    
@@ -55,16 +57,23 @@
 	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);
+
+	sqlite3_stmt*    insert(sqlite3* db);
 	
 	
 protected:
 		
 	char*          m_name;
+	
 	char*          m_create_sql;
+	char*          m_insert_sql;
+	
 	Column**       m_columns;
 	uint32_t       m_column_count;
 	uint32_t       m_column_max;
+	
+	sqlite3_stmt*  m_prepared_insert;
+	
 };
 
 #endif

Modified: branches/PR-7489777/darwinup/main.cpp
===================================================================
--- branches/PR-7489777/darwinup/main.cpp	2010-02-02 17:17:49 UTC (rev 685)
+++ branches/PR-7489777/darwinup/main.cpp	2010-02-03 18:26:14 UTC (rev 686)
@@ -33,8 +33,12 @@
 #include "Archive.h"
 #include "Depot.h"
 #include "Utils.h"
-#include "Database.h"
+#include "DB.h"
 
+//XXX: remove me
+#include "File.h"
+#include "Digest.h"
+
 #include <libgen.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -139,8 +143,16 @@
 		exit(2);
 	}
 	
-	DarwinupDatabase testdb = DarwinupDatabase("/.DarwinDepot/Database-V200");
+	// XXX: test area for new database... remove me
+	DarwinupDatabase* testdb = new DarwinupDatabase("/.DarwinDepot/Database-V200");
+	File* f = FileFactory("/etc/services");
+	Archive* a = new Archive("/.DarwinDepot/Archives/56E93DEE-E6BB-44B2-80A4-32E961751DD8.tar.bz2");
+	const char* mypath = "/path/to/file";
+	testdb->insert_file(1, 2, 3, 4, f->digest(), a, mypath);
+	exit(0);
+	// XXX
 	
+	
 	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/20100203/a18b8fb1/attachment-0001.html>


More information about the darwinbuild-changes mailing list