[27524] trunk/base/src/cregistry

source_changes at macosforge.org source_changes at macosforge.org
Mon Aug 6 13:12:54 PDT 2007


Revision: 27524
          http://trac.macosforge.org/projects/macports/changeset/27524
Author:   sfiera at macports.org
Date:     2007-08-06 13:12:54 -0700 (Mon, 06 Aug 2007)

Log Message:
-----------
Wrap map/unmap in transaction; fix de-uniquing of file map

Modified Paths:
--------------
    trunk/base/src/cregistry/entry.c
    trunk/base/src/cregistry/sql.c
    trunk/base/src/cregistry/sql.h

Modified: trunk/base/src/cregistry/entry.c
===================================================================
--- trunk/base/src/cregistry/entry.c	2007-08-06 20:12:49 UTC (rev 27523)
+++ trunk/base/src/cregistry/entry.c	2007-08-06 20:12:54 UTC (rev 27524)
@@ -36,6 +36,7 @@
 
 #include <cregistry/entry.h>
 #include <cregistry/registry.h>
+#include <cregistry/sql.h>
 
 /**
  * Concatenates `src` to string `dst`.
@@ -279,7 +280,7 @@
 }
 
 /*
- * Frees the entries in `entries`.
+ * Frees the given entry
  */
 void reg_entry_free(sqlite3* db UNUSED, reg_entry* entry) {
     sqlite3_stmt* stmt;
@@ -542,34 +543,61 @@
 int reg_entry_map(sqlite3* db, reg_entry* entry, char** files, int file_count,
         reg_error* errPtr) {
     sqlite3_stmt* stmt;
-    char* query = "INSERT INTO registry.files (id, path) VALUES (?, ?)";
-    if ((sqlite3_prepare(db, query, -1, &stmt, NULL) == SQLITE_OK)
-            && (sqlite3_bind_int64(stmt, 1, entry->id) == SQLITE_OK)) {
+    sqlite3_stmt* stmt2 = NULL;
+    char* insert = "INSERT INTO registry.files (id, path) VALUES (?, ?)";
+    char* select = "SELECT registry.ports.name FROM registry.files "
+        "INNER JOIN registry.ports USING(id) WHERE registry.files.path=?";
+    begin_exclusive(db);
+    if ((sqlite3_prepare(db, insert, -1, &stmt, NULL) == SQLITE_OK)
+            && (sqlite3_bind_int64(stmt, 1, entry->id) == SQLITE_OK)
+            && (sqlite3_prepare(db, select, -1, &stmt2, NULL) == SQLITE_OK)) {
         int i;
         for (i=0; i<file_count; i++) {
+            if ((sqlite3_bind_text(stmt2, 1, files[i], -1, SQLITE_STATIC)
+                    == SQLITE_OK)
+                    && (sqlite3_step(stmt2) == SQLITE_ROW)) {
+                char* port = sqlite3_column_text(stmt2, 0);
+                errPtr->code = "registry::already-owned";
+                errPtr->description = sqlite3_mprintf("file at path \"%s\" is "
+                        "already owned by port %s", files[i], port);
+                errPtr->free = sqlite3_free;
+                sqlite3_finalize(stmt);
+                sqlite3_finalize(stmt2);
+                rollback_transaction(db);
+                return -1;
+            }
             if (sqlite3_bind_text(stmt, 2, files[i], -1, SQLITE_STATIC)
                     == SQLITE_OK) {
                 int r = sqlite3_step(stmt);
                 switch (r) {
                     case SQLITE_DONE:
                         sqlite3_reset(stmt);
+                        sqlite3_reset(stmt2);
                         continue;
                     default:
-                        reg_sqlite_error(db, errPtr, query);
+                        reg_sqlite_error(db, errPtr, insert);
                         sqlite3_finalize(stmt);
+                        sqlite3_finalize(stmt2);
+                        rollback_transaction(db);
                         return i;
                 }
             } else {
-                reg_sqlite_error(db, errPtr, query);
+                reg_sqlite_error(db, errPtr, insert);
                 sqlite3_finalize(stmt);
+                sqlite3_finalize(stmt2);
+                rollback_transaction(db);
                 return i;
             }
         }
         sqlite3_finalize(stmt);
+        sqlite3_finalize(stmt2);
+        commit_transaction(db);
         return file_count;
     } else {
-        reg_sqlite_error(db, errPtr, query);
+        reg_sqlite_error(db, errPtr, insert);
         sqlite3_finalize(stmt);
+        sqlite3_finalize(stmt2);
+        commit_transaction(db);
         return 0;
     }
 }
@@ -578,6 +606,7 @@
         reg_error* errPtr) {
     sqlite3_stmt* stmt;
     char* query = "DELETE FROM registry.files WHERE id=? AND path=?";
+    begin_exclusive(db);
     if ((sqlite3_prepare(db, query, -1, &stmt, NULL) == SQLITE_OK)
             && (sqlite3_bind_int64(stmt, 1, entry->id) == SQLITE_OK)) {
         int i;
@@ -593,6 +622,7 @@
                                 "given file";
                             errPtr->free = NULL;
                             sqlite3_finalize(stmt);
+                            rollback_transaction(db);
                             return i;
                         } else {
                             sqlite3_reset(stmt);
@@ -601,19 +631,23 @@
                     default:
                         reg_sqlite_error(db, errPtr, query);
                         sqlite3_finalize(stmt);
+                        rollback_transaction(db);
                         return i;
                 }
             } else {
                 reg_sqlite_error(db, errPtr, query);
                 sqlite3_finalize(stmt);
+                rollback_transaction(db);
                 return i;
             }
         }
         sqlite3_finalize(stmt);
+        commit_transaction(db);
         return file_count;
     } else {
         reg_sqlite_error(db, errPtr, query);
         sqlite3_finalize(stmt);
+        commit_transaction(db);
         return 0;
     }
 }

Modified: trunk/base/src/cregistry/sql.c
===================================================================
--- trunk/base/src/cregistry/sql.c	2007-08-06 20:12:49 UTC (rev 27523)
+++ trunk/base/src/cregistry/sql.c	2007-08-06 20:12:54 UTC (rev 27524)
@@ -61,6 +61,47 @@
 }
 
 /**
+ * Acquires an exclusive lock on the database.
+ */
+void begin_exclusive(sqlite3* db) {
+    int status;
+    do {
+        status = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
+    } while (status != SQLITE_OK);
+}
+
+/**
+ * Acquires a shared lock on the database.
+ */
+void begin_shared(sqlite3* db) {
+    int status;
+    do {
+        status = sqlite3_exec(db, "BEGIN", NULL, NULL, NULL);
+    } while (status != SQLITE_OK);
+}
+
+/**
+ * Releases a shared or exclusive lock on the database and rolls back changes
+ */
+void rollback_transaction(sqlite3* db) {
+    int status;
+    char* err;
+    do {
+        status = sqlite3_exec(db, "ROLLBACK", NULL, NULL, &err);
+    } while (status != SQLITE_OK);
+}
+
+/**
+ * Releases a shared or exclusive lock on the database and commits changes
+ */
+void commit_transaction(sqlite3* db) {
+    int status;
+    do {
+        status = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
+    } while (status != SQLITE_OK);
+}
+
+/**
  * REGEXP function for sqlite3.
  *
  * Takes two arguments; the first is the value and the second the pattern. If

Modified: trunk/base/src/cregistry/sql.h
===================================================================
--- trunk/base/src/cregistry/sql.h	2007-08-06 20:12:49 UTC (rev 27523)
+++ trunk/base/src/cregistry/sql.h	2007-08-06 20:12:54 UTC (rev 27524)
@@ -36,6 +36,11 @@
 
 #include <cregistry/registry.h>
 
+void begin_exclusive(sqlite3* db);
+void begin_shared(sqlite3* db);
+void rollback_transaction(sqlite3* db);
+void commit_transaction(sqlite3* db);
+
 int create_tables(sqlite3* db, reg_error* errPtr);
 int init_db(sqlite3* db, reg_error* errPtr);
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070806/4e4fbf9d/attachment.html


More information about the macports-changes mailing list