Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions buf.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type packetType uint8

type header struct {
PacketType packetType
Status uint8
Status byte
Size uint16
Spid uint16
PacketNo uint8
Expand Down Expand Up @@ -45,6 +45,7 @@ type tdsBuffer struct {
wpos int
wPacketSeq byte
wPacketType packetType
wSpid uint16

// Read fields.
rbuf []byte
Expand All @@ -57,6 +58,8 @@ type tdsBuffer struct {
// before the first use. It is executed after the first packet is
// written and then removed.
afterFirst func()

serverConn *tdsSession
}

func newTdsBuffer(bufsize uint16, transport io.ReadWriteCloser) *tdsBuffer {
Expand Down Expand Up @@ -86,6 +89,7 @@ func (w *tdsBuffer) flush() (err error) {
// Write packet size.
w.wbuf[0] = byte(w.wPacketType)
binary.BigEndian.PutUint16(w.wbuf[2:], uint16(w.wpos))
binary.BigEndian.PutUint16(w.wbuf[4:], w.wSpid)
w.wbuf[6] = w.wPacketSeq

// Write packet into underlying transport.
Expand Down Expand Up @@ -169,12 +173,14 @@ func (r *tdsBuffer) readNextPacket() error {
PacketNo: buf[6],
Pad: buf[7],
}

if int(h.Size) > r.packetSize {
return errors.New("invalid packet size, it is longer than buffer size")
}
if headerSize > int(h.Size) {
return errors.New("invalid packet size, it is shorter than header size")
}

_, err = io.ReadFull(r.transport, r.rbuf[headerSize:h.Size])
//s := base64.StdEncoding.EncodeToString(r.rbuf[headerSize:h.Size])
//fmt.Print(s)
Expand All @@ -183,12 +189,34 @@ func (r *tdsBuffer) readNextPacket() error {
}
r.rpos = headerSize
r.rsize = int(h.Size)
r.final = h.Status != 0
r.final = h.Status&0x1 != 0
r.rPacketType = h.PacketType

if r.serverConn != nil {
_, err := r.serverConn.buf.Write(r.rbuf[r.rpos:r.rsize])
if err != nil {
return err
}

if r.final {
r.serverConn.buf.wSpid = h.Spid
if err := r.serverConn.buf.FinishPacket(); err != nil {
return err
}
} else {
if err := r.serverConn.buf.flush(); err != nil {
return err
}
}
}
return nil
}

func (r *tdsBuffer) BeginRead() (packetType, error) {
if r.serverConn != nil {
r.serverConn.buf.BeginPacket(r.rPacketType, false)
}

err := r.readNextPacket()
if err != nil {
return 0, err
Expand Down
18 changes: 11 additions & 7 deletions examples/simple/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"log"
"strings"

_ "github.com/microsoft/go-mssqldb"
)
Expand Down Expand Up @@ -37,21 +38,24 @@ func main() {
}
defer conn.Close()

stmt, err := conn.Prepare("select 1, 'abc'")
stmt, err := conn.Prepare("EXEC UpdateUserComments @UserID=?, @Comment=?")
if err != nil {
log.Fatal("Error preparing statement: ", err.Error())
}
defer stmt.Close()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [golangci] reported by reviewdog 🐶
Error return value of stmt.Close is not checked (errcheck)


//comment := "Your long comment text here..."
comment := strings.Repeat("A long comment text ", 500) // Simulate a long text

_, err = stmt.Exec(10, comment)
if err != nil {
log.Fatal("Prepare failed:", err.Error())
}
defer stmt.Close()

row := stmt.QueryRow()
var somenumber int64
var somechars string
err = row.Scan(&somenumber, &somechars)
if err != nil {
log.Fatal("Scan failed:", err.Error())
}
fmt.Printf("somenumber:%d\n", somenumber)
fmt.Printf("somechars:%s\n", somechars)

fmt.Printf("bye\n")
}
Loading
Loading