📄 sqlora.c
字号:
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 + -