/* data/database/dbi.c librock_CHISEL _summary Call-level Interface to relational databases. Copyright (c) 2001-2002, Forrest J. Cavalier III, doing business as Mib Software, Saylorsburg Pennsylvania USA Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /**************************************************************/ #ifdef librock_NOTLIBROCK /* ABOUT THIS FILE: GUIDE TO QUICK REUSE WITHOUT REWORK All source code from librock is Free (libre), free (no cost), rock- stable API, namespace restricted, industrial-level quality. Works on gcc/MS/Windows/Linux/BSD/more. Get originals, updates, and details at http://www.mibsoftware.com/librock This file has many preprocessor conditional blocks which are used in publishing http://www.mibsoftware.com/librock/ Here is an easy method to use this file without those features: 1. At compile time, enable this conditional block by defining the preprocessor symbol librock_NOTLIBROCK, either with a compiler command line parameter, or as a #define in a source file which then #includes this source file. 2. Define any preprocessor symbols in this block (if any) appropriately for your machine and compilation environment. 3. Copy and use the declarations from this block in your source files as appropriate. */ #define librock_ISOLATED #include #define librock_PTR #define librock_CONST const #define librock_PRIVATE static void *librock_dbi_open(const char *params,char **ppaszErr); const char *librock_dbi_close(void *idConn,char **ppaszErr); void *librock_dbi_exec(void *idConn,const char *str,char **ppaszErr); const char *librock_dbi_fetch_row(void *idResults,const char ***ppCols,int *pnCols,char **ppaszErr); const char *librock_dbi_quote(void *idConn,char **ppaszQuoted,const char *val,int cnt); #endif /* ifdef librock_NOTLIBROCK */ #ifndef librock_ISOLATED /**************************************************************/ #define librock_IMPLEMENT_dbi #define librock_WANT_db_s #include #include #include #include /**************************************************************/ #endif #ifndef librock_NOIMPL_LIDESC_dbi /* License description features are documented at http://www.mibsoftware.com/librock/ */ /* librock_ACQUIRED: #FIXME: YYYY-MM-DD# #FIXME: download-url# #FIXME: homepage# */ #ifdef librock_IMPL_LIDESC /**************************************************************/ #include /* librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */ char *librock_LIDESC_dbi[] = { "\n" __FILE__ librock_LIDESC_librock "\n", 0 }; /**************************************************************/ #endif #endif #ifndef librock_WRAP /* Function wrapping and tracing features are documented at http://www.mibsoftware.com/librock/ */ /**************************************************************/ #define librock_body_dbi_open librock_dbi_open #define librock_body_dbi_close librock_dbi_close #define librock_body_dbi_exec librock_dbi_exec #define librock_body_dbi_fetch_row librock_dbi_fetch_row #define librock_body_dbi_quote librock_dbi_quote #define librock_body_dbi_fail_open librock_dbi_fail_open #define librock_body_dbi_fail_close librock_dbi_fail_close #define librock_body_dbi_fail_exec librock_dbi_fail_exec #define librock_body_dbi_fail_fetch_row librock_dbi_fail_fetch_row #define librock_body_dbi_fail_quote librock_dbi_fail_quote /**************************************************************/ #endif #ifndef librock_NOIMPL_dbi_open /**************************************************************/ void *librock_body_dbi_open(const char *pszParams,char **ppaszErr) {/*Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_MD5=f2a00374df769e694451262ac9df1336 */ #ifdef librock_MANUAL_dbi_open /* librock_dbi_open - Initiate a connection to a database manager librock_dbi_close - Close a connection opened with librock_dbi_open librock_dbi_exec - Perform a database operation librock_dbi_fetch_row - Retrieve results from a database operation librock_dbi_quote - Encode special characters */ /**/ #include void * /* a connection ID for use in other calls */ librock_dbi_open( const char *pszParams, /* blank-separated list of parameters. First is driver name */ char **ppaszErr /* stores a librock_astring error message */ ); /* These functions implement a standard API to database manager call-level interfaces. The call to librock_dbi_open specifies which driver to use, and that sets up function pointers which correspond to the other librock_dbi_ functions. The implementation of librock_dbi_exec must intercept the special query "SHOW TABLES" and perform the appropriate action so that librock_db_fetch_row will return a list of tables. If the caller expects to have more than one query open simultaneously, (i.e. a call to librock_dbi_exec() before finishing the with results of a previous query) it must call librock_dbi_open() for each simultaneous query. (The implementation may pool such connections, but is not required to.) Based on compile-time flags, drivers can be disabled by #define librock_dbi_DRIVER_open librock_dbi_fail_open As of 2002-06-14, the driver supported is 'odbc'. The paramete for open is the DSN. Typical use is */ char *err = 0; void *idConn = librock_dbi_open("odbc DRIVER={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=g:\\reuse\\db\\;",&err); void *idStmt; if (!idConn) { printf("%s\n",err); return -1; } idStmt = librock_dbi_exec(idConn,"SELECT * FROM tablename",&err); if (idStmt) { const char **pCols; int n; int i; while(1) { librock_dbi_fetch_row(idStmt,&pCols,&n,&err); if (err && !strncmp(err,"I-106-",5)) { librock_dbi_fetch_row(idStmt,0,0,&err); break; } i =0; while(i < n) { if (i) { printf("\t%s",pCols[i]); } else { printf("%s",pCols[i]); } i++; } printf("\n"); } } librock_dbi_close(idConn,&err); librock_astrfree(&err); /* librock_wordcmp librock_dbi_odbc_open */ /* Copyright 1998-2002 Forrest J. Cavalier III, http://www.mibsoftware.com Licensed under BSD-ish license, NO WARRANTY. Copies must retain this block. License text in librock_LIDESC_MD5=f2a00374df769e694451262ac9df1336 */ #endif /* MANUAL */ /*-------------------------------------------*/ if (!librock_wordcmp(pszParams,"odbc")) { return librock_dbi_odbc_open(pszParams,ppaszErr); } if (ppaszErr) { librock_astrcpy(ppaszErr,"E-1-Unknown driver"); } return 0; /* Error */ } /**************************************************************/ #endif /* NOIMP section */ #ifndef librock_NOIMPL_dbi_close /**************************************************************/ const char *librock_body_dbi_close(void *idConn,char **ppaszErr) { /* Returns an error explanation */ struct librock_db_s *r = (struct librock_db_s *)idConn; *(r->pfnClose)(idConn,ppaszErr); return 0; /* No error */ } const char *librock_body_dbi_fail_close(void *idConn,char **ppaszErr) { /* Returns an error explanation */ const char *ret = "E-1-Not supported"; if (ppaszErr) { librock_astrcpy(ppaszErr,ret); } return ret; } /**************************************************************/ #endif /* NOIMP section */ #ifndef librock_NOIMPL_dbi_exec /**************************************************************/ void *librock_body_dbi_exec(void *idConn,const char *str,char **ppaszErr) { /* Returns idQuery, 0 on error */ struct librock_db_s *r = (struct librock_db_s *)idConn; return (*r->pfnExec)(idConn,str,ppaszErr); } void *librock_body_dbi_fail_exec(void *idConn,const char *str,char **ppaszErr) { /* Returns idQuery, 0 on error */ if (ppaszErr) { librock_astrcpy(ppaszErr,"E-1-Not supported"); } return 0; } /**************************************************************/ #endif /* NOIMP section */ #ifndef librock_NOIMPL_dbi_fetch_row /**************************************************************/ const char *librock_body_dbi_fetch_row(void *idResults,const char ***ppCols,int *pnCols,char **ppaszErr) { /* Returns an error explanation */ struct librock_db_s *r = (struct librock_db_s *)idResults; return (*r->pfnFetch)(idResults,ppCols,pnCols,ppaszErr); } const char *librock_body_dbi_fail_fetch_row(void *idResults,const char ***ppCols,int *pnCols,char **ppaszErr) { /* Returns an error explanation */ const char *ret = "E-1-Not supported"; if (ppaszErr) { librock_astrcpy(ppaszErr,ret); } return ret; } /**************************************************************/ #endif /* NOIMP section */ #ifndef librock_NOIMPL_dbi_quote /**************************************************************/ const char *librock_body_dbi_quote(void *idConn,char **ppaszQuoted,const char *str,int cnt) { /* Returns an error explanation */ struct librock_db_s *r = (struct librock_db_s *)idConn; return (*r->pfnQuote)(idConn,ppaszQuoted,str,cnt); } const char *librock_body_dbi_fail_quote(char **ppaszQuoted,const char *str,int cnt) { const char *ret = "E-1-Not supported"; return ret; } /**************************************************************/ #endif /* NOIMP section */ /**************************************************************/ /* $Log$ rights#1 License text in librock_LIDESC_HC=12440211096131f5976d36be0cddca4cd9152e45 */