⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlora.c

📁 Linux下的操作oracle数据库的连接库
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: sqlora.c,v 1.71 2004/05/28 03:04:15 kpoitschke Exp $ *//** * @file sqlora.c * libsqlora8 Implementation * * @author Kai Poitschke * * Copyright (c) 1991-2004 Kai Poitschke (kai[_at_]poitschke.de) * *   This file is part of the libsqlora8 package which can be found *   at http://www.poitschke.de/libsqlora8/ *//* *     Permission to use, copy, modify, and distribute this software for *     any purpose with or without fee is hereby granted, provided that *     the above copyright notice and this permission notice appear in all *     copies. * *     THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR *     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. */const char * _sqlo_sqloraID="$Id: sqlora.c,v 1.71 2004/05/28 03:04:15 kpoitschke Exp $";#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include <errno.h>#ifdef HAVE_UNISTD_H            /* for my windows friends  */#    include <unistd.h>#endif#include <ctype.h>#include <assert.h>#if defined(ENABLE_WINTHREADS)#include <windows.h>#else# if defined(HAVE_PTHREAD_H)#include <pthread.h># endif#endif#include "oci.h"#include "sqlora.h"/* If glib is enabled, we use the glib allocators */#ifdef USE_GLIB_ALLOC#  include "glib.h"#  define MALLOC g_malloc#  define REALLOC g_realloc#  define FREE(_p) {void ** l_p= (void **)&(_p); if ( *l_p != NULL ) {g_free( *l_p); *l_p = NULL; } }#else#  define MALLOC malloc#  define REALLOC realloc#  define FREE(_p) {void ** l_p= (void**)&(_p); if ( *l_p != NULL ) {free( *l_p); *l_p = NULL; } }#endif#if defined(WIN32)#define inline __inline#endif#if defined (__STDC__) || defined (_AIX) || defined(PROTOTYPES) ||\            (defined (__mips) && defined (_SYSTYPE_SVR4)) ||\             defined(WIN32) || defined(__cplusplus)\            #  define AND ,#  define DEFUN(name, arglist, args)      name(args)#  define DEFUN_VOID(name)                name(void) /* * Macro to use instead of "void" for arguments that must have * type "void *" in ANSI C;  maps them to type "char *" in * non-ANSI systems. */#  define VOID void#else#  define AND ;#  define DEFUN(name, arglist, args)      name arglist args;#  define DEFUN_VOID(name)                name()#  define VOID char#endif#ifndef NULL#   define NULL 0#endif/*#define TEST_WITH_SIZEOF_RETURNING_ULONG*/#ifdef TEST_WITH_SIZEOF_RETURNING_ULONG#define sizeof(_a) (unsigned long)sizeof(_a)#endif#if defined(ENABLE_PTHREADS) || defined(ENABLE_ORATHREADS) || defined(ENABLE_WINTHREADS)/** * Defines if the library was compiled with --enable-pthreads */enum {THREADS_ENABLED = 1};#elseenum {THREADS_ENABLED = 0};#endif#ifdef ENABLE_PTHREADStypedef pthread_t sqlo_thread_t;typedef pthread_mutex_t sqlo_mutex_t;#else#  ifdef ENABLE_ORATHREADStypedef OCIThreadMutex * sqlo_mutex_t;typedef OCIThreadId * sqlo_thread_t;#  else#    ifdef ENABLE_WINTHREADStypedef HANDLE sqlo_mutex_t;typedef unsigned long sqlo_thread_t;#    elsetypedef unsigned long sqlo_mutex_t; /* dummy */typedef unsigned long sqlo_thread_t; /* dummy */#    endif#  endif#endif/** * @def EXEC_WHEN_THREADING * Executes _cmd if library was compiled with threading and initialized in threaded mode * @param _cmd I - The code to execute */#define EXEC_WHEN_THREADING(_cmd) \     if (THREADS_ENABLED && OCI_THREADED == _oci_init_mode) { _cmd }/** * @def UNLOCK_ALL * Release all mutex locks */#define UNLOCK_ALL EXEC_WHEN_THREADING(_dbv_unlock(); _env_unlock(); _init_unlock(); )#define ENCODE_STH(_sth, _dbh) ((int)(_dbh << (sizeof(sqlo_stmt_handle_t)/2 * 8) | _sth))#define DECODE_STH(_sth) ((ub4) _sth & 0x0000ffff)#define DECODE_DBH(_sth) ((ub4) (_sth >> (sizeof(sqlo_stmt_handle_t)/2 * 8)) & 0x007fff)/*------------------------------------------------------------------------- * CONSTANTS *-----------------------------------------------------------------------*//** * @enum _sqlora_constants */enum _sqlora_constants {                         SQLO_MAX_DB = 0x00007fff,           /**< max. number of allowed db connections */  SQLO_MAX_CURSORS = 0x0000ffff,      /**< max. number of allowed cursors per db connection */  /* changed the MIN_ sizes for better testing (to make sure we do some reallocations) */  MIN_BINDP = 1 /*64*/,               /**< Initial number of bind pointers                                 * that were allocated                                  */  MIN_DEFNP = 1 /*32*/,               /**< Initial number of define pointers                                 * that were allocated                                  */  MIN_OBUF_SIZE = 1 /*32*/,           /**< Minimum size of the output buffer for columns                                  * in the select list                                  */  MIN_COL_NAME_LEN = 1 /*31*/,        /**< Minimum size for a name or a column */  MIN_STMT_SIZE =  10 /* 1024*/,        /**< Mininum allocation for sqlo_stmt_t.stmt */  DEF_PREFETCH_ROWS = 100,      /**< The default number of prefetched rows */  SQLO_MAX_ERRMSG_LEN = 2047,   /**< The maximum length of the error message buffer */  MAX_PATH_LEN = 512,           /**< for the trace file */    MAX_VNAME_LEN = 255,          /**< Max variable name len read from the environment */    MAX_LONG_SIZE = (1024*64),     /**< Max size for LONG output variables */#ifdef LIBSQLORA8_TRACE_ENABLED  TRACE_ENABLED = 1      /**< configured with enabled trace */#else  TRACE_ENABLED = 0      /**< configured with disabled trace */#endif};/*------------------------------------------------------------------------- * MACROS *-----------------------------------------------------------------------*/#undef TRUE#undef FALSE/** * Boolean TRUE */#define TRUE ((1 == 1))/** * Boolean FALSE */#define FALSE (!TRUE)/** * @def TRACE * Execute cmd when the trace level of the library is >= the trace level * passed to the macro. * @param p_trace_level   I - The min trace level where cmd should be executed * @param p_cmd           I - The commands to be executed in case of  *                            _trace_level >= p_trace_level. * * @par Example: * TRACE(3, fprintf(g_ftp, "Calling foo()\n");); */#define TRACE(p_trace_level, p_cmd)               \   if ( TRACE_ENABLED &&                          \       (NULL != _trace_fp) &&                     \       (_trace_level >= p_trace_level) ) {        \      { p_cmd }                                   \      (void) fflush(_trace_fp);                   \   }/** * @def ERRMALLOC * Allocates _len bytes memory for _ptr * * If no memory could be allocated, an error message is * put in p_dbp->errmsg, p_dbp->status is set to p_retcode and * the macro returns p_retcode * p_func should be a string identifying the * location (function name) where the ERRMALLOC was called * @param p_dbp     I - The pointer to the database strucuture * @param p_ptr     O - The allocated memory * @param p_len     I - The number of bytes to allocate * @param p_func    I - The function name where this macro was called * @param p_retcode I - The return code, the caller wants to return if the malloc fails. */#define ERRMALLOC(p_dbp, p_ptr, p_len, p_func, p_retcode)       \{                                                               \   sqlo_db_struct_ptr_t l_dbp = p_dbp;                          \   int l_len = p_len;                                           \   CONST char * l_func = p_func;                                \   int l_retcode = p_retcode;                                   \   (p_ptr) = MALLOC((l_len));                                   \   if ( !(p_ptr) ) {                                            \     if ( l_dbp ) {                                             \       sprintf( (l_dbp)->errmsg,                                \		"Cannot malloc %u bytes in %s\n",               \		(unsigned int)(l_len), l_func);                 \       TRACE(1, (void) fputs((l_dbp)->errmsg,                   \			     _get_trace_fp(l_dbp)););		\     }                                                          \     l_dbp->status = l_retcode;                                 \     /* make sure we release all locks */                       \     UNLOCK_ALL;                                                \     return l_retcode;                                          \   }                                                            \   TRACE(4, fprintf( _get_trace_fp(l_dbp),                      \                     "Allocated %u bytes in %s\n",              \                     (unsigned int) (l_len), l_func););         \}/** * @def ERREALLOC * Rellocates _len bytes memory at _ptr. * If no memory could be allocated, an error message is * put in p_dbp->errmsg, p_dbp->status is set to p_retcode *  and the macro returns p_retcode * _func should be a string identifying the * location (function name) where the ERRMALLOC was called * @param p_dbp      I - The pointer to the database strucuture * @param p_ptr      O - The allocated memory * @param p_len      I - The number of bytes to allocate * @param p_func     I - The function name where this macro was called * @param p_retcode  I - The return code, the caller wants to return if the malloc fails. */#define ERREALLOC(p_dbp, p_ptr, p_len, p_func, p_retcode)      \{                                                              \   sqlo_db_struct_ptr_t l_dbp = p_dbp;                         \   int l_len = p_len;                                          \   CONST char * l_func = p_func;                               \   int l_retcode = p_retcode;                                  \   (p_ptr) = REALLOC((p_ptr), (l_len));                        \   if ( !(p_ptr) ) {                                           \     if ( l_dbp ) {                                            \     sprintf( (l_dbp)->errmsg,                                 \              "Cannot realloc %u bytes in %s\n",               \              (unsigned int)(l_len), l_func);                  \     TRACE( 1, (void) fputs((l_dbp)->errmsg,                   \            _get_trace_fp(l_dbp)););                           \     }                                                         \     /* make sure we release all locks */                      \     l_dbp->status = p_retcode;                                \     UNLOCK_ALL;                                               \     return l_retcode;                                         \   }                                                           \   TRACE(4, fprintf(_get_trace_fp(l_dbp),                      \         "Reallocated %u bytes in %s\n",                       \         (unsigned int)(l_len), l_func););                     \}/** * @def CHECK_DBHANDLE * Checks for a valid dbh and sets the dbp or returns with error. * If the db handle is invalid, the macro calls return _errval. * @param p_dbp    O - The pointer to the _sqlo_db_t structure for the _dbh. * @param p_dbh    I - The database handle to check. * @param p_func   I - The callers function name. Used for error message. * @param p_errval I - The value to return in case of an error. */#define CHECK_DBHANDLE(p_dbp, p_dbh, p_func, p_errval)           \{                                                                \  int l_dbh = p_dbh;                                             \  CONST char * l_func = p_func;                                  \  if ( !VALID_DBH_RANGE(l_dbh) ||                                \       !_dbv[ l_dbh ] ||                                         \       !_dbv[ l_dbh ]->used) {                                   \    TRACE(1, fprintf(_trace_fp,                                  \         "Invalid Database handle %d in %s\n",                   \          l_dbh, l_func););                                      \    /* make sure we release all locks */                         \    UNLOCK_ALL;                                                  \    return (p_errval);                                           \  }                                                              \  p_dbp = _dbv[ l_dbh ];                                         \}/** * @def CHECK_STHANDLE * Checks for a valid sth and sets the stp or returns with error * If the st handle is invalid, the macro calls return _errval. * @param p_stp    O - The pointer to the _sqlo_stmt_t structure for the _sth. * @param p_sth    I - The statement handle to check. * @param p_func   I - The callers function name. Used for error message. * @param p_errval I - The value to return in case of an error. */#define CHECK_STHANDLE(p_stp, p_sth, p_func, p_errval)          \{                                                               \  if ( NULL == (p_stp = _sth2stp( p_sth, p_func ) ) ||          \       !p_stp->used ) {                                         \    return p_errval;                                            \  }                                                             \}/** * @def CHECK_OCI_STATUS * Checks and saves the OCI return status. * If the status is != OCI_SUCCESS, the function _save_oci_status is called to * save the error message in the database structure. * * @param p_dbp    I - The pointer to the database structure. * @param p_stat   I - The status to check. * @param p_action I - The action you executed causing this status * @param p_object I - The object on which you did _action. */#define CHECK_OCI_STATUS(p_dbp, p_stat, p_action, p_object)      \{                                                                \  sqlo_db_struct_ptr_t l_dbp = p_dbp;                            \  int l_stat = p_stat;                                           \  (l_dbp)->status = p_stat;                                      \  TRACE(4, fprintf(_get_trace_fp(l_dbp),                         \                   "CHECK_OCI_STATUS[%u]: %d at %d\n",           \                   l_dbp->dbh, l_stat, __LINE__););              \  if (OCI_SUCCESS != l_stat &&                                   \    OCI_STILL_EXECUTING != l_stat) {                             \    _save_oci_status(l_dbp, p_action, p_object, __LINE__);       \  }                                                              \}/** * @def CHECK_OCI_STATUS_RETURN * Checks and saves the OCI status and returns the status on failure. * * Calls CHECK_OCI_STATUS and returns the status if it is != OCI_SUCCESS. * * @param p_dbp  I - The pointer to the database structure. * @param p_stat I - The status to check. * @param p_action I - The action you executed causing this status * @param p_object I - The object on which you did _action. */#define CHECK_OCI_STATUS_RETURN(p_dbp, p_stat, p_action, p_object) \{                                                                  \  sqlo_db_struct_ptr_t l_dbp2 = p_dbp;                             \  int l_stat2 = p_stat;                                            \  CHECK_OCI_STATUS(l_dbp2, l_stat2, p_action, p_object);           \  if (OCI_SUCCESS != l_stat2) {                                    \    UNLOCK_ALL;                                                    \    return (l_stat2);                                              \  }                                                                \}/** * @def VALID_DBH_RANGE * Expression resolves to true, if the passed dbh is in a valid range. * * @param _dbh  I - The dbh to be checked. */#define VALID_DBH_RANGE(_dbh) ( _dbh >= 0 && _dbh < (int)_dbv_size )/* If we have usleep we wait this amount of microseconds in a  * OCI_STILL_EXECUTING loop */#ifdef HAVE_USLEEP#  define SQLO_USLEEP usleep(1000)#else#  define SQLO_USLEEP#endif/*------------------------------------------------------------------------- * TYPES *-----------------------------------------------------------------------*//** * Boolean type */typedef unsigned char bool_t;/**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -