     
     - parameter block: A block that accesses the databse.
     */
-    public func inDatabase(block: (db: Database) -> Void) {
+    public func inDatabase<R>(block: (db: Database) throws -> R) rethrows -> R {
         guard databaseQueueID != dispatch_get_specific(DatabaseQueue.databaseQueueIDKey) else {
             fatalError("DatabaseQueue.inDatabase(_:) was called reentrantly on the same queue, which would lead to a deadlock.")
         }
         
-        dispatch_sync(queue) { () -> Void in
-            block(db: self.database)
-        }
-    }
-    
-    /**
-    Executes a non-throwing block in the database queue, and returns its result.
-    
-        let rows = dbQueue.inDatabase { db in
-            db.fetch(...)
-        }
-    
-    This method is not reentrant.
-    
-    - parameter block: A block that accesses the databse and returns some result.
-    */
-    public func inDatabase<Result>(block: (db: Database) -> Result) -> Result {
-        guard databaseQueueID != dispatch_get_specific(DatabaseQueue.databaseQueueIDKey) else {
-            fatalError("DatabaseQueue.inDatabase(_:) was called reentrantly on the same queue, which would lead to a deadlock.")
-        }
-        
-        var result: Result? = nil
-        dispatch_sync(queue) { () -> Void in
-            result = block(db: self.database)
-        }
-        return result!
-    }
-    
+        return try DatabaseQueue.performSync(queue) { () -> R in
+            return try block(db: self.database)
+        }
+    }
     
     /**
     Executes a block in the database queue, wrapped inside a transaction.

            fatalError("DatabaseQueue.inTransaction(_:) was called reentrantly on the same queue, which would lead to a deadlock.")
        }
        
        var dbError: ErrorType?
        let database = self.database
        dispatch_sync(queue) { () -> Void in
            do {
                try database.inTransaction(type) { () in
                    return try block(db: database)
                }
            } catch {
                dbError = error
            }
        }
        if let dbError = dbError {
            throw dbError
        }
    }
    

        dispatch_queue_set_specific(queue, DatabaseQueue.databaseQueueIDKey, databaseQueueID, nil)
    }
    
    // A function declared as rethrows that synchronously executes a throwing
    // block in a dispatch_queue.
    static func performSync<R>(queue: dispatch_queue_t, block: () throws -> R) rethrows -> R {
        func rethrow(myerror:ErrorType) throws ->()
        {
            throw myerror
        }
        func perform_sync_impl(queue: dispatch_queue_t, block: () throws -> R, block2:((myerror:ErrorType) throws -> ()) ) rethrows -> R {
            var result: R? = nil
            var blockError: ErrorType? = nil
            dispatch_sync(queue) {
                do {
                    result = try block()
                } catch {
                    blockError = error
                }
            }
            if let blockError = blockError {
                try block2(myerror: blockError)
            }
            return result!
        }
        return try perform_sync_impl(queue, block: block, block2: rethrow)
    }

}

typealias DatabaseQueueID = UnsafeMutablePointer<Void>
