1 /*
2  * Copyright (C) 2019, HuntLabs
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 module hunt.database.driver.postgresql.impl.codec.PgParamDesc;
18 
19 import hunt.database.driver.postgresql.impl.codec.DataType;
20 import hunt.database.driver.postgresql.impl.codec.DataTypeCodec;
21 import hunt.database.driver.postgresql.impl.codec.DataTypeDesc;
22 
23 import hunt.database.base.impl.ParamDesc;
24 import hunt.database.base.Util;
25 
26 import hunt.collection.List;
27 import hunt.Exceptions;
28 import hunt.logging;
29 
30 import std.array;
31 import std.algorithm;
32 import std.conv;
33 import std.variant;
34 
35 
36 /**
37  * @author <a href="mailto:emad.albloushi@gmail.com">Emad Alblueshi</a>
38  */
39 class PgParamDesc : ParamDesc {
40 
41     // OIDs
42     private DataTypeDesc[] _paramDataTypes;
43 
44     this(DataTypeDesc[] paramDataTypes) {
45         this._paramDataTypes = paramDataTypes;
46     }
47 
48     DataTypeDesc[] paramDataTypes() {
49         return _paramDataTypes;
50     }
51 
52     override
53     string prepare(List!(Variant) values) {
54         if (values.size() != cast(int)_paramDataTypes.length) {
55             return buildReport(values);
56         }
57         for (int i = 0;i < cast(int)_paramDataTypes.length;i++) {
58             DataTypeDesc paramDataType = _paramDataTypes[i];
59             Variant value = values.get(i);
60             Variant val = DataTypeCodec.prepare(paramDataType, value);
61             version(HUNT_DB_DEBUG) tracef("DataType: %s, value: %s, val: %s", paramDataType, value, val);
62             if (val != value) {
63                 if (val == DataTypeCodec.REFUSED_SENTINEL) {
64                     return buildReport(values);
65                 } else {
66                     values.set(i, val);
67                 }
68             }
69         }
70         return null;
71     }
72 
73     private string buildReport(List!(Variant) values) {
74         string[] types;
75         paramDataTypes.each!((type) { types = types ~ type.decodingType; });
76 
77         return Util.buildInvalidArgsError(values.toArray(), types);
78     }
79 
80     override
81     string toString() {
82         return "PgParamDesc{paramDataTypes=" ~ _paramDataTypes.to!string() ~ "}";
83     }
84 }