[darwinbuild-changes] [705] branches/PR-7489777/darwinup
source_changes at macosforge.org
source_changes at macosforge.org
Thu Feb 18 13:34:36 PST 2010
Revision: 705
http://trac.macosforge.org/projects/darwinbuild/changeset/705
Author: wsiegrist at apple.com
Date: 2010-02-18 13:34:36 -0800 (Thu, 18 Feb 2010)
Log Message:
-----------
Some support for reading rows and columns
Modified Paths:
--------------
branches/PR-7489777/darwinup/Column.cpp
branches/PR-7489777/darwinup/Column.h
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/Table.cpp
branches/PR-7489777/darwinup/Table.h
branches/PR-7489777/darwinup/main.cpp
Modified: branches/PR-7489777/darwinup/Column.cpp
===================================================================
--- branches/PR-7489777/darwinup/Column.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Column.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -53,7 +53,8 @@
m_is_unique = false;
}
-Column::Column(const char* name, uint32_t type, bool is_index, bool is_pk, bool is_unique) {
+Column::Column(const char* name, uint32_t type,
+ bool is_index, bool is_pk, bool is_unique) {
m_name = strdup(name);
m_create_sql = NULL;
m_type = type;
@@ -71,7 +72,7 @@
return m_name;
}
-const int Column::type() {
+uint32_t Column::type() {
return m_type;
}
@@ -92,6 +93,13 @@
}
}
+uint32_t Column::size() {
+ // integers are stored inband in the record
+ if (m_type == SQLITE_INTEGER) return sizeof(uint64_t);
+ // everything else is stored out of band
+ return sizeof(void*);
+}
+
const bool Column::is_index() {
return m_is_index;
}
Modified: branches/PR-7489777/darwinup/Column.h
===================================================================
--- branches/PR-7489777/darwinup/Column.h 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Column.h 2010-02-18 21:34:36 UTC (rev 705)
@@ -40,12 +40,14 @@
struct Column {
Column();
Column(const char* name, uint32_t type);
- Column(const char* name, uint32_t type, bool is_index, bool is_pk, bool is_unique);
+ Column(const char* name, uint32_t type,
+ bool is_index, bool is_pk, bool is_unique);
virtual ~Column();
const char* name();
- const int type();
+ uint32_t type();
const char* typestr();
+ uint32_t size();
const char* create();
const char* index();
@@ -60,7 +62,6 @@
bool m_is_index;
bool m_is_pk;
bool m_is_unique;
-
};
#endif
Modified: branches/PR-7489777/darwinup/DB.cpp
===================================================================
--- branches/PR-7489777/darwinup/DB.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/DB.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -67,7 +67,7 @@
assert(m_files_table->add_column(new Column("uid", TYPE_INTEGER))==0);
assert(m_files_table->add_column(new Column("gid", TYPE_INTEGER))==0);
assert(m_files_table->add_column(new Column("size", TYPE_INTEGER))==0);
- assert(m_files_table->add_column(new Column("digest", TYPE_BLOB))==0);
+ assert(m_files_table->add_column(new Column("digest", TYPE_BLOB))==0);
assert(m_files_table->add_column(new Column("path", TYPE_TEXT, true, false, false))==0);
assert(this->add_table(this->m_files_table)==0);
}
@@ -87,9 +87,9 @@
this->m_archives_table,
this->m_archives_table->column(4), // active
(void**)active,
- 1,
+ 1, // number of where conditions
this->m_archives_table->column(0), // serial
- serial); // convert from bool to int
+ serial);
}
int DarwinupDatabase::update_archive(uint64_t serial, uuid_t uuid, const char* name,
@@ -122,18 +122,16 @@
return this->last_insert_id();
}
-uint64_t DarwinupDatabase::get_file_serial_from_archive(Archive* archive, const char* path) {
- uint64_t serial = 0;
- this->get_value("file_serial__archive_path",
- (void**)&serial,
- this->m_files_table,
- this->m_files_table->column(0), // serial
- 2, // number of where conditions
- this->m_files_table->column(1), // archive
- (uint64_t)archive->serial(),
- this->m_files_table->column(8), // path
- path);
- return serial;
+int DarwinupDatabase::get_file_serial_from_archive(Archive* archive, const char* path, uint64_t** serial) {
+ return this->get_value("file_serial__archive_path",
+ (void**)serial,
+ this->m_files_table,
+ this->m_files_table->column(0), // serial
+ 2, // number of where conditions
+ this->m_files_table->column(1), // archive
+ (uint64_t)archive->serial(),
+ this->m_files_table->column(8), // path
+ path);
}
int DarwinupDatabase::update_file(uint64_t serial, Archive* archive, uint32_t info, mode_t mode,
@@ -186,12 +184,12 @@
uint64_t DarwinupDatabase::count_files(Archive* archive, const char* path) {
int res = SQLITE_OK;
- uint64_t* c = (uint64_t*)malloc(sizeof(uint64_t));
+ uint64_t* c;
if (!c) fprintf(stderr, "Error: ran out of memory in DarwinupDatabase::count_files().\n");
res = this->count("count_files",
- (void**)c,
+ (void**)&c,
this->m_files_table,
- 2, // number of where conditions
+ 2, // number of where conditions
this->m_files_table->column(1), // archive
(uint64_t)archive->serial(),
this->m_files_table->column(8), // path
@@ -228,9 +226,92 @@
int DarwinupDatabase::delete_files(Archive* archive) {
return this->del("delete_files__archive",
this->m_files_table,
- 1,
+ 1, // number of where conditions
this->m_files_table->column(1), // archive
(uint64_t)archive->serial());
}
+int DarwinupDatabase::get_inactive_archive_serials(uint64_t** serials, uint32_t* count) {
+ int res = this->get_column("inactive_archive_serials",
+ (void**)serials, count,
+ this->m_archives_table,
+ this->m_archives_table->column(0), // serial
+ 1,
+ this->m_archives_table->column(4), // active
+ (uint64_t)0);
+ return res;
+}
+
+int DarwinupDatabase::get_file_serials(uint64_t** serials, uint32_t* count) {
+ return this->get_column("file_serials", (void**)serials, count,
+ this->m_files_table,
+ this->m_files_table->column(0),
+ 0);
+}
+
+
+// serial uuid name date_added active info
+
+/*
+int DarwinupDatabase::process_archive_results() {
+ const unsigned char* name = sqlite3_column_text(stmt, 1);
+ uuid_t uuid;
+ const void* blob = sqlite3_column_blob(stmt, 1);
+ int blobsize = sqlite3_column_bytes(stmt, 1);
+ if (blobsize > 0) {
+ assert(blobsize == sizeof(uuid_t));
+ memcpy(uuid, blob, sizeof(uuid_t));
+ } else {
+ uuid_clear(uuid);
+ }
+ uint64_t serial = sqlite3_column_int64(stmt, 0);
+ uint64_t info = sqlite3_column_int64(stmt, 2);
+ time_t date_added = sqlite3_column_int(stmt, 3);
+ return 0;
+}
+*/
+
+int DarwinupDatabase::get_archive(uint8_t** data, uuid_t uuid) {
+ return this->get_row("archive__uuid",
+ data,
+ this->m_archives_table,
+ 1,
+ this->m_archives_table->column(1), // uuid
+ uuid, sizeof(uuid_t));
+}
+
+int DarwinupDatabase::get_archive(uint8_t** data, uint64_t serial) {
+ return this->get_row("archive__serial",
+ data,
+ this->m_archives_table,
+ 1,
+ this->m_archives_table->column(0), // serial
+ serial);
+}
+
+int DarwinupDatabase::get_archive(uint8_t** data, const char* name) {
+ return this->get_row("archive__name",
+ data,
+ this->m_archives_table,
+ 1,
+ this->m_archives_table->column(2), // name
+ name);
+}
+
+int DarwinupDatabase::archive_offset(int column) {
+ return column*8;
+}
+
+
+/*
+get_all_archives(include_rollbacks?)
+
+count_archives(include_rollbacks?)
+
+get_files(archive)
+
+
+*/
+
+
Modified: branches/PR-7489777/darwinup/DB.h
===================================================================
--- branches/PR-7489777/darwinup/DB.h 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/DB.h 2010-02-18 21:34:36 UTC (rev 705)
@@ -60,7 +60,12 @@
uint64_t count_files(Archive* archive, const char* path);
- // Archives table modifications
+ // Archives
+ int get_archive(uint8_t** data, uuid_t uuid);
+ int get_archive(uint8_t** data, uint64_t serial);
+ int get_archive(uint8_t** data, const char* name);
+ int get_inactive_archive_serials(uint64_t** serials, uint32_t* count);
+ int archive_offset(int column);
int activate_archive(uint64_t serial);
int deactivate_archive(uint64_t serial);
int update_archive(uint64_t serial, uuid_t uuid, const char* name,
@@ -70,8 +75,9 @@
int delete_archive(Archive* archive);
int delete_archive(uint64_t serial);
- // Files table modifications
- uint64_t get_file_serial_from_archive(Archive* archive, const char* path);
+ // Files
+ int get_file_serials(uint64_t** serials, uint32_t* count);
+ int get_file_serial_from_archive(Archive* archive, const char* path, uint64_t** serial);
int update_file(uint64_t serial, Archive* archive, uint32_t info, mode_t mode,
uid_t uid, gid_t gid, Digest* digest, const char* path);
uint64_t insert_file(uint32_t info, mode_t mode, uid_t uid, gid_t gid,
Modified: branches/PR-7489777/darwinup/Database.cpp
===================================================================
--- branches/PR-7489777/darwinup/Database.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Database.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -32,6 +32,13 @@
#include "Database.h"
+// initial number of rows we allocate for when querying
+#define INITIAL_ROWS 8
+
+// how much we grow by when we need more space
+#define REALLOC_FACTOR 4
+#define ERROR_BUF_SIZE 1024
+
/**
* sqlite3_trace callback for debugging
*/
@@ -56,7 +63,7 @@
this->init_cache();
m_db = NULL;
m_path = NULL;
- m_error_size = 1024;
+ m_error_size = ERROR_BUF_SIZE;
m_error = (char*)malloc(m_error_size);
}
@@ -70,7 +77,7 @@
if (!m_path) {
fprintf(stderr, "Error: ran out of memory when constructing database object.\n");
}
- m_error_size = 1024;
+ m_error_size = ERROR_BUF_SIZE;
m_error = (char*)malloc(m_error_size);
}
@@ -186,12 +193,12 @@
int Database::add_table(Table* t) {
if (m_table_count >= m_table_max) {
- m_tables = (Table**)realloc(m_tables, m_table_max * sizeof(Table*) * 4);
+ m_tables = (Table**)realloc(m_tables, m_table_max * sizeof(Table*) * REALLOC_FACTOR);
if (!m_tables) {
fprintf(stderr, "Error: unable to reallocate memory to add a table\n");
return 1;
}
- m_table_max *= 4;
+ m_table_max *= REALLOC_FACTOR;
}
m_tables[m_table_count++] = t;
@@ -274,11 +281,9 @@
if (col->is_pk()) continue; \
uint8_t* bdata = NULL; \
uint32_t bsize = 0; \
- uint64_t val = 1234; \
switch(col->type()) { \
case TYPE_INTEGER: \
- val = va_arg(args, uint64_t); \
- res = sqlite3_bind_int64(stmt, param++, val); \
+ res = sqlite3_bind_int64(stmt, param++, va_arg(args, uint64_t)); \
break; \
case TYPE_TEXT: \
res = sqlite3_bind_text(stmt, param++, va_arg(args, char*), -1, SQLITE_STATIC); \
@@ -304,16 +309,21 @@
#define __bind_va_columns(_lastarg) \
va_list args; \
va_start(args, _lastarg); \
+ fprintf(stderr, "DEBUG: sql: %s \n", sqlite3_sql(stmt)); \
for (uint32_t i=0; i<count; i++) { \
Column* col = va_arg(args, Column*); \
uint8_t* bdata = NULL; \
uint32_t bsize = 0; \
+ uint64_t val; \
switch(col->type()) { \
case TYPE_INTEGER: \
- res = sqlite3_bind_int64(stmt, param++, va_arg(args, uint64_t)); \
+ val = va_arg(args, uint64_t); \
+ res = sqlite3_bind_int64(stmt, param++, val); \
+ fprintf(stderr, "DEBUG: bind int: %llu \n", val); \
break; \
case TYPE_TEXT: \
res = sqlite3_bind_text(stmt, param++, va_arg(args, char*), -1, SQLITE_STATIC); \
+ fprintf(stderr, "DEBUG: bind text \n"); \
break; \
case TYPE_BLOB: \
bdata = va_arg(args, uint8_t*); \
@@ -322,12 +332,13 @@
bdata, \
bsize, \
SQLITE_STATIC); \
+ fprintf(stderr, "DEBUG: bind blob \n"); \
break; \
} \
if (res != SQLITE_OK) { \
fprintf(stderr, "Error: failed to bind parameter #%d with column #%d of type %d " \
- "table %s \n", \
- param, i, col->type(), table->name()); \
+ "table %s res %d: %s \n", \
+ param-1, i, col->type(), table->name(), res, sqlite3_errmsg(m_db)); \
return res; \
} \
} \
@@ -346,27 +357,153 @@
} \
free(key);
-#define __step_and_store(_stmt, _type, _output) \
- res = sqlite3_step(_stmt); \
- if (res == SQLITE_ROW) { \
- switch(_type) { \
- case TYPE_INTEGER: \
- *(uint64_t*)_output = (uint64_t)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; \
- } \
- } else { \
- fprintf(stderr, "ERROR: __step_and_store(_stmt, _type_output) = %d \n", res); \
- return res; \
- } \
- sqlite3_reset(_stmt); \
- cache_release_value(m_statement_cache, &_stmt);
+size_t Database::store_column(sqlite3_stmt* stmt, int column, uint8_t* output) {
+ IF_DEBUG("store_column: column = %d output = %p \n", column, output);
+ size_t used;
+ int type = sqlite3_column_type(stmt, column);
+ const void* blob;
+ int blobsize;
+ IF_DEBUG("column type = %d \n", type);
+ switch(type) {
+ case SQLITE_INTEGER:
+ *(uint64_t*)output = (uint64_t)sqlite3_column_int64(stmt, column);
+ used = sizeof(uint64_t);
+ IF_DEBUG("store_column used=%u output(%p) = %llu \n",
+ (uint32_t)used, output, *(uint64_t*)output);
+ break;
+ case SQLITE_TEXT:
+ *(const char**)output = strdup((const char*)sqlite3_column_text(stmt, column));
+ IF_DEBUG("store text: %p %s \n", (char*)output, (char*)output);
+ used = sizeof(char*);
+ IF_DEBUG("store_column used=%u output(%p) = %s \n",
+ (uint32_t)used, output, *(char**)output);
+ break;
+ case SQLITE_BLOB:
+ blob = sqlite3_column_blob(stmt, column);
+ blobsize = sqlite3_column_bytes(stmt, column);
+ IF_DEBUG("blob(%p) size=%d \n", blob, blobsize);
+ *(void**)output = malloc(blobsize);
+ if (*output && blobsize) memcpy(*(void**)output, blob, blobsize);
+ used = sizeof(void*);
+ IF_DEBUG("store_column used=%u output(%p) = %s \n",
+ (uint32_t)used, output, *(char**)output);
+ break;
+ default:
+ fprintf(stderr, "Error: unhandled column type in Database::store_column(): %d \n",
+ type);
+ return 0;
+ }
+ return used;
+}
+
+/**
+ *
+ *
+ * will not realloc memory for output since caller should know how
+ * much to alloc in the first place. Sets used to be how many bytes
+ * were written to output
+ */
+int Database::step_once(sqlite3_stmt* stmt, uint8_t* output, uint32_t* used) {
+ int res = sqlite3_step(stmt);
+ uint8_t* current = output;
+ IF_DEBUG("output = %p current = %p \n", output, current);
+ if (used) *used = 0;
+ if (used) IF_DEBUG("step_once used(%p) = %u \n", used, *used);
+
+ if (res == SQLITE_ROW) {
+ int count = sqlite3_column_count(stmt);
+ for (int i = 0; i < count; i++) {
+ IF_DEBUG("loop current ptr before = %p \n", current);
+ current += this->store_column(stmt, i, current);
+ IF_DEBUG("loop current ptr after = %p \n", current);
+ }
+ if (used) {
+ *used = current - output;
+ IF_DEBUG("step_once after store used(%p) = %u \n", used, *used);
+ }
+ res = SQLITE_OK;
+ }
+
+ return res;
+}
+
+int Database::step_column(sqlite3_stmt* stmt, void** output, uint32_t size, uint32_t* count) {
+ uint32_t used = 0;
+ uint32_t total_used = used;
+ uint32_t rowsize = size / INITIAL_ROWS;
+ uint8_t* current = *(uint8_t**)output;
+ *count = 0;
+ IF_DEBUG("rowsize = %u \n", rowsize);
+ int res = SQLITE_OK;
+ while (res == SQLITE_OK) {
+ current = *(uint8_t**)output + total_used;
+ IF_DEBUG("calling step_once with current(%p) \n", current);
+ res = this->step_once(stmt, current, &used);
+ if (res == SQLITE_OK) (*count)++;
+ total_used += used;
+ IF_DEBUG("stepped: used = %u total_used = %u size = %u \n", used, total_used, size);
+ if (total_used >= (size - rowsize)) {
+ size *= REALLOC_FACTOR;
+ *output = realloc(*output, size);
+ IF_DEBUG("reallocating: output = %p size = %u \n", *output, size);
+ if (!*output) {
+ fprintf(stderr, "Error: ran out of memory in Database::step_once \n");
+ return SQLITE_ERROR;
+ }
+ }
+ }
+ sqlite3_reset(stmt);
+ return res;
+}
+
+int Database::get_value(const char* name, void** output, Table* table, Column* value_column,
+ uint32_t count, ...) {
+ __get_stmt(table->get_column(m_db, value_column, count, args));
+ int res = SQLITE_OK;
+ uint32_t param = 1;
+ __bind_va_columns(count);
+ uint32_t size = value_column->size();
+ *output = malloc(size);
+ res = this->step_once(stmt, (uint8_t*)*output, NULL);
+ IF_DEBUG("get_value output(%p) = %llu \n", *output, **(uint64_t**)output);
+ sqlite3_reset(stmt);
+ cache_release_value(m_statement_cache, &stmt);
+ return res;
+}
+
+int Database::get_column(const char* name, void** output, uint32_t* result_count,
+ Table* table, Column* column, uint32_t count, ...) {
+ __get_stmt(table->get_column(m_db, column, count, args));
+ IF_DEBUG("stmt = %s \n", sqlite3_sql(stmt));
+ int res = SQLITE_OK;
+ uint32_t param = 1;
+ __bind_va_columns(count);
+ uint32_t size = INITIAL_ROWS * column->size();
+ *output = malloc(size);
+ IF_DEBUG("get_column output = %p size = %u \n", *output, size);
+ res = this->step_column(stmt, output, size, result_count);
+ IF_DEBUG("get_colu output(%p) = %llu \n", *output, **(uint64_t**)output);
+ sqlite3_reset(stmt);
+ cache_release_value(m_statement_cache, &stmt);
+ return res;
+}
+
+int Database::get_row(const char* name, uint8_t** output, Table* table, uint32_t count, ...) {
+ __get_stmt(table->get_row(m_db, count, args));
+ IF_DEBUG("stmt = %s \n", sqlite3_sql(stmt));
+ int res = SQLITE_OK;
+ uint32_t param = 1;
+ __bind_va_columns(count);
+ *output = table->alloc_result();
+ IF_DEBUG("Table::alloc_result = %p \n", *output);
+ res = this->step_once(stmt, *output, NULL);
+ IF_DEBUG("get_row output(%p) = %llu \n", *output, **(uint64_t**)output);
+ sqlite3_reset(stmt);
+ cache_release_value(m_statement_cache, &stmt);
+ return output == NULL;
+}
+
int Database::sql(const char* name, const char* fmt, ...) {
sqlite3_stmt* stmt;
char* key = strdup(name);
@@ -394,20 +531,13 @@
int res = SQLITE_OK;
uint32_t param = 1;
__bind_va_columns(count);
- __step_and_store(stmt, TYPE_INTEGER, output);
+ *output = malloc(sizeof(uint64_t));
+ res = this->step_once(stmt, *(uint8_t**)output, NULL);
+ sqlite3_reset(stmt);
+ cache_release_value(m_statement_cache, &stmt);
return output == NULL;
}
-int Database::get_value(const char* name, void** output, Table* table, Column* value_column,
- uint32_t count, ...) {
- __get_stmt(table->get_value(m_db, value_column, count, args));
- int res = SQLITE_OK;
- uint32_t param = 1;
- __bind_va_columns(count);
- __step_and_store(stmt, value_column->type(), output);
- return output == NULL;
-}
-
/**
* Given a table and an arg list in the same order as Table::add_column() calls,
* binds and executes a sql update. The Table is responsible for preparing the
@@ -521,7 +651,6 @@
#undef __bind_all_columns
#undef __get_stmt
-#undef __step_and_store
uint64_t Database::last_insert_id() {
return (uint64_t)sqlite3_last_insert_rowid(m_db);
Modified: branches/PR-7489777/darwinup/Database.h
===================================================================
--- branches/PR-7489777/darwinup/Database.h 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Database.h 2010-02-18 21:34:36 UTC (rev 705)
@@ -93,6 +93,9 @@
int count(const char* name, void** output, Table* table, uint32_t count, ...);
int get_value(const char* name, void** output, Table* table, Column* value_column,
uint32_t count, ...);
+ int get_column(const char* name, void** output, uint32_t* result_count,
+ Table* table, Column* column, uint32_t count, ...);
+ int get_row(const char* name, uint8_t** output, Table* table, uint32_t count, ...);
int update_value(const char* name, Table* table, Column* value_column, void** value,
uint32_t count, ...);
int update(Table* table, uint64_t pkvalue, ...);
@@ -115,6 +118,10 @@
int execute(sqlite3_stmt* stmt);
+ size_t store_column(sqlite3_stmt* stmt, int column, uint8_t* output);
+ int step_once(sqlite3_stmt* stmt, uint8_t* output, uint32_t* used);
+ int step_column(sqlite3_stmt* stmt, void** output, uint32_t size, uint32_t* count);
+
// libcache
void init_cache();
void destroy_cache();
Modified: branches/PR-7489777/darwinup/Depot.cpp
===================================================================
--- branches/PR-7489777/darwinup/Depot.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Depot.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -75,6 +75,10 @@
}
Depot::~Depot() {
+
+ // XXX: this is expensive, but is it necessary?
+ //this->check_consistency();
+
if (m_lock_fd != -1) this->unlock();
delete m_db2;
if (m_db) sqlite3_close(m_db);
@@ -126,7 +130,7 @@
}
m_db2 = new DarwinupDatabase(m_database_path);
-
+
return res;
}
@@ -689,11 +693,6 @@
assert(rollback != NULL);
assert(archive != NULL);
- // Check the consistency of the database before proceeding with the installation
- // If this fails, abort the installation.
- // res = this->check_consistency();
- // if (res != 0) return res;
-
res = this->lock(LOCK_EX);
if (res != 0) return res;
@@ -896,9 +895,6 @@
return -1;
}
-// res = this->check_consistency();
-// if (res != 0) return res;
-
res = this->lock(LOCK_EX);
if (res != 0) return res;
@@ -1110,34 +1106,22 @@
SerialSet* inactive = new SerialSet();
assert(inactive != NULL);
- static sqlite3_stmt* stmt = NULL;
- if (stmt == NULL && m_db) {
- const char* query = "SELECT serial FROM archives WHERE active=0 ORDER BY serial DESC";
- 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);
+ // get inactive archives serials from the database
+ uint64_t* serials;
+ uint32_t count;
+ this->m_db2->get_inactive_archive_serials(&serials, &count);
+ for (uint32_t i=0; i < count; i++) {
+ inactive->add(serials[i]);
}
- if (stmt && res == 0) {
- while (res == 0) {
- res = sqlite3_step(stmt);
- if (res == SQLITE_ROW) {
- res = 0;
- uint64_t serial = sqlite3_column_int64(stmt, 0);
- inactive->add(serial);
- } else if (res == SQLITE_DONE) {
- res = 0;
- break;
- } else {
- fprintf(stderr, "%s:%d: unexpected SQL error: %d\n", __FILE__, __LINE__, res);
- }
- }
- sqlite3_reset(stmt);
- }
+ free(serials);
+ // print a list of inactive archives
if (res == 0 && inactive && inactive->count > 0) {
- fprintf(stderr, "The following archive%s in an inconsistent state and must be uninstalled before proceeding:\n\n", inactive->count > 1 ? "s are" : " is");
+ fprintf(stderr, "The following archive%s in an inconsistent state and must be uninstalled "
+ "before proceeding:\n\n", inactive->count > 1 ? "s are" : " is");
uint32_t i;
- fprintf(stderr, "%-36s %-23s %s\n", "UUID", "Date Installed", "Name");
- fprintf(stderr, "==================================== ======================= =================\n");
+ fprintf(stderr, "%-6s %-36s %-23s %s\n", "Serial", "UUID", "Date Installed", "Name");
+ fprintf(stderr, "====== ==================================== ======================= =================\n");
for (i = 0; i < inactive->count; ++i) {
Archive* archive = this->archive(inactive->values[i]);
if (archive) {
@@ -1219,7 +1203,8 @@
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());
@@ -1231,14 +1216,16 @@
if (this->has_file(archive, file)) {
do_update = 1;
- uint64_t serial = this->m_db2->get_file_serial_from_archive(archive, relpath);
+ res = this->m_db2->get_file_serial_from_archive(archive, relpath, &serial);
if (!serial) {
fprintf(stderr, "Error: unable to find file from archive %llu at path %s \n",
archive->serial(), relpath);
return 1;
}
- res = m_db2->update_file(serial, archive, file->info(), file->mode(), file->uid(), file->gid(),
- file->digest(), relpath);
+ if (res == SQLITE_OK) {
+ res = m_db2->update_file(*serial, archive, file->info(), file->mode(), file->uid(), file->gid(),
+ file->digest(), relpath);
+ }
} else {
file->m_serial = m_db2->insert_file(file->info(), file->mode(), file->uid(), file->gid(),
file->digest(), archive, relpath);
Modified: branches/PR-7489777/darwinup/Table.cpp
===================================================================
--- branches/PR-7489777/darwinup/Table.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Table.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -51,6 +51,9 @@
m_column_max = 1;
m_column_count = 0;
m_columns = (Column**)malloc(sizeof(Column*) * m_column_max);
+ m_result_max = 1;
+ m_result_count = 0;
+ m_results = (uint8_t**)malloc(sizeof(uint8_t*) * m_result_max);
m_name = strdup("unnamed_table");
m_create_sql = NULL;
m_insert_sql = NULL;
@@ -66,6 +69,9 @@
m_column_max = 1;
m_column_count = 0;
m_columns = (Column**)malloc(sizeof(Column*) * m_column_max);
+ m_result_max = 1;
+ m_result_count = 0;
+ m_results = (uint8_t**)malloc(sizeof(uint8_t*) * m_result_max);
m_name = strdup(name);
m_create_sql = NULL;
m_insert_sql = NULL;
@@ -80,8 +86,14 @@
for (uint32_t i = 0; i < m_column_count; i++) {
delete m_columns[i];
}
-
free(m_columns);
+
+ for (uint32_t i=0; i < m_result_count; i++) {
+ this->free_row(m_results[i]);
+ free(m_results[i]);
+ }
+ free(m_results);
+
free(m_name);
free(m_create_sql);
@@ -100,6 +112,10 @@
return m_name;
}
+uint32_t Table::row_size() {
+ return m_column_count*8;
+}
+
const Column** Table::columns() {
return (const Column**)m_columns;
}
@@ -120,6 +136,54 @@
}
+uint8_t* Table::alloc_result() {
+ if (m_result_count >= m_result_max) {
+ m_results = (uint8_t**)realloc(m_results, m_result_max * sizeof(uint8_t*) * 4);
+ if (!m_results) {
+ fprintf(stderr, "Error: unable to reallocate memory to add a result row\n");
+ return NULL;
+ }
+ m_result_max *= 4;
+ }
+ m_result_count++;
+ m_results[m_result_count-1] = (uint8_t*)calloc(1, this->row_size());
+ return m_results[m_result_count-1];
+}
+
+int Table::free_row(uint8_t* row) {
+ uint8_t* current = row;
+ for (uint32_t i=0; i < m_column_count; i++) {
+ switch (m_columns[i]->type()) {
+ case SQLITE_INTEGER:
+ current += sizeof(uint64_t);
+ // nothing to free
+ break;
+ default:
+ free(current);
+ current += sizeof(void*);
+ }
+ }
+ return 0;
+}
+
+int Table::free_result(uint8_t* result) {
+ for (uint32_t i=0; i < m_result_count; i++) {
+ // look for matching result
+ if (result == m_results[i]) {
+ this->free_row((uint8_t*)m_results[i]);
+ free(m_results[i]);
+ // if we did not free the last result,
+ // move last result to the empty slot
+ if (i != (m_result_count - 1)) {
+ m_results[i] = m_results[m_column_count-1];
+ m_results[m_column_count-1] = NULL;
+ }
+ }
+ }
+ return 0;
+}
+
+
char* Table::create() {
if (!m_create_sql) {
uint32_t i = 0;
@@ -234,7 +298,7 @@
return stmt;
}
-sqlite3_stmt* Table::get_value(sqlite3* db, Column* value_column, uint32_t count, va_list args) {
+sqlite3_stmt* Table::get_column(sqlite3* db, Column* value_column, uint32_t count, va_list args) {
__alloc_stmt_query;
strlcpy(query, "SELECT ", size);
__check_and_cat(value_column->name());
@@ -243,12 +307,25 @@
__check_and_cat(" WHERE 1");
__where_va_columns;
strlcat(query, ";", size);
- IF_DEBUG("[TABLE] get_value query: %s \n", query);
+ IF_DEBUG("[TABLE] get_column query: %s \n", query);
__prepare_stmt;
return stmt;
}
+sqlite3_stmt* Table::get_row(sqlite3* db, uint32_t count, va_list args) {
+ __alloc_stmt_query;
+ strlcpy(query, "SELECT * FROM ", size);
+ __check_and_cat(m_name);
+ __check_and_cat(" WHERE 1");
+ __where_va_columns;
+ strlcat(query, ";", size);
+ IF_DEBUG("[TABLE] get_row query: %s \n", query);
+ __prepare_stmt;
+
+ return stmt;
+}
+
sqlite3_stmt* Table::update_value(sqlite3* db, Column* value_column, uint32_t count, va_list args) {
__alloc_stmt_query;
strlcpy(query, "UPDATE ", size);
Modified: branches/PR-7489777/darwinup/Table.h
===================================================================
--- branches/PR-7489777/darwinup/Table.h 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/Table.h 2010-02-18 21:34:36 UTC (rev 705)
@@ -38,6 +38,7 @@
#include <sqlite3.h>
#include "Column.h"
+
struct Table {
Table();
Table(const char* name);
@@ -47,19 +48,22 @@
const Column** columns();
Column* column(uint32_t index);
uint32_t column_count();
+
+ uint8_t* alloc_result();
+ int free_result(uint8_t* result);
+
int add_column(Column*);
-
+ uint32_t row_size();
+
// return SQL statements for this table
char* create();
- char* drop();
- char* select(const char* where);
- char* select_column(const char* column, const char* where);
+ char* drop(); // XXX: implement this
-
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* get_column(sqlite3* db, Column* value_column, uint32_t count,
+ va_list args);
+ sqlite3_stmt* get_row(sqlite3* db, uint32_t count, va_list args);
sqlite3_stmt* update_value(sqlite3* db, Column* value_column, uint32_t count,
va_list args);
sqlite3_stmt* insert(sqlite3* db);
@@ -69,6 +73,8 @@
protected:
+ int free_row(uint8_t* row);
+
char* m_name;
char* m_create_sql;
@@ -84,6 +90,10 @@
sqlite3_stmt* m_prepared_update;
sqlite3_stmt* m_prepared_delete;
+ uint8_t** m_results;
+ uint32_t m_result_count;
+ uint32_t m_result_max;
+
};
#endif
Modified: branches/PR-7489777/darwinup/main.cpp
===================================================================
--- branches/PR-7489777/darwinup/main.cpp 2010-02-12 05:17:03 UTC (rev 704)
+++ branches/PR-7489777/darwinup/main.cpp 2010-02-18 21:34:36 UTC (rev 705)
@@ -46,6 +46,32 @@
#include <unistd.h>
#include <limits.h>
+void __data_hex(uint8_t* data, uint32_t size) {
+ if (!size) return;
+ for (uint32_t i=0; i < size; i++) {
+ if (!(i%8)) {
+ if (i<10) fprintf(stderr, " ");
+ fprintf(stderr, "%d", i);
+ } else {
+ fprintf(stderr, " ");
+ }
+ }
+ fprintf(stderr, "\n");
+ for (uint32_t i=0; i < size; i++) {
+ fprintf(stderr, "%02x", data[i]);
+ }
+ fprintf(stderr, "\n");
+}
+
+void __str_hex(const char* str) {
+ int i = 0;
+ while (str[i]) {
+ fprintf(stderr, "%02x", str[i++]);
+ }
+ fprintf(stderr, "\n");
+}
+
+
void usage(char* progname) {
fprintf(stderr, "usage: %s [-v] [-p DIR] [command] [args] \n", progname);
fprintf(stderr, "version: 15 \n");
@@ -145,12 +171,72 @@
exit(2);
}
- /*
+
// XXX: test area for new database... remove me
DarwinupDatabase* testdb = depot->get_db2();
+ uuid_t uuid;
+ uuid_parse("5A41995B-CA3F-4BF3-84AC-2F5A42357769", uuid);
+ uint8_t* data;
+ fprintf(stderr, "main: data %p uuid %14s \n", &data, uuid);
+ testdb->get_archive(&data, uuid);
+ fprintf(stderr, "RESULT: %llu \n", (uint64_t)data[0]);
+ free(data);
+ uuid_clear(uuid);
+
+ testdb->get_archive(&data, 42);
+ fprintf(stderr, "DATA: %p \n", data);
+ __data_hex(data, 48);
+ char* p;
+ memcpy(&p, &data[16], 8);
+ uint64_t ss = 0;
+ memcpy(&ss, &data[0], 8);
+ time_t t = 0;
+ memcpy(&t, &data[24], 8);
+
+ fprintf(stderr, "RESULT: %llu \n", ss);
+ fprintf(stderr, "RESULT: %p -> %s \n", p, p);
+ fprintf(stderr, "RESULT: %llu \n", (uint64_t)t);
+
+
+
+ testdb->get_archive(&data, "root2");
+ char ustr[37];
+ uuid_t* up;
+ memcpy(&up, &data[8], sizeof(uuid_t*));
+ uuid_unparse_upper(*up, ustr);
+ fprintf(stderr, "RESULT: %s \n", ustr);
+
+
+
+
+ uint64_t* s;
+ uint64_t a_serial = 3;
+ Archive* a = depot->archive(a_serial);
+ res = testdb->get_file_serial_from_archive(a, "/e/ee/e_data.txt", &s);
+ if (!res) {
+ IF_DEBUG("s = %llu \n", *s);
+ } else {
+ IF_DEBUG("DID NOT FIND SERIAL\n");
+ }
+
+ uint64_t* serials;
+ uint32_t sc;
+ testdb->get_file_serials(&serials, &sc);
+ IF_DEBUG("serials(%p) = %llu sc = %u \n", serials, serials[0], sc);
+ for (uint32_t i=0; i < sc; i++) {
+ fprintf(stderr, "TEST: %d = %llu \n", i, serials[i]);
+ }
+
+ testdb->get_inactive_archive_serials(&serials, &sc);
+ IF_DEBUG("serials(%p) = %llu sc = %u \n", serials, serials[0], sc);
+ for (uint32_t i=0; i < sc; i++) {
+ fprintf(stderr, "INACTIVE: %d = %llu \n", i, serials[i]);
+ }
+
+ /*
Archive* a = new Archive("/.DarwinDepot/Archives/21BDC360-726B-436E-B426-B06B57F8A0CC.tar.bz2");
- //uint64_t s = testdb->insert_archive(a->uuid(), a->info(), a->name(), a->date_installed());
+ uint64_t s = testdb->insert_archive(a->uuid(), a->info(), a->name(), a->date_installed());
const char* mypath = "/etc/services";
File* f = FileFactory(mypath);
@@ -167,10 +253,10 @@
if (depot->has_file(a, f)) {
fprintf(stderr, "HASFILE: true\n");
}
+ */
exit(0);
// XXX
- */
if (argc == 2 && strcmp(argv[0], "install") == 0) {
char uuid[37];
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100218/f204d2d5/attachment-0001.html>
More information about the darwinbuild-changes
mailing list