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

📄 sqlora.c

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

  dbp->errcode = 0;
  *(dbp->errmsg) = '\0';
  dbp->status = 0;

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

  dbp->attached = FALSE;
  dbp->session_created = FALSE;
  dbp->used = FALSE;

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



/*---------------------------------------------------------------------------*/
/**
 * Returns the thread id of this thread.
 * @return The thread id
 */
static inline sqlo_thread_t
DEFUN_VOID(_get_thread_id) 
{
#ifdef ENABLE_PTHREADS
  return pthread_self();
#elif ENABLE_ORATHREADS
  sqlo_thread_t tid = NULL;
  OCIThreadIdInit(_oci_envhp, _oci_errhp, &tid);
  OCIThreadIdGet(_oci_envhp, _oci_errhp, tid);
  return tid;
#endif
  return 0;
}




/*-------------------------------------------------------------------------*/
/**
 * Resets the number of bindpv entries.
 */
static void
DEFUN(_bindpv_reset, (stp), sqlo_stmt_ptr_t  stp)
{
  unsigned int bindp_idx;

  if (stp) {
    for (bindp_idx = 0; bindp_idx < stp->num_bindpv; ++bindp_idx) {
      stp->bindpv[ bindp_idx ] = NULL;
    }

    stp->num_bindpv = 0;

  }

}

/*---------------------------------------------------------------------------*/
/**
 * Compares two thread ids and returns if they are equal
 * @return TRUE if they are equal, FALSE if not.
 */
static inline bool_t
DEFUN(_thread_id_equal, (id1, id2), sqlo_thread_t id1 AND sqlo_thread_t id2)
{
#if ENABLE_ORATHREADS
  boolean result;
  OCIThreadIdSame(_oci_envhp, _oci_errhp, id1, id2, &result);
  return result ? TRUE : FALSE;
#else
  return id1 == id2 ? TRUE : FALSE;
#endif

}



/*-------------------------------------------------------------------------*/
/**
 * Adds a new stmt to @ref _stmtv[].
 * Allocates either a new entry in _stmtv[], or returns an unused.

 * @param dbp I - The database ptr.
 * @return The new entry, marked as used.
 */
static sqlo_stmt_ptr_t 
DEFUN(_get_stmt_ptr, (dbp), const_sqlo_db_ptr_t dbp)
{
  register unsigned stmt_idx;
  unsigned int first_null_idx;                       /* first null slot */
  unsigned int free_idx;
  bool_t found_free;
  bool_t first_null_idx_set;

  register sqlo_stmt_ptr_t *stpp;

  /* check for initialization */
  if ((! _sqlo_init) || (_stmtv_size <= 0))
    return (NULL) ;
  
  EXEC_WHEN_THREADING( _stmtv_lock(); );  /* start of critical section */
  
  /* we need to check first if there is an unused allocated slot */
  first_null_idx_set = FALSE;
  found_free         = FALSE;
  free_idx           = 0;
  first_null_idx     = 0;

  for (stmt_idx = 0, stpp = _stmtv; stmt_idx < _stmtv_size; ++stmt_idx, ++stpp) {
    if ((*stpp) && (! (*stpp)->used)) {  /* free slot found */
      free_idx   = stmt_idx;
      found_free = TRUE;
      break ;
    } else if ( !first_null_idx_set && !*stpp) {
      first_null_idx     = stmt_idx;               /* save the first null slot */
      first_null_idx_set = TRUE;
      break;
    }
  }
  
  /* an unused allocated slot was found */
  if (found_free) {
    stpp = &_stmtv[ free_idx ];
    TRACE(3, fprintf(_get_trace_fp(dbp),
                     "_get_stmt_ptr: Reusing handle %u\n", free_idx););
    (*stpp)->sth = free_idx ;
    (*stpp)->used = TRUE ; /* set this flag *before* releasing the mutex */

  } else { /* we need to find a NULL slot and allocate it */

    if (first_null_idx_set) {  
      TRACE(3, fprintf(_get_trace_fp(dbp), "_get_stmt_ptr: Added new handle %u\n", 
                       first_null_idx););

      stpp = &_stmtv[ first_null_idx ];
      *stpp = MALLOC(sizeof(sqlo_stmt_t)) ;

      if (*stpp) {
        TRACE(4, fprintf(_get_trace_fp(dbp), "_get_stmt_ptr: Allocated %u bytes\n", 
                         (unsigned int)sizeof(sqlo_stmt_t)););
        memset( *stpp, 0, sizeof(sqlo_stmt_t)) ;
        (*stpp)->sth  = first_null_idx ;
        (*stpp)->used = TRUE ; /* set the in use flag *before* releasing the mutex */

      } else {
        EXEC_WHEN_THREADING( _stmtv_unlock(); );   /* end of critical section */
        return (NULL) ;
      }

    } else {
      /* no null slot found */
      EXEC_WHEN_THREADING( _stmtv_unlock(); );   /* end of critical section */
      return (NULL) ;
    }
  }

  EXEC_WHEN_THREADING((*stpp)->thread_id = _get_thread_id(););

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

  return (*stpp) ;
}


/*-------------------------------------------------------------------------*/
/**
 * Releases a statement.
 * Release is done by setting used to 0.
 */
#ifdef CC_PRAGMA_INLINE
#define PRAGMA INLINE _stmt_release
#endif
static inline void
DEFUN(_stmt_release, (stp), sqlo_stmt_ptr_t  stp)
{
  EXEC_WHEN_THREADING(_stmtv_lock(););  /* enter critical section */

  stp->thread_id = 0;

  stp->used = FALSE;

  EXEC_WHEN_THREADING(_stmtv_unlock();); /* leave critical section */
}


/*-------------------------------------------------------------------------*/
/**
 * Initializes the stmt structure
 * Sets the dbp into stp and copies stmt into the structure.
 * @return SQLO_SUCCESS or SQLO_ERRMALLOC
 */
static int
DEFUN(_stmt_init, (stp, dbp, stmt),
       sqlo_stmt_ptr_t  stp AND
       sqlo_db_ptr_t  dbp AND
       const char *stmt)
{
  unsigned int len = (unsigned int)strlen(stmt) + 1;

  stp->dbp       = dbp;
  stp->stmthp    = NULL;
  stp->stype     = 0;
  stp->opened    = FALSE;
  stp->prepared  = FALSE;
  stp->still_executing = FALSE;
  stp->num_executions  = 0;
  stp->cursor_type = DEFAULT;


  if (!stp->stmt) {
    if ( MIN_STMT_SIZE > len )
      len = MIN_STMT_SIZE;
    
    ERRMALLOC(stp->dbp, stp->stmt, sizeof(char) * len, 
              "_stmt_init(alloc stmt)", SQLO_ERRMALLOC);
    stp->stmt_size = len;
    
  } else if (stp->stmt_size < len ) {
    
    ERREALLOC(stp->dbp, stp->stmt, sizeof(char) * len, 
              "_stmt_init(realloc stmt))", SQLO_ERRMALLOC);
    stp->stmt_size = len;
  }

  strcpy(stp->stmt, stmt);
    
  return SQLO_SUCCESS;
}


/*-------------------------------------------------------------------------*/
/**
 * Creates a new stmt.
 * Allocates the stmt entry via @ref _get_stmt_ptr, allocates the statement handle and
 * initializes the structure.
 * The stmt structure is initialized.
 * 
 * @return SQLO_SUCCESS or < 0 on error.
 */
static int
DEFUN(_stmt_new, (dbp, stmt, stpp),
       sqlo_db_ptr_t  dbp AND
       const char * stmt AND
      sqlo_stmt_ptr_t *stpp)
{
  register sqlo_stmt_ptr_t  stp;
  int status;

  stp = _get_stmt_ptr(dbp);

  if (! stp) {
    sprintf(dbp->errmsg, "SLQORALIB *** FATAL *** : allocation of statement failed") ;
    return SQLO_ERRMALLOC;
  }

  /* init the structure */
  if (SQLO_SUCCESS != (status = _stmt_init(stp, dbp, stmt))) {
    _stmt_release(stp);
    return SQLO_ERROR;
  }

  /* 
   * Allocate the statement handle
   */
  status = OCIHandleAlloc( (dvoid *) dbp->envhp, (dvoid **) &stp->stmthp,
                           OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);
  if (status) {
    _stmt_release(stp);
    return status;
  }  
  *stpp = stp;

  return SQLO_SUCCESS;
}


/*-------------------------------------------------------------------------*/
/**
 *
 * (Re)allocates space for stp->bindpv[] and stp->indpv[] if necessary.
 * Sets stp->bindpv_size to the new size.
 * Allocates always in steps of MIN_BINDP, to avoid too many reallocations.
 *
 * @param stp  I - The statement pointer.
 * @param size I - The requested size.
 * 
 * @return <ul>
 * <li>SQLO_SUCCESS on error.
 * <li>SQLO_ERRMALLOC on failure.
 * </ul>
 */
static int 
DEFUN(_alloc_bindp, (stp, size), 
      sqlo_stmt_ptr_t  stp AND 
      unsigned int size)
{
  if (!stp->bindpv_size ) {    /* complety empty ? */

    /* allocate MIN_BINDP to avoid a lot of reallocations */
    if (size < MIN_BINDP)
      size = MIN_BINDP;

    TRACE(4, fprintf(_get_trace_fp(stp->dbp),
                     "_alloc_bindp: alloc sth: %u to %u elements\n",
                     stp->sth, size););

    ERRMALLOC(stp->dbp, stp->bindpv, sizeof(OCIBind*) * size,
              "_alloc_bindp(bindp)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->indpv, sizeof(short) * size, 
              "_alloc_bindp(ind)", SQLO_ERRMALLOC);

    stp->bindpv_size = size;
    _bindpv_reset(stp);

    memset(stp->bindpv, 0, size * sizeof(OCIBind*));
    memset(stp->indpv,  0, size * sizeof(short));

  } else {
    /* Still enough space, or realloc necessary? */
    if (size > stp->bindpv_size) {
      size = 2 * size; /* alloc twice as much, so we don't have to realloc it too often */

      TRACE(4, fprintf(_get_trace_fp(stp->dbp),
                       "_alloc_bindpv: realloc sth: %u to %u elements\n",
                       stp->sth, size););

      ERREALLOC(stp->dbp, stp->bindpv, sizeof(OCIBind*) * size,
                "sqlo_realloc_bind(bindpv)",  SQLO_ERRMALLOC );

      ERREALLOC(stp->dbp, stp->indpv, sizeof(short) * size,  
                "sqlo_realloc_bind(indp)", SQLO_ERRMALLOC );

      stp->bindpv_size = size;
      /* init the new elements */
      size = size - stp->bindpv_size; /* number of elements to be initialized */
      memset(&stp->bindpv[ stp->bindpv_size ], 0, size * sizeof(OCIBind *));
      memset(&stp->indpv[ stp->bindpv_size ],  0, size * sizeof(short));

    }
  }
  return(SQLO_SUCCESS);
}


/*-------------------------------------------------------------------------*/
/**
 * (Re)allocates more space for output variables.
 * (Re)allocates more space for stp->ocolsv[], stp->outv,
 * stp->defnpv, stp->ocol_namev_size and stp->ocol_namev.
 * Sets stp->defnpv_size is set to the new size.
 * Allocates always in steps of MINUM_DEFNPV, to avoid too much memory free/allocs
 *
 * @param stp  I - The statement pointer
 * @param size I - The requested size.
 *
 * @return <ul>
 * <li>SQLO_SUCCESS on error.
 * <li>SQLO_ERRMALLOC on failure.
 * </ul>
 */
static int 
DEFUN(_alloc_definep, (stp, size),  sqlo_stmt_ptr_t  stp AND unsigned int size)
{
  register unsigned int i;

  if (!stp->defnpv_size ) {     /* complety empty ? */

    /* allocate MIN_DEFNP to avoid a lot of reallocations */
    if (size < MIN_DEFNP)
      size = MIN_DEFNP;

    TRACE(4, fprintf(_get_trace_fp(stp->dbp),
                     "_alloc_definep: alloc sth: %u for %u columns\n",
                     stp->sth, size););

    ERRMALLOC(stp->dbp, stp->defnpv, sizeof(OCIDefine *) * size, 
              "_alloc_definep(alloc defnpv)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->ocolsv, sizeof(sqlo_col_t) * size, 
              "_alloc_definep(alloc ocols)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->outv, sizeof(char *) * size, 
              "_alloc_definep(alloc outv)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->outv_size, sizeof(int) * size, 
              "_alloc_definep(alloc outv_size)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->oindv, sizeof(ub2) * size, 
              "_alloc_definep(alloc oindv)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->rlenv, sizeof(ub2) * size, 
              "_alloc_definep(alloc rlenv)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->ocol_namev, sizeof(char *) * size, 
              "_alloc_definep(alloc ocol_namev)", SQLO_ERRMALLOC);

    ERRMALLOC(stp->dbp, stp->ocol_namev_size, sizeof(int) * size, 
              "_alloc_definep(alloc ocol_namev_size)", SQLO_ERRMALLOC);

    memset(stp->defnpv, 0,  sizeof(OCIDefine *) * size);
    memset(stp->ocolsv, 0, sizeof(sqlo_col_t) * size);
    memset(stp->outv, 0, sizeof(char *) * size);
    memset(stp->outv_size, 0, sizeof(int) * size);
    memset(stp->oindv, 0, sizeof(ub2) * size);
    memset(stp->rlenv, 0, sizeof(ub2) * size);
    memset(stp->ocol_namev, 0, sizeof(char *) * size);
    memset(stp->ocol_namev_size, 0, sizeof(int) * size);

⌨️ 快捷键说明

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