[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(&reg->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