📄 sqlora.c
字号:
* Cursor types */typedef enum { DEFAULT = 0, /**< standard cursor */ REFCURSOR = 1, /**< ref cursor type */ NTABLE = 2 /**< nested table cursor */} sqlo_cursor_type_e;/** * Stores information about the database connection. */typedef struct _sqlo_db_struct { struct _sqlo_stmt_struct *stmtv; /**< The statements (cursors) for this connection */ unsigned int stmtv_size; /**< max size of stmtv[] */ ub4 dbh; /**< The db handle used to address this entry */ OCIServer * srvhp; /**< OCI server handle */ OCIError * errhp; /**< OCI error handle */ OCISvcCtx * svchp; /**< OCI service context handle */ OCISession * authp; /**< OCI authorization session handle */ OCIEnv * envhp; /**< pointer to the OCI environment for the thread */ char * tnsname; /**< The TNS name of the database */ int status; /**< The last status code */ char errmsg[SQLO_MAX_ERRMSG_LEN+1]; /**< The last error message */ sb4 errcode; /**< The last oracle error code */ 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_thread_t thread_id; /**< The thread id of the thread who opened this cursor */} sqlo_db_struct_t, * sqlo_db_struct_ptr_t;/** * This pointer type defines a pointer to a const sqlo_db_struct_t. */typedef const sqlo_db_struct_t * const_sqlo_db_struct_ptr_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 _sqlo_col_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. */ 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_struct_t * stp; /**< link to the stmt structure (see @ref sqlo_stmt_struct_t) */} sqlo_col_struct_t, * sqlo_col_struct_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 _sqlo_stmt_struct { ub4 sth; /**< The own handle that identifies this entry. This is the plain sth, not the encoded one. */ sqlo_db_struct_ptr_t dbp; /**< The link to the database connection (see @ref sqlo_db_struct_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_struct_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 */ unsigned num_executions; /**< number of times the statement was executed */} sqlo_stmt_struct_t, * sqlo_stmt_struct_ptr_t;/** * This pointer type defines a pointer to a const sqlo_stmt_struct_t. */typedef const sqlo_stmt_struct_t * const_sqlo_stmt_struct_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 _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_struct_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_struct_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 _max_cursors * The maximum number of cursors for one database connection */static unsigned int _max_cursors;/** * @var _env_mux * A mutex to protect the call to OCIEnvCreate */#ifdef ENABLE_THREADS# ifdef ENABLE_PTHREADS static pthread_mutex_t _env_mux = PTHREAD_MUTEX_INITIALIZER;# else# ifdef ENABLE_ORATHREADS static OCIThreadMutex *_env_mux;# else# ifdef ENABLE_WINTHREADS static HANDLE _env_mux;# endif# endif# endif#endif/** * @var _dbv_mux * A mutex to protect @ref _dbv. * @see _dbv_lock, _dbv_unlock */#ifdef ENABLE_THREADS# ifdef ENABLE_PTHREADS static pthread_mutex_t _dbv_mux = PTHREAD_MUTEX_INITIALIZER;# else# ifdef ENABLE_ORATHREADS static OCIThreadMutex *_dbv_mux; # else# ifdef ENABLE_WINTHREADS static HANDLE _dbv_mux;# endif# endif# endif#endif/** * @var _init_mux * A mutex to protect @ref _sqlo_init. */#ifdef ENABLE_THREADS# ifdef ENABLE_PTHREADS static pthread_mutex_t _init_mux = PTHREAD_MUTEX_INITIALIZER;# else# ifdef ENABLE_ORATHREADS static OCIThreadMutex *_init_mux; # else# ifdef ENABLE_WINTHREADS static HANDLE _init_mux;# endif# endif# endif#endif/** * @var _init_mux_initialized * Flag indicating if the _init_mux was initialized */#ifdef ENABLE_THREADSstatic int _init_mux_initialized = 0; /* Is set to 1 in _init_init_mux */#endif/** * @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_ORATHREADSstatic 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 */static char _errmsg[SQLO_MAX_ERRMSG_LEN+1]; /**< The variable for error messages when no dbp->errmsg is available *//*--------------------------------------------------------------------------- * 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 _env_lock __P((void));static int _env_unlock __P((void));static int _init_lock __P((void));static int _init_unlock __P((void));#ifdef ENABLE_WINTHREADSstatic int _winmutex_lock __P((sqlo_mutex_t mp));static int _winmutex_unlock __P((sqlo_mutex_t mp));#endifstatic int _init_init_mux __P((void));static int _sqlo_getenv __P((void));static int _save_oci_status __P((sqlo_db_struct_ptr_t dbp, const char *action, const char *object, int lineno));static int _bind_argv __P(( sqlo_stmt_struct_ptr_t stp, unsigned int argc, const char ** argv));static int _bind_by_pos __P((sqlo_stmt_struct_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_struct_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_struct_ptr_t stp, sqlo_col_struct_t *colp, unsigned int pos));static int _define_output __P((sqlo_stmt_struct_ptr_t stp));static int _open_global_trace_file __P((void));#if 0static int _close_global_trace_file __P((void));#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -