Changeset 508 for Dev/trunk/src/server
- Timestamp:
- 03/12/14 02:23:11 (11 years ago)
- Location:
- Dev/trunk/src/server
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Dev/trunk/src/server/app.js
r507 r508 154 154 } 155 155 function areDocsPublished(docs) { 156 return _.every(docs, isDocPublished);156 return _.every(docs, isDocPublished); 157 157 } 158 158 function isDocPublished(doc) { … … 592 592 if ( !areDocsUnique(doc.questions) ) { 593 593 hr = new HTTPResult(400,{error:"Survey contains duplicate questions."}); 594 } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) {594 } else if ( isDocPublished(doc) && !areDocsPublished(doc.questions) ) { 595 595 hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."}); 596 596 } else { … … 610 610 var doc = req.body; 611 611 var rev = etags.parse(req.header('If-Match'))[0] || (doc && doc._rev); 612 var hr;613 612 if ( !areDocsUnique(doc.questions) ) { 614 613 new HTTPResult(400,{error:"Survey contains duplicate questions."}) 615 614 .handle(res.send.bind(res)); 616 } else if ( !areDocsPublished(doc.questions) || isDocPublished(doc) ) { 617 hr = new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."}); 615 } else if ( isDocPublished(doc) && !areDocsPublished(doc.questions) ) { 616 new HTTPResult(400,{error:"Cannot publish Survey with unpublished questions."}) 617 .handle(res.send.bind(res)); 618 618 } else { 619 619 putDocument(id,rev,'Survey',doc) … … 718 718 .handle({ 719 719 200: function(responses) { 720 var flatResponses = responsesToVariables(responses); 720 var answers = _.map(responses,function(response){ 721 return response.answers; 722 }); 721 723 res.set({ 722 724 'Content-Disposition': 'attachment; filename=surveyRun-'+id+'-responses.csv' 723 725 }); 724 726 res.status(200); 725 writeObjectsToCSVStream( flatResponses, res);727 writeObjectsToCSVStream(answers, res); 726 728 res.end(); 727 729 }, … … 953 955 } 954 956 955 function responsesToVariables(responses) {956 return _.map(responses, responseToVariables);957 }958 959 function responseToVariables(response) {960 var result = flattenObject(response.answers);961 return result;962 }963 964 function flattenObject(value) {965 var result = {};966 (function agg(val,key,res){967 if ( _.isObject(val) ) {968 var keys = _.keys(val);969 // FIXME : dirty hack for questions with only one input970 if ( keys.length === 1 ) {971 agg(val[keys[0]],key,res);972 } else {973 _.forEach(val, function(v,k){974 agg(v,(key ? key+'.' : '')+k,res);975 });976 }977 } else if ( _.isArray(val) ) {978 // FIXME : dirty hack for questions with only one input979 if ( val.length === 1 ) {980 agg(val[0],key,res);981 } else {982 _.forEach(val, function(v,i){983 agg(v,(key ? key+'.' : '')+i,res);984 });985 }986 } else {987 res[key] = val;988 }989 })(value,null,result);990 return result;991 }992 993 957 function writeObjectsToCSVStream(objects, stream, prelude) { 994 958 var keys = _.chain(objects) -
Dev/trunk/src/server/config/couchdb-design-docs.js
r506 r508 11 11 12 12 "qed/schemaInfo": { 13 version: " 3"13 version: "4" 14 14 }, 15 15 -
Dev/trunk/src/server/config/couchdb-schema.json
r506 r508 2 2 "$schema": "http://json-schema.org/draft-04/schema#", 3 3 "title": "QED Object Schema", 4 "version": " 3",4 "version": "4", 5 5 "type": "object", 6 6 "oneOf": [ … … 10 10 "definitions": { 11 11 "nonEmptyString": { "type": "string", "minLength": 1 }, 12 "codeString": { "type": "string", "pattern": "^[A-Za-z0-9]+$" }, 12 13 "schemaInfo": { 13 14 "type": "object", … … 37 38 "_rev": { "$ref": "#/definitions/nonEmptyString" }, 38 39 "categories": { "type": "array", "items": { "$ref": "#/definitions/nonEmptyString" } }, 39 "code": { "$ref": "#/definitions/ nonEmptyString" },40 "code": { "$ref": "#/definitions/codeString" }, 40 41 "content": { "type": "array", "items": { "$ref": "#/definitions/content/any" } }, 41 42 "description": { "$ref": "#/definitions/nonEmptyString" }, … … 86 87 "_id": { "$ref": "#/definitions/nonEmptyString" }, 87 88 "_rev": { "$ref": "#/definitions/nonEmptyString" }, 88 "answers": { "type": "object" }, 89 "answers": { 90 "type": "object", 91 "patternProperties": { 92 "^[A-Za-z0-9]+$": {} 93 }, 94 "additionalProperties": false 95 }, 89 96 "email": { "type": "string", "format": "email" }, 90 97 "publicationDate": { "type": "string", "format": "datetime" }, … … 139 146 "properties": { 140 147 "type": { "type": "string", "pattern": "^StringInput$" }, 141 "subcode": { "$ref": "#/definitions/ nonEmptyString" },148 "subcode": { "$ref": "#/definitions/codeString" }, 142 149 "text": { "$ref": "#/definitions/nonEmptyString" } 143 150 }, … … 150 157 "type": { "type": "string", "pattern": "^TextInput$" }, 151 158 "maxLength": { "type": "integer" }, 152 "subcode": { "$ref": "#/definitions/ nonEmptyString" },159 "subcode": { "$ref": "#/definitions/codeString" }, 153 160 "text": { "$ref": "#/definitions/nonEmptyString" } 154 161 }, … … 163 170 "max": { "type": "integer" }, 164 171 "places": { "type": "integer" }, 165 "subcode": { "$ref": "#/definitions/ nonEmptyString" },172 "subcode": { "$ref": "#/definitions/codeString" }, 166 173 "text": { "$ref": "#/definitions/nonEmptyString" } 167 174 }, … … 183 190 "minLabel": { "$ref": "#/definitions/nonEmptyString" }, 184 191 "maxLabel": { "$ref": "#/definitions/nonEmptyString" }, 185 "subcode": { "$ref": "#/definitions/ nonEmptyString" },192 "subcode": { "$ref": "#/definitions/codeString" }, 186 193 "text": { "$ref": "#/definitions/nonEmptyString" } 187 194 }, … … 201 208 "type": "object", 202 209 "properties": { 203 "subcode": { "$ref": "#/definitions/ nonEmptyString" },210 "subcode": { "$ref": "#/definitions/codeString" }, 204 211 "text": { "$ref": "#/definitions/nonEmptyString" } 205 212 }, … … 210 217 "type": "object", 211 218 "properties": { 212 "subcode": { "$ref": "#/definitions/ nonEmptyString" },219 "subcode": { "$ref": "#/definitions/codeString" }, 213 220 "text": { "$ref": "#/definitions/nonEmptyString" } 214 221 },
Note: See TracChangeset
for help on using the changeset viewer.