[darwinbuild-changes] [708] branches/PR-7489777/darwinup
source_changes at macosforge.org
source_changes at macosforge.org
Fri Feb 19 15:07:41 PST 2010
Revision: 708
http://trac.macosforge.org/projects/darwinbuild/changeset/708
Author: wsiegrist at apple.com
Date: 2010-02-19 15:07:41 -0800 (Fri, 19 Feb 2010)
Log Message:
-----------
Implement ordered row queries, fix double free during Table destructor.
Modified Paths:
--------------
branches/PR-7489777/darwinup/Archive.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/Depot.h
branches/PR-7489777/darwinup/Table.cpp
branches/PR-7489777/darwinup/Table.h
Modified: branches/PR-7489777/darwinup/Archive.h
===================================================================
--- branches/PR-7489777/darwinup/Archive.h 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Archive.h 2010-02-19 23:07:41 UTC (rev 708)
@@ -39,7 +39,14 @@
#include <time.h>
#include <uuid/uuid.h>
+typedef char* archive_name_t;
+enum archive_keyword_t {
+ DEPOT_ARCHIVE_NEWEST,
+ DEPOT_ARCHIVE_OLDEST
+};
+
+
//
// ARCHIVE_INFO flags stored in the database
//
Modified: branches/PR-7489777/darwinup/DB.cpp
===================================================================
--- branches/PR-7489777/darwinup/DB.cpp 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/DB.cpp 2010-02-19 23:07:41 UTC (rev 708)
@@ -185,7 +185,6 @@
int res = SQLITE_OK;
uint64_t* c;
- if (!c) fprintf(stderr, "Error: ran out of memory in DarwinupDatabase::count_files().\n");
res = this->count("count_files",
(void**)&c,
this->m_files_table,
@@ -295,6 +294,26 @@
name);
}
+int DarwinupDatabase::get_archive(uint8_t** data, archive_keyword_t keyword) {
+ int res = SQLITE_OK;
+ int order = ORDER_BY_DESC;
+
+ if (keyword == DEPOT_ARCHIVE_OLDEST) {
+ order = ORDER_BY_ASC;
+ }
+
+ res = this->get_row_ordered("archive__keyword",
+ data,
+ this->m_archives_table,
+ this->m_archives_table->column(3), // order by date_added
+ order,
+ 1,
+ this->m_archives_table->column(2), // name
+ "!<Rollback>");
+
+ return res;
+}
+
int DarwinupDatabase::archive_offset(int column) {
return this->m_archives_table->offset(column);
}
Modified: branches/PR-7489777/darwinup/DB.h
===================================================================
--- branches/PR-7489777/darwinup/DB.h 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/DB.h 2010-02-19 23:07:41 UTC (rev 708)
@@ -44,6 +44,7 @@
#include "File.h"
+
/**
*
* Darwinup database abstraction. This class is responsible
@@ -65,6 +66,7 @@
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_archive(uint8_t** data, archive_keyword_t keyword);
int get_inactive_archive_serials(uint64_t** serials, uint32_t* count);
int archive_offset(int column);
int activate_archive(uint64_t serial);
Modified: branches/PR-7489777/darwinup/Database.cpp
===================================================================
--- branches/PR-7489777/darwinup/Database.cpp 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Database.cpp 2010-02-19 23:07:41 UTC (rev 708)
@@ -32,13 +32,6 @@
#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
*/
@@ -313,16 +306,15 @@
Column* col = va_arg(args, Column*); \
uint8_t* bdata = NULL; \
uint32_t bsize = 0; \
- uint64_t val; \
+ char* tval; \
switch(col->type()) { \
case TYPE_INTEGER: \
- val = va_arg(args, uint64_t); \
- res = sqlite3_bind_int64(stmt, param++, val); \
- fprintf(stderr, "DEBUG: bind int: %llu \n", 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); \
- fprintf(stderr, "DEBUG: bind text \n"); \
+ tval = va_arg(args, char*); \
+ if (tval[0] == '!' || tval[0] == '>' || tval[0] == '<') tval++; \
+ res = sqlite3_bind_text(stmt, param++, tval, -1, SQLITE_STATIC); \
break; \
case TYPE_BLOB: \
bdata = va_arg(args, uint8_t*); \
@@ -331,7 +323,6 @@
bdata, \
bsize, \
SQLITE_STATIC); \
- fprintf(stderr, "DEBUG: bind blob \n"); \
break; \
} \
if (res != SQLITE_OK) { \
@@ -372,7 +363,7 @@
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);
+ IF_DEBUG("[ALLOC] 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);
@@ -382,6 +373,7 @@
blobsize = sqlite3_column_bytes(stmt, column);
IF_DEBUG("blob(%p) size=%d \n", blob, blobsize);
*(void**)output = malloc(blobsize);
+ IF_DEBUG("[ALLOC] blob %p \n", (void*)*output);
if (*output && blobsize) memcpy(*(void**)output, blob, blobsize);
used = sizeof(void*);
IF_DEBUG("store_column used=%u output(%p) = %s \n",
@@ -503,6 +495,23 @@
return res;
}
+int Database::get_row_ordered(const char* name, uint8_t** output, Table* table, Column* order_by,
+ int order, uint32_t count, ...) {
+ __get_stmt(table->get_row_ordered(m_db, order_by, order, 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_ordered output(%p) = %llu \n", *output, **(uint64_t**)output);
+ sqlite3_reset(stmt);
+ cache_release_value(m_statement_cache, &stmt);
+ return res;
+}
+
+
int Database::sql(const char* name, const char* fmt, ...) {
sqlite3_stmt* stmt;
char* key = strdup(name);
Modified: branches/PR-7489777/darwinup/Database.h
===================================================================
--- branches/PR-7489777/darwinup/Database.h 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Database.h 2010-02-19 23:07:41 UTC (rev 708)
@@ -47,6 +47,19 @@
#include "Digest.h"
#include "Archive.h"
+#define ORDER_BY_DESC 0
+#define ORDER_BY_ASC 1
+
+// 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
+
+
+
+
// libcache callbacks
bool cache_key_is_equal(void* key1, void* key2, void* user);
void cache_key_retain(void* key_in, void** key_out, void* user_data);
@@ -96,6 +109,8 @@
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 get_row_ordered(const char* name, uint8_t** output, Table* table, Column* order_by,
+ int order, 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, ...);
Modified: branches/PR-7489777/darwinup/Depot.cpp
===================================================================
--- branches/PR-7489777/darwinup/Depot.cpp 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Depot.cpp 2010-02-19 23:07:41 UTC (rev 708)
@@ -35,7 +35,6 @@
#include "File.h"
#include "SerialSet.h"
#include "Utils.h"
-
#include <assert.h>
#include <copyfile.h>
#include <errno.h>
@@ -47,9 +46,9 @@
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
-
#include <sqlite3.h>
+
Depot::Depot() {
m_prefix = NULL;
m_depot_path = NULL;
@@ -183,28 +182,10 @@
Archive* Depot::archive(archive_keyword_t keyword) {
int res = 0;
Archive* archive = NULL;
- static sqlite3_stmt* stmt = NULL;
- const char* query = NULL;
- if (stmt == NULL && m_db) {
- if (keyword == DEPOT_ARCHIVE_NEWEST) {
- query = "SELECT serial FROM archives WHERE name != '<Rollback>' ORDER BY date_added DESC LIMIT 1";
- } else if (keyword == DEPOT_ARCHIVE_OLDEST) {
- query = "SELECT serial FROM archives WHERE name != '<Rollback>' ORDER BY date_added ASC LIMIT 1";
- } else {
- fprintf(stderr, "Error: unknown archive keyword.\n");
- res = -1;
- }
- if (res == 0) 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) {
- res = sqlite3_step(stmt);
- if (res == SQLITE_ROW) {
- uint64_t serial = sqlite3_column_int64(stmt, 0);
- archive = Depot::archive(serial);
- }
- sqlite3_reset(stmt);
- }
+ uint8_t* data;
+
+ res = this->m_db2->get_archive(&data, keyword);
+ if (res == 0) archive = this->m_db2->make_archive(data);
return archive;
}
Modified: branches/PR-7489777/darwinup/Depot.h
===================================================================
--- branches/PR-7489777/darwinup/Depot.h 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Depot.h 2010-02-19 23:07:41 UTC (rev 708)
@@ -37,20 +37,15 @@
#include <uuid/uuid.h>
#include <sqlite3.h>
#include "DB.h"
+#include "Archive.h"
struct Archive;
struct File;
+struct DarwinupDatabase;
typedef int (*ArchiveIteratorFunc)(Archive* archive, void* context);
typedef int (*FileIteratorFunc)(File* file, void* context);
-typedef char* archive_name_t;
-
-enum archive_keyword_t {
- DEPOT_ARCHIVE_NEWEST,
- DEPOT_ARCHIVE_OLDEST
-};
-
struct Depot {
Depot();
Depot(const char* prefix);
Modified: branches/PR-7489777/darwinup/Table.cpp
===================================================================
--- branches/PR-7489777/darwinup/Table.cpp 2010-02-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Table.cpp 2010-02-19 23:07:41 UTC (rev 708)
@@ -34,10 +34,13 @@
#include <string.h>
#include <stdlib.h>
#include "Table.h"
+#include "Database.h"
+
// how much we grow by when we need more space
#define REALLOC_FACTOR 4
+
// XXX
void __hex_str(const char* s) {
int len = strlen(s);
@@ -56,6 +59,7 @@
m_result_max = 1;
m_result_count = 0;
m_results = (uint8_t**)malloc(sizeof(uint8_t*) * m_result_max);
+ IF_DEBUG("[ALLOC] constructor %p \n", m_results);
m_name = strdup("unnamed_table");
m_create_sql = NULL;
m_insert_sql = NULL;
@@ -74,6 +78,7 @@
m_result_max = 1;
m_result_count = 0;
m_results = (uint8_t**)malloc(sizeof(uint8_t*) * m_result_max);
+ IF_DEBUG("[ALLOC] constructor %p \n", m_results);
m_name = strdup(name);
m_create_sql = NULL;
m_insert_sql = NULL;
@@ -90,10 +95,14 @@
}
free(m_columns);
+
for (uint32_t i=0; i < m_result_count; i++) {
- this->free_row(m_results[i]);
- free(m_results[i]);
+ if (m_results[i]) {
+ IF_DEBUG("[FREE] destructor loop %d %p \n", i, m_results[i]);
+ this->free_result(m_results[i]);
+ }
}
+ IF_DEBUG("[FREE] destructor free %p \n", m_results);
free(m_results);
free(m_name);
@@ -150,6 +159,7 @@
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*) * REALLOC_FACTOR);
+ IF_DEBUG("[ALLOC] realloc m_results %p \n", m_results);
if (!m_results) {
fprintf(stderr, "Error: unable to reallocate memory to add a result row\n");
return NULL;
@@ -158,6 +168,8 @@
}
m_result_count++;
m_results[m_result_count-1] = (uint8_t*)calloc(1, this->row_size());
+ IF_DEBUG("[ALLOC] calloc(%d) %d %p \n", this->row_size(), m_result_count-1,
+ m_results[m_result_count-1]);
return m_results[m_result_count-1];
}
@@ -172,6 +184,7 @@
break;
default:
memcpy(&ptr, current, sizeof(void*));
+ IF_DEBUG("[FREE] %s: %p (type of %d: %d) \n", m_name, ptr, i, m_columns[i]->type());
free(ptr);
current += sizeof(void*);
}
@@ -184,7 +197,9 @@
// look for matching result
if (result == m_results[i]) {
this->free_row((uint8_t*)m_results[i]);
+ IF_DEBUG("[FREE] %s result %d %p \n", m_name, i, m_results[i]);
free(m_results[i]);
+ m_results[i] = NULL;
// if we did not free the last result,
// move last result to the empty slot
if (i != (m_result_count - 1)) {
@@ -259,11 +274,30 @@
#define __where_va_columns \
char tmpstr[256]; \
+ char* val; \
+ const char* op = "="; \
int len; \
for (uint32_t i=0; i < count; i++) { \
+ fprintf(stderr, "DEBUG: __where_va i=%u \n", i); \
Column* col = va_arg(args, Column*); \
- va_arg(args, void*); \
- len = snprintf(tmpstr, 256, " AND %s=?", col->name()); \
+ fprintf(stderr, "DEBUG: __where_va col %p \n", col); \
+ if (col->type() == SQLITE_TEXT) { \
+ val = va_arg(args, char*); \
+ switch (val[0]) { \
+ case '!': \
+ op = "!="; \
+ break; \
+ case '>': \
+ op = ">"; \
+ break; \
+ case '<': \
+ op = "<"; \
+ break; \
+ } \
+ } else { \
+ va_arg(args, void*); \
+ } \
+ len = snprintf(tmpstr, 256, " AND %s%s?", col->name(), op); \
if (len >= 255) { \
fprintf(stderr, "Error: column name is too big (limit: 248): %s\n", col->name()); \
return NULL; \
@@ -336,6 +370,24 @@
return stmt;
}
+sqlite3_stmt* Table::get_row_ordered(sqlite3* db, Column* order_by, int order,
+ 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;
+ __check_and_cat(" ORDER BY ");
+ __check_and_cat(order_by->name());
+ __check_and_cat((order == ORDER_BY_DESC ? " DESC" : " ASC"));
+ strlcat(query, ";", size);
+ IF_DEBUG("[TABLE] get_row_ordered 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-19 00:40:07 UTC (rev 707)
+++ branches/PR-7489777/darwinup/Table.h 2010-02-19 23:07:41 UTC (rev 708)
@@ -33,11 +33,11 @@
#ifndef _TABLE_H
#define _TABLE_H
-
#include <stdint.h>
#include <sqlite3.h>
#include "Column.h"
+
struct Table {
Table();
Table(const char* name);
@@ -63,6 +63,8 @@
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* get_row_ordered(sqlite3* db, Column* order_by, int order,
+ 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);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/darwinbuild-changes/attachments/20100219/d2ec0ec4/attachment-0001.html>
More information about the darwinbuild-changes
mailing list