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 } }