00001 /***************************************************************************** 00002 * vlc_sql.h: SQL abstraction layer 00003 ***************************************************************************** 00004 * Copyright (C) 2009 VLC authors and VideoLAN 00005 * $Id: 8dae6ef3440812990df767bcbf5b892c1fad9e25 $ 00006 * 00007 * Authors: Antoine Lejeune <phytos@videolan.org> 00008 * Jean-Philippe André <jpeg@videolan.org> 00009 * Srikanth Raju <srikiraju@gmail.com> 00010 * 00011 * This program is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as published by 00013 * the Free Software Foundation; either version 2.1 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 00024 *****************************************************************************/ 00025 00026 #ifndef VLC_SQL_H 00027 # define VLC_SQL_H 00028 00029 # ifdef __cplusplus 00030 extern "C" { 00031 # endif 00032 00033 00034 /***************************************************************************** 00035 * General structure: SQL object. 00036 *****************************************************************************/ 00037 00038 /** 00039 * Return values for the function @see sql_Run() 00040 */ 00041 #define VLC_SQL_ROW 1 00042 #define VLC_SQL_DONE 2 00043 00044 typedef struct sql_t sql_t; 00045 typedef struct sql_sys_t sql_sys_t; 00046 typedef struct sql_stmt_t sql_stmt_t; 00047 00048 typedef int ( *sql_query_callback_t ) ( void*, int, char**, char** ); 00049 00050 typedef enum { 00051 SQL_NULL, 00052 SQL_INT, 00053 SQL_DOUBLE, 00054 SQL_TEXT, 00055 SQL_BLOB 00056 } sql_type_e; 00057 00058 typedef struct 00059 { 00060 int length; 00061 union 00062 { 00063 int i; 00064 double dbl; 00065 char* psz; 00066 void* ptr; 00067 } value; 00068 } sql_value_t; 00069 00070 struct sql_t 00071 { 00072 VLC_COMMON_MEMBERS 00073 00074 /** Module properties */ 00075 module_t *p_module; 00076 00077 /** Connection Data */ 00078 char *psz_host; /**< Location or host of the database */ 00079 char *psz_user; /**< Username used to connect to database */ 00080 char *psz_pass; /**< Password used to connect to database */ 00081 int i_port; /**< Port on which database is running */ 00082 00083 /** Internal data */ 00084 sql_sys_t *p_sys; 00085 00086 /** All the functions are implemented as threadsafe functions */ 00087 /** Perform a query with a row-by-row callback function */ 00088 int (*pf_query_callback) ( sql_t *, const char *, sql_query_callback_t, void * ); 00089 00090 /** Perform a query and return result directly */ 00091 int (*pf_query) ( sql_t *, const char *, char ***, int *, int * ); 00092 00093 /** Get database tables */ 00094 int (*pf_get_tables) ( sql_t *, char *** ); 00095 00096 /** Free result of a call to sql_Query or sql_GetTables */ 00097 void (*pf_free) ( sql_t *, char ** ); 00098 00099 /** vmprintf replacement for SQL */ 00100 char* (*pf_vmprintf) ( const char*, va_list args ); 00101 00102 /** Begin transaction */ 00103 int (*pf_begin) ( sql_t* ); 00104 00105 /** Commit transaction */ 00106 int (*pf_commit) ( sql_t* ); 00107 00108 /** Rollback transaction */ 00109 void (*pf_rollback) ( sql_t* ); 00110 00111 /** Create a statement object */ 00112 sql_stmt_t* (*pf_prepare) ( sql_t* p_sql, const char* p_fmt, 00113 int i_length ); 00114 00115 /** Bind parameters to a statement */ 00116 int (*pf_bind) ( sql_t* p_sql, sql_stmt_t* p_stmt, int i_pos, 00117 unsigned int type, const sql_value_t* p_value ); 00118 00119 /** Run the prepared statement */ 00120 int (*pf_run) ( sql_t* p_sql, sql_stmt_t* p_stmt ); 00121 00122 /** Reset the prepared statement */ 00123 int (*pf_reset) ( sql_t* p_sql, sql_stmt_t* p_stmt ); 00124 00125 /** Destroy the statement object */ 00126 int (*pf_finalize) ( sql_t* p_sql, sql_stmt_t* p_stmt ); 00127 00128 /** Get the datatype for a specified column */ 00129 int (*pf_gettype) ( sql_t* p_sql, sql_stmt_t* p_stmt, int i_col, 00130 int* type ); 00131 00132 /** Get the data from a specified column */ 00133 int (*pf_getcolumn) ( sql_t* p_sql, sql_stmt_t* p_stmt, int i_col, 00134 int type, sql_value_t *p_res ); 00135 00136 /** Get column size of a specified column */ 00137 int (*pf_getcolumnsize) ( sql_t* p_sql, sql_stmt_t* p_stmt, int i_col ); 00138 }; 00139 00140 /***************************************************************************** 00141 * SQL Function headers 00142 *****************************************************************************/ 00143 00144 /** 00145 * @brief Create a new SQL object. 00146 * @param p_this Parent object to attach the SQL object to. 00147 * @param psz_host URL to the database 00148 * @param i_port Port on which the database is running 00149 * @param psz_user Username to access the database 00150 * @param psz_pass Password for the database 00151 * @return The VLC SQL object, type sql_t. 00152 **/ 00153 VLC_API sql_t *sql_Create( vlc_object_t *p_this, const char *psz_name, 00154 const char* psz_host, int i_port, 00155 const char* psz_user, const char* psz_pass ); 00156 #define sql_Create( a, b, c, d, e, f ) sql_Create( VLC_OBJECT(a), b, c, d, e, f ) 00157 00158 00159 /** 00160 * @brief Destructor for p_sql object 00161 * @param obj This p_sql object 00162 * @return Nothing 00163 */ 00164 VLC_API void sql_Destroy( vlc_object_t *obj ); 00165 #define sql_Destroy( a ) sql_Destroy( VLC_OBJECT( a ) ) 00166 00167 00168 /** 00169 * @brief Perform a query using a callback function 00170 * @param p_sql This SQL object. 00171 * @param psz_query The SQL query string. 00172 * @param pf_callback A callback function that will be called for each row of 00173 * the result: 1st argument is be p_opaque, 00174 * 2nd argument is the number of columns, 00175 * 3rd is the result columns (array of strings), 00176 * 4th is the columns names (array of strings). 00177 * @param p_opaque Any pointer to an object you may need in the callback. 00178 * @return VLC_SUCCESS or VLC_EGENERIC. 00179 * @note The query will not necessarily be processed in a separate thread, but 00180 * it is threadsafe 00181 **/ 00182 static inline int sql_QueryCallback( sql_t *p_sql, const char *psz_query, 00183 sql_query_callback_t pf_callback, 00184 void *p_opaque ) 00185 { 00186 return p_sql->pf_query_callback( p_sql, psz_query, pf_callback, p_opaque ); 00187 } 00188 00189 /** 00190 * @brief Perform a query directly 00191 * @param p_sql This SQL object. 00192 * @param psz_query The SQL query string. 00193 * @param pppsz_result A pointer to a array of strings: result of the query. 00194 * Dynamically allocated. 00195 * @param pi_rows Pointer to an integer that will receive the number of result 00196 * rows written. 00197 * @param pi_cols Pointer to an integer that will receive the number of result 00198 * columns written. 00199 * @return VLC_SUCCESS or VLC_EGENERIC. 00200 * @note pppsz_result will point to an array of strings, ppsz_result. 00201 * This array of strings contains actually a 2D-matrix of strings where the 00202 * first row (row 0) contains the SQL table header names. 00203 * *pi_rows will be the number of result rows, so that the number of text rows 00204 * in ppsz_result will be (*pi_rows + 1) (because of row 0). 00205 * To get result[row,col] use (*pppsz_result)[ (row+1) * (*pi_cols) + col ]. 00206 * This function is threadsafe 00207 **/ 00208 static inline int sql_Query( sql_t *p_sql, const char *psz_query, 00209 char ***pppsz_result, int *pi_rows, int *pi_cols ) 00210 { 00211 return p_sql->pf_query( p_sql, psz_query, pppsz_result, pi_rows, pi_cols ); 00212 } 00213 00214 /** 00215 * @brief Get database table name list 00216 * @param p_sql This SQL object. 00217 * @param pppsz_tables Pointer to an array of strings. Dynamically allocated. 00218 * Similar to pppsz_result of sql_Query but with only one row. 00219 * @return Number of tables or <0 in case of error. 00220 * @note This function is threadsafe 00221 **/ 00222 static inline int sql_GetTables( sql_t *p_sql, char ***pppsz_tables ) 00223 { 00224 return p_sql->pf_get_tables( p_sql, pppsz_tables ); 00225 } 00226 00227 /** 00228 * @brief Free the result of a query. 00229 * @param p_sql This SQL object. 00230 * @param ppsz_result The result of sql_Query or sql_GetTables. See above. 00231 * @return Nothing. 00232 * @note This function is threadsafe 00233 **/ 00234 static inline void sql_Free( sql_t *p_sql, char **ppsz_result ) 00235 { 00236 p_sql->pf_free( p_sql, ppsz_result ); 00237 } 00238 00239 /** 00240 * @brief printf-like function that can escape forbidden/reserved characters. 00241 * @param p_sql This SQL object. 00242 * @param psz_fmt Format of the string (with %q, %Q and %z enabled). 00243 * @param ... Printf arguments 00244 * @return Dynamically allocated string or NULL in case of error. 00245 * @note Refer to SQLite documentation for more details about %q, %Q and %z. 00246 **/ 00247 static inline char* sql_Printf( sql_t *p_sql, const char *psz_fmt, ... ) 00248 { 00249 va_list args; 00250 va_start( args, psz_fmt ); 00251 char *r = p_sql->pf_vmprintf( psz_fmt, args ); 00252 va_end( args ); 00253 return r; 00254 } 00255 00256 /** 00257 * @brief vprintf replacement for SQL queries, escaping forbidden characters 00258 * @param p_sql This SQL object 00259 * @param psz_fmt Format of the string 00260 * @param arg Variable list of arguments 00261 * @return Dynamically allocated string or NULL in case of error. 00262 **/ 00263 static inline char* sql_VPrintf( sql_t *p_sql, const char *psz_fmt, 00264 va_list arg ) 00265 { 00266 return p_sql->pf_vmprintf( psz_fmt, arg ); 00267 } 00268 00269 /** 00270 * @brief Begin a SQL transaction 00271 * @param p_sql The SQL object 00272 * @return VLC error code or success 00273 * @note This function is threadsafe 00274 **/ 00275 static inline int sql_BeginTransaction( sql_t *p_sql ) 00276 { 00277 return p_sql->pf_begin( p_sql ); 00278 } 00279 00280 /** 00281 * @brief Commit a SQL transaction 00282 * @param p_sql The SQL object 00283 * @return VLC error code or success 00284 * @note This function is threadsafe 00285 **/ 00286 static inline int sql_CommitTransaction( sql_t *p_sql ) 00287 { 00288 return p_sql->pf_commit( p_sql ); 00289 } 00290 00291 /** 00292 * @brief Rollback a SQL transaction 00293 * @param p_sql The SQL object 00294 * @return VLC error code or success 00295 * @note This function is threadsafe 00296 **/ 00297 static inline void sql_RollbackTransaction( sql_t *p_sql ) 00298 { 00299 p_sql->pf_rollback( p_sql ); 00300 } 00301 00302 /** 00303 * @brief Prepare an sql statement 00304 * @param p_sql The SQL object 00305 * @param p_fmt SQL query string 00306 * @param i_length length of the string. If negative, length will be 00307 * considered up to the first \0 character equivalent to strlen(p_fmt). 00308 * Otherwise the first i_length bytes will be used 00309 * @return a sql_stmt_t pointer or NULL on failure 00310 */ 00311 static inline sql_stmt_t* sql_Prepare( sql_t* p_sql, const char* p_fmt, 00312 int i_length ) 00313 { 00314 return p_sql->pf_prepare( p_sql, p_fmt, i_length ); 00315 } 00316 00317 /** 00318 * @brief Bind arguments to a sql_stmt_t object 00319 * @param p_sql The SQL object 00320 * @param p_stmt Statement Object 00321 * @param type Data type of the value 00322 * @param p_value Value to be bound 00323 * @param i_pos Position at which the parameter should be bound 00324 * @return VLC_SUCCESS or VLC_EGENERIC 00325 */ 00326 static inline int sql_BindGeneric( sql_t* p_sql, sql_stmt_t* p_stmt, 00327 int i_pos, int type, const sql_value_t* p_value ) 00328 { 00329 return p_sql->pf_bind( p_sql, p_stmt, i_pos, type, p_value ); 00330 } 00331 00332 /** 00333 * @brief Bind a NULL value to a position 00334 * @param p_sql The SQL object 00335 * @param p_stmt Statement Object 00336 * @param i_pos Position at which the parameter should be bound 00337 * @return VLC_SUCCESS or VLC_EGENERIC 00338 */ 00339 static inline int sql_BindNull( sql_t *p_sql, sql_stmt_t* p_stmt, int i_pos ) 00340 { 00341 int i_ret = sql_BindGeneric( p_sql, p_stmt, i_pos, SQL_NULL, NULL ); 00342 return i_ret; 00343 } 00344 00345 /** 00346 * @brief Bind an integer to the statement object at some position 00347 * @param p_sql The SQL object 00348 * @param p_stmt Statement Object 00349 * @param i_pos Position at which the parameter should be bound 00350 * @param i_int Value to be bound 00351 * @return VLC_SUCCESS or VLC_EGENERIC 00352 */ 00353 static inline int sql_BindInteger( sql_t *p_sql, sql_stmt_t* p_stmt, 00354 int i_pos, int i_int ) 00355 { 00356 sql_value_t value; 00357 value.length = 0; 00358 value.value.i = i_int; 00359 int i_ret = sql_BindGeneric( p_sql, p_stmt, i_pos, SQL_INT, &value ); 00360 return i_ret; 00361 } 00362 00363 /** 00364 * @brief Bind a double to the statement object at some position 00365 * @param p_sql The SQL object 00366 * @param p_stmt Statement Object 00367 * @param i_pos Position at which the parameter should be bound 00368 * @param d_dbl Value to be bound 00369 * @return VLC_SUCCESS or VLC_EGENERIC 00370 */ 00371 static inline int sql_BindDouble( sql_t *p_sql, sql_stmt_t* p_stmt, 00372 int i_pos, double d_dbl ) 00373 { 00374 sql_value_t value; 00375 value.length = 0; 00376 value.value.dbl = d_dbl; 00377 int i_ret = sql_BindGeneric( p_sql, p_stmt, i_pos, SQL_INT, &value ); 00378 return i_ret; 00379 } 00380 00381 /** 00382 * @brief Bind Text to the statement 00383 * @param p_sql The SQL object 00384 * @param p_stmt Statement Object 00385 * @param i_pos Position at which the parameter should be bound 00386 * @param p_fmt Value to be bound 00387 * @param i_length Length of text. If -ve text up to the first null char 00388 * will be selected. 00389 * @return VLC_SUCCESS or VLC_EGENERIC 00390 */ 00391 static inline int sql_BindText( sql_t *p_sql, sql_stmt_t* p_stmt, int i_pos, 00392 char* p_fmt, int i_length ) 00393 { 00394 sql_value_t value; 00395 value.length = i_length; 00396 value.value.psz = p_fmt; 00397 int i_ret = sql_BindGeneric( p_sql, p_stmt, i_pos, SQL_TEXT, &value ); 00398 return i_ret; 00399 } 00400 00401 /** 00402 * @brief Bind a binary object to the statement 00403 * @param p_sql The SQL object 00404 * @param p_stmt Statement Object 00405 * @param i_pos Position at which the parameter should be bound 00406 * @param p_ptr Value to be bound 00407 * @param i_length Size of the blob to read 00408 * @return VLC_SUCCESS or VLC_EGENERIC 00409 */ 00410 static inline int sql_BindBlob( sql_t *p_sql, sql_stmt_t* p_stmt, int i_pos, 00411 void* p_ptr, int i_length ) 00412 { 00413 sql_value_t value; 00414 value.length = i_length; 00415 value.value.ptr = p_ptr; 00416 int i_ret = sql_BindGeneric( p_sql, p_stmt, i_pos, SQL_INT, &value ); 00417 return i_ret; 00418 } 00419 00420 /** 00421 * @brief Run the SQL statement. If the statement fetches data, then only 00422 * one row of the data is fetched at a time. Run this function again to 00423 * fetch the next row. 00424 * @param p_sql The SQL object 00425 * @param p_stmt The statement 00426 * @return VLC_SQL_DONE if done fetching all rows or there are no rows to fetch 00427 * VLC_SQL_ROW if a row was fetched for this statement. 00428 * VLC_EGENERIC if this function failed 00429 */ 00430 static inline int sql_Run( sql_t* p_sql, sql_stmt_t* p_stmt ) 00431 { 00432 return p_sql->pf_run( p_sql, p_stmt ); 00433 } 00434 00435 /** 00436 * @brief Reset the SQL statement. Resetting the statement will unbind all 00437 * the values that were bound on this statement 00438 * @param p_sql The SQL object 00439 * @param p_stmt The sql statement object 00440 * @return VLC_SUCCESS or VLC_EGENERIC 00441 */ 00442 static inline int sql_Reset( sql_t* p_sql, sql_stmt_t* p_stmt ) 00443 { 00444 return p_sql->pf_reset( p_sql, p_stmt ); 00445 } 00446 00447 /** 00448 * @brief Destroy the sql statement object. This will free memory. 00449 * @param p_sql The SQL object 00450 * @param p_stmt The statement object 00451 * @return VLC_SUCCESS or VLC_EGENERIC 00452 */ 00453 static inline int sql_Finalize( sql_t* p_sql, sql_stmt_t* p_stmt ) 00454 { 00455 return p_sql->pf_finalize( p_sql, p_stmt ); 00456 } 00457 00458 /** 00459 * @brief Get the datatype of the result of the column 00460 * @param p_sql The SQL object 00461 * @param p_stmt The sql statement object 00462 * @param i_col The column 00463 * @param type pointer to datatype of the given column 00464 * @return VLC_SUCCESS or VLC_EGENERIC 00465 */ 00466 static inline int sql_GetColumnType( sql_t* p_sql, sql_stmt_t* p_stmt, 00467 int i_col, int* type ) 00468 { 00469 return p_sql->pf_gettype( p_sql, p_stmt, i_col, type ); 00470 } 00471 00472 /** 00473 * @brief Get the column data 00474 * @param p_sql The SQL object 00475 * @param p_stmt The statement object 00476 * @param i_col The column number 00477 * @param type Datatype of result 00478 * @param p_res The structure which contains the value of the result 00479 * @return VLC_SUCCESS or VLC_EGENERIC 00480 */ 00481 static inline int sql_GetColumn( sql_t* p_sql, sql_stmt_t* p_stmt, 00482 int i_col, int type, sql_value_t *p_res ) 00483 { 00484 return p_sql->pf_getcolumn( p_sql, p_stmt, i_col, type, p_res ); 00485 } 00486 00487 /** 00488 * @brief Get an integer from the results of a statement 00489 * @param p_sql The SQL object 00490 * @param p_stmt The statement object 00491 * @param i_col The column number 00492 * @param i_res Pointer of the location for result to be stored 00493 * @return VLC_SUCCESS or VLC_EGENERIC 00494 */ 00495 static inline int sql_GetColumnInteger( sql_t* p_sql, sql_stmt_t* p_stmt, 00496 int i_col, int* pi_res ) 00497 { 00498 sql_value_t tmp; 00499 int i_ret = p_sql->pf_getcolumn( p_sql, p_stmt, i_col, SQL_INT, &tmp ); 00500 if( i_ret == VLC_SUCCESS ) 00501 *pi_res = tmp.value.i; 00502 return i_ret; 00503 } 00504 00505 /** 00506 * @brief Get a double from the results of a statement 00507 * @param p_sql The SQL object 00508 * @param p_stmt The statement object 00509 * @param i_col The column number 00510 * @param d_res Pointer of the location for result to be stored 00511 * @return VLC_SUCCESS or VLC_EGENERIC 00512 */ 00513 static inline int sql_GetColumnDouble( sql_t* p_sql, sql_stmt_t* p_stmt, 00514 int i_col, double* pd_res ) 00515 { 00516 sql_value_t tmp; 00517 int i_ret = p_sql->pf_getcolumn( p_sql, p_stmt, i_col, SQL_DOUBLE, &tmp ); 00518 if( i_ret == VLC_SUCCESS ) 00519 *pd_res = tmp.value.dbl; 00520 return i_ret; 00521 } 00522 00523 /** 00524 * @brief Get some text from the results of a statement 00525 * @param p_sql The SQL object 00526 * @param p_stmt The statement object 00527 * @param i_col The column number 00528 * @param pp_res Pointer of the location for result to be stored 00529 * @return VLC_SUCCESS or VLC_EGENERIC 00530 */ 00531 static inline int sql_GetColumnText( sql_t* p_sql, sql_stmt_t* p_stmt, 00532 int i_col, char** pp_res ) 00533 { 00534 sql_value_t tmp; 00535 int i_ret = p_sql->pf_getcolumn( p_sql, p_stmt, i_col, SQL_TEXT, &tmp ); 00536 if( i_ret == VLC_SUCCESS ) 00537 *pp_res = tmp.value.psz; 00538 return i_ret; 00539 } 00540 00541 /** 00542 * @brief Get a blob from the results of a statement 00543 * @param p_sql The SQL object 00544 * @param p_stmt The statement object 00545 * @param i_col The column number 00546 * @param pp_res Pointer of the location for result to be stored 00547 * @return VLC_SUCCESS or VLC_EGENERIC 00548 */ 00549 static inline int sql_GetColumnBlob( sql_t* p_sql, sql_stmt_t* p_stmt, 00550 int i_col, void** pp_res ) 00551 { 00552 sql_value_t tmp; 00553 int i_ret = p_sql->pf_getcolumn( p_sql, p_stmt, i_col, SQL_BLOB, &tmp ); 00554 if( i_ret == VLC_SUCCESS ) 00555 *pp_res = tmp.value.ptr; 00556 return i_ret; 00557 } 00558 00559 /** 00560 * @brief Get the size of the column in bytes 00561 * @param p_sql The SQL object 00562 * @param p_stmt The sql statement object 00563 * @param i_col The column 00564 * @return Size of the column in bytes, excluding the zero terminator 00565 */ 00566 static inline int sql_GetColumnSize( sql_t* p_sql, sql_stmt_t* p_stmt, 00567 int i_col ) 00568 { 00569 return p_sql->pf_getcolumnsize( p_sql, p_stmt, i_col ); 00570 } 00571 00572 # ifdef __cplusplus 00573 } 00574 # endif /* C++ extern "C" */ 00575 00576 #endif /* VLC_SQL_H */
1.7.1