1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  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/* Overview of what this is and does:
18 * http://www.apache.org/~niq/dbd.html
19 */
20
21#ifndef APR_DBD_INTERNAL_H
22#define APR_DBD_INTERNAL_H
23
24#include <stdarg.h>
25
26#include "apr_dbd.h"
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define TXN_IGNORE_ERRORS(t) \
33  ((t) && ((t)->mode & APR_DBD_TRANSACTION_IGNORE_ERRORS))
34#define TXN_NOTICE_ERRORS(t) \
35  ((t) && !((t)->mode & APR_DBD_TRANSACTION_IGNORE_ERRORS))
36
37#define TXN_DO_COMMIT(t)   (!((t)->mode & APR_DBD_TRANSACTION_ROLLBACK))
38#define TXN_DO_ROLLBACK(t) ((t)->mode & APR_DBD_TRANSACTION_ROLLBACK)
39
40#define TXN_MODE_BITS \
41  (APR_DBD_TRANSACTION_ROLLBACK|APR_DBD_TRANSACTION_IGNORE_ERRORS)
42
43struct apr_dbd_driver_t {
44    /** name */
45    const char *name;
46
47    /** init: allow driver to perform once-only initialisation.
48     *  Called once only.  May be NULL
49     */
50    void (*init)(apr_pool_t *pool);
51
52    /** native_handle: return the native database handle of the underlying db
53     *
54     * @param handle - apr_dbd handle
55     * @return - native handle
56     */
57    void *(*native_handle)(apr_dbd_t *handle);
58
59    /** open: obtain a database connection from the server rec.
60     *  Must be explicitly closed when you're finished with it.
61     *  WARNING: only use this when you need a connection with
62     *  a lifetime other than a request
63     *
64     *  @param pool - a pool to use for error messages (if any).
65     *  @param params - connection parameters.
66     *  @param error - descriptive error.
67     *  @return database handle, or NULL on error.
68     */
69    apr_dbd_t *(*open)(apr_pool_t *pool, const char *params,
70                       const char **error);
71
72    /** check_conn: check status of a database connection
73     *
74     *  @param pool - a pool to use for error messages (if any).
75     *  @param handle - the connection to check
76     *  @return APR_SUCCESS or error
77     */
78    apr_status_t (*check_conn)(apr_pool_t *pool, apr_dbd_t *handle);
79
80    /** close: close/release a connection obtained from open()
81     *
82     *  @param handle - the connection to release
83     *  @return APR_SUCCESS or error
84     */
85    apr_status_t (*close)(apr_dbd_t *handle);
86
87    /** set_dbname: select database name.  May be a no-op if not supported.
88     *
89     *  @param pool - working pool
90     *  @param handle - the connection
91     *  @param name - the database to select
92     *  @return 0 for success or error code
93     */
94    int (*set_dbname)(apr_pool_t* pool, apr_dbd_t *handle, const char *name);
95
96    /** transaction: start a transaction.  May be a no-op.
97     *
98     *  @param pool   - a pool to use for error messages (if any).
99     *  @param handle - the connection
100     *  @param trans  - ptr to a transaction.  May be null on entry
101     *  @return 0 for success or error code
102     */
103    int (*start_transaction)(apr_pool_t *pool, apr_dbd_t *handle,
104                             apr_dbd_transaction_t **trans);
105
106    /** end_transaction: end a transaction
107     *  (commit on success, rollback on error).
108     *  May be a no-op.
109     *
110     *  @param trans - the transaction.
111     *  @return 0 for success or error code
112     */
113    int (*end_transaction)(apr_dbd_transaction_t *trans);
114
115    /** query: execute an SQL query that doesn't return a result set
116     *
117     *  @param handle - the connection
118     *  @param nrows - number of rows affected.
119     *  @param statement - the SQL statement to execute
120     *  @return 0 for success or error code
121     */
122    int (*query)(apr_dbd_t *handle, int *nrows, const char *statement);
123
124    /** select: execute an SQL query that returns a result set
125     *
126     *  @param pool - pool to allocate the result set
127     *  @param handle - the connection
128     *  @param res - pointer to result set pointer.  May point to NULL on entry
129     *  @param statement - the SQL statement to execute
130     *  @param random - 1 to support random access to results (seek any row);
131     *                  0 to support only looping through results in order
132     *                    (async access - faster)
133     *  @return 0 for success or error code
134     */
135    int (*select)(apr_pool_t *pool, apr_dbd_t *handle, apr_dbd_results_t **res,
136                  const char *statement, int random);
137
138    /** num_cols: get the number of columns in a results set
139     *
140     *  @param res - result set.
141     *  @return number of columns
142     */
143    int (*num_cols)(apr_dbd_results_t *res);
144
145    /** num_tuples: get the number of rows in a results set
146     *  of a synchronous select
147     *
148     *  @param res - result set.
149     *  @return number of rows, or -1 if the results are asynchronous
150     */
151    int (*num_tuples)(apr_dbd_results_t *res);
152
153    /** get_row: get a row from a result set
154     *
155     *  @param pool - pool to allocate the row
156     *  @param res - result set pointer
157     *  @param row - pointer to row pointer.  May point to NULL on entry
158     *  @param rownum - row number, or -1 for "next row".  Ignored if random
159     *                  access is not supported.
160     *  @return 0 for success, -1 for rownum out of range or data finished
161     */
162    int (*get_row)(apr_pool_t *pool, apr_dbd_results_t *res,
163                   apr_dbd_row_t **row, int rownum);
164
165    /** get_entry: get an entry from a row
166     *
167     *  @param row - row pointer
168     *  @param col - entry number
169     *  @param val - entry to fill
170     *  @return 0 for success, -1 for no data, +1 for general error
171     */
172    const char* (*get_entry)(const apr_dbd_row_t *row, int col);
173
174    /** error: get current error message (if any)
175     *
176     *  @param handle - the connection
177     *  @param errnum - error code from operation that returned an error
178     *  @return the database current error message, or message for errnum
179     *          (implementation-dependent whether errnum is ignored)
180     */
181    const char *(*error)(apr_dbd_t *handle, int errnum);
182
183    /** escape: escape a string so it is safe for use in query/select
184     *
185     *  @param pool - pool to alloc the result from
186     *  @param string - the string to escape
187     *  @param handle - the connection
188     *  @return the escaped, safe string
189     */
190    const char *(*escape)(apr_pool_t *pool, const char *string,
191                          apr_dbd_t *handle);
192
193    /** prepare: prepare a statement
194     *
195     *  @param pool - pool to alloc the result from
196     *  @param handle - the connection
197     *  @param query - the SQL query
198     *  @param label - A label for the prepared statement.
199     *                 use NULL for temporary prepared statements
200     *                 (eg within a Request in httpd)
201     *  @param nargs - number of parameters in the query
202     *  @param nvals - number of values passed in p[b]query/select
203     *  @param types - pointer to an array with types of parameters
204     *  @param statement - statement to prepare.  May point to null on entry.
205     *  @return 0 for success or error code
206     */
207    int (*prepare)(apr_pool_t *pool, apr_dbd_t *handle, const char *query,
208                   const char *label, int nargs, int nvals,
209                   apr_dbd_type_e *types, apr_dbd_prepared_t **statement);
210
211    /** pvquery: query using a prepared statement + args
212     *
213     *  @param pool - working pool
214     *  @param handle - the connection
215     *  @param nrows - number of rows affected.
216     *  @param statement - the prepared statement to execute
217     *  @param args - args to prepared statement
218     *  @return 0 for success or error code
219     */
220    int (*pvquery)(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
221                   apr_dbd_prepared_t *statement, va_list args);
222
223    /** pvselect: select using a prepared statement + args
224     *
225     *  @param pool - working pool
226     *  @param handle - the connection
227     *  @param res - pointer to query results.  May point to NULL on entry
228     *  @param statement - the prepared statement to execute
229     *  @param random - Whether to support random-access to results
230     *  @param args - args to prepared statement
231     *  @return 0 for success or error code
232     */
233    int (*pvselect)(apr_pool_t *pool, apr_dbd_t *handle,
234                    apr_dbd_results_t **res,
235                    apr_dbd_prepared_t *statement, int random, va_list args);
236
237    /** pquery: query using a prepared statement + args
238     *
239     *  @param pool - working pool
240     *  @param handle - the connection
241     *  @param nrows - number of rows affected.
242     *  @param statement - the prepared statement to execute
243     *  @param args - args to prepared statement
244     *  @return 0 for success or error code
245     */
246    int (*pquery)(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
247                  apr_dbd_prepared_t *statement, const char **args);
248
249    /** pselect: select using a prepared statement + args
250     *
251     *  @param pool - working pool
252     *  @param handle - the connection
253     *  @param res - pointer to query results.  May point to NULL on entry
254     *  @param statement - the prepared statement to execute
255     *  @param random - Whether to support random-access to results
256     *  @param args - args to prepared statement
257     *  @return 0 for success or error code
258     */
259    int (*pselect)(apr_pool_t *pool, apr_dbd_t *handle,
260                   apr_dbd_results_t **res, apr_dbd_prepared_t *statement,
261                   int random, const char **args);
262
263
264    /** get_name: get a column title from a result set
265     *
266     *  @param res - result set pointer
267     *  @param col - entry number
268     *  @return param name, or NULL if col is out of bounds.
269     */
270    const char* (*get_name)(const apr_dbd_results_t *res, int col);
271
272    /** transaction_mode_get: get the mode of transaction
273     *
274     *  @param trans - the transaction.
275     *  @return mode of transaction
276     */
277    int (*transaction_mode_get)(apr_dbd_transaction_t *trans);
278
279    /** transaction_mode_set: get the mode of transaction
280     *
281     *  @param trans - the transaction.
282     *  @param mode  - new mode of the transaction
283     *  @return the mode of transaction in force after the call
284     */
285    int (*transaction_mode_set)(apr_dbd_transaction_t *trans, int mode);
286
287    /** format of prepared statement parameters */
288    const char *pformat;
289
290    /** pvbquery: query using a prepared statement + binary args
291     *
292     *  @param pool - working pool
293     *  @param handle - the connection
294     *  @param nrows - number of rows affected.
295     *  @param statement - the prepared statement to execute
296     *  @param args - binary args to prepared statement
297     *  @return 0 for success or error code
298     */
299    int (*pvbquery)(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
300                    apr_dbd_prepared_t *statement, va_list args);
301
302    /** pvbselect: select using a prepared statement + binary args
303     *
304     *  @param pool - working pool
305     *  @param handle - the connection
306     *  @param res - pointer to query results.  May point to NULL on entry
307     *  @param statement - the prepared statement to execute
308     *  @param random - Whether to support random-access to results
309     *  @param args - binary args to prepared statement
310     *  @return 0 for success or error code
311     */
312    int (*pvbselect)(apr_pool_t *pool, apr_dbd_t *handle,
313                     apr_dbd_results_t **res,
314                     apr_dbd_prepared_t *statement, int random, va_list args);
315
316    /** pbquery: query using a prepared statement + binary args
317     *
318     *  @param pool - working pool
319     *  @param handle - the connection
320     *  @param nrows - number of rows affected.
321     *  @param statement - the prepared statement to execute
322     *  @param args - binary args to prepared statement
323     *  @return 0 for success or error code
324     */
325    int (*pbquery)(apr_pool_t *pool, apr_dbd_t *handle, int *nrows,
326                   apr_dbd_prepared_t *statement,const void **args);
327
328    /** pbselect: select using a prepared statement + binary args
329     *
330     *  @param pool - working pool
331     *  @param handle - the connection
332     *  @param res - pointer to query results.  May point to NULL on entry
333     *  @param statement - the prepared statement to execute
334     *  @param random - Whether to support random-access to results
335     *  @param args - binary args to prepared statement
336     *  @return 0 for success or error code
337     */
338    int (*pbselect)(apr_pool_t *pool, apr_dbd_t *handle,
339                    apr_dbd_results_t **res, apr_dbd_prepared_t *statement,
340                    int random, const void **args);
341
342    /** datum_get: get a binary entry from a row
343     *
344     *  @param row - row pointer
345     *  @param col - entry number
346     *  @param type - type of data to get
347     *  @param data - pointer to data, allocated by the caller
348     *  @return APR_SUCCESS, an error code on error or if col is out of bounds
349     */
350    apr_status_t (*datum_get)(const apr_dbd_row_t *row, int col,
351                              apr_dbd_type_e type, void *data);
352};
353
354/* Export mutex lock/unlock for drivers that need it
355 * deprecated; create a per-dbd mutex within the (*init) function
356 * to avoid blocking other providers running on other threads
357 */
358APU_DECLARE(apr_status_t) apr_dbd_mutex_lock(void);
359APU_DECLARE(apr_status_t) apr_dbd_mutex_unlock(void);
360
361#ifdef __cplusplus
362}
363#endif
364
365#endif
366