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

📄 sqlora.c

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

  } else {
    /* Still enough space, or realloc necessary? */
    if (size > stp->defnpv_size) {

        size = 2 * size; /* alloc twice as much, so we don't have to realloc too often */

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

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

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

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

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

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

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

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

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

      /* init the new elements */
      i = size - stp->defnpv_size;

      memset(&stp->defnpv[ stp->defnpv_size ], 0,  sizeof(OCIDefine *) * i);

      memset(&stp->ocolsv[ stp->defnpv_size ], 0, sizeof(sqlo_col_t) * i);

      memset(&stp->outv[ stp->defnpv_size ], 0, sizeof(char*) * i);

      memset(&stp->outv_size[ stp->defnpv_size ], 0, sizeof(int) * i);

      memset(&stp->oindv[ stp->defnpv_size ], 0, sizeof(ub2) * i);

      memset(&stp->rlenv[ stp->defnpv_size ], 0, sizeof(ub2) * i);

      memset(&stp->ocol_namev_size[ stp->defnpv_size ], 0, sizeof(int) * i);

      stp->defnpv_size = size;
    }
  }
  return(SQLO_SUCCESS);
}


/*-------------------------------------------------------------------------*/
/**
 * Set our parameters from the environment.
 * @return <ul>
 * <li> SQLO_SUCCESS
 * <li> != 0 on error
 * </ul>
 */
static int
DEFUN_VOID(_sqlo_getenv)
{
  register int i;
  char * ep;
  char vname[MAX_VNAME_LEN+1];

  /* Preset trace file name */
  strcpy(_trace_file, DEFAULT_TRACE_FNAME);
  
  /* 
   * Get the parameters from the environment 
   */
  for ( i = 0; g_params[i].name ; i++) {
    sprintf(vname, "SQLORA_%s", g_params[i].name);
    ep = vname;

    if ( NULL != (ep = getenv(vname)) && strlen (getenv(vname)) ) {
      switch (g_params[i].vtyp) {
      case INTEGER:
        if (g_params[i].value)
          *((int*) g_params[i].value) = atoi (ep); 
        break;
      case STRING:
        if (g_params[i].value)
          strcpy( (char *) g_params[i].value, ep); 
        break;
      default:
        break;
      }
      if (g_params[i].trigger_fct)
        if (SQLO_SUCCESS != g_params[i].trigger_fct(i))
          return SQLO_ERROR;
    }
  }
  return SQLO_SUCCESS;
} 

/*-------------------------------------------------------------------------*/
/**
 * Opens the trace file.
 *
 * If open fails, an error is printed to stderr.
 * If _trace_level is 0 the trace file will be closed.
 * @param dbp I - The databse pointer (NULL allowed for global trace file).
 * @return  Returns SQLO_SUCCESS or SQLO_ERROR.
 */
static int 
DEFUN(_open_trace_file, (dbp), sqlo_db_ptr_t dbp)
{
  /* If dbp is null, we open the global trace file, else we open a session specific trace file */
  if (NULL == dbp) {
    if (_trace_level > 0 && !_trace_fp) {
      if (NULL == (_trace_fp = fopen(_trace_file, "w"))) {
        fprintf(stderr,"Cannot open %s (errno=%d)\n", _trace_file, errno);
        return SQLO_ERROR;
      }
      fprintf(_trace_fp, "\n**** Starting new trace log ****\n");

    } else if ( 0 == _trace_level && _trace_fp ) {
      fclose(_trace_fp); 
      _trace_fp = NULL;
    }
  } else {
    if (_trace_level > 0) {
      char trace_file[MAX_PATH_LEN+1];
      /* Note: we open a session specific trace file, not a dbh specific one, because
       * dbh's may be recycled.
       */
      _session_count++;              /* increase the session counter */
      /* maybe the dbp holds already a open fp. Close it first */
      if (dbp->trace_fp)
        fclose(dbp->trace_fp);

      sprintf(trace_file, "%s%u", _trace_file, _session_count);
      
      if (NULL == (dbp->trace_fp = fopen(trace_file, "w"))) {
        fprintf(stderr,"Cannot open %s (errno=%d)\n", trace_file, errno);
        return SQLO_ERROR;
      }
      fprintf(dbp->trace_fp, 
              "\n**** Starting new trace log for dbh=%u session=%u ****\n", 
              dbp->dbh, _session_count);
    }
  }
  return SQLO_SUCCESS;
}


/*-------------------------------------------------------------------------*/
/**
 * Saves the error message for dbp->status.
 *
 * This function is called by @ref CHECK_OCI_STATUS_RETURN if dbp->status != 0.
 * If dbp->status is OCI_ERROR, dbp->errcode is set to the Oracle error code.
 * @param dbp    I - The database pointer
 * @param action I - A string identifying the action that lead to the status
 * @param object I - A string identifying the object where the action was executed on.
 * @param lineno I - The line in the source code, where the error occured.
 *
 * @return SQLO_SUCCESS
 */
static int
DEFUN(_save_oci_status, (dbp, action, object, lineno),
      sqlo_db_ptr_t  dbp AND 
      const char *action AND
      const char *object
      AND int lineno)
{
  char errbuf[SQLO_MAX_ERRMSG_LEN+1];
  unsigned int len;

  if (!dbp)
    return 0;

  if (!object)
    object = "";

  *errbuf = '\0';
  dbp->errcode = dbp->status;   /* preset with something usefull */
  TRACE(3, 
        if (dbp->status != OCI_SUCCESS) {
          fprintf(_get_trace_fp(dbp),"_save_oci_status: %d\n", dbp->status);
        }
        );
  switch (dbp->status) {

  case OCI_SUCCESS:
    break;
  
  case OCI_SUCCESS_WITH_INFO:
    (void) OCIErrorGet(dbp->errhp, (ub4) 1, (text *) NULL,
                       &dbp->errcode,
                       (text *)errbuf, (ub4) sizeof(errbuf), 
                       OCI_HTYPE_ERROR);
    sprintf(dbp->errmsg, 
            "%s\n(sqlora line: %d)\n", errbuf, lineno);
    break;

  case OCI_NEED_DATA:
    sprintf(dbp->errmsg, 
            "ERROR: OCI_NEED_DATA\n(sqlora line: %d)\n", lineno);
    break;

  case OCI_NO_DATA:
    sprintf(dbp->errmsg, 
            "ERROR: OCI_NO_DATA\n(sqlora line: %d)\n", lineno);
    break;

  case OCI_ERROR:

    (void)OCIErrorGet(dbp->errhp, (ub4) 1, (text *) NULL, &dbp->errcode,
                       (text *)errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
    sprintf(dbp->errmsg, 
            "%s\n(sqlora line: %d)\n", errbuf, lineno);

    break;

  case OCI_INVALID_HANDLE:
    sprintf(dbp->errmsg, 
            "ERROR: OCI_INVALID_HANDLE\n(sqlora line: %d)\n", lineno);
    break;

  case OCI_STILL_EXECUTING:
    sprintf(dbp->errmsg, 
            "ERROR: OCI_STILL_EXECUTING\n(sqlora line: %d)\n", lineno);
    break;

  case OCI_CONTINUE:
    sprintf(dbp->errmsg, 
            "ERROR: OCI_CONTINUE\n(sqlora line: %d)\n", lineno);
    break;

  case SQLO_INVALID_DB_HANDLE:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Invalid database handle.\n(sqlora line: %d)\n", 
            dbp->status, lineno);
    break;
  case SQLO_INVALID_STMT_HANDLE:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Invalid statement handle.\n(sqlora line: %d)\n", 
            dbp->status, lineno);
    break;
  case SQLO_STMT_NOT_OPENED:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Cursor is not open.\n(sqlora line: %d)\n", 
            dbp->status, lineno);
    break;
  case SQLO_STMT_NOT_PARSED:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Stmt is not prepared.\n(sqlora line: %d)\n", 
            dbp->status, lineno);
    break;
  case SQLO_INVALID_STMT_TYPE:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Sorry, this function cannot handle your type of statement.\n"
            "(sqlora line: %d)\n", dbp->status, lineno);
    break;

  case SQLO_INVALID_SQL:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8%05d: Invalid SQL parsed.\n"
            "(sqlora line: %d)\n", dbp->status, lineno);
    break;
  case SQLO_ERRMALLOC:
    /* concatenate the error message. */
    sprintf(&dbp->errmsg[strlen(dbp->errmsg)], 
            "LIBSQLORA8%05d: Memory allocation error.\n(sqlora line: %d)\n", dbp->status,
            lineno);
    break;

  default:
    sprintf(dbp->errmsg, 
            "LIBSQLORA8-00000: Unknown status %d\n(sqlora line: %d)\n", dbp->status,
            lineno);
    break;
  }

  if ((len = strlen (dbp->errmsg) + strlen (action) + strlen (object) + 40)
      > SQLO_MAX_ERRMSG_LEN)
    {
      len = SQLO_MAX_ERRMSG_LEN - strlen (dbp->errmsg) - strlen (action) - 40;
    }
  else
    len = (unsigned int) strlen(object);

  if (strlen(action) ) {
    sprintf (&dbp->errmsg[strlen(dbp->errmsg)], "\nSQL error while doing %s", action);

    if (len) {
      sprintf (&dbp->errmsg[strlen(dbp->errmsg)], " on:\n\"%*.*s\"", (int) len, 
               (int) len, object);
    }
  }
  strcat(dbp->errmsg,"\n");
  TRACE(1, (void) fputs(dbp->errmsg, _get_trace_fp(dbp)););
  strcpy(_errmsg, dbp->errmsg);
  return (SQLO_SUCCESS);
}


/*---------------------------------------------------------------------------*/
/**
 * Returns the statement type as a string.
 * @param stype The statement type
 * @return A constant string telling you the kind of statement.
 */
static const char *
DEFUN(_get_stmt_type_str, (stype), int stype)
{
  switch (stype) {
  case OCI_STMT_SELECT: return "SELECT"; break;
  case OCI_STMT_UPDATE: return "UPDATE"; break;
  case OCI_STMT_DELETE: return "DELETE"; break;
  case OCI_STMT_INSERT: return "INSERT"; break;
  case OCI_STMT_CREATE: return "CREATE"; break;
  case OCI_STMT_DROP: return "DROP"; break;
  case OCI_STMT_ALTER: return "ALTER"; break;
  case OCI_STMT_BEGIN: return "BEGIN"; break;
  case OCI_STMT_DECLARE: return "DECLARE"; break;
  default:
    return "UNKNOWN";
    break;
  }
}


/*---------------------------------------------------------------------------*/
/**
 * Returns the data type as string
 * @param dtype The data type
 * @return A constant string telling you the data type.
 */
static const char *
DEFUN(_get_data_type_str, (dtype), int dtype)
{
  /* the constants are defined in ocidfn.h */
  switch (dtype) {
  case SQLT_CHR: return "character string"; break;
  case SQLT_NUM: return "oracle numeric"; break;
  case SQLT_INT: return "integer"; break;
  case SQLT_FLT: return "floating point number"; break;
  case SQLT_STR: return "zero terminated string"; break;
  case SQLT_VNU: return "num with preceding length byte"; break;
  case SQLT_PDN: return "packed decimal numeric"; break;
  case SQLT_LNG: return "long"; break;
  case SQLT_VCS: return "variable character string"; break;
  case SQLT_NON: return "Null/empty PCC Descriptor entry "; break;
  case SQLT_RID: return "rowid"; break;
  case SQLT_DAT: return "date in oracle format"; break;
  case SQLT_VBI: return "binary in VCS format"; break;
  case SQLT_BIN: return "binary data(DTYBIN)"; break;
  case SQLT_LBI: return "long binary"; break;
  case SQLT_UIN: return "unsigned integer"; break;
  case SQLT_SLS: return "dispay sign leading separate"; break;
  case SQLT_LVC: return "longer longs (char)"; break;
  case SQLT_LVB: return "longer longs (binary)"; break;
  case SQLT_AFC: return "ansi fixed char"; break;
  case SQLT_AVC: return "ansi var char"; break;
  case SQLT_CUR: return "cursor type"; break;
  case SQLT_RDD: return "rowid descriptor"; break;
  case SQLT_LAB: return "label type"; break;
  case SQLT_OSL: return "oslabel type"; break;
  case SQLT_NTY: return "named object type"; break;
  case SQLT_REF: return "ref type"; break;
  case SQLT_CLOB: return "character lob"; break;
  case SQLT_BLOB: return "binary lob"; break;
  case SQLT_BFILEE: return "binary file lob"; break;
  case SQLT_CFILEE: return "character file lob"; break;
  case SQLT_RSET: return "result set type"; break;
  case SQLT_NCO: return "named collection type"; break;
  case SQLT_VST: return "OCIString type"; break;
  case SQLT_ODT: return "OCIDate type"; break;
  default:
    return "UNKNOWN";
    break;
  }
}


/*---------------------------------------------------------------------------*/
/** 
 * Strips all trailing blanks in s.
 * @param s   I - The string to strip
 * @param len I - The current string length.
 */
#if CC_PRAGMA_INLINE
#pragma INLINE _strip_string
#endif
static inline void 
DEFUN(_strip_string, (s, len), char * s AND unsigned int len )
{
  register char *p;

  for ( p = &s[len - 1]; len > 0 && ' ' == *p ; --len)
     *p = '\0';
}

/*---------------------------------------------------------------------------*/
/**
 * Returns the last error code. 
 * Saves it also 

⌨️ 快捷键说明

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