Index: /Dev/trunk/src/server/config/config-couchdb.js
===================================================================
--- /Dev/trunk/src/server/config/config-couchdb.js	(revision 455)
+++ /Dev/trunk/src/server/config/config-couchdb.js	(revision 455)
@@ -0,0 +1,110 @@
+var q = require('q');
+var http = require('q-io/http');
+var fs = require('q-io/fs');
+var _ = require('underscore');
+
+var dbURL = "http://localhost:5984/";
+var designDocs = require('./couchdb-design-docs');
+
+function stringifyFunctions(value) {
+    if ( value === null ) {
+        return null;
+    } else if ( _.isArray(value) ) {
+        return value;
+    } else if ( _.isFunction(value) ) {
+        return value.toString();
+    } else if ( _.isObject(value) ) {
+        value = _.clone(value);
+        _.each(value, function(propValue, propName){
+            value[propName] = stringifyFunctions(propValue);
+        });
+        return value;
+    } else {
+        return value;
+    }
+}
+
+function request(method,path,content) {
+    var url = dbURL+path;
+    return http.request({
+        url: url,
+        method: method,
+        headers: {
+            'content-type': 'application/json; charset=utf-8',
+            'accept': 'application/json'
+        },
+        body: {
+            forEach: function(callback) {
+                callback(JSON.stringify(content || {}));
+            }
+        }
+    }).then(function(res){
+        return res.body.read().then(function(content){
+            return JSON.parse(content);
+        });
+    },function(res){
+        return res.body.read().then(function(error){
+            return JSON.parse(error);
+        });
+    });
+}
+
+console.log("Configuring CouchDB for QED");
+console.log("Checking CouchDB version");
+request('GET','')
+.then(function(res){
+    if (res.version !== "1.2.0" ) {
+        console.log("Found "+res.version+", only tested with CouchDB 1.2.0");
+    } else {
+        console.log("CouchDB 1.2.0 found");
+    }
+    console.log("Checking database 'qed'");
+}).then(function(res){
+    return request('GET','qed')
+    .then(function(res){
+        if (res.error) {
+            console.log("Creating database 'qed'");
+            return request('PUT','qed');
+        } else {
+            console.log("Database 'qed' found.");
+            return null;
+        }
+    },function(err){
+        console.log("Creating database 'qed'");
+        return request('PUT','qed');
+    });
+}).then(function(){
+    console.log("Putting documents in database.");
+    designDocs = stringifyFunctions(designDocs);
+    return q.all(_.map(designDocs, function(doc,docUrl){
+        var configAction = doc.__configAction;
+        delete doc.__configAction;
+        switch (configAction) {
+            case "ignore":
+                console.log(docUrl+" ignored.");
+            case "update":
+                console.log(docUrl+" updating.");
+                return request('GET',docUrl)
+                .then(function(oldDoc){
+                    _.extend(oldDoc,doc);
+                    return request('PUT',docUrl,oldDoc);
+                },function(){
+                    return request('PUT',docUrl,doc);
+                });
+            case "replace":
+            default:
+                console.log(docUrl+" replacing.");
+                return request('GET',docUrl)
+                .then(function(oldDoc){
+                    _.extend(oldDoc,_.pick(oldDoc,'_rev'));
+                    return request('PUT',docUrl,doc);
+                },function(){
+                    return request('PUT',docUrl,doc);
+                });
+        }
+    }));
+}).then(function(){
+    console.log("Done!");
+},function(err){
+    console.error("ERROR",err);
+});
Index: /Dev/trunk/src/server/config/couchdb-design-docs.js
===================================================================
--- /Dev/trunk/src/server/config/couchdb-design-docs.js	(revision 455)
+++ /Dev/trunk/src/server/config/couchdb-design-docs.js	(revision 455)
@@ -0,0 +1,115 @@
+module.exports = {
+    "_users/qed_admin": {
+        __configAction: "ignore",
+        _id: "org.couchdb.user:qed_admin",
+        name: "qed_admin",
+        password: "Welkom01",
+        roles: [ "qed_admin" ],
+        type: "user"
+    },
+    "qed/_security": {
+        __configAction: "ignore",
+        admins: {
+            names: [],
+            roles: ["qed_admin"]
+        },
+        readers: {
+            names: [],
+            roles: ["qed_user"]
+        }
+    },
+    "qed/_design/default": {
+        __configAction: "replace",
+        _id: "_design/default",
+        language: "javascript",
+        validate_doc_update: function(newDoc, oldDoc, userCtx, secObj) {
+            if ( oldDoc && oldDoc.publicationDate ) { throw({forbidden:'Published documents cannot be modified.'}); }
+        },
+        views: {
+            by_type: {
+                map: function(doc){
+                    emit(doc.type, doc);
+                }
+            }
+        }
+    },
+    "qed/_design/questions": {
+        __configAction: "replace",
+        _id: "_design/questions",
+        language: "javascript",
+        views: {
+            all: {
+                map: function(doc){
+                    if ( doc.type !== 'Question' ) { return; }
+                    if ( doc.categories && doc.categories.length > 0 ) {
+                        for ( var i = 0; i < doc.categories.length; i++ ) { 
+                            emit([doc.categories[i],doc.topic||null],1);
+                        } 
+                    } else { 
+                        emit([null,null],1); 
+                    } 
+                },
+                reduce: function(keys,values){ return sum(values); }
+            },
+            published: {
+                map: function(doc){
+                    if ( doc.type!=='Question' || !doc.publicationDate ) { return; }
+                    if ( doc.categories && doc.categories.length > 0 ) {
+                        for ( var i = 0; i < doc.categories.length; i++ ) {
+                            emit([doc.categories[i],doc.topic||null],1);
+                        }
+                    } else {
+                        emit([null,null],1);
+                    }
+                },
+                reduce: function(keys,values){ return sum(values); }
+            },
+            all_topics: {
+                map: function(doc){
+                    if( doc.type !== 'Question' ){ return; }
+                    emit(doc.topic);
+                },
+                reduce: function(key, values, rereduce) { return null; }
+            },
+            published_topics: {
+                map: function(doc){
+                    if ( doc.type !== 'Question' || !doc.publicationDate ) { return; }
+                    emit(doc.topic);
+                },
+                reduce: function(key, values, rereduce) { return null; }
+            }
+        }
+    },
+    "qed/_design/surveys": {
+        __configAction: "replace",
+        _id: "_design/surveys",
+        language: "javascript",
+        views: {
+            drafts: {
+                map: function(doc){
+                    if ( doc.type !== 'Survey' || doc.publicationDate ) { return; }
+                    emit(doc._id,doc);
+                }
+            },
+            published: {
+                map: function(doc){
+                    if ( doc.type !== 'Survey' || !doc.publicationDate ) { return; }
+                    emit(doc._id,doc);
+                }
+            }
+        }
+    },
+    "qed/_design/responses": {
+        __configAction: "replace",
+        _id: "_design/responses",
+        language: "javascript",
+        views: {
+            by_surveyrun: {
+                map: function(doc){
+                    if ( doc.type !== 'Response' ) { return; }
+                    emit(doc.surveyRunId, doc);
+                }
+            }
+        }
+    }
+};
