gitee.com/chunanyong/dm@v1.8.12/j.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 6 package dm 7 8 import "database/sql/driver" 9 10 type DmArray struct { 11 TypeData 12 m_arrDesc *ArrayDescriptor // 数组的描述信息 13 14 m_arrData []TypeData // 数组中各行数据值 15 16 m_objArray interface{} // 从服务端获取的 17 18 m_itemCount int // 本次获取的行数 19 20 m_itemSize int // 数组中一个数组项的大小,单位bytes 21 22 m_objCount int // 一个数组项中存在对象类型的个数(class、动态数组) 23 24 m_strCount int // 一个数组项中存在字符串类型的个数 25 26 m_objStrOffs []int // 对象在前,字符串在后 27 28 typeName string 29 30 elements []interface{} 31 32 // Valid为false代表DmArray数据在数据库中为NULL 33 Valid bool 34 } 35 36 func (da *DmArray) init() *DmArray { 37 da.initTypeData() 38 da.m_itemCount = 0 39 da.m_itemSize = 0 40 da.m_objCount = 0 41 da.m_strCount = 0 42 da.m_objStrOffs = nil 43 da.m_dumyData = nil 44 da.m_offset = 0 45 46 da.m_objArray = nil 47 da.Valid = true 48 return da 49 } 50 51 // 数据库自定义数组Array构造函数,typeName为库中定义的数组类型名称,elements为该数组类型的每个值 52 // 53 // 例如,自定义数组类型语句为:create or replace type myArray is array int[]; 54 // 55 // 则绑入绑出的go对象为: val := dm.NewDmArray("myArray", []interface{} {123, 456}) 56 func NewDmArray(typeName string, elements []interface{}) *DmArray { 57 da := new(DmArray) 58 da.typeName = typeName 59 da.elements = elements 60 da.Valid = true 61 return da 62 } 63 64 func (da *DmArray) create(dc *DmConnection) (*DmArray, error) { 65 desc, err := newArrayDescriptor(da.typeName, dc) 66 if err != nil { 67 return nil, err 68 } 69 return da.createByArrayDescriptor(desc, dc) 70 } 71 72 func (da *DmArray) createByArrayDescriptor(arrDesc *ArrayDescriptor, conn *DmConnection) (*DmArray, error) { 73 74 if nil == arrDesc { 75 return nil, ECGO_INVALID_PARAMETER_VALUE.throw() 76 } 77 78 da.init() 79 80 da.m_arrDesc = arrDesc 81 if nil == da.elements { 82 da.m_arrData = make([]TypeData, 0) 83 } else { 84 // 若为静态数组,判断给定数组长度是否超过静态数组的上限 85 if arrDesc.getMDesc() == nil || (arrDesc.getMDesc().getDType() == SARRAY && len(da.elements) > arrDesc.getMDesc().getStaticArrayLength()) { 86 return nil, ECGO_INVALID_ARRAY_LEN.throw() 87 } 88 89 var err error 90 da.m_arrData, err = TypeDataSV.toArray(da.elements, da.m_arrDesc.getMDesc()) 91 if err != nil { 92 return nil, err 93 } 94 } 95 96 da.m_itemCount = len(da.m_arrData) 97 return da, nil 98 } 99 100 func newDmArrayByTypeData(atData []TypeData, desc *TypeDescriptor) *DmArray { 101 da := new(DmArray) 102 da.init() 103 da.m_arrDesc = newArrayDescriptorByTypeDescriptor(desc) 104 da.m_arrData = atData 105 return da 106 } 107 108 func (da *DmArray) checkIndex(index int64) error { 109 if index < 0 || index > int64(len(da.m_arrData)-1) { 110 return ECGO_INVALID_LENGTH_OR_OFFSET.throw() 111 } 112 return nil 113 } 114 115 func (da *DmArray) checkIndexAndCount(index int64, count int) error { 116 err := da.checkIndex(index) 117 if err != nil { 118 return err 119 } 120 121 if count <= 0 || index+int64(count) > int64(len(da.m_arrData)) { 122 return ECGO_INVALID_LENGTH_OR_OFFSET.throw() 123 } 124 return nil 125 } 126 127 // 获取Array对象在数据库中的类型名称 128 func (da *DmArray) GetBaseTypeName() (string, error) { 129 if err := da.checkValid(); err != nil { 130 return "", err 131 } 132 return da.m_arrDesc.m_typeDesc.getFulName() 133 } 134 135 // 获取Array对象的go数组对象 136 func (da *DmArray) GetArray() (interface{}, error) { 137 if da.m_arrData == nil || len(da.m_arrData) <= 0 { 138 return nil, nil; 139 } 140 141 return TypeDataSV.toJavaArray(da, 0, len(da.m_arrData), da.m_arrDesc.getItemDesc().getDType()) 142 } 143 144 // 获取Array对象的指定偏移和执行长度go数据对象 index从0开始 145 func (da *DmArray) GetObjArray(index int64, count int) (interface{}, error) { 146 var err error 147 if err = da.checkValid(); err != nil { 148 return nil, err 149 } 150 if err = da.checkIndexAndCount(index, count); err != nil { 151 return nil, err 152 } 153 154 return TypeDataSV.toJavaArray(da, index, count, da.m_arrDesc.getItemDesc().getDType()) 155 } 156 157 func (da *DmArray) GetIntArray(index int64, count int) ([]int, error) { 158 var err error 159 if err = da.checkValid(); err != nil { 160 return nil, err 161 } 162 if err = da.checkIndexAndCount(index, count); err != nil { 163 return nil, err 164 } 165 166 tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_INTEGER) 167 if err != nil { 168 return nil, err 169 } 170 return tmp.([]int), nil 171 } 172 173 func (da *DmArray) GetInt16Array(index int64, count int) ([]int16, error) { 174 var err error 175 if err = da.checkValid(); err != nil { 176 return nil, err 177 } 178 if err = da.checkIndexAndCount(index, count); err != nil { 179 return nil, err 180 } 181 182 tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_SHORT) 183 if err != nil { 184 return nil, err 185 } 186 return tmp.([]int16), nil 187 } 188 189 func (da *DmArray) GetInt64Array(index int64, count int) ([]int64, error) { 190 var err error 191 if err = da.checkValid(); err != nil { 192 return nil, err 193 } 194 if err = da.checkIndexAndCount(index, count); err != nil { 195 return nil, err 196 } 197 198 tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_LONG) 199 if err != nil { 200 return nil, err 201 } 202 203 return tmp.([]int64), nil 204 } 205 206 func (da *DmArray) GetFloatArray(index int64, count int) ([]float32, error) { 207 var err error 208 if err = da.checkValid(); err != nil { 209 return nil, err 210 } 211 if err = da.checkIndexAndCount(index, count); err != nil { 212 return nil, err 213 } 214 215 tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_FLOAT) 216 if err != nil { 217 return nil, err 218 } 219 220 return tmp.([]float32), nil 221 } 222 223 func (da *DmArray) GetDoubleArray(index int64, count int) ([]float64, error) { 224 var err error 225 if err = da.checkValid(); err != nil { 226 return nil, err 227 } 228 if err = da.checkIndexAndCount(index, count); err != nil { 229 return nil, err 230 } 231 232 tmp, err := TypeDataSV.toNumericArray(da, index, count, ARRAY_TYPE_DOUBLE) 233 if err != nil { 234 return nil, err 235 } 236 237 return tmp.([]float64), nil 238 } 239 240 func (dest *DmArray) Scan(src interface{}) error { 241 if dest == nil { 242 return ECGO_STORE_IN_NIL_POINTER.throw() 243 } 244 switch src := src.(type) { 245 case nil: 246 *dest = *new(DmArray) 247 // 将Valid标志置false表示数据库中该列为NULL 248 (*dest).Valid = false 249 return nil 250 case *DmArray: 251 *dest = *src 252 return nil 253 default: 254 return UNSUPPORTED_SCAN.throw() 255 } 256 } 257 258 func (array DmArray) Value() (driver.Value, error) { 259 if !array.Valid { 260 return nil, nil 261 } 262 return array, nil 263 } 264 265 func (array *DmArray) checkValid() error { 266 if !array.Valid { 267 return ECGO_IS_NULL.throw() 268 } 269 return nil 270 }