[78943] branches/gsoc11-rev-upgrade/base/src/cregistry
cal at macports.org
cal at macports.org
Fri May 27 12:45:32 PDT 2011
Revision: 78943
http://trac.macports.org/changeset/78943
Author: cal at macports.org
Date: 2011-05-27 12:45:32 -0700 (Fri, 27 May 2011)
Log Message:
-----------
rev-upgrade: type file for the cregistry
Modified Paths:
--------------
branches/gsoc11-rev-upgrade/base/src/cregistry/Makefile
Added Paths:
-----------
branches/gsoc11-rev-upgrade/base/src/cregistry/file.c
branches/gsoc11-rev-upgrade/base/src/cregistry/file.h
Modified: branches/gsoc11-rev-upgrade/base/src/cregistry/Makefile
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/Makefile 2011-05-27 19:45:21 UTC (rev 78942)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/Makefile 2011-05-27 19:45:32 UTC (rev 78943)
@@ -1,6 +1,6 @@
# $Id$
-OBJS = registry.o entry.o sql.o vercomp.o util.o
+OBJS = registry.o entry.o sql.o vercomp.o util.o file.o
STLIB_NAME = cregistry.a
RANLIB = ranlib
Added: branches/gsoc11-rev-upgrade/base/src/cregistry/file.c
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/file.c (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/file.c 2011-05-27 19:45:32 UTC (rev 78943)
@@ -0,0 +1,282 @@
+/*
+ * entry.c
+ * $Id: entry.c 78229 2011-04-29 03:15:29Z jmr at macports.org $
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "file.h"
+#include "util.h"
+#include "registry.h"
+#include "sql.h"
+
+#include <sqlite3.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * Converts a `sqlite3_stmt` into a `reg_file`. The first column of the stmt's
+ * row must be the id of a file; the second column must be the path of a file;
+ * the third either `SQLITE_NULL` or the address of the entry in memory.
+ *
+ * @param [in] userdata sqlite3 database
+ * @param [out] file file described by `stmt`
+ * @param [in] stmt `sqlite3_stmt` with appropriate columns
+ * @param [out] errPtr unused
+ * @return true if success; false if failure
+ */
+static int reg_stmt_to_file(void* userdata, void** file, void* stmt,
+ reg_error* errPtr UNUSED) {
+ int is_new;
+ reg_registry* reg = (reg_registry*)userdata;
+ sqlite_int64 id = sqlite3_column_int64(stmt, 0);
+ const unsigned char* path = sqlite3_column_text(stmt, 1);
+
+ /* FIXME: custom hashing */
+ Tcl_HashEntry* hash = Tcl_CreateHashEntry(®->open_entries,
+ (const char*)&id, &is_new);
+ if (is_new) {
+ reg_file* f = malloc(sizeof(reg_file));
+ if (!f) {
+ return 0;
+ }
+ f->reg = reg;
+ f->id = id;
+ f->path = strdup((const char*) path);
+ if (!f->path) {
+ return 0;
+ }
+ f->proc = NULL;
+ *file = f;
+ Tcl_SetHashValue(hash, f);
+ } else {
+ *file = Tcl_GetHashValue(hash);
+ }
+ return 1;
+}
+
+/**
+ * Frees a file. Normally this is unnecessary, as open entries will be
+ * automatically freed when the registry is detached. Calling this method
+ * externally should only be necessary following `reg_entry_delete`.
+ *
+ * @param [in] entry the entry to free
+ */
+void reg_file_free(reg_file* file) {
+ /* FIXME: custom hashing */
+ Tcl_HashEntry* hash = Tcl_FindHashEntry(&file->reg->open_entries,
+ (const char*)&file->id);
+ Tcl_DeleteHashEntry(hash);
+ if (file->proc != NULL) {
+ free(file->proc);
+ }
+ if (file->path) {
+ free(file->path);
+ }
+ free(file);
+}
+
+/**
+ * Type-safe version of `reg_all_objects` for `reg_file`.
+ *
+ * @param [in] reg registry to select entries from
+ * @param [in] query the select query to execute
+ * @param [in] query_len length of the query (or -1 for automatic)
+ * @param [out] objects the files selected
+ * @param [out] errPtr on error, a description of the error that occurred
+ * @return the number of entries if success; negative if failure
+ */
+static int reg_all_files(reg_registry* reg, char* query, int query_len,
+ reg_file*** objects, reg_error* errPtr) {
+ return reg_all_objects(reg, query, query_len, (void***)objects,
+ reg_stmt_to_file, NULL, errPtr);
+}
+
+/**
+ * Searches the registry for files for which each key's value is equal to the
+ * given value. To find all files, pass a key_count of 0.
+ *
+ * Bad keys should cause sqlite3 errors but not permit SQL injection attacks.
+ * Pass it good keys anyway.
+ *
+ * @param [in] reg registry to search in
+ * @param [in] keys a list of keys to search by
+ * @param [in] vals a list of values to search by, matching keys
+ * @param [in] strats a list of strategies to use when searching
+ * @param [in] key_count the number of key/value pairs passed
+ * @param [out] files a list of matching files
+ * @param [out] errPtr on error, a description of the error that occurred
+ * @return the number of entries if success; false if failure
+ */
+int reg_file_search(reg_registry* reg, char** keys, char** vals, int* strats,
+ int key_count, reg_file*** files, reg_error* errPtr) {
+ int i;
+ char* kwd = " WHERE ";
+ char* query;
+ size_t query_len, query_space;
+ int result;
+
+ /* build the query */
+ query = strdup("SELECT id, path FROM registry.ports");
+ if (!query) {
+ return -1;
+ }
+ query_len = query_space = strlen(query);
+
+ for (i = 0; i < key_count; i++) {
+ char* op;
+ char* cond;
+
+ /* get the strategy */
+ if ((op = reg_strategy_op(strats[i], errPtr)) == NULL) {
+ free(query);
+ return -1;
+ }
+
+ cond = sqlite3_mprintf(op, keys[i], vals[i]);
+ if (!cond || !reg_strcat(&query, &query_len, &query_space, kwd)
+ || !reg_strcat(&query, &query_len, &query_space, cond)) {
+ free(query);
+ return -1;
+ }
+ sqlite3_free(cond);
+ kwd = " AND ";
+ }
+
+ /* do the query */
+ result = reg_all_files(reg, query, -1, files, errPtr);
+ free(query);
+ return result;
+}
+
+/**
+ * Gets a named property of a file. That property can be set using
+ * `reg_file_propset`. The property named must be one that exists in the table
+ * and must not be one with internal meaning such as `id`.
+ *
+ * @param [in] file file to get property from
+ * @param [in] key property to get
+ * @param [out] value the value of the property
+ * @param [out] errPtr on error, a description of the error that occurred
+ * @return true if success; false if failure
+ */
+int reg_file_propget(reg_file* file, char* key, char** value,
+ reg_error* errPtr) {
+ reg_registry* reg = file->reg;
+ int result = 0;
+ sqlite3_stmt* stmt = NULL;
+ char* query;
+ const char *text;
+ query = sqlite3_mprintf("SELECT %q FROM registry.file WHERE id=%lld "
+ "AND path='%q'", key, file->id, file->path);
+ if (sqlite3_prepare(reg->db, query, -1, &stmt, NULL) == SQLITE_OK) {
+ int r;
+ do {
+ r = sqlite3_step(stmt);
+ switch (r) {
+ case SQLITE_ROW:
+ text = (const char*)sqlite3_column_text(stmt, 0);
+ if (text) {
+ *value = strdup(text);
+ result = 1;
+ } else {
+ reg_sqlite_error(reg->db, errPtr, query);
+ }
+ break;
+ case SQLITE_DONE:
+ errPtr->code = REG_INVALID;
+ errPtr->description = "an invalid file was passed";
+ errPtr->free = NULL;
+ break;
+ case SQLITE_BUSY:
+ continue;
+ default:
+ reg_sqlite_error(reg->db, errPtr, query);
+ break;
+ }
+ } while (r == SQLITE_BUSY);
+ } else {
+ reg_sqlite_error(reg->db, errPtr, query);
+ }
+ if (stmt) {
+ sqlite3_finalize(stmt);
+ }
+ sqlite3_free(query);
+ return result;
+}
+
+/**
+ * Sets a named property of a file. That property can be later retrieved using
+ * `reg_file_propget`. The property named must be one that exists in the table
+ * and must not be one with internal meaning such as `id`.
+ *
+ * @param [in] file file to set property for
+ * @param [in] key property to set
+ * @param [in] value the desired value of the property
+ * @param [out] errPtr on error, a description of the error that occurred
+ * @return true if success; false if failure
+ */
+int reg_file_propset(reg_file* file, char* key, char* value,
+ reg_error* errPtr) {
+ reg_registry* reg = file->reg;
+ int result = 0;
+ sqlite3_stmt* stmt = NULL;
+ char* query;
+ query = sqlite3_mprintf("UPDATE registry.ports SET %q = '%q' WHERE id=%lld "
+ "AND path='%q'", key, value, file->id, file->path);
+ if (sqlite3_prepare(reg->db, query, -1, &stmt, NULL) == SQLITE_OK) {
+ int r;
+ do {
+ r = sqlite3_step(stmt);
+ switch (r) {
+ case SQLITE_DONE:
+ result = 1;
+ break;
+ case SQLITE_BUSY:
+ continue;
+ default:
+ if (sqlite3_reset(stmt) == SQLITE_CONSTRAINT) {
+ errPtr->code = REG_CONSTRAINT;
+ errPtr->description = "a constraint was disobeyed";
+ errPtr->free = NULL;
+ } else {
+ reg_sqlite_error(reg->db, errPtr, query);
+ }
+ break;
+ }
+ } while (r == SQLITE_BUSY);
+ } else {
+ reg_sqlite_error(reg->db, errPtr, query);
+ }
+ if (stmt) {
+ sqlite3_finalize(stmt);
+ }
+ sqlite3_free(query);
+ return result;
+}
+
Added: branches/gsoc11-rev-upgrade/base/src/cregistry/file.h
===================================================================
--- branches/gsoc11-rev-upgrade/base/src/cregistry/file.h (rev 0)
+++ branches/gsoc11-rev-upgrade/base/src/cregistry/file.h 2011-05-27 19:45:32 UTC (rev 78943)
@@ -0,0 +1,59 @@
+/*
+ * file.h
+ * vim:tw=80:expandtab
+ * $Id$
+ *
+ * Copyright (c) 2007 Chris Pickel <sfiera at macports.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ */
+#ifndef _CFILE_H
+#define _CFILE_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "registry.h"
+
+#include <sqlite3.h>
+
+typedef struct {
+ /* rowid and path form the primary key */
+ /* unfortunately, we don't have a surrogate key in this db */
+ sqlite_int64 id; /* rowid in database */
+ char *path; /* path in database */
+ reg_registry* reg; /* associated registry */
+ char* proc; /* name of Tcl proc, if using Tcl */
+} reg_file;
+
+void reg_file_free(reg_file* file); /* TODO: is this actually being used? */
+
+int reg_file_search(reg_registry* reg, char** keys, char** vals, int* strats,
+ int key_count, reg_file*** files, reg_error* errPtr);
+
+int reg_file_propget(reg_file* file, char* key, char** value,
+ reg_error* errPtr);
+int reg_file_propset(reg_file* file, char* key, char* value,
+ reg_error* errPtr);
+
+#endif /* _CFILE_H */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20110527/9ef26b2f/attachment.html>
More information about the macports-changes
mailing list