1 module dpq2.args; 2 3 @safe: 4 5 public import dpq2.conv.from_d_types; 6 public import dpq2.conv.from_bson; 7 8 import dpq2.value; 9 import dpq2.oids: Oid; 10 import std.conv: to; 11 import std.string: toStringz; 12 13 /// Query parameters 14 struct QueryParams 15 { 16 string sqlCommand; /// SQL command 17 ValueFormat resultFormat = ValueFormat.BINARY; /// Result value format 18 private Value[] _args; // SQL command arguments 19 20 /// SQL command arguments 21 @property void args(Value[] vargs) 22 { 23 _args = vargs; 24 } 25 26 /// ditto 27 @property ref inout (Value[]) args() inout pure 28 { 29 return _args; 30 } 31 32 /// Useful for simple text-only query params 33 /// Postgres infers a data type for the parameter in the same way it would do for an untyped literal string. 34 @property void argsFromArray(in string[] arr) 35 { 36 _args.length = arr.length; 37 38 foreach(i, ref a; _args) 39 a = toValue(arr[i], ValueFormat.TEXT); 40 } 41 42 @property string preparedStatementName() const { return sqlCommand; } 43 @property void preparedStatementName(string s){ sqlCommand = s; } 44 } 45 46 /// Used as parameters by PQexecParams-like functions 47 package struct InternalQueryParams 48 { 49 private 50 { 51 const(string)* sqlCommand; 52 Oid[] oids; 53 int[] formats; 54 int[] lengths; 55 const(ubyte)*[] values; 56 } 57 58 ValueFormat resultFormat; 59 60 this(in QueryParams* qp) pure 61 { 62 sqlCommand = &qp.sqlCommand; 63 resultFormat = qp.resultFormat; 64 65 oids = new Oid[qp.args.length]; 66 formats = new int[qp.args.length]; 67 lengths = new int[qp.args.length]; 68 values = new const(ubyte)* [qp.args.length]; 69 70 for(int i = 0; i < qp.args.length; ++i) 71 { 72 oids[i] = qp.args[i].oidType; 73 formats[i] = qp.args[i].format; 74 75 if(!qp.args[i].isNull) 76 { 77 lengths[i] = qp.args[i].data.length.to!int; 78 79 immutable ubyte[] zeroLengthArg = [123]; // fake value, isn't used as argument 80 81 if(qp.args[i].data.length == 0) 82 values[i] = &zeroLengthArg[0]; 83 else 84 values[i] = &qp.args[i].data[0]; 85 } 86 } 87 } 88 89 /// Values used by PQexecParams-like functions 90 const(char)* command() pure const 91 { 92 return cast(const(char)*) (*sqlCommand).toStringz; 93 } 94 95 /// ditto 96 const(char)* stmtName() pure const 97 { 98 return command(); 99 } 100 101 /// ditto 102 int nParams() pure const 103 { 104 return values.length.to!int; 105 } 106 107 /// ditto 108 const(Oid)* paramTypes() pure 109 { 110 if(oids.length == 0) 111 return null; 112 else 113 return &oids[0]; 114 } 115 116 /// ditto 117 const(ubyte*)* paramValues() pure 118 { 119 if(values.length == 0) 120 return null; 121 else 122 return &values[0]; 123 } 124 125 /// ditto 126 const(int)* paramLengths() pure 127 { 128 if(lengths.length == 0) 129 return null; 130 else 131 return &lengths[0]; 132 } 133 134 /// ditto 135 const(int)* paramFormats() pure 136 { 137 if(formats.length == 0) 138 return null; 139 else 140 return &formats[0]; 141 } 142 }