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

📄 sqlora.c

📁 一个很好用的Linux/Unix下Oracle OCI开发接口封装库
💻 C
📖 第 1 页 / 共 5 页
字号:
  sb4 errcode;                                 /**< The last oracle error code */

  OCIEnv * envhp;               /**< pointer to the OCI environment for the thread */

  OCIStmt * stmthp;               /**< @ref sqlo_exec stores its stmthp here.
                                     This is not dangerous, because during a non-blocking
                                     OCI call, you cannot open other stmts 
                                  */

  /* CONTROL FLAGS */
  bool_t used;                    /**< Flag, if this one is in use or not */
  bool_t attached;                /**<  not zero, if we are attached to the server */
  bool_t session_created;         /**< not zero, if a session was created */

  FILE * trace_fp;              /**< connection specific trace file */

} sqlo_db_t, * sqlo_db_ptr_t;

/**
 * This pointer type defines a pointer to a const sqlo_db_t.
 */
typedef const sqlo_db_t * const_sqlo_db_ptr_t;

struct _sqlo_stmt_t;

/**
 * Stores information about a column in the select list.
 * This structure is not used if you bind the select list manually be
 * @ref sqlo_define_by_pos or @ref sqlo_define_by_pos2.
 */
typedef struct  {

  unsigned pos;                /**< The position in the select list (0 based).
   * This variable can be used to address the right
   * data or ind element in the stmt structure. */

  OCIParam * paramd;           /**< The parameter handle pointer used to describe
   * an output column
   */
  ub2  dtype;                   /**< The datatype (@ref sqlo_data_types) */

  char * col_name;              /**< The column name */

  unsigned col_name_size;       /**< The max allocated length of col_name */

  ub2  dbsize;                  /**< The size in the database */

  ub1  prec;                    /**< The precision */

  ub1  scale;                   /** The scale */

  ub1  nullok;                  /**< Flag: Null allowed */

  struct _sqlo_stmt_t * stp;    /**< link to the stmt structure (see @ref sqlo_stmt_t) */

} sqlo_col_t, * sqlo_col_ptr_t;

/**
 * Stores information about an sql statement.
 * This structure stores all OCI handles plus the data buffers used to
 * retrieve the data.
 */
typedef struct {
  unsigned sth;                     /**< The own handle that identifies this entry */

  sqlo_db_ptr_t  dbp;               /**< The link to the database connection (see @ref sqlo_db_t). */ 

  OCIStmt * stmthp;              /**< The OCI statement handle pointer. */


  char * stmt;                   /**< The sql statement. */

  unsigned stmt_size;           /**< The allocated size of  stmt. */

  /* INPUT */
  OCIBind ** bindpv;             /**< The vector of input bind variables. */

  unsigned num_bindpv;          /**< The number of used entries in bindpv[]. */

  unsigned bindpv_size;         /**< The current capacity of size of bindpv[] and indp[]. */

  ub2 stype;                    /**< The OCI Statement type (see oci.h). */

  short * indpv;                /**< Indicator variable vector for input bind variables. */
  
  /* OUTPUT */
  sqlo_col_t * ocolsv;           /**< The output columns of the select list. */

  OCIDefine ** defnpv;           /**< The OCI define pointers. */

  unsigned num_defnpv;          /**< The current number of output variables. */

  unsigned defnpv_size;         /**< The current size of the arrays defnpv, outv, 
                                   outv_size,  oindv, rlenv, ocol_namev_size and 
                                   ocol_namev_size.
                                */

  char ** outv;                 /**< The output columns as a vector. 
                                   See @ref sqlo_values. 
                                */

  unsigned * outv_size;         /**< The current size of an outv[i] element */

  ub2 * oindv;                  /**< The indicator array for output variables */

  ub2 * rlenv;                  /**< The  actual length of a returned column. */

  char ** ocol_namev;           /**< Output column names. 
                                   The actual number of filled entries is num_defnpv#.
                                */

  unsigned * ocol_namev_size;        /**< The sizes of a colum name  in ocol_namev[]. */

  sqlo_cursor_type_e cursor_type; /**< The cursor type see @ref sqlo_cursor_type_e */

  /* status flags */
  bool_t opened;                            /**< 1 if the cursor is open, 0 if not. */ 

  bool_t prepared;                   /**< 1 if the statement is prepared, 0 if not. */

  bool_t used;             /**< 1 indicates that this structure is in use, 0 if not. */

  bool_t still_executing;  /**< Is 1 in non-blocking mode and a call 
                              to OCIStmtExecute returned OCI_STILL_EXECUTING 
                           */

  bool_t num_executions;       /**< number of times the statement was executed */

  sqlo_thread_t thread_id; /**< The thread id of the thread who opened this cursor */

} sqlo_stmt_t, * sqlo_stmt_ptr_t;

/**
 * This pointer type defines a pointer to a const sqlo_stmt_t.
 */
typedef const sqlo_stmt_t * const_sqlo_stmt_ptr_t;

/**
 * Structure to store parameter name, pointer to the variable
 * and a optional trigger fct, that is executed when parameter is 
 * changed. 
 * @see g_params.
 */
typedef struct {
  char * name;                                          /**< parameter name */

  enum {INTEGER, STRING} vtyp;                           /**< type of value */

  VOID * value;                               /**< The address of the value */

  int (*trigger_fct) __P((int));       /**< Function that handles this type */

} sqlora_param_t;

/*-------------------------------------------------------------------------
 * EXPORTED GLOBALS
 *-----------------------------------------------------------------------*/

/* define some variables where the user can check the version */
const unsigned sqlo_major_version = LIBSQLORA8_MAJOR_VERSION;
const unsigned sqlo_minor_version = LIBSQLORA8_MINOR_VERSION;
const unsigned sqlo_micro_version = LIBSQLORA8_MICRO_VERSION;
const unsigned sqlo_interface_age = LIBSQLORA8_INTERFACE_AGE;
const unsigned sqlo_binary_age    = LIBSQLORA8_BINARY_AGE;

/* for backward compatibility */
const unsigned sqlora8_major_version = LIBSQLORA8_MAJOR_VERSION;
const unsigned sqlora8_minor_version = LIBSQLORA8_MINOR_VERSION;
const unsigned sqlora8_micro_version = LIBSQLORA8_MICRO_VERSION;
const unsigned sqlora8_interface_age = LIBSQLORA8_INTERFACE_AGE;
const unsigned sqlora8_binary_age    = LIBSQLORA8_BINARY_AGE;


/*-------------------------------------------------------------------------
 * MODULE GLOBAL VARIABLES
 *-----------------------------------------------------------------------*/

/**
 * @var _errmsg
 * A buffer for the error messages.
 * This buffer is used when the connection specific buffer cannot be used,
 * because there is no db structure allocated.
 */
static char _errmsg[SQLO_MAX_ERRMSG_LEN+1];

/**
 * @var _oci_init_mode
 * The mode of the library.
 * Either OCI_DEFAULT or OCI_THREADED.
 */
static int _oci_init_mode = OCI_DEFAULT; /* the mode we initialize the OCI lib */


/**
 * @var _max_long_size
 *
 * The maxiumum length of a LONG result.
 * Can be changed by setting the environment variable SQLORA_LONGSIZE.
 * Default is @ref MAX_LONG_SIZE.
 */
static unsigned int _max_long_size = MAX_LONG_SIZE; 

/**
 * @var _dbv
 * The array of @ref sqlo_db_t pointers.
 * The array is allocated in @ref sqlo_init with the size of the passed max_db
 * parameter. 
 * The array is proteced by the mutex @ref _dbv_mux when compiled with threading
 * enabled.
 */
static sqlo_db_t ** _dbv = NULL; /* array for database connections */

/**
 * @var _dbv_size
 * The size of the @ref _dbv[].
 */
static unsigned int _dbv_size = 0;           /* number of available entries in _dbv[] */

/**
 * @var _env_mux
 * A mutex to protect the call to OCIEnvCreate
 */
#if ENABLE_PTHREADS
static pthread_mutex_t _env_mux = PTHREAD_MUTEX_INITIALIZER;
#elif ENABLE_ORATHREADS
static OCIThreadMutex *_env_mux;
#endif

/**
 * @var _dbv_mux
 * A mutex to protect @ref _dbv.
 * @see _dbv_lock, _dbv_unlock
 */
#if ENABLE_PTHREADS
static pthread_mutex_t _dbv_mux = PTHREAD_MUTEX_INITIALIZER;
#elif ENABLE_ORATHREADS
static OCIThreadMutex *_dbv_mux; 
#endif

/**
 * @var _stmtv_mux
 * A mutex to protect the array @ref _stmtv when compiled in threaded mode.
 */
#if ENABLE_PTHREADS
static pthread_mutex_t _stmtv_mux = PTHREAD_MUTEX_INITIALIZER;
#elif ENABLE_ORATHREADS
static OCIThreadMutex *_stmtv_mux;
#endif

/**
 * @var _stmtv
 * A array to store all @ref sqlo_stmt_t pointers.
 * This array is allocated in @ref sqlo_init with the size of
 * the parameter max_cursors.
 * The array is proteced by the mutex @ref _stmtv_mux when compiled in threaded mode.
 */
static sqlo_stmt_t **_stmtv = NULL; /* array to hold statements */

/**
 * @var _stmtv_size
 * The max size of @ref _stmtv.
 */
static unsigned int _stmtv_size = 0;             /* max size of _stmtv[] */



/**
 * @var _num_prefetch_rows
 * The number of rows Oracle should prefetch for us.
 * The variable is initialized with @ref DEF_PREFETCH_ROWS, but can
 * be changed by the environment variable SQLORA_PREFETCH_ROWS.
 */
static ub4 _num_prefetch_rows = DEF_PREFETCH_ROWS; /* out prefetch value */

/**
 * @var _sqlo_init
 * A flag indicating if the library was successfully initialized
 */
static int _sqlo_init = 0;                      /* Is set to 1 by sqlo_init */

/**
 * @var _trace_level
 *
 * The trace level of the library.
 * The level is initialized from the environment variable SQLORA_TRACE_LEVEL
 *
 * <ul>
 * <li>0 : Trace disabled (default)
 * <li>1 : Print errors to tracefile
 * <li>2 : Print function calls to tracefile
 * <li>3 : Print more detailed information to tracefile
 * <li>4 : Print also malloc/realloc operations.
 * </ul>
 */
static int _trace_level = 0; 

/**
 * @var _trace_file
 * The name of the trace file.
 * Default is sqlora8.trc, but can be changed by setting the environment
 * variable SQLORA_TRACE_FILE
 */
static char _trace_file[MAX_PATH_LEN+1] = "";

/* These handles are needed by the Oracle OCIThread package.
 * We cannot use the ones in _dbv, because this is the structure
 * we want to protect.
 */
#ifdef ENABLE_ORATHREADS
static OCIEnv *_oci_envhp;
static OCIError *_oci_errhp;
#endif


/**
 * @var DEFAULT_TRACE_FNAME
 * The default trace filename.
 */
static const char * DEFAULT_TRACE_FNAME = "sqlora8.trc"; 

static FILE * _trace_fp = NULL;     /**< The filepointer of the global tracefile  */

static unsigned int _session_count = 0; /**< The nubmer of created sessions. Used to name the trace file */

/*---------------------------------------------------------------------------
 * PROTOTYPES
 *--------------------------------------------------------------------------*/
/* functions needed in threaded mode */
static int _init_mutexes __P((void));
static int _dbv_lock __P((void));
static int _dbv_unlock __P((void));
static int _stmtv_lock __P((void));
static int _stmtv_unlock __P((void));
static int _env_lock __P((void));
static int _env_unlock __P((void));

static int _sqlo_getenv __P((void));

static int _save_oci_status __P((sqlo_db_ptr_t dbp, 
                                 const char *action, 
                                 const char *object, 
                                 int lineno));

static int _bind_argv __P(( sqlo_stmt_ptr_t  stp, unsigned int argc, const char ** argv));

static int _bind_by_pos __P((sqlo_stmt_ptr_t  stp, unsigned int param_pos, int param_type,
                            const void * param_addr, unsigned int  param_size,
                            short * ind_addr, int is_array));

static int _bind_by_pos2 __P((sqlo_stmt_ptr_t  stp, unsigned int param_pos, int param_type,
                            const void * param_addr, unsigned int  param_size,
                            short * ind_addr, unsigned short * rcode_addr, 
                               unsigned int skip_size));

static void _strip_string __P((char *s, unsigned int len));

static int _define_ocol_by_pos __P((sqlo_stmt_ptr_t stp, sqlo_col_t *colp, 
                                    unsigned int pos));

static int _define_output __P((sqlo_stmt_ptr_t stp));
static int _open_trace_file __P((sqlo_db_ptr_t dbp));
static sqlo_stmt_ptr_t _get_stmt_ptr __P((const_sqlo_db_ptr_t dbp));
static int _stmt_new __P((sqlo_db_ptr_t dbp, const char * stmt, sqlo_stmt_ptr_t *stpp));
static void _stmt_release __P((sqlo_stmt_ptr_t  stp));
static void _bindpv_reset __P((sqlo_stmt_ptr_t  stp));
static int _stmt_init __P((sqlo_stmt_ptr_t  stp, sqlo_db_ptr_t dbp, const char *stmt));

static const char * _get_stmt_type_str __P((int stype));
static const char * _get_data_type_str __P((int dtype));
static sqlo_db_ptr_t _db_add __P((void));
static void _db_release __P((sqlo_db_ptr_t dbp));

static int _define_by_pos __P((sqlo_stmt_ptr_t  stp, unsigned int value_pos, 
                               int value_type, const void * value_addr, 
                               unsigned int  value_size, short * ind_addr, 
                               ub2 * rlen_addr, ub2 * rcode_addr, int is_array));

static int _define_by_pos2 __P((sqlo_stmt_ptr_t  stp, unsigned int value_pos, 
                                int value_type, const void * value_addr, 
                                unsigned int  value_size, short * ind_addr, 
                                ub2 * rlen_addr, ub2 * rcode_addr, 
                                unsigned int skip_size));

static  int _calc_obuf_size __P(( unsigned int *bufsizep, unsigned int data_type,
                                  int prec, int scale, unsigned int dbsize));

static int _get_blocking_mode __P((sqlo_db_ptr_t dbp, unsigned * blocking));

static int _get_errcode __P(( sqlo_db_ptr_t dbp));

static int _set_prefetch_rows __P((sqlo_stmt_ptr_t stp, unsigned int nrows));

static const char * _get_stmt_string __P((sqlo_stmt_ptr_t stp));
static int _get_stmt_state __P((sqlo_stmt_ptr_t stp));
static int _alloc_definep __P((sqlo_stmt_ptr_t stp, unsigned int size));
static int _alloc_bindp __P((sqlo_stmt_ptr_t stp, unsigned int size));
static void _close_all_db_cursors __P((const_sqlo_db_ptr_t dbp));
static void _close_all_executing_cursors __P((const_sqlo_db_ptr_t dbp));
static FILE * _get_trace_fp __P((const_sqlo_db_ptr_t dbp));
static int _prepare __P((const_sqlo_stmt_ptr_t stp, const char * stmt, ub2 * stmt_type));
static sqlo_thread_t _get_thread_id __P((void));
static bool_t _thread_id_equal __P(( sqlo_thread_t id1, sqlo_thread_t id2));

/* Prototypes of functions not present in oracle header files */
int osnsui __P((int * handlep, sqlo_signal_handler_t signal_handler, char * ctx));
int osncui __P((int handle));

/*---------------------------------------------------------------------------
 * END PROTOTYPES
 *--------------------------------------------------------------------------*/

⌨️ 快捷键说明

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