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

📄 sqlora.c

📁 一个很好用的Linux/Unix下Oracle OCI开发接口封装库
💻 C
📖 第 1 页 / 共 5 页
字号:

#ifdef HAVE_STRDUP
/* Sometimes strdup is  not defined in strict ansi mode,
 * even if it is in libc 
 */
extern char * strdup __P((const char *s));
#else

/**
 * strdup if not available on the target system
 * @param s  I - The string to duplicate
 * @return The newly allocated string.
 */
char * DEFUN(strdup, (s), const char * s)
{
  char *n;
  n = (char *) MALLOC(sizeof(char) * (strlen(s) + 1) );
  TRACE(4, fprintf(_trace_fp,"strdup: Allocated %d bytes\n", (strlen(s) + 1)););
  if (n)
    strcpy(n, s);
  return(n);
}

#endif



/*---------------------------------------------------------------------------
  Parameters (Can be changed by environment variables or sqlo_set)
  Naming conventions of environment variables:
  SQLORA_ || upper(<param_name>)
---------------------------------------------------------------------------*/
          /* Parameters, sort them by name */
static sqlora_param_t g_params[] = {
  {"PREFETCH_ROWS", INTEGER,       (VOID *)&_num_prefetch_rows,    NULL},
  {"LONGSIZE",      INTEGER,       (VOID *)&_max_long_size,    NULL},
  {"TRACE_FILE",    STRING,        _trace_file,          NULL},
  {"TRACE_LEVEL",   INTEGER,       &_trace_level,        NULL},
  {NULL,            INTEGER,       NULL,                NULL}
};

/*-------------------------------------------------------------------------
 * STATIC FUNCTIONS
 *-----------------------------------------------------------------------*/

/*-------------------------------------------------------------------------*/
/**
 * Inits all mutexes.
 * @returns OCI status.
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _init_mutexes
#endif
static inline int
DEFUN_VOID(_init_mutexes)
{
  int status = SQLO_SUCCESS;
#ifdef ENABLE_PTHREADS
  pthread_mutex_init(&_dbv_mux, NULL);
  pthread_mutex_init(&_stmtv_mux, NULL);
  pthread_mutex_init(&_env_mux, NULL);

#elif ENABLE_ORATHREADS
  status = (OCIThreadMutexInit(_oci_envhp, _oci_errhp, &_dbv_mux) ||
            OCIThreadMutexInit(_oci_envhp, _oci_errhp, &_stmtv_mux) ||
            OCIThreadMutexInit(_oci_envhp, _oci_errhp, &_env_mux) );
#endif
  return status;
}

/*-------------------------------------------------------------------------*/
/**
 * Lock @ref _env_mux
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _env_lock
#endif
static inline int
DEFUN_VOID(_env_lock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_lock(&_env_mux);
#elif ENABLE_ORATHREADS
  return(OCIThreadMutexAcquire(_oci_envhp, _oci_errhp, _env_mux));
#endif
  return OCI_SUCCESS;
}

/*-------------------------------------------------------------------------*/
/**
 * Unlock @ref _env_mux.
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _env_unlock
#endif
static inline int
DEFUN_VOID(_env_unlock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_unlock(&_env_mux);
#elif ENABLE_ORATHREADS
  return (OCIThreadMutexRelease(_oci_envhp, _oci_errhp, _env_mux));
#endif 
  return(OCI_SUCCESS);
}

/*-------------------------------------------------------------------------*/
/**
 * Lock @ref _dbv
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _dbv_lock
#endif
static inline int
DEFUN_VOID(_dbv_lock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_lock(&_dbv_mux);
#elif ENABLE_ORATHREADS
  return(OCIThreadMutexAcquire(_oci_envhp, _oci_errhp, _dbv_mux));
#endif
  return OCI_SUCCESS;
}

/*-------------------------------------------------------------------------*/
/**
 * Unlock @ref _dbv.
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _dbv_unlock
#endif
static inline int
DEFUN_VOID(_dbv_unlock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_unlock(&_dbv_mux);
#elif ENABLE_ORATHREADS
  return (OCIThreadMutexRelease(_oci_envhp, _oci_errhp, _dbv_mux));
#endif 
  return(OCI_SUCCESS);
}


/*-------------------------------------------------------------------------*/
/**
 * Lock @ref _stmtv
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _stmtv_lock
#endif
static inline int
DEFUN_VOID(_stmtv_lock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_lock(&_stmtv_mux);
#elif ENABLE_ORATHREADS
  return (OCIThreadMutexAcquire(_oci_envhp, _oci_errhp, _stmtv_mux));
#endif
  return(OCI_SUCCESS);
}


/*-------------------------------------------------------------------------*/
/**
 * Unlock @ref _stmtv.
 * @return OCI status
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _stmtv_unlock
#endif
static inline int
DEFUN_VOID(_stmtv_unlock)
{
#ifdef ENABLE_PTHREADS
  pthread_mutex_unlock(&_stmtv_mux);
#elif ENABLE_ORATHREADS
  return (OCIThreadMutexRelease(_oci_envhp, _oci_errhp, _stmtv_mux));
#endif
  return(OCI_SUCCESS);
}



/*-------------------------------------------------------------------------*/
/**
 * Sets the attribute PREFETCH_ROWS.
 * @param stp   I - statement pointer
 * @param nrows I - Number of rows to prefetch
 * @return OCI status code
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _set_prefetch_rows
#endif
static inline int
DEFUN(_set_prefetch_rows, (stp, nrows), 
      sqlo_stmt_ptr_t  stp AND
      unsigned int nrows)
{
  unsigned int prefetch_rows = nrows;
  int status;

  status = OCIAttrSet((dvoid*)stp->stmthp, 
                        (ub4)OCI_HTYPE_STMT,
                        &prefetch_rows, 
                        (ub4) sizeof(prefetch_rows),
                        (ub4)OCI_ATTR_PREFETCH_ROWS, 
                        stp->dbp->errhp);
  return(status);
}


/*-------------------------------------------------------------------------*/
/**
 * Gets the statement text and puts it into stp->stmt.
 *
 * @param stp   I - statement pointer
 * @return OCI status code
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _get_stmt_string
#endif
static inline const char *
DEFUN(_get_stmt_string, (stp),
      sqlo_stmt_ptr_t  stp 
     )
{
  static const char *nostmt = "_get_stmt_string: No statement avalailable";
  if (!stp->stmt)
    return(nostmt);
  
  return stp->stmt;
}


/*-------------------------------------------------------------------------*/
/**
 * Gets the statement state
 *
 * @param stp   I - statement pointer
 * @return The statement state or -1 on error.
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _get_stmt_state
#endif
static inline int
DEFUN(_get_stmt_state, (stp),
      sqlo_stmt_ptr_t  stp 
     )
{
  int status;
  ub4 st = 0;

  /* OCI_ATTR_STMT_STATE is not defined in Oracle < 9i 
   * I define this here, to make it compile with Oracle 8,8i,
   * but nobody should call this 
   * function
   */
#ifndef OCI_ATTR_STMT_STATE
#define OCI_ATTR_STMT_STATE 182
#endif

  if( (status = OCIAttrGet((dvoid*)stp->stmthp, 
                           (ub4)OCI_HTYPE_STMT,
                           (dvoid *)&st, 
                           (ub4 *) 0,
                           (ub4)OCI_ATTR_STMT_STATE, 
                           stp->dbp->errhp)))
    return (status);
  return ((int)st);
}



/*-------------------------------------------------------------------------*/
/**
 * Adds a new database entry to @ref _dbv[].
 * Alllocates a new entry entry if necessary, or reuses an old one.
 * @return The pointer to the entry. The entry is marked used.
 */
static sqlo_db_ptr_t 
DEFUN_VOID(_db_add)
{
  register unsigned int dbv_idx;
  unsigned int first_null_idx;                       /* first null slot */
  bool_t first_null_idx_set;      /* Flag indicates that first_null_idx is valid */
  bool_t found_free;
  unsigned int free_idx;

  TRACE(4, fprintf(_trace_fp, "_db_add starts _dbv_size=%u\n", _dbv_size););

  /* check for initialization */
  if ((! _sqlo_init) || (_dbv_size <= 0))
    return (NULL) ;

  EXEC_WHEN_THREADING(_dbv_lock(););  /* start of critical section */

  /* we need to check first if there is an unused allocated slot */
  found_free = FALSE;
  first_null_idx_set = FALSE;
  free_idx = 0;
  first_null_idx = 0;

  for (dbv_idx = 0; dbv_idx < _dbv_size; ++dbv_idx) {
    if ((_dbv[ dbv_idx ]) && (! _dbv[ dbv_idx ]->used)) {  /* free slot found */
      free_idx = dbv_idx;
      found_free = TRUE;
      break ;
    } else if ( !first_null_idx_set && !_dbv[ dbv_idx ]) {
      first_null_idx     = dbv_idx;           
      first_null_idx_set = TRUE;
    }
  }

  TRACE(4, fprintf(_trace_fp, "_db_add: found_free=%d, free_idx=%u "
                   "first_null_idx_set=%d, first_null_idx=%u\n",
                   found_free, free_idx,
                   first_null_idx_set, first_null_idx););

  /* if an unused allocated slot was found */
  if (found_free) {
    TRACE(3, fprintf(_trace_fp, "_db_add: Reusing db handle %u\n", free_idx););

    _dbv[ free_idx ]->dbh = free_idx;
    _dbv[ free_idx ]->used = TRUE ; /* set the in use flag *before* releasing the mutex */

  } else { 
    /* alloc a new if possible */
    if (first_null_idx_set) {

      TRACE(3, fprintf(_trace_fp,"_db_add: Added new handle %u\n", first_null_idx););
      _dbv[ first_null_idx ] = MALLOC(sizeof(sqlo_db_t)) ;
      
      if (_dbv[ first_null_idx ]) {
        TRACE(4, fprintf(_trace_fp,"_db_add: Allocated %u bytes\n", 
                         (unsigned int) sizeof(sqlo_db_t)););
        memset(_dbv[ first_null_idx ], 0, sizeof(sqlo_db_t)) ;
        
        _dbv[ first_null_idx ]->dbh  =  first_null_idx;
        _dbv[ first_null_idx ]->used = TRUE ; /* set this flag *before* releasing the mutex */
        free_idx = first_null_idx;
      } else {
        /* alloc failed */
        EXEC_WHEN_THREADING(_dbv_unlock(););   /* end of critical section */
        return (NULL);
      }
    } else {
      /* no free slots */
      EXEC_WHEN_THREADING(_dbv_unlock(););   /* end of critical section */
      return (NULL);
    }
  }


  EXEC_WHEN_THREADING(_dbv_unlock();); /* end of critical section */

  return (_dbv[ free_idx ]) ;
}



/*-------------------------------------------------------------------------*/
/**
 * Release a database in _dbv[].
 * Marks it as unused and frees all allocated handles.
 *
 * @param dbp - I The pointer to the database structure
 */
static void
DEFUN(_db_release, (dbp), sqlo_db_ptr_t dbp)
{
  if (!dbp)
    return;

  TRACE(2, fprintf(_get_trace_fp(dbp), "_db_release[%u] starts\n", dbp->dbh); );

  if (dbp->srvhp)
    (void)OCIHandleFree((dvoid *) dbp->srvhp, OCI_HTYPE_SERVER);

  if (dbp->svchp)
    (void)OCIHandleFree((dvoid *) dbp->svchp, OCI_HTYPE_SVCCTX);

  if (dbp->errhp)
    (void)OCIHandleFree((dvoid *) dbp->errhp, OCI_HTYPE_ERROR);

  if (dbp->authp)
    (void)OCIHandleFree((dvoid *) dbp->authp, OCI_HTYPE_SESSION);

  if (dbp->envhp)
    (void)OCIHandleFree((dvoid *) dbp->envhp, OCI_HTYPE_ENV);

  dbp->srvhp = NULL;
  dbp->svchp = NULL;
  dbp->errhp = NULL;
  dbp->authp = NULL;
  dbp->envhp = NULL;

  if (dbp->tnsname) {
    FREE(dbp->tnsname);
    dbp->tnsname = NULL;
  }

  /* close the trace file */
  if (dbp->trace_fp) {
    fclose(dbp->trace_fp);
    dbp->trace_fp = NULL;
  }

⌨️ 快捷键说明

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