| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- /*
- * Copyright (c) 2000-2018, 达梦数据库有限公司.
- * All rights reserved.
- */
- package dm
- import (
- "database/sql/driver"
- "io"
- )
- type DmBlob struct {
- lob
- data []byte
- offset int64
- }
- func newDmBlob() *DmBlob {
- return &DmBlob{
- 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,
- },
- offset: 1,
- }
- }
- func newBlobFromDB(value []byte, conn *DmConnection, column *column, fetchAll bool) *DmBlob {
- var blob = newDmBlob()
- blob.connection = conn
- blob.lobFlag = LOB_FLAG_BYTE
- blob.compatibleOracle = conn.CompatibleOracle()
- blob.local = false
- blob.updateable = !column.readonly
- blob.tabId = column.lobTabId
- blob.colId = column.lobColId
- blob.inRow = Dm_build_1.Dm_build_94(value, NBLOB_HEAD_IN_ROW_FLAG) == LOB_IN_ROW
- blob.blobId = Dm_build_1.Dm_build_108(value, NBLOB_HEAD_BLOBID)
- if !blob.inRow {
- blob.groupId = Dm_build_1.Dm_build_98(value, NBLOB_HEAD_OUTROW_GROUPID)
- blob.fileId = Dm_build_1.Dm_build_98(value, NBLOB_HEAD_OUTROW_FILEID)
- blob.pageNo = Dm_build_1.Dm_build_103(value, NBLOB_HEAD_OUTROW_PAGENO)
- }
- if conn.NewLobFlag {
- blob.tabId = Dm_build_1.Dm_build_103(value, NBLOB_EX_HEAD_TABLE_ID)
- blob.colId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_COL_ID)
- blob.rowId = Dm_build_1.Dm_build_108(value, NBLOB_EX_HEAD_ROW_ID)
- blob.exGroupId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_FPA_GRPID)
- blob.exFileId = Dm_build_1.Dm_build_98(value, NBLOB_EX_HEAD_FPA_FILEID)
- blob.exPageNo = Dm_build_1.Dm_build_103(value, NBLOB_EX_HEAD_FPA_PAGENO)
- }
- blob.resetCurrentInfo()
- blob.length = blob.getLengthFromHead(value)
- if blob.inRow {
- blob.data = make([]byte, blob.length)
- if conn.NewLobFlag {
- Dm_build_1.Dm_build_57(blob.data, 0, value, NBLOB_EX_HEAD_SIZE, len(blob.data))
- } else {
- Dm_build_1.Dm_build_57(blob.data, 0, value, NBLOB_INROW_HEAD_SIZE, len(blob.data))
- }
- } else if fetchAll {
- blob.loadAllData()
- }
- return blob
- }
- func newBlobOfLocal(value []byte, conn *DmConnection) *DmBlob {
- var blob = newDmBlob()
- blob.connection = conn
- blob.lobFlag = LOB_FLAG_BYTE
- blob.data = value
- blob.length = int64(len(blob.data))
- return blob
- }
- func NewBlob(value []byte) *DmBlob {
- var blob = newDmBlob()
- blob.lobFlag = LOB_FLAG_BYTE
- blob.data = value
- blob.length = int64(len(blob.data))
- return blob
- }
- func (blob *DmBlob) Read(dest []byte) (n int, err error) {
- if err = blob.checkValid(); err != nil {
- return
- }
- result, err := blob.getBytes(blob.offset, int32(len(dest)))
- if err != nil {
- return 0, err
- }
- blob.offset += int64(len(result))
- copy(dest, result)
- if len(result) == 0 {
- return 0, io.EOF
- }
- return len(result), nil
- }
- func (blob *DmBlob) ReadAt(pos int, dest []byte) (n int, err error) {
- if err = blob.checkValid(); err != nil {
- return
- }
- result, err := blob.getBytes(int64(pos), int32(len(dest)))
- if err != nil {
- return 0, err
- }
- if len(result) == 0 {
- return 0, io.EOF
- }
- copy(dest[0:len(result)], result)
- return len(result), nil
- }
- func (blob *DmBlob) Write(pos int, src []byte) (n int, err error) {
- if err = blob.checkValid(); err != nil {
- return
- }
- if err = blob.checkFreed(); err != nil {
- return
- }
- if pos < 1 {
- err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- return
- }
- if !blob.updateable {
- err = ECGO_RESULTSET_IS_READ_ONLY.throw()
- return
- }
- pos -= 1
- if blob.local || blob.fetchAll {
- if int64(pos) > blob.length {
- err = ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- return
- }
- blob.setLocalData(pos, src)
- n = len(src)
- } else {
- if err = blob.connection.checkClosed(); err != nil {
- return -1, err
- }
- var writeLen, err = blob.connection.Access.dm_build_907(blob, pos, src)
- if err != nil {
- return -1, err
- }
- if blob.groupId == -1 {
- blob.setLocalData(pos, src)
- } else {
- blob.inRow = false
- blob.length = -1
- }
- n = writeLen
- }
- blob.modify = true
- return
- }
- func (blob *DmBlob) Truncate(length int64) error {
- var err error
- if err = blob.checkValid(); err != nil {
- return err
- }
- if err = blob.checkFreed(); err != nil {
- return err
- }
- if length < 0 {
- return ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- if !blob.updateable {
- return ECGO_RESULTSET_IS_READ_ONLY.throw()
- }
- if blob.local || blob.fetchAll {
- if length >= int64(len(blob.data)) {
- return nil
- }
- tmp := make([]byte, length)
- Dm_build_1.Dm_build_57(tmp, 0, blob.data, 0, len(tmp))
- blob.data = tmp
- blob.length = int64(len(tmp))
- } else {
- if err = blob.connection.checkClosed(); err != nil {
- return err
- }
- blob.length, err = blob.connection.Access.dm_build_921(&blob.lob, int(length))
- if err != nil {
- return err
- }
- if blob.groupId == -1 {
- tmp := make([]byte, blob.length)
- Dm_build_1.Dm_build_57(tmp, 0, blob.data, 0, int(blob.length))
- blob.data = tmp
- }
- }
- blob.modify = true
- return nil
- }
- func (dest *DmBlob) Scan(src interface{}) error {
- if dest == nil {
- return ECGO_STORE_IN_NIL_POINTER.throw()
- }
- switch src := src.(type) {
- case nil:
- *dest = *new(DmBlob)
- (*dest).Valid = false
- return nil
- case []byte:
- *dest = *NewBlob(src)
- return nil
- case *DmBlob:
- *dest = *src
- return nil
- default:
- return UNSUPPORTED_SCAN.throw()
- }
- }
- func (blob DmBlob) Value() (driver.Value, error) {
- if !blob.Valid {
- return nil, nil
- }
- return blob, nil
- }
- func (blob *DmBlob) getBytes(pos int64, length int32) ([]byte, error) {
- var err error
- var leaveLength int64
- if err = blob.checkFreed(); err != nil {
- return nil, err
- }
- if pos < 1 || length < 0 {
- return nil, ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- pos = pos - 1
- if leaveLength, err = blob.GetLength(); err != nil {
- return nil, err
- }
- leaveLength -= pos
- if leaveLength < 0 {
- return nil, ECGO_INVALID_LENGTH_OR_OFFSET.throw()
- }
- if int64(length) > leaveLength {
- length = int32(leaveLength)
- }
- if blob.local || blob.inRow || blob.fetchAll {
- return blob.data[pos : pos+int64(length)], nil
- } else {
- return blob.connection.Access.dm_build_870(blob, int32(pos), length)
- }
- }
- func (blob *DmBlob) loadAllData() {
- blob.checkFreed()
- if blob.local || blob.inRow || blob.fetchAll {
- return
- }
- len, _ := blob.GetLength()
- blob.data, _ = blob.getBytes(1, int32(len))
- blob.fetchAll = true
- }
- func (blob *DmBlob) setLocalData(pos int, p []byte) {
- if pos+len(p) >= int(blob.length) {
- var tmp = make([]byte, pos+len(p))
- Dm_build_1.Dm_build_57(tmp, 0, blob.data, 0, pos)
- Dm_build_1.Dm_build_57(tmp, pos, p, 0, len(p))
- blob.data = tmp
- } else {
- Dm_build_1.Dm_build_57(blob.data, pos, p, 0, len(p))
- }
- blob.length = int64(len(blob.data))
- }
|