1 // Written in D programming language 2 /** 3 * Part of asynchronous pool realization. 4 * 5 * Copyright: © 2014 DSoftOut 6 * License: Subject to the terms of the MIT license, as written in the included LICENSE file. 7 * Authors: NCrashed <ncrashed@gmail.com> 8 */ 9 module pgator.db.async.respond; 10 11 import pgator.db.connection; 12 import pgator.db.pq.api; 13 import vibe.data.bson; 14 import std.container; 15 import std.range; 16 import derelict.pq.pq; 17 18 /// Worker returns this as query result 19 struct Respond 20 { 21 /// Constructing from error 22 /** 23 * The constructor is used when pool detects problem 24 * at its own level. $(B collect) method handles other 25 * cases. 26 */ 27 this(QueryException e, shared IConnection conn) 28 { 29 scope(exit) conn.clearRaisedMsgs; 30 31 failed = true; 32 exception = e.msg; 33 msgs = conn.raisedMsgs.array.idup; 34 } 35 36 /** 37 * Transforms raw result from data base into BSON format. Also handles 38 * errors that was raised in the connection. 39 */ 40 bool collect(InputRange!(shared IPGresult) results, shared IConnection conn, bool oneRowConstraint, size_t queryId) 41 { 42 scope(exit) conn.clearRaisedMsgs; 43 msgs ~= conn.raisedMsgs.array.idup; 44 45 bool localSucc = true; 46 foreach(res; results) 47 { 48 if( res.resultStatus != ExecStatusType.PGRES_TUPLES_OK && 49 res.resultStatus != ExecStatusType.PGRES_COMMAND_OK) 50 { 51 failed = true; 52 exception = res.resultErrorMessage; 53 localSucc = false; 54 } 55 if(localSucc) 56 { 57 auto temp = res.asColumnBson(conn); 58 if(oneRowConstraint && !isOneRow(temp)) 59 { 60 failed = true; 61 onRowConstaintFailed = true; 62 constraintFailQueryId = queryId; 63 localSucc = false; 64 } else 65 { 66 result ~= temp; 67 } 68 } 69 res.clear(); 70 } 71 return localSucc; 72 } 73 74 private bool isOneRow(Bson res) 75 { 76 Bson[string] columns; 77 try 78 { 79 columns = res.get!(Bson[string]); 80 } 81 catch(Exception e) 82 { 83 // something wrong with columns 84 return false; 85 } 86 87 foreach(col; columns) return col.length == 1; 88 return false; 89 } 90 91 /// Flag to distinct error case from normal respond 92 bool failed = false; 93 94 bool onRowConstaintFailed = false; 95 size_t constraintFailQueryId; 96 97 /// Error stored in string 98 string exception; 99 /// Collected result 100 immutable(Bson)[] result; 101 /// Additional messages 102 immutable(string)[] msgs; 103 }