| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763 |
- /*
- * Copyright (c) 2000-2018, 达梦数据库有限公司.
- * All rights reserved.
- */
- package dm
- import (
- "database/sql/driver"
- )
- const (
- OBJ_BLOB_MAGIC = 78111999
- CLTN_TYPE_IND_TABLE = 3
- CLTN_TYPE_NST_TABLE = 2
- CLTN_TYPE_VARRAY = 1
- )
- type TypeDescriptor struct {
- column *column
- m_sqlName *sqlName
- m_objId int
- m_objVersion int
- m_outerId int
- m_outerVer int
- m_subId int
- m_cltnType int
- m_maxCnt int
- m_length int
- m_size int
- m_conn *DmConnection
- m_serverEncoding string
- m_arrObj *TypeDescriptor
- m_fieldsObj []TypeDescriptor
- m_descBuf []byte
- }
- func newTypeDescriptorWithFulName(fulName string, conn *DmConnection) *TypeDescriptor {
- td := new(TypeDescriptor)
- td.init()
- td.m_sqlName = newSqlNameByFulName(fulName)
- td.m_conn = conn
- return td
- }
- func newTypeDescriptor(conn *DmConnection) *TypeDescriptor {
- td := new(TypeDescriptor)
- td.init()
- td.m_sqlName = newSqlNameByConn(conn)
- td.m_conn = conn
- return td
- }
- func (typeDescriptor *TypeDescriptor) init() {
- typeDescriptor.column = new(column).InitColumn()
- typeDescriptor.m_sqlName = nil
- typeDescriptor.m_objId = -1
- typeDescriptor.m_objVersion = -1
- typeDescriptor.m_outerId = 0
- typeDescriptor.m_outerVer = 0
- typeDescriptor.m_subId = 0
- typeDescriptor.m_cltnType = 0
- typeDescriptor.m_maxCnt = 0
- typeDescriptor.m_length = 0
- typeDescriptor.m_size = 0
- typeDescriptor.m_conn = nil
- typeDescriptor.m_serverEncoding = ""
- typeDescriptor.m_arrObj = nil
- typeDescriptor.m_fieldsObj = nil
- typeDescriptor.m_descBuf = nil
- }
- func (typeDescriptor *TypeDescriptor) parseDescByName() error {
- sql := "BEGIN ? = SF_DESCRIBE_TYPE(?); END;"
- params := make([]driver.Value, 2)
- params[1] = typeDescriptor.m_sqlName.m_fulName
- rs, err := typeDescriptor.m_conn.query(sql, params)
- if err != nil {
- return err
- }
- rs.close()
- l, err := params[0].(*DmBlob).GetLength()
- if err != nil {
- return err
- }
- buf, err := params[0].(*DmBlob).getBytes(1, int32(l))
- if err != nil {
- return err
- }
- typeDescriptor.m_serverEncoding = typeDescriptor.m_conn.getServerEncoding()
- err = typeDescriptor.unpack(Dm_build_366(buf))
- if err != nil {
- return err
- }
- return nil
- }
- func (typeDescriptor *TypeDescriptor) getFulName() (string, error) {
- return typeDescriptor.m_sqlName.getFulName()
- }
- func (typeDescriptor *TypeDescriptor) getDType() int {
- return int(typeDescriptor.column.colType)
- }
- func (typeDescriptor *TypeDescriptor) getPrec() int {
- return int(typeDescriptor.column.prec)
- }
- func (typeDescriptor *TypeDescriptor) getScale() int {
- return int(typeDescriptor.column.scale)
- }
- func (typeDescriptor *TypeDescriptor) getServerEncoding() string {
- if typeDescriptor.m_serverEncoding == "" {
- return typeDescriptor.m_conn.getServerEncoding()
- } else {
- return typeDescriptor.m_serverEncoding
- }
- }
- func (typeDescriptor *TypeDescriptor) getObjId() int {
- return typeDescriptor.m_objId
- }
- func (typeDescriptor *TypeDescriptor) getStaticArrayLength() int {
- return typeDescriptor.m_length
- }
- func (typeDescriptor *TypeDescriptor) getStrctMemSize() int {
- return typeDescriptor.m_size
- }
- func (typeDescriptor *TypeDescriptor) getOuterId() int {
- return typeDescriptor.m_outerId
- }
- func (typeDescriptor *TypeDescriptor) getCltnType() int {
- return typeDescriptor.m_cltnType
- }
- func (typeDescriptor *TypeDescriptor) getMaxCnt() int {
- return typeDescriptor.m_maxCnt
- }
- func getPackSize(typeDesc *TypeDescriptor) (int, error) {
- len := 0
- switch typeDesc.column.colType {
- case ARRAY, SARRAY:
- return getPackArraySize(typeDesc)
- case CLASS:
- return getPackClassSize(typeDesc)
- case PLTYPE_RECORD:
- return getPackRecordSize(typeDesc)
- }
- len += ULINT_SIZE
- len += ULINT_SIZE
- len += ULINT_SIZE
- return len, nil
- }
- func pack(typeDesc *TypeDescriptor, msg *Dm_build_361) error {
- switch typeDesc.column.colType {
- case ARRAY, SARRAY:
- return packArray(typeDesc, msg)
- case CLASS:
- return packClass(typeDesc, msg)
- case PLTYPE_RECORD:
- return packRecord(typeDesc, msg)
- }
- msg.Dm_build_416(typeDesc.column.colType)
- msg.Dm_build_416(typeDesc.column.prec)
- msg.Dm_build_416(typeDesc.column.scale)
- return nil
- }
- func getPackArraySize(arrDesc *TypeDescriptor) (int, error) {
- l := 0
- l += ULINT_SIZE
- name := arrDesc.m_sqlName.m_name
- l += USINT_SIZE
- serverEncoding := arrDesc.getServerEncoding()
- ret := Dm_build_1.Dm_build_217(name, serverEncoding, arrDesc.m_conn)
- l += len(ret)
- l += ULINT_SIZE
- l += ULINT_SIZE
- l += ULINT_SIZE
- i, err := getPackSize(arrDesc.m_arrObj)
- if err != nil {
- return 0, err
- }
- l += i
- return l, nil
- }
- func packArray(arrDesc *TypeDescriptor, msg *Dm_build_361) error {
- msg.Dm_build_416(arrDesc.column.colType)
- msg.Dm_build_472(arrDesc.m_sqlName.m_name, arrDesc.getServerEncoding(), arrDesc.m_conn)
- msg.Dm_build_416(int32(arrDesc.m_objId))
- msg.Dm_build_416(int32(arrDesc.m_objVersion))
- msg.Dm_build_416(int32(arrDesc.m_length))
- return pack(arrDesc.m_arrObj, msg)
- }
- func packRecord(strctDesc *TypeDescriptor, msg *Dm_build_361) error {
- msg.Dm_build_416(strctDesc.column.colType)
- msg.Dm_build_472(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn)
- msg.Dm_build_416(int32(strctDesc.m_objId))
- msg.Dm_build_416(int32(strctDesc.m_objVersion))
- msg.Dm_build_412(int16(strctDesc.m_size))
- for i := 0; i < strctDesc.m_size; i++ {
- err := pack(&strctDesc.m_fieldsObj[i], msg)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func getPackRecordSize(strctDesc *TypeDescriptor) (int, error) {
- l := 0
- l += ULINT_SIZE
- name := strctDesc.m_sqlName.m_name
- l += USINT_SIZE
- serverEncoding := strctDesc.getServerEncoding()
- ret := Dm_build_1.Dm_build_217(name, serverEncoding, strctDesc.m_conn)
- l += len(ret)
- l += ULINT_SIZE
- l += ULINT_SIZE
- l += USINT_SIZE
- for i := 0; i < strctDesc.m_size; i++ {
- i, err := getPackSize(&strctDesc.m_fieldsObj[i])
- if err != nil {
- return 0, err
- }
- l += i
- }
- return l, nil
- }
- func getPackClassSize(strctDesc *TypeDescriptor) (int, error) {
- l := 0
- l += ULINT_SIZE
- name := strctDesc.m_sqlName.m_name
- l += USINT_SIZE
- serverEncoding := strctDesc.getServerEncoding()
- ret := Dm_build_1.Dm_build_217(name, serverEncoding, strctDesc.m_conn)
- l += len(ret)
- l += ULINT_SIZE
- l += ULINT_SIZE
- if strctDesc.m_objId == 4 {
- l += ULINT_SIZE
- l += ULINT_SIZE
- l += USINT_SIZE
- }
- return l, nil
- }
- func packClass(strctDesc *TypeDescriptor, msg *Dm_build_361) error {
- msg.Dm_build_416(strctDesc.column.colType)
- msg.Dm_build_472(strctDesc.m_sqlName.m_name, strctDesc.getServerEncoding(), strctDesc.m_conn)
- msg.Dm_build_416(int32(strctDesc.m_objId))
- msg.Dm_build_416(int32(strctDesc.m_objVersion))
- if strctDesc.m_objId == 4 {
- msg.Dm_build_416(int32(strctDesc.m_outerId))
- msg.Dm_build_416(int32(strctDesc.m_outerVer))
- msg.Dm_build_416(int32(strctDesc.m_subId))
- }
- return nil
- }
- func (typeDescriptor *TypeDescriptor) unpack(buffer *Dm_build_361) error {
- typeDescriptor.column.colType = buffer.Dm_build_490()
- switch typeDescriptor.column.colType {
- case ARRAY, SARRAY:
- return typeDescriptor.unpackArray(buffer)
- case CLASS:
- return typeDescriptor.unpackClass(buffer)
- case PLTYPE_RECORD:
- return typeDescriptor.unpackRecord(buffer)
- }
- typeDescriptor.column.prec = buffer.Dm_build_490()
- typeDescriptor.column.scale = buffer.Dm_build_490()
- return nil
- }
- func (typeDescriptor *TypeDescriptor) unpackArray(buffer *Dm_build_361) error {
- typeDescriptor.m_sqlName.m_name = buffer.Dm_build_540(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
- typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_490())
- typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_490())
- typeDescriptor.m_objId = int(buffer.Dm_build_490())
- typeDescriptor.m_objVersion = int(buffer.Dm_build_490())
- typeDescriptor.m_length = int(buffer.Dm_build_490())
- if typeDescriptor.column.colType == ARRAY {
- typeDescriptor.m_length = 0
- }
- typeDescriptor.m_arrObj = newTypeDescriptor(typeDescriptor.m_conn)
- return typeDescriptor.m_arrObj.unpack(buffer)
- }
- func (typeDescriptor *TypeDescriptor) unpackRecord(buffer *Dm_build_361) error {
- typeDescriptor.m_sqlName.m_name = buffer.Dm_build_540(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
- typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_490())
- typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_490())
- typeDescriptor.m_objId = int(buffer.Dm_build_490())
- typeDescriptor.m_objVersion = int(buffer.Dm_build_490())
- typeDescriptor.m_size = int(buffer.Dm_build_505())
- typeDescriptor.m_fieldsObj = make([]TypeDescriptor, typeDescriptor.m_size)
- for i := 0; i < typeDescriptor.m_size; i++ {
- typeDescriptor.m_fieldsObj[i] = *newTypeDescriptor(typeDescriptor.m_conn)
- typeDescriptor.m_fieldsObj[i].unpack(buffer)
- }
- return nil
- }
- func (typeDescriptor *TypeDescriptor) unpackClnt_nestTab(buffer *Dm_build_361) error {
- typeDescriptor.m_maxCnt = int(buffer.Dm_build_490())
- typeDescriptor.m_arrObj = newTypeDescriptor(typeDescriptor.m_conn)
- typeDescriptor.m_arrObj.unpack(buffer)
- return nil
- }
- func (typeDescriptor *TypeDescriptor) unpackClnt(buffer *Dm_build_361) error {
- typeDescriptor.m_outerId = int(buffer.Dm_build_490())
- typeDescriptor.m_outerVer = int(buffer.Dm_build_490())
- typeDescriptor.m_subId = int(buffer.Dm_build_505())
- typeDescriptor.m_cltnType = int(buffer.Dm_build_505())
- switch typeDescriptor.m_cltnType {
- case CLTN_TYPE_IND_TABLE:
- return ECGO_UNSUPPORTED_TYPE.throw()
- case CLTN_TYPE_NST_TABLE, CLTN_TYPE_VARRAY:
- return typeDescriptor.unpackClnt_nestTab(buffer)
- }
- return nil
- }
- func (typeDescriptor *TypeDescriptor) unpackClass(buffer *Dm_build_361) error {
- typeDescriptor.m_sqlName.m_name = buffer.Dm_build_540(typeDescriptor.getServerEncoding(), typeDescriptor.m_conn)
- typeDescriptor.m_sqlName.m_schId = int(buffer.Dm_build_490())
- typeDescriptor.m_sqlName.m_packId = int(buffer.Dm_build_490())
- typeDescriptor.m_objId = int(buffer.Dm_build_490())
- typeDescriptor.m_objVersion = int(buffer.Dm_build_490())
- if typeDescriptor.m_objId == 4 {
- return typeDescriptor.unpackClnt(buffer)
- } else {
- typeDescriptor.m_size = int(buffer.Dm_build_505())
- typeDescriptor.m_fieldsObj = make([]TypeDescriptor, typeDescriptor.m_size)
- for i := 0; i < typeDescriptor.m_size; i++ {
- typeDescriptor.m_fieldsObj[i] = *newTypeDescriptor(typeDescriptor.m_conn)
- err := typeDescriptor.m_fieldsObj[i].unpack(buffer)
- if err != nil {
- return err
- }
- }
- return nil
- }
- }
- func calcChkDescLen_array(desc *TypeDescriptor) (int, error) {
- offset := 0
- offset += USINT_SIZE
- offset += ULINT_SIZE
- tmp, err := calcChkDescLen(desc)
- if err != nil {
- return 0, err
- }
- offset += tmp
- return offset, nil
- }
- func calcChkDescLen_record(desc *TypeDescriptor) (int, error) {
- offset := 0
- offset += USINT_SIZE
- offset += USINT_SIZE
- for i := 0; i < desc.m_size; i++ {
- tmp, err := calcChkDescLen(&desc.m_fieldsObj[i])
- if err != nil {
- return 0, err
- }
- offset += tmp
- }
- return offset, nil
- }
- func calcChkDescLen_class_normal(desc *TypeDescriptor) (int, error) {
- offset := 0
- offset += USINT_SIZE
- for i := 0; i < desc.m_size; i++ {
- tmp, err := calcChkDescLen(&desc.m_fieldsObj[i])
- if err != nil {
- return 0, err
- }
- offset += tmp
- }
- return offset, nil
- }
- func calcChkDescLen_class_cnlt(desc *TypeDescriptor) (int, error) {
- offset := 0
- offset += USINT_SIZE
- offset += ULINT_SIZE
- switch desc.getCltnType() {
- case CLTN_TYPE_IND_TABLE:
- return 0, ECGO_UNSUPPORTED_TYPE.throw()
- case CLTN_TYPE_VARRAY, CLTN_TYPE_NST_TABLE:
- i, err := calcChkDescLen(desc.m_arrObj)
- if err != nil {
- return 0, err
- }
- offset += i
- }
- return offset, nil
- }
- func calcChkDescLen_class(desc *TypeDescriptor) (int, error) {
- offset := 0
- offset += USINT_SIZE
- offset += BYTE_SIZE
- if desc.m_objId == 4 {
- i, err := calcChkDescLen_class_cnlt(desc)
- if err != nil {
- return 0, err
- }
- offset += i
- } else {
- i, err := calcChkDescLen_class_normal(desc)
- if err != nil {
- return 0, err
- }
- offset += i
- }
- return offset, nil
- }
- func calcChkDescLen_buildin() int {
- offset := 0
- offset += USINT_SIZE
- offset += USINT_SIZE
- offset += USINT_SIZE
- return offset
- }
- func calcChkDescLen(desc *TypeDescriptor) (int, error) {
- switch desc.getDType() {
- case ARRAY, SARRAY:
- return calcChkDescLen_array(desc)
- case PLTYPE_RECORD:
- return calcChkDescLen_record(desc)
- case CLASS:
- return calcChkDescLen_class(desc)
- default:
- return calcChkDescLen_buildin(), nil
- }
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_array(offset int, desc *TypeDescriptor) (int, error) {
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, ARRAY)
- offset += USINT_SIZE
- Dm_build_1.Dm_build_17(typeDescriptor.m_descBuf, offset, int32(desc.m_length))
- offset += ULINT_SIZE
- return typeDescriptor.makeChkDesc(offset, desc)
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_record(offset int, desc *TypeDescriptor) (int, error) {
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, PLTYPE_RECORD)
- offset += USINT_SIZE
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, int16(desc.m_size))
- offset += USINT_SIZE
- var err error
- for i := 0; i < desc.m_size; i++ {
- offset, err = typeDescriptor.makeChkDesc(offset, &desc.m_fieldsObj[i])
- if err != nil {
- return 0, err
- }
- }
- return offset, nil
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_buildin(offset int, desc *TypeDescriptor) int {
- dtype := int16(desc.getDType())
- prec := 0
- scale := 0
- if dtype != BLOB {
- prec = desc.getPrec()
- scale = desc.getScale()
- }
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, dtype)
- offset += USINT_SIZE
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, int16(prec))
- offset += USINT_SIZE
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, int16(scale))
- offset += USINT_SIZE
- return offset
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_class_normal(offset int, desc *TypeDescriptor) (int, error) {
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, int16(desc.m_size))
- offset += USINT_SIZE
- var err error
- for i := 0; i < desc.m_size; i++ {
- offset, err = typeDescriptor.makeChkDesc(offset, &desc.m_fieldsObj[i])
- if err != nil {
- return 0, err
- }
- }
- return offset, nil
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_class_clnt(offset int, desc *TypeDescriptor) (int, error) {
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, int16(desc.m_cltnType))
- offset += USINT_SIZE
- Dm_build_1.Dm_build_17(typeDescriptor.m_descBuf, offset, int32(desc.getMaxCnt()))
- offset += ULINT_SIZE
- switch desc.m_cltnType {
- case CLTN_TYPE_IND_TABLE:
- return 0, ECGO_UNSUPPORTED_TYPE.throw()
- case CLTN_TYPE_NST_TABLE, CLTN_TYPE_VARRAY:
- return typeDescriptor.makeChkDesc(offset, desc.m_arrObj)
- }
- return offset, nil
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc_class(offset int, desc *TypeDescriptor) (int, error) {
- Dm_build_1.Dm_build_12(typeDescriptor.m_descBuf, offset, CLASS)
- offset += USINT_SIZE
- isClnt := false
- if desc.m_objId == 4 {
- isClnt = true
- }
- if isClnt {
- Dm_build_1.Dm_build_2(typeDescriptor.m_descBuf, offset, byte(1))
- } else {
- Dm_build_1.Dm_build_2(typeDescriptor.m_descBuf, offset, byte(0))
- }
- offset += BYTE_SIZE
- if isClnt {
- return typeDescriptor.makeChkDesc_class_clnt(offset, desc)
- } else {
- return typeDescriptor.makeChkDesc_class_normal(offset, desc)
- }
- }
- func (typeDescriptor *TypeDescriptor) makeChkDesc(offset int, subDesc *TypeDescriptor) (int, error) {
- switch subDesc.getDType() {
- case ARRAY, SARRAY:
- return typeDescriptor.makeChkDesc_array(offset, subDesc)
- case PLTYPE_RECORD:
- return typeDescriptor.makeChkDesc_record(offset, subDesc)
- case CLASS:
- return typeDescriptor.makeChkDesc_class(offset, subDesc)
- default:
- return typeDescriptor.makeChkDesc_buildin(offset, subDesc), nil
- }
- }
- func (typeDescriptor *TypeDescriptor) getClassDescChkInfo() ([]byte, error) {
- if typeDescriptor.m_descBuf != nil {
- return typeDescriptor.m_descBuf, nil
- }
- l, err := calcChkDescLen(typeDescriptor)
- if err != nil {
- return nil, err
- }
- typeDescriptor.m_descBuf = make([]byte, l)
- typeDescriptor.makeChkDesc(0, typeDescriptor)
- return typeDescriptor.m_descBuf, nil
- }
|