1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.data.mapping.engines.sqlshared.sqladapter;
7 
8 import std.variant : Variant;
9 
10 import diamond.data.mapping.model;
11 import diamond.database : DbParam;
12 
13 /// Wrapper around a sql adapter.
14 abstract class SqlAdapter(TModel)
15 {
16   private:
17   /// The connection string.
18   string _connectionString;
19 
20   public:
21   /**
22   * Creates a new sql adapter.
23   * Params:
24   *   connectionString = The connection string of the adapter.
25   */
26   final this(string connectionString)
27   {
28     _connectionString = connectionString;
29   }
30 
31   @property
32   {
33     /// Gets the connection string.
34     final string connectionString() { return _connectionString; }
35   }
36 
37   public:
38   /**
39   *  Executes an sql statement.
40   *  Params:
41   *    query =                The sql query.
42   *    params =             The parameters.
43   *    connectionString =  The connection string. (If null, it will select the default)
44   *  Returns:
45   *    The amount of rows affected.
46   */
47   abstract ulong execute(string query, DbParam[string] params, string connectionString = null);
48 
49   /**
50   *  Executes a raw sql statement.
51   *  Params:
52   *    query =                The sql query.
53   *    params =             The parameters.
54   *    connectionString =  The connection string. (If null, it will select the default)
55   *  Returns:
56   *    The amount of rows affected.
57   */
58   abstract ulong executeRaw(string query, DbParam[] params, string connectionString = null);
59 
60   /**
61   *  Validates whether a row is selected from the query or not.
62   *  Params:
63   *    query =                The sql query.
64   *    params =             The parameters.
65   *    connectionString =  The connection string. (If null, it will select the default)
66   *  Returns:
67   *    True if the row exists, false otherwise.
68   */
69   abstract bool exists(string query, DbParam[string] params, string connectionString = null);
70 
71   /**
72   *  Validates whether a row is selected from the raw query or not.
73   *  Params:
74   *    query =                The sql query.
75   *    params =             The parameters.
76   *    connectionString =  The connection string. (If null, it will select the default)
77   *  Returns:
78   *    True if the row exists, false otherwise.
79   */
80   abstract bool existsRaw(string query, DbParam[] params, string connectionString = null);
81 
82   /**
83   *  Executes a multi sql read.
84   *  Params:
85   *    query =                The sql query.
86   *    params =             The parameters.
87   *    connectionString =  The connection string. (If null, it will select the default)
88   *  Returns:
89   *    A range filled models with the rows returned by the sql read.
90   */
91   abstract TModel[] readMany(string query, DbParam[string] params, string connectionString = null);
92 
93   /**
94   *  Executes a raw multi sql read.
95   *  Params:
96   *    query =                The sql query.
97   *    params =             The parameters.
98   *    connectionString =  The connection string. (If null, it will select the default)
99   *  Returns:
100   *    A range filled models with the rows returned by the sql read.
101   */
102   abstract TModel[] readManyRaw(string query, DbParam[] params, string connectionString = null);
103 
104   /**
105   *  Executes a single sql read.
106   *  Params:
107   *    query =                The sql query.
108   *    params =             The parameters.
109   *    connectionString =  The connection string. (If null, it will select the default)
110   *  Returns:
111   *    The model of the first row read.
112   */
113   abstract TModel readSingle(string query, DbParam[string] params, string connectionString = null);
114 
115   /**
116   *  Executes a single raw sql read.
117   *  Params:
118   *    query =                The sql query.
119   *    params =             The parameters.
120   *    connectionString =  The connection string. (If null, it will select the default)
121   *  Returns:
122   *    The model of the first row read.
123   */
124   abstract TModel readSingleRaw(string query, DbParam[] params, string connectionString = null);
125 
126   protected
127   {
128     /**
129     *  Executes a scalar sql statement.
130     *  Params:
131     *    query =                The sql query.
132     *    params =             The parameters.
133     *    connectionString =  The connection string. (If null, it will select the default)
134     *  Returns:
135     *    The value of the statement.
136     */
137     abstract Variant scalarImpl(string query, DbParam[string] params, string connectionString = null);
138 
139     /**
140     *  Executes a raw scalar sql statement.
141     *  Params:
142     *    query =                The sql query.
143     *    params =             The parameters.
144     *    connectionString =  The connection string. (If null, it will select the default)
145     *  Returns:
146     *    The value of the statement.
147     */
148     abstract Variant scalarRawImpl(string query, DbParam[] params, string connectionString = null);
149 
150     /**
151     *  Executes a scalar insert sql statement.
152     *  Params:
153     *    query =                The sql query.
154     *    params =             The parameters.
155     *    connectionString =  The connection string. (If null, it will select the default)
156     *  Returns:
157     *    The id of inserted row.
158     */
159     abstract Variant scalarInsertImpl(string query, DbParam[string] params, string connectionString = null);
160 
161     /**
162     *  Executes a raw scalar insert sql statement.
163     *  Params:
164     *    sql =                The sql query.
165     *    params =             The parameters.
166     *    connectionString =  The connection string. (If null, it will select the default)
167     *  Returns:
168     *    The id of the inserted row.
169     */
170     abstract Variant scalarInsertRawImpl(string query, DbParam[] params, string connectionString = null);
171   }
172 
173   public:
174   final:
175   /**
176   *  Executes a scalar sql statement.
177   *  Params:
178   *    query =                The sql query.
179   *    params =             The parameters.
180   *    connectionString =  The connection string. (If null, it will select the default)
181   *  Returns:
182   *    The value of the statement.
183   */
184   T scalar(T)(string query, DbParam[string] params, string connectionString = null)
185   {
186     Variant value = scalarImpl(query, params, connectionString);
187 
188     if (!value.hasValue)
189     {
190       return T.init;
191     }
192 
193     return value.get!T;
194   }
195 
196   /**
197   *  Executes a raw scalar sql statement.
198   *  Params:
199   *    query =                The sql query.
200   *    params =             The parameters.
201   *    connectionString =  The connection string. (If null, it will select the default)
202   *  Returns:
203   *    The value of the statement.
204   */
205   T scalarRaw(T)(string query, DbParam[] params, string connectionString = null)
206   {
207     Variant value = scalarRawImpl(query, params, connectionString);
208 
209     if (!value.hasValue)
210     {
211       return T.init;
212     }
213 
214     return value.get!T;
215   }
216 
217   /**
218   *  Executes a scalar insert sql statement.
219   *  Params:
220   *    query =                The sql query.
221   *    params =             The parameters.
222   *    connectionString =  The connection string. (If null, it will select the default)
223   *  Returns:
224   *    The id of inserted row.
225   */
226   T scalarInsert(T)(string query, DbParam[string] params, string connectionString = null)
227   {
228     Variant value = scalarInsertImpl(query, params, connectionString);
229 
230     if (!value.hasValue)
231     {
232       return T.init;
233     }
234 
235     return value.get!T;
236   }
237 
238   /**
239   *  Executes a raw scalar insert sql statement.
240   *  Params:
241   *    query =                The sql query.
242   *    params =             The parameters.
243   *    connectionString =  The connection string. (If null, it will select the default)
244   *  Returns:
245   *    The id of the inserted row.
246   */
247   T scalarInsertRaw(T)(string query, DbParam[] params, string connectionString = null)
248   {
249     Variant value = scalarInsertRawImpl(query, params, connectionString);
250 
251     if (!value.hasValue)
252     {
253       return T.init;
254     }
255 
256     return value.get!T;
257   }
258 }