|
@@ -0,0 +1,346 @@
|
|
|
|
+package xugu
|
|
|
|
+
|
|
|
|
+import "fmt"
|
|
|
|
+
|
|
|
|
+//定义 XGCSParam 结构体
|
|
|
|
+type XGCSParam struct {
|
|
|
|
+ Type HANDLE_TYPE // 句柄类型
|
|
|
|
+ ParamNum uint32 // 单行参数数量
|
|
|
|
+ PResourceNum int // 参数名称资源数量,步长128
|
|
|
|
+ ParamArraySize int // 参数数组长度(数组大小)
|
|
|
|
+ ValueP []byte // 实际参数指针数组,指向参数地址
|
|
|
|
+ VType []uint32 // 参数类型:数组,参数数量
|
|
|
|
+ VParamSize []uint32 // 参数缓冲区长度,参数数量
|
|
|
|
+ VDbType *int // 参考数据库数据类型,参数数量
|
|
|
|
+ VActuallenp [][]int // 参数数据实际大小数组,[参数数组大小][参数数量]
|
|
|
|
+ VParamName [][]byte // 参数名称
|
|
|
|
+ VParamNo []uint32 // 参数序列数组
|
|
|
|
+ VInOut []int // 输入输出类型
|
|
|
|
+ ErrStr []byte // 错误字符串
|
|
|
|
+ MemType int // 内存使用模式(0:引用,1:驱动程序分配)
|
|
|
|
+ ImpExpType int // 0 隐式创建,1 显式创建,2 由服务器提供的准备语句获取
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//按序号绑定
|
|
|
|
+/*=====================================
|
|
|
|
+p_conn 连接句柄
|
|
|
|
+param_no 参数号: 从1开始
|
|
|
|
+param_type 参数输入输出型
|
|
|
|
+datatype 参数数据类型
|
|
|
|
+value 参数值
|
|
|
|
+param_size 单个参数的空间大小 buffer
|
|
|
|
+rlen_val 具体的每个参数 的对应实际大小
|
|
|
|
+======================================*/
|
|
|
|
+func xgSockBindparamByPos(pconn *xuguConn, param_no int, param_type int, datatype int, value []byte, param_size int, rlen_val []int) int {
|
|
|
|
+ if pconn.Type == HT_CONN {
|
|
|
|
+ if pconn.params == nil {
|
|
|
|
+ pconn.params = &XGCSParam{Type: HT_PARAMS}
|
|
|
|
+ }
|
|
|
|
+ if param_no > 4000 {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC051]Error invalid param NO %d out of range paramnum", param_no))
|
|
|
|
+ return -51
|
|
|
|
+ }
|
|
|
|
+ if !(param_type == 1 || param_type == 2 || param_type == 3 || param_type == 6) {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC052]Error invalid param type %d", param_type))
|
|
|
|
+ return -52
|
|
|
|
+ }
|
|
|
|
+ if param_no < 1 {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC054]Error param_no param seq %d invalid", param_no))
|
|
|
|
+ return -54
|
|
|
|
+ }
|
|
|
|
+ } else if pconn.params.Type == HT_PARAMS {
|
|
|
|
+ if param_no > 4000 {
|
|
|
|
+ pconn.params.ErrStr = []byte(fmt.Sprintf("[EC051]Error invalid param NO %d out of range paramnum", param_no))
|
|
|
|
+ //set error 参数绑定序列值 超过合理范围
|
|
|
|
+ return -51
|
|
|
|
+ }
|
|
|
|
+ if !(param_type == 1 || param_type == 2 || param_type == 3 || param_type == 6) {
|
|
|
|
+ pconn.params.ErrStr = []byte(fmt.Sprintf("[EC052]Error invalid param type %d", param_type))
|
|
|
|
+ return -52 //参数绑定类型非法
|
|
|
|
+ }
|
|
|
|
+ if param_no < 1 {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC054]Error param_no param seq %d invalid", param_no))
|
|
|
|
+ return -54
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ //invalid ptr set
|
|
|
|
+ return XG_INVALID_ARG
|
|
|
|
+ }
|
|
|
|
+ ret := xgSockBindParamsByPos(*pconn.params, param_no, param_type, datatype, value, param_size, rlen_val)
|
|
|
|
+
|
|
|
|
+ if ret < 0 {
|
|
|
|
+ if ret == -55 {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC055]Error bindparam jump long %d invalid", ret))
|
|
|
|
+ return -55
|
|
|
|
+ } else if ret == -8 {
|
|
|
|
+ pconn.errStr = []byte(fmt.Sprintf("[EC056]Error bindparam unsurpported ret %d invalid", ret))
|
|
|
|
+ return -8
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ret
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func xgSockBindParamsByPos(pParams XGCSParam, param_no int, param_type int, datatype int, value []byte, param_size int, rlen_val []int) int {
|
|
|
|
+ ipar := param_no
|
|
|
|
+ ipar--
|
|
|
|
+ if pParams.ParamNum == 0 { // 初始化空间
|
|
|
|
+ pParams.PResourceNum = 128
|
|
|
|
+
|
|
|
|
+ pParams.VType = make([]uint32, 128)
|
|
|
|
+ pParams.VParamSize = make([]uint32, 128)
|
|
|
|
+ //pParams.VDbType = make([][]int, 128)
|
|
|
|
+ pParams.VActuallenp = make([][]int, 128)
|
|
|
|
+ pParams.VParamNo = make([]uint32, 128)
|
|
|
|
+ pParams.VInOut = make([]int, 128)
|
|
|
|
+ pParams.VParamName = nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if int(pParams.ParamNum) < param_no { //分配空间(加增)
|
|
|
|
+ if pParams.PResourceNum < param_no { //资源分配
|
|
|
|
+ if pParams.PResourceNum+128 < param_no {
|
|
|
|
+ return -55 // set error 参数绑定跳跃度过大
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //go 切片会自动分配内存 切片扩容机制
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if param_type == 6 {
|
|
|
|
+ //函数返回值绑定
|
|
|
|
+ pParams.VParamNo[uint32(ipar)] = uint32(ipar) //意义不大 或者可以改成valid
|
|
|
|
+ pParams.VType[uint32(ipar)] = uint32(datatype)
|
|
|
|
+ pParams.ValueP = value
|
|
|
|
+ pParams.VParamSize[uint32(ipar)] = uint32(param_size)
|
|
|
|
+ pParams.VActuallenp[uint32(ipar)] = rlen_val
|
|
|
|
+ pParams.VInOut[uint32(ipar)] = param_type
|
|
|
|
+
|
|
|
|
+ } else if param_type == 1 { //input
|
|
|
|
+
|
|
|
|
+ pParams.VParamNo[uint32(ipar)] = uint32(ipar) //意义不大 或者可以改成valid
|
|
|
|
+ pParams.VType[uint32(ipar)] = uint32(datatype)
|
|
|
|
+ //tmp ===================== value cpoy ================================
|
|
|
|
+ pParams.ValueP = value
|
|
|
|
+ pParams.VActuallenp[uint32(ipar)] = rlen_val //tmp end
|
|
|
|
+ pParams.MemType = 1
|
|
|
|
+ pParams.VInOut[uint32(ipar)] = 1
|
|
|
|
+
|
|
|
|
+ } else if param_type == 2 || param_type == 3 { //output ||inoutput
|
|
|
|
+ pParams.VParamNo[uint32(ipar)] = uint32(ipar)
|
|
|
|
+ pParams.VType[uint32(ipar)] = uint32(datatype)
|
|
|
|
+
|
|
|
|
+ pParams.ValueP = value
|
|
|
|
+ pParams.VParamSize[uint32(ipar)] = uint32(param_size) //buff长度
|
|
|
|
+ pParams.VActuallenp[uint32(ipar)] = rlen_val
|
|
|
|
+ pParams.VInOut[uint32(ipar)] = param_type
|
|
|
|
+ } else { //3
|
|
|
|
+ return -8 //尚未实现
|
|
|
|
+ //参数绑定类型不合格
|
|
|
|
+ }
|
|
|
|
+ return 0
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//批量
|
|
|
|
+/*=============================================
|
|
|
|
+p_conn 连接句柄
|
|
|
|
+param_no 参数号: 从1开始
|
|
|
|
+param_type 参数输入输出型
|
|
|
|
+datatype 参数数据类型
|
|
|
|
+array_size 数组的大小长度
|
|
|
|
+array_value 参数值数组
|
|
|
|
+param_size 单个参数的空间大小 buffer
|
|
|
|
+rlen_val 具体的每个参数 的对应实际大小[与参数值大小一一对应]
|
|
|
|
+==============================================*/
|
|
|
|
+func xgSockBindParamArrayByPos(pConn *xuguConn, param_no int, param_num int, param_type int, datatype int, array_size int, array_value []byte, param_size int, rlen_val []int) int {
|
|
|
|
+ if pConn.Type == HT_CONN {
|
|
|
|
+ if pConn.params == nil {
|
|
|
|
+ pConn.params = new(XGCSParam)
|
|
|
|
+ pConn.params.Type = HT_PARAMS //imp_exp_type= 0;
|
|
|
|
+ }
|
|
|
|
+ if param_no > 4000 || param_num > 4000 || param_num < -1 {
|
|
|
|
+ //set error 参数绑定序列值 超过合理范围
|
|
|
|
+ pConn.errStr = []byte(fmt.Sprintf("[EC051]Error invalid param NO %d out of range paramnum", param_num))
|
|
|
|
+ return -51
|
|
|
|
+ }
|
|
|
|
+ if !(param_type == 1 || param_type == 2 || param_type == 3 || param_type == 6) {
|
|
|
|
+ pConn.errStr = []byte(fmt.Sprintf("[EC052]Error invalid param type %d", param_type))
|
|
|
|
+ return -52 //参数绑定类型非法
|
|
|
|
+ }
|
|
|
|
+ if param_no < 1 {
|
|
|
|
+ pConn.errStr = []byte(fmt.Sprintf("[EC054]Error param_no param seq %d invalid", param_no))
|
|
|
|
+ return -54
|
|
|
|
+ }
|
|
|
|
+ } else if pConn.Type == HT_PARAMS {
|
|
|
|
+ //pParams := pConn.params
|
|
|
|
+ if param_no > 4000 {
|
|
|
|
+ pConn.params.ErrStr = []byte(fmt.Sprintf("[EC051]Error invalid param NO %d out of range paramnum", param_no))
|
|
|
|
+ return -51
|
|
|
|
+ }
|
|
|
|
+ if !(param_type == 1 || param_type == 2 || param_type == 3 || param_type == 6) {
|
|
|
|
+ pConn.params.ErrStr = []byte(fmt.Sprintf("[EC052]Error invalid param type %d", param_type))
|
|
|
|
+ return -52 //参数绑定类型非法
|
|
|
|
+ }
|
|
|
|
+ if param_no < 1 {
|
|
|
|
+ pConn.params.ErrStr = []byte(fmt.Sprintf("[EC054]Error param_no param seq %d invalid", param_no))
|
|
|
|
+ return -54
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ return XG_INVALID_ARG
|
|
|
|
+ }
|
|
|
|
+ ret := xgSockBindParamsArrayByPos(pConn.params, param_no, param_num, param_type, datatype, array_size, array_value, param_size, rlen_val)
|
|
|
|
+ return ret
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func xgSockBindParamsArrayByPos(pParams *XGCSParam, param_no int, param_num int, param_type int, datatype int, array_size int,
|
|
|
|
+ array_value []byte, param_size int, rlen_val []int) int {
|
|
|
|
+ ipar := param_no - 1
|
|
|
|
+ if pParams.ParamNum == 0 {
|
|
|
|
+ //以下部分需要重新封装 使得看起来比较代码简练
|
|
|
|
+
|
|
|
|
+ if param_num == 0 { //顶层资源 一次分配128
|
|
|
|
+ pParams.PResourceNum = 128
|
|
|
|
+
|
|
|
|
+ pParams.VType = make([]uint32, 128)
|
|
|
|
+ pParams.VParamSize = make([]uint32, 128)
|
|
|
|
+ //pParams.VDbType = make([][]int, 128)
|
|
|
|
+ pParams.VActuallenp = make([][]int, 128)
|
|
|
|
+ pParams.VParamNo = make([]uint32, 128)
|
|
|
|
+ pParams.VInOut = make([]int, 128)
|
|
|
|
+ pParams.VParamName = nil
|
|
|
|
+ } else { //已知参数列数
|
|
|
|
+ pParams.ParamArraySize = array_size //数组容量确定
|
|
|
|
+
|
|
|
|
+ pParams.VType = make([]uint32, param_num)
|
|
|
|
+ pParams.VParamSize = make([]uint32, param_num)
|
|
|
|
+ //pParams.VDbType = make([][]int, 128)
|
|
|
|
+ pParams.VActuallenp = make([][]int, param_num) //这个p_params->v_actuallenp[ipar][0]指向传入数组就行了
|
|
|
|
+ pParams.VParamNo = make([]uint32, param_num)
|
|
|
|
+ pParams.VInOut = make([]int, param_num)
|
|
|
|
+ //pParams.VParamName = nil
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if pParams.ParamNum < uint32(param_no) {
|
|
|
|
+ if pParams.PResourceNum < param_no { //资源分配
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ pParams.ParamNum = uint32(param_no) //允许了中间的空洞
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if param_type == 6 { //1236 in out inout return value
|
|
|
|
+ //函数返回值绑定
|
|
|
|
+
|
|
|
|
+ } else if param_type == 1 { //input
|
|
|
|
+ pParams.VParamNo[ipar] = uint32(param_no) ////意义不大 或者可以改成valid
|
|
|
|
+ pParams.VType[ipar] = uint32(datatype)
|
|
|
|
+
|
|
|
|
+ //off := 0
|
|
|
|
+ //ptrLen := 0 //varchar长度指示器
|
|
|
|
+ var ptr []byte
|
|
|
|
+ copy(pParams.VActuallenp[ipar], rlen_val)
|
|
|
|
+ if needCopyV(datatype) {
|
|
|
|
+ //m_ele_siz := getDbTypeLen(datatype)
|
|
|
|
+ copy(ptr, array_value)
|
|
|
|
+ } else if datatype == XG_C_CHAR || datatype == XG_C_NCHAR {
|
|
|
|
+ copy(ptr, array_value)
|
|
|
|
+ } else {
|
|
|
|
+ // ptr=(char*)malloc(param_size);//no
|
|
|
|
+ //memcpy(ptr,array_value,param_size);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for irow := 0; irow < array_size; irow++ {
|
|
|
|
+ switch datatype {
|
|
|
|
+ // case XG_C_INTEGER, XG_C_FLOAT:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+
|
|
|
|
+ // case XG_C_NCHAR, XG_C_CHAR:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+
|
|
|
|
+ // case XG_C_BIGINT, DATETIME_ASLONG:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ // case XG_C_DOUBLE:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ // case XG_C_NUMERIC:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ // case XG_C_DATE, XG_C_TIME, XG_C_DATETIME, XG_C_TIME_TZ, XG_C_DATETIME_TZ, XG_C_BINARY, XG_C_INTERVAL_YEAR_TO_MONTH, XG_C_INTERVAL_DAY_TO_SECOND:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ // case XG_C_SHORT:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ // case XG_C_TINYINT, XG_C_BOOL, XG_C_CHARN1:
|
|
|
|
+ // pParams.ValueP[irow][ipar] = ptr[off]
|
|
|
|
+ // off++
|
|
|
|
+ default:
|
|
|
|
+ fmt.Println("bindparam unsurpported datatype")
|
|
|
|
+ pParams.ErrStr = []byte(fmt.Sprintf("[EC058]Error bindparam unsurpported datatype %d invalid", datatype))
|
|
|
|
+ return -58
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ pParams.VParamSize[ipar] = uint32(param_size) //buff长度
|
|
|
|
+ pParams.VInOut[ipar] = 1
|
|
|
|
+ } else if param_type == 2 { //output
|
|
|
|
+ // p_params->v_actuallenp[ipar] = rlen_val;//这里之所以是引用传递 那是因为 out or inout 型时 需要反馈实际的参数的长度
|
|
|
|
+ return -8 //尚未实现
|
|
|
|
+ } else { //3
|
|
|
|
+ return -8 //尚未实现
|
|
|
|
+ //参数绑定类型不合格
|
|
|
|
+ }
|
|
|
|
+ return XG_OK
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//按名绑定
|
|
|
|
+/*=====================================
|
|
|
|
+p_conn 连接句柄 2 p_conn 参数句柄(显式创建参数句柄)
|
|
|
|
+param_name 参数名: 当出现一样的参数名时,会进行覆盖但是不会报错
|
|
|
|
+param_type 参数输入输出型
|
|
|
|
+datatype 参数数据类型
|
|
|
|
+value 参数值
|
|
|
|
+param_size 单个参数的空间大小 buffer
|
|
|
|
+rlen_val 具体的每个参数 的对应实际大小
|
|
|
|
+======================================*/
|
|
|
|
+func xgSockBindParamByName(pConn *xuguConn, param_name []byte, param_type int, datatype int, void []byte, param_sizeint, rt_code *int, rlen_val []int) int {
|
|
|
|
+ pParams := pConn.params
|
|
|
|
+ if pConn.Type == HT_CONN {
|
|
|
|
+ if nil == pConn.params {
|
|
|
|
+
|
|
|
|
+ pConn.params = &XGCSParam{}
|
|
|
|
+ pConn.params.Type = HT_PARAMS //imp_exp_type= 0;
|
|
|
|
+ }
|
|
|
|
+ pParams = pConn.params
|
|
|
|
+ } else if pConn.Type == HT_PARAMS {
|
|
|
|
+ pParams = pConn.params
|
|
|
|
+ } else {
|
|
|
|
+ //invalid ptr set
|
|
|
|
+ return XG_INVALID_ARG
|
|
|
|
+ }
|
|
|
|
+ if !(param_type == 1 || param_type == 2 || param_type == 3 || param_type == 6) {
|
|
|
|
+ if pConn.Type == HT_CONN {
|
|
|
|
+ pConn.params.ErrStr = []byte(fmt.Sprintf("[EC052]Error invalis param type %d", param_type))
|
|
|
|
+ } else {
|
|
|
|
+ pParams.ErrStr = []byte(fmt.Sprintf("[EC052]Error invalis param type %d", param_type))
|
|
|
|
+ }
|
|
|
|
+ return -52
|
|
|
|
+ }
|
|
|
|
+ return 0
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func xgSockBindParamByNameSub(pParams *XGCSParam) {
|
|
|
|
+ if pParams.ParamNum == 0 { //优先考虑 参数不足128个时的情况
|
|
|
|
+ pParams.PResourceNum = 128
|
|
|
|
+ pParams.ValueP = make([]byte, 128)
|
|
|
|
+ pParams.VType = make([]uint32, 128)
|
|
|
|
+ pParams.VParamSize = make([]uint32, 128)
|
|
|
|
+ //pParams.VDbType = make([][]int, 128)
|
|
|
|
+ pParams.VActuallenp = make([][]int, 128)
|
|
|
|
+ pParams.VParamNo = make([]uint32, 128)
|
|
|
|
+ pParams.VInOut = make([]int, 128)
|
|
|
|
+ pParams.VParamName = nil
|
|
|
|
+ }
|
|
|
|
+}
|