| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- /*
- * Copyright (c) 2000-2018, 达梦数据库有限公司.
- * All rights reserved.
- */
- package dm
- import (
- "database/sql/driver"
- "io"
- )
- type DmClob struct {
- lob
- data []rune
- serverEncoding string
- }
- func newDmClob() *DmClob {
- return &DmClob{
- lob: lob{
- inRow: true,
- groupId: -1,
- fileId: -1,
- pageNo: -1,
- readOver: false,
- local: true,
- updateable: true,
- length: -1,
- compatibleOracle: false,
- fetchAll: false,
- freed: false,
- modify: false,
- Valid: true,
- },
- }
- }
- func newClobFromDB(value []byte, conn *DmConnection, column *column, fetchAll bool) *DmClob {
- var clob = newDmClob()
- clob.connection = conn
- clob.lobFlag = LOB_FLAG_CHAR
- clob.compatibleOracle = conn.CompatibleOracle()
- clob.local = false
- clob.updateable = !column.readonly
- clob.tabId = column.lobTabId
- clob.colId = column.lobColId
- clob.inRow = Dm_build_1.Dm_build_94(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW
- clob.blobId = Dm_build_1.Dm_build_108(value, NBLOB_HEAD_BLOBID)
- if !clob.inRow {
- clob.groupId = Dm_build_1.Dm_build_98(value, NBLOB_HEAD_OUTROW_GROUPID)
- clob.fileId = Dm_build_1.Dm_build_98(value, NBLOB_HEAD_OUTROW_FILEID)
- clob.pageNo = Dm_build_1.Dm_build_103(value, NBLOB_HEAD_OUTROW_PAGENO)
- }
- if conn.NewLobFlag {
- clob.tabId = Dm_build_1.Dm_build_103(value, NBLOB_EX_HEAD_TABLE_ID)
- clob.colId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_COL_ID)
- clob.rowId = Dm_build_1.Dm_build_108(value, NBLOB_EX_HEAD_ROW_ID)
- clob.exGroupId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_FPA_GRPID)
- clob.exFileId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_FPA_FILEID)
- clob.exPageNo = Dm_build_1.Dm_build_103(value, NBLOB_EX_HEAD_FPA_PAGENO)
- }
- clob.resetCurrentInfo()
- clob.serverEncoding = conn.getServerEncoding()
- if clob.inRow {
- if conn.NewLobFlag {
- clob.data = []rune(Dm_build_1.Dm_build_158(value, NBLOB_EX_HEAD_SIZE, int(clob.getLengthFromHead(value)), clob.serverEncoding, conn))
- } else {
- clob.data = []rune(Dm_build_1.Dm_build_158(value, NBLOB_INROW_HEAD_SIZE, int(clob.getLengthFromHead(value)), clob.serverEncoding, conn))
- }
- clob.length = int64(len(clob.data))
- } else if fetchAll {
- clob.loadAllData()
- }
- return clob
- }
- func newClobOfLocal(value string, conn *DmConnection) *DmClob {
- var clob = newDmClob()
- clob.connection = conn
- clob.lobFlag = LOB_FLAG_CHAR
- clob.data = []rune(value)
- clob.length = int64(len(clob.data))
- return clob
- }
- func NewClob(value string) *DmClob {
- var clob = newDmClob()
- clob.lobFlag = LOB_FLAG_CHAR
- clob.data = []rune(value)
- clob.length = int64(len(clob.data))
- return clob
- }
- func (clob *DmClob) ReadString(pos int, length int) (result string, err error) {
- if err = clob.checkValid(); err != nil {
- return
- }
- result, err = clob.getSubString(int64(pos), int32(length))
- if err != nil {
- return
- }
- if len(result) == 0 {
- err = io.EOF
- return
- }
- return
- }
- func (clob *DmClob) WriteString(pos int, s string) (n int, err error) {
- if err = clob.checkValid(); err != nil {
- return
- }
- if err = clob.checkFreed(); err != nil {
- return
- }
- if pos < 1 {
- err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- return
- }
- if !clob.updateable {
- err = ECGO_RESULTSET_IS_READ_ONLY.throw()
- return
- }
- pos -= 1
- if clob.local || clob.fetchAll {
- if int64(pos) > clob.length {
- err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- return
- }
- clob.setLocalData(pos, s)
- n = len(s)
- } else {
- if err = clob.connection.checkClosed(); err != nil {
- return -1, err
- }
- var writeLen, err = clob.connection.Access.dm_build_891(clob, pos, s, clob.serverEncoding)
- if err != nil {
- return -1, err
- }
- if clob.groupId == -1 {
- clob.setLocalData(pos, s)
- } else {
- clob.inRow = false
- clob.length = -1
- }
- n = writeLen
- }
- clob.modify = true
- return
- }
- func (clob *DmClob) Truncate(length int64) error {
- var err error
- if err = clob.checkValid(); err != nil {
- return err
- }
- if err = clob.checkFreed(); err != nil {
- return err
- }
- if length < 0 {
- return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- if !clob.updateable {
- return ECGO_RESULTSET_IS_READ_ONLY.throw()
- }
- if clob.local || clob.fetchAll {
- if length >= int64(len(clob.data)) {
- return nil
- }
- clob.data = clob.data[0:length]
- clob.length = int64(len(clob.data))
- } else {
- if err = clob.connection.checkClosed(); err != nil {
- return err
- }
- clob.length, err = clob.connection.Access.dm_build_921(&clob.lob, int(length))
- if err != nil {
- return err
- }
- if clob.groupId == -1 {
- clob.data = clob.data[0:clob.length]
- }
- }
- clob.modify = true
- return nil
- }
- func (dest *DmClob) Scan(src interface{}) error {
- if dest == nil {
- return ECGO_STORE_IN_NIL_POINTER.throw()
- }
- switch src := src.(type) {
- case nil:
- *dest = *new(DmClob)
- (*dest).Valid = false
- return nil
- case string:
- *dest = *NewClob(src)
- return nil
- case *DmClob:
- *dest = *src
- return nil
- default:
- return UNSUPPORTED_SCAN.throw()
- }
- }
- func (clob DmClob) Value() (driver.Value, error) {
- if !clob.Valid {
- return nil, nil
- }
- return clob, nil
- }
- func (clob *DmClob) getSubString(pos int64, len int32) (string, error) {
- var err error
- var leaveLength int64
- if err = clob.checkFreed(); err != nil {
- return "", err
- }
- if pos < 1 || len < 0 {
- return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- pos = pos - 1
- if leaveLength, err = clob.GetLength(); err != nil {
- return "", err
- }
- if pos > leaveLength {
- pos = leaveLength
- }
- leaveLength -= pos
- if leaveLength < 0 {
- return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- if int64(len) > leaveLength {
- len = int32(leaveLength)
- }
- if clob.local || clob.inRow || clob.fetchAll {
- if pos > clob.length {
- return "", ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- return string(clob.data[pos : pos+int64(len)]), nil
- } else {
- return clob.connection.Access.dm_build_880(clob, int32(pos), len)
- }
- }
- func (clob *DmClob) loadAllData() {
- clob.checkFreed()
- if clob.local || clob.inRow || clob.fetchAll {
- return
- }
- len, _ := clob.GetLength()
- s, _ := clob.getSubString(1, int32(len))
- clob.data = []rune(s)
- clob.fetchAll = true
- }
- func (clob *DmClob) setLocalData(pos int, str string) {
- if pos+len(str) >= int(clob.length) {
- clob.data = []rune(string(clob.data[0:pos]) + str)
- } else {
- clob.data = []rune(string(clob.data[0:pos]) + str + string(clob.data[pos+len(str):len(clob.data)]))
- }
- clob.length = int64(len(clob.data))
- }
|