wire

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package wire implements the Firebird wire protocol encoding and operations.

Index

Constants

View Source
const (
	PluginSrp256 = "Srp256"
	PluginSrp    = "Srp"
)

SRP plugin names recognized by Firebird 3.0+.

View Source
const (
	IscDpbPageSize         byte = 4
	IscDpbNoGarbageCollect byte = 16
	IscDpbSysUserName      byte = 19
	IscDpbForceWrite       byte = 24
	IscDpbUserName         byte = 28
	IscDpbPassword         byte = 29
	IscDpbPasswordEnc      byte = 30
	IscDpbLcCtype          byte = 48
	IscDpbConnectTimeout   byte = 57
	IscDpbDummyPktInterval byte = 58
	IscDpbSQLDialect       byte = 63
	IscDpbSetDBReadOnly    byte = 64
	IscDpbSetDBCharset     byte = 68
	IscDpbUtf8Filename     byte = 77
	IscDpbAuthBlock        byte = 79
	IscDpbClientVersion    byte = 80
	IscDpbRemoteProtocol   byte = 81
	IscDpbHostName         byte = 82
	IscDpbOsUser           byte = 83
	IscDpbSpecificAuthData byte = 84
	IscDpbAuthPluginList   byte = 85
	IscDpbAuthPluginName   byte = 86
	IscDpbConfig           byte = 87
	IscDpbNolinger         byte = 88
	IscDpbProcessID        byte = 89
	IscDpbProcessName      byte = 90
	IscDpbSessionTimeZone  byte = 91
	IscDpbSetDBReplica     byte = 92
	IscDpbSetBind          byte = 93
	IscDpbSetBindOfRPT     byte = IscDpbSetBind
	IscDpbDecfloatRound    byte = 94
	IscDpbDecfloatTraps    byte = 95
	IscDpbParallelWorkers  byte = 100
)

DPB tag constants.

View Source
const (
	// Database info items
	IscInfoDBID            byte = 4
	IscInfoIscVersion      byte = 12
	IscInfoBaseLevel       byte = 13
	IscInfoPageSize        byte = 14
	IscInfoOdsVersion      byte = 32
	IscInfoOdsMinorVersion byte = 33
	IscInfoDBSQLDialect    byte = 62
	IscInfoDBReadOnly      byte = 63
	IscInfoDBSizeInPages   byte = 64
	IscInfoDBProvider      byte = 108
	IscInfoFirebirdVersion byte = 103

	// Transaction info items
	IscInfoTraID        byte = 4
	IscInfoTraIsolation byte = 8
	IscInfoTraAccess    byte = 9

	// SQL info items
	IscInfoSQLSelect       byte = 4
	IscInfoSQLBind         byte = 5
	IscInfoSQLNumVariables byte = 6
	IscInfoSQLDescribeVars byte = 7
	IscInfoSQLDescribeEnd  byte = 8
	IscInfoSQLSQLDASeq     byte = 9
	IscInfoSQLType         byte = 11
	IscInfoSQLSubType      byte = 12
	IscInfoSQLScale        byte = 13
	IscInfoSQLLength       byte = 14
	IscInfoSQLNullInd      byte = 15
	IscInfoSQLField        byte = 16
	IscInfoSQLRelation     byte = 17
	IscInfoSQLOwner        byte = 18
	IscInfoSQLAlias        byte = 19
	IscInfoSQLSqldaStart   byte = 20
	IscInfoSQLStmtType     byte = 21

	// SQL record count items
	IscInfoSQLRecords     byte = 23
	IscInfoReqSelectCount byte = 13
	IscInfoReqInsertCount byte = 14
	IscInfoReqUpdateCount byte = 15
	IscInfoReqDeleteCount byte = 16

	// BLOB info items
	IscInfoBlobNumSegments byte = 4
	IscInfoBlobMaxSegment  byte = 5
	IscInfoBlobTotalLength byte = 6
	IscInfoBlobType        byte = 7
)

Info item constants for database, transaction, SQL, and BLOB info requests.

View Source
const (
	ProtocolVersion10 uint32 = 10
	ProtocolVersion11 uint32 = 0x800B
	ProtocolVersion12 uint32 = 0x800C
	ProtocolVersion13 uint32 = 0x800D
	ProtocolVersion14 uint32 = 0x800E
	ProtocolVersion15 uint32 = 0x800F
	ProtocolVersion16 uint32 = 0x8010
	ProtocolVersion17 uint32 = 0x8011
	ProtocolVersion18 uint32 = 0x8012
	ProtocolVersion19 uint32 = 0x8013

	FBProtocolFlag uint32 = 0x8000
	FBProtocolMask uint32 = 0x7FFF
)
View Source
const (
	ConnectVersion2 uint32 = 2
	ConnectVersion3 uint32 = 3
	ArchGeneric     uint32 = 1
	InvalidObject   uint32 = 0xFFFF
)
View Source
const (
	PtypeRPC       uint32 = 2
	PtypeBatchSend uint32 = 3
	PtypeOutOfBand uint32 = 4
	PtypeLazySend  uint32 = 5
	PtypeMask      uint32 = 0xFF
)
View Source
const (
	CnctUser             byte = 1
	CnctPasswd           byte = 2
	CnctHost             byte = 4
	CnctGroup            byte = 5
	CnctUserVerification byte = 6
	CnctSpecificData     byte = 7
	CnctPluginName       byte = 8
	CnctLogin            byte = 9
	CnctPluginList       byte = 10
	CnctClientCrypt      byte = 11
)
View Source
const (
	WireCryptDisabled uint32 = 0
	WireCryptEnabled  uint32 = 1
	WireCryptRequired uint32 = 2
)
View Source
const (
	DSQLClose     uint32 = 1
	DSQLDrop      uint32 = 2
	DSQLUnprepare uint32 = 4
)
View Source
const (
	StmtSelect        int32 = 1
	StmtInsert        int32 = 2
	StmtUpdate        int32 = 3
	StmtDelete        int32 = 4
	StmtDDL           int32 = 5
	StmtGetSegment    int32 = 6
	StmtPutSegment    int32 = 7
	StmtExecProcedure int32 = 8
	StmtStartTrans    int32 = 9
	StmtCommit        int32 = 10
	StmtRollback      int32 = 11
	StmtSelectForUpd  int32 = 12
	StmtSetGenerator  int32 = 13
	StmtSavepoint     int32 = 14
)
View Source
const (
	SQLDialectV5      uint32 = 1
	SQLDialectV6Trans uint32 = 2
	SQLDialectV6      uint32 = 3
	SQLDialectCurrent uint32 = 3
)
View Source
const (
	CancelDisable uint32 = 1
	CancelEnable  uint32 = 2
	CancelRaise   uint32 = 3
	CancelAbort   uint32 = 4
)
View Source
const (
	IscArgEnd         int32 = 0
	IscArgGds         int32 = 1
	IscArgString      int32 = 2
	IscArgCstring     int32 = 3
	IscArgNumber      int32 = 4
	IscArgInterpreted int32 = 5
	IscArgWarning     int32 = 18
	IscArgSQLState    int32 = 19
)
View Source
const (
	IscInfoEnd          byte = 1
	IscInfoTruncated    byte = 2
	IscInfoError        byte = 3
	IscInfoDataNotReady byte = 4
	IscInfoLength       byte = 126
	IscInfoFlagEnd      byte = 127
)
View Source
const (
	IscDpbVersion1 byte = 1
	IscDpbVersion2 byte = 2
	IscTpbVersion1 byte = 1
	IscTpbVersion3 byte = 3
	IscSpbVersion1 byte = 1
	IscSpbVersion2 byte = 2
	IscSpbVersion3 byte = 3
)
View Source
const (
	SQLText          int32 = 452
	SQLVarying       int32 = 448
	SQLShort         int32 = 500
	SQLLong          int32 = 496
	SQLFloat         int32 = 482
	SQLDouble        int32 = 480
	SQLDFloat        int32 = 530
	SQLTimestamp     int32 = 510
	SQLBlob          int32 = 520
	SQLArray         int32 = 540
	SQLQuad          int32 = 550
	SQLTypeDate      int32 = 570
	SQLTypeTime      int32 = 560
	SQLInt64         int32 = 580
	SQLInt128        int32 = 32752
	SQLTimestampTZ   int32 = 32754
	SQLTimeTZ        int32 = 32756
	SQLTimeTZEx      int32 = 32750
	SQLTimestampTZEx int32 = 32748
	SQLDec16         int32 = 32760
	SQLDec34         int32 = 32762
	SQLBoolean       int32 = 32764
	SQLNull          int32 = 32766
)
View Source
const (
	BlrShort         byte = 7
	BlrLong          byte = 8
	BlrQuad          byte = 9
	BlrFloat         byte = 10
	BlrDFloat        byte = 11
	BlrSQLDate       byte = 12
	BlrSQLTime       byte = 13
	BlrText          byte = 14
	BlrText2         byte = 15
	BlrInt64         byte = 16
	BlrBlob2         byte = 17
	BlrBool          byte = 23
	BlrDec64         byte = 24
	BlrDec128        byte = 25
	BlrInt128        byte = 26
	BlrDouble        byte = 27
	BlrSQLTimeTZ     byte = 28
	BlrTimestampTZ   byte = 29
	BlrExTimeTZ      byte = 30
	BlrExTimestampTZ byte = 31
	BlrTimestamp     byte = 35
	BlrVarying       byte = 37
	BlrVarying2      byte = 38
)
View Source
const (
	BlrVersion4 byte = 4
	BlrVersion5 byte = 5
	BlrBegin    byte = 2
	BlrMessage  byte = 4
	BlrEnd      byte = 255
	BlrEOC      byte = 76
)
View Source
const (
	FetchNext     int32 = 0
	FetchPrior    int32 = 1
	FetchFirst    int32 = 2
	FetchLast     int32 = 3
	FetchAbsolute int32 = 4
	FetchRelative int32 = 5
)
View Source
const (
	BlobSeekFromHead int32 = 0
	BlobSeekRelative int32 = 1
	BlobSeekFromTail int32 = 2
)
View Source
const (
	IscTpbConsistency      byte = 1
	IscTpbConcurrency      byte = 2
	IscTpbWait             byte = 6
	IscTpbNowait           byte = 7
	IscTpbRead             byte = 8
	IscTpbWrite            byte = 9
	IscTpbReadCommitted    byte = 15
	IscTpbAutocommit       byte = 16
	IscTpbRecVersion       byte = 17
	IscTpbNoRecVersion     byte = 18
	IscTpbLockTimeout      byte = 21
	IscTpbReadConsistency  byte = 22
	IscTpbAtSnapshotNumber byte = 23
)

TPB tag constants.

View Source
const DefaultPluginList = PluginSrp256 + "," + PluginSrp

DefaultPluginList is the preferred comma-separated list of auth plugins. Srp256 is preferred; Srp is the fallback for older Firebird 3.0 configurations.

Variables

DescribeItems is the standard set of info items for describing output columns. It intentionally omits relation/owner metadata because the driver never uses it.

Functions

func AppendBLR

func AppendBLR(dst []byte, descs []ColumnDescriptor) []byte

AppendBLR appends the BLR for the given column descriptors to dst and returns the extended buffer.

func BuildBLR

func BuildBLR(descs []ColumnDescriptor) []byte

BuildBLR generates the Binary Language Representation for a set of column descriptors. The BLR tells the server how to format row data.

Format: version5 + begin + message(0, count*2) + [type + null_ind]... + end + eoc

func BuildParamBLR

func BuildParamBLR(descs []ColumnDescriptor) []byte

BuildParamBLR generates BLR for input parameters. For parameters, we use the declared types from the descriptor.

func DateToMJD

func DateToMJD(t time.Time) int32

DateToMJD converts a time.Time to Modified Julian Date (days since epoch). Uses the wall-clock date (like TimeToTicks uses the wall clock) and civil arithmetic: time.Duration saturates at ±292 years, which corrupts dates beyond ~2150, and converting to UTC shifts the date across midnight for non-UTC locations.

func DecodeColumn

func DecodeColumn(r *Reader, desc *ColumnDescriptor) any

DecodeColumn decodes a single column value from the reader based on its SQL type descriptor. Returns the Go value or nil for NULL.

func DecodeRow

func DecodeRow(r *Reader, descs []ColumnDescriptor, nullBuf []byte, row []any) error

DecodeRow decodes one protocol 13+ row using the supplied descriptors.

func EncodeNamedParams

func EncodeNamedParams(w *Writer, descs []ColumnDescriptor, values []driver.NamedValue)

EncodeNamedParams encodes database/sql named values without first boxing them into a transient []any slice.

func EncodeNamedParamsErr

func EncodeNamedParamsErr(w *Writer, descs []ColumnDescriptor, values []driver.NamedValue) error

EncodeNamedParamsErr encodes database/sql named values and reports conversion errors.

func EncodeNamedParamsStackErr

func EncodeNamedParamsStackErr(w *StackWriter, descs []ColumnDescriptor, values []driver.NamedValue) error

EncodeNamedParamsStackErr encodes parameters using a StackWriter and reports conversion errors.

func EncodeParams

func EncodeParams(w *Writer, descs []ColumnDescriptor, values []any)

EncodeParams encodes parameter values into wire format for op_execute. Returns the null bitset + encoded data as a single buffer. Optimized: single-pass encoding that builds null bitset and writes values.

func EncodeParamsErr

func EncodeParamsErr(w *Writer, descs []ColumnDescriptor, values []any) error

EncodeParamsErr encodes parameter values and reports conversion errors.

func EncodeParamsOptimal

func EncodeParamsOptimal(sw *StackWriter, descs []ColumnDescriptor, values []driver.NamedValue) []byte

EncodeParamsOptimal encodes named parameters, using a stack-allocated buffer for small parameter sets and falling back to a pooled writer for larger ones. The returned bytes reference the StackWriter's buffer when used (caller must consume them before sw goes out of scope) or a copy when falling back to pool.

Usage:

var sw StackWriter
paramData := EncodeParamsOptimal(&sw, descs, values)

func EncodeParamsOptimalErr

func EncodeParamsOptimalErr(sw *StackWriter, descs []ColumnDescriptor, values []driver.NamedValue) ([]byte, error)

EncodeParamsOptimalErr encodes named parameters and reports conversion errors.

func EstimateParamSize

func EstimateParamSize(descs []ColumnDescriptor, values []driver.NamedValue) int

EstimateParamSize estimates the wire size needed for encoding the given parameters. Used to decide if stack-allocated buffer can be used.

func IOLength

func IOLength(sqlType, length int32) int

IOLength returns the wire size for a given SQL type. Negative = fixed size in bytes, positive = (length+1), 0 = variable (XDR buffer).

func IsNull

func IsNull(bitset []byte, idx int) bool

IsNull checks if column idx is null in the bitset.

func MJDToDate

func MJDToDate(mjd int32) time.Time

MJDToDate converts a Modified Julian Date to time.Time.

func ParseRecordCounts

func ParseRecordCounts(data []byte) (selectCount, insertCount, updateCount, deleteCount int64)

ParseRecordCounts parses an isc_info_sql_records response to extract select, insert, update, and delete counts.

func ParseSQLDescribeInfo

func ParseSQLDescribeInfo(buf []byte) (stmtType int32, outputs []ColumnDescriptor, inputs []ColumnDescriptor)

ParseSQLDescribeInfo parses the info buffer from op_prepare_statement and returns column descriptors for output columns and input parameters. If the buffer was truncated (isc_info_truncated) the result is partial; use WireConnection.CompleteSQLDescribe to follow continuations.

func PrepareExecInfoItems

func PrepareExecInfoItems() []byte

PrepareExecInfoItems returns the reduced item set needed for ad-hoc Exec paths.

func PrepareInfoItems

func PrepareInfoItems() []byte

PrepareInfoItems is the default set of items requested during op_prepare_statement for statements that may be queried later.

func PutWriter

func PutWriter(w *Writer)

PutWriter returns a Writer to the pool.

func TicksToTime

func TicksToTime(ticks uint32) time.Time

TicksToTime converts 100µs ticks since midnight to time.Time (date = zero).

func TimeTZExToTime

func TimeTZExToTime(ticks uint32, tzValue uint32, offsetMinutes int32) time.Time

TimeTZExToTime converts UTC time ticks + timezone value + explicit offset to time.Time. TIME WITH TIME ZONE has no date, so using the explicit Firebird offset avoids historical IANA rules for year zero.

func TimeToTicks

func TimeToTicks(t time.Time) uint32

TimeToTicks converts a time.Time to 100µs ticks since midnight.

func TimestampTZExToTime

func TimestampTZExToTime(mjd int32, ticks uint32, tzValue uint32, offsetMinutes int32) time.Time

TimestampTZExToTime converts date + time + timezone value + explicit offset to time.Time. The explicit offset is authoritative for the returned value, so a Go tzdata version mismatch cannot shift the decoded wall clock.

func TimestampToTime

func TimestampToTime(mjd int32, ticks uint32) time.Time

TimestampToTime converts MJD date + ticks to time.Time.

Types

type ColumnDescriptor

type ColumnDescriptor struct {
	FieldName    string
	RelationName string
	OwnerName    string
	AliasName    string
	SQLType      int32
	SubType      int32
	Scale        int32
	Length       int32
	Nullable     bool
	// SubTypeFromNone indica que la columna es NONE en la base y que SubType
	// fue reinterpretado por none_charset (ver applyNoneCharset). Decode y
	// encode usan SubType, pero el BLR debe seguir pidiendo NONE: pedirla en
	// otro charset haría transliterar al servidor, que aborta el fetch con
	// "Malformed string" ante bytes que no son válidos en el charset pedido.
	// El cero (false) mantiene el comportamiento de siempre: BLR = SubType.
	SubTypeFromNone bool
}

ColumnDescriptor describes a column or parameter from SQL statement metadata. Fields are ordered by alignment size (largest first) to minimize padding.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn encapsulates a network connection with optional encryption.

Layer order (write): caller → encrypt → TCP Layer order (read): TCP → decrypt → caller

The pipe acts as a pivot point. When encryption is activated, pipe's internals are swapped to route through the cipher layer.

func NewConn

func NewConn(conn net.Conn) *Conn

NewConn wraps a network connection for use with the wire protocol.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the underlying TCP connection and releases layer resources. The TCP connection is closed first since the Firebird disconnect sequence (op_detach + op_disconnect) has already been sent through the layers.

func (*Conn) Read

func (c *Conn) Read(p []byte) (int, error)

Read reads from the top of the layer stack.

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadline on the underlying connection.

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline on the underlying connection.

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline on the underlying connection.

func (*Conn) Write

func (c *Conn) Write(p []byte) (int, error)

Write writes to the top of the layer stack.

type DPBBuilder

type DPBBuilder struct {
	// contains filtered or unexported fields
}

DPBBuilder constructs a Database Parameter Buffer. Uses a reusable internal buffer.

func NewDPBBuilder

func NewDPBBuilder() *DPBBuilder

NewDPBBuilder creates a DPB builder with DPB version 2 (protocol 13+).

func (*DPBBuilder) Bytes

func (b *DPBBuilder) Bytes() []byte

Bytes returns the built DPB.

func (*DPBBuilder) Reset

func (b *DPBBuilder) Reset()

Reset clears the buffer and writes the version byte.

func (*DPBBuilder) WriteByteTag

func (b *DPBBuilder) WriteByteTag(tag byte, value byte)

WriteByteTag appends a single-byte value tag.

func (*DPBBuilder) WriteBytes

func (b *DPBBuilder) WriteBytes(tag byte, value []byte)

WriteBytes appends a raw byte value tag with 4-byte LE length.

func (*DPBBuilder) WriteMarker

func (b *DPBBuilder) WriteMarker(tag byte)

WriteMarker appends a marker tag with zero length.

func (*DPBBuilder) WriteString

func (b *DPBBuilder) WriteString(tag byte, value string)

WriteString appends a string tag with 4-byte LE length (DPB v2 format).

type FetchResponse

type FetchResponse struct {
	Status   int32 // 0 = row available, 100 = EOF
	Messages int32 // number of messages (0 or 1)
}

FetchResponse holds the parsed fields of an op_fetch_response message.

type GDSError

type GDSError struct {
	Code     int32
	SQLState string
	Message  string
	Params   []any
}

GDSError represents a single GDS error or warning entry.

func (*GDSError) Error

func (e *GDSError) Error() string

Error returns a human-readable representation of the GDS error.

type GenericResponse

type GenericResponse struct {
	Handle int32
	BlobID int64
	Data   []byte
	Status StatusVector
}

GenericResponse holds the parsed fields of an op_response message.

type HandshakeResult

type HandshakeResult struct {
	ProtocolVersion uint32
	DBHandle        int32
}

HandshakeResult holds the outcome of a successful protocol handshake.

type InfoItem

type InfoItem struct {
	Tag  byte
	Data []byte
}

InfoItem represents a parsed tag-length-value info item.

func ParseInfoBuffer

func ParseInfoBuffer(buf []byte) (items []InfoItem, truncated bool)

ParseInfoBuffer parses a TLV info buffer with Int16 LE lengths. Returns the parsed items and whether the buffer was truncated. Item Data fields reference the original buffer (zero-copy); callers must not modify the input buffer while items are in use.

Only isc_info_end (1) and isc_info_truncated (2) are treated as control tags. Tag values 3+ are parsed as normal TLV items because the same byte values are reused across info contexts (e.g. tag 4 is isc_info_tra_id in transaction info, isc_info_blob_num_segments in blob info, isc_info_db_id in database info).

func (*InfoItem) Int32LE

func (item *InfoItem) Int32LE() int32

Int32LE returns the item data as a little-endian int32.

func (*InfoItem) String

func (item *InfoItem) String() string

String returns the item data as a string.

type ProtocolConfig

type ProtocolConfig struct {
	Host     string
	Port     string
	Database string
	User     string
	Password string

	// Charset for the connection. Default: "UTF8".
	Charset string
	// NoneCharset is the character set assumed for text columns declared
	// CHARACTER SET NONE. Empty (or "NONE") keeps them as raw bytes.
	NoneCharset string
	// SQL dialect. Default: 3.
	Dialect uint32
	// Wire encryption preference. Default: WireCryptEnabled.
	WireCrypt    uint32
	WireCryptSet bool // true if WireCrypt was explicitly set
	// Auth plugin list. Default: "Srp256,Srp".
	AuthPluginList string
	// Role for the connection.
	Role string
	// DataTypeBind maps to isc_dpb_set_bind (Firebird 4+).
	DataTypeBind string
	// SessionTimeZone maps to isc_dpb_session_time_zone (Firebird 4+).
	SessionTimeZone string
}

ProtocolConfig holds the parameters for the wire protocol handshake.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader reads XDR-encoded data from an underlying io.Reader. It keeps a sliding window over an internal buffer so small reads can be satisfied without calling io.ReadFull for every field.

func NewReader

func NewReader(r io.Reader) *Reader

NewReader returns a new Reader with a reusable 16KB internal buffer.

func (*Reader) Err

func (r *Reader) Err() error

Err returns the first error encountered during reads.

func (*Reader) ReadBuffer

func (r *Reader) ReadBuffer() []byte

ReadBuffer reads a length-prefixed buffer and returns a slice over the reader's internal buffer. The returned slice is valid until the next read that refills or compacts that buffer.

Applies sign-extension fixup for compatibility with older servers: if the upper 16 bits of the length are 0xFFFF, they are masked off.

func (*Reader) ReadInt32

func (r *Reader) ReadInt32() int32

ReadInt32 reads a 32-bit signed integer in big-endian byte order.

func (*Reader) ReadInt64

func (r *Reader) ReadInt64() int64

ReadInt64 reads a 64-bit signed integer in big-endian byte order.

func (*Reader) ReadLazyResponse

func (r *Reader) ReadLazyResponse() (GenericResponse, error)

ReadLazyResponse reads a deferred response, used with lazy send protocol.

func (*Reader) ReadOpaque

func (r *Reader) ReadOpaque(buf []byte, n int)

ReadOpaque reads exactly n bytes of opaque data into buf, plus alignment padding. The caller must ensure len(buf) >= n.

func (*Reader) ReadOpcode

func (r *Reader) ReadOpcode() int32

ReadOpcode reads an operation code, skipping any op_dummy (71) keep-alives.

func (*Reader) ReadResponse

func (r *Reader) ReadResponse() (GenericResponse, error)

ReadResponse reads the next response from the wire, dispatching by opcode. Returns a GenericResponse for op_response. For other response types, callers should use the specific read methods.

func (*Reader) ReadString

func (r *Reader) ReadString() string

ReadString reads a length-prefixed string from the wire.

func (*Reader) ReadUInt32

func (r *Reader) ReadUInt32() uint32

ReadUInt32 reads a 32-bit unsigned integer in big-endian byte order.

func (*Reader) Reset

func (r *Reader) Reset(rd io.Reader)

Reset replaces the underlying reader and clears any stored error.

func (*Reader) ResetErr

func (r *Reader) ResetErr()

ResetErr clears any stored error, allowing reads to resume.

func (*Reader) SkipPadding

func (r *Reader) SkipPadding(n int)

SkipPadding discards alignment padding for n bytes of data.

type SQLResponse

type SQLResponse struct {
	Messages int32 // 0 = no data, 1 = data follows
}

SQLResponse holds the parsed fields of an op_sql_response message.

type StackWriter

type StackWriter struct {
	// contains filtered or unexported fields
}

StackWriter is a Writer that uses a stack-allocated buffer. Use this for small, short-lived encoding operations to avoid pool overhead. If the buffer overflows, the overflow flag is set and can be checked with Overflowed().

func (*StackWriter) Bytes

func (w *StackWriter) Bytes() []byte

Bytes returns the buffered bytes.

func (*StackWriter) Overflowed

func (w *StackWriter) Overflowed() bool

Overflowed returns true if any write operation exceeded the buffer capacity.

func (*StackWriter) Reset

func (w *StackWriter) Reset()

Reset clears the buffer for reuse.

func (*StackWriter) WriteBuffer

func (w *StackWriter) WriteBuffer(data []byte)

WriteBuffer writes a length-prefixed buffer.

func (*StackWriter) WriteInt32

func (w *StackWriter) WriteInt32(v int32)

WriteInt32 writes a 32-bit signed integer.

func (*StackWriter) WriteInt64

func (w *StackWriter) WriteInt64(v int64)

WriteInt64 writes a 64-bit signed integer.

func (*StackWriter) WriteString

func (w *StackWriter) WriteString(s string)

WriteString writes a string as length-prefixed buffer.

func (*StackWriter) WriteUInt32

func (w *StackWriter) WriteUInt32(v uint32)

WriteUInt32 writes a 32-bit unsigned integer.

type StatusError

type StatusError struct {
	SV StatusVector
}

StatusError is returned whenever a server response carries a non-zero status vector. It retains the full StatusVector so callers can inspect individual GDS codes with errors.As.

func (*StatusError) Error

func (e *StatusError) Error() string

Error implements the error interface.

func (*StatusError) GDSCode

func (e *StatusError) GDSCode() int32

GDSCode returns the primary GDS error code, or 0 if the vector is empty.

func (*StatusError) SQLState

func (e *StatusError) SQLState() string

SQLState returns the SQLSTATE of the primary error entry, or "" when it cannot be determined. Firebird does not send SQLSTATE in the wire status vector: like fbclient/jaybird, it is derived client-side from the GDS code (tabla generada en internal/errmsg). Si el vector trae isc_arg_sql_state (poco común), ese valor tiene prioridad.

type StatusVector

type StatusVector struct {
	Errors   []GDSError
	Warnings []GDSError
}

StatusVector represents a parsed Firebird status vector containing errors and warnings from a server response.

func (*StatusVector) Error

func (sv *StatusVector) Error() string

Error returns a human-readable representation of the full error chain. Firebird reports errors as a chain of GDS entries where the first code is often generic (e.g. "unsuccessful metadata update") and the details (object names, SQLCODE) arrive in later entries, so all entries are rendered. The primary GDS code and SQLSTATE are appended for logs and support; use errors.As with *StatusError for programmatic access.

func (*StatusVector) HasError

func (sv *StatusVector) HasError() bool

HasError returns true if the status vector contains errors.

func (*StatusVector) HasWarning

func (sv *StatusVector) HasWarning() bool

HasWarning returns true if the status vector contains warnings.

type TPBBuilder

type TPBBuilder struct {
	// contains filtered or unexported fields
}

TPBBuilder constructs a Transaction Parameter Buffer.

func NewTPBBuilder

func NewTPBBuilder() *TPBBuilder

NewTPBBuilder creates a TPB builder with TPB version 3.

func (*TPBBuilder) Bytes

func (b *TPBBuilder) Bytes() []byte

Bytes returns the built TPB.

func (*TPBBuilder) Reset

func (b *TPBBuilder) Reset()

Reset clears the buffer and writes the version byte.

func (*TPBBuilder) WriteTag

func (b *TPBBuilder) WriteTag(tag byte)

WriteTag appends a single-byte tag (marker).

type WireConnection

type WireConnection struct {
	// contains filtered or unexported fields
}

WireConnection manages a single Firebird database connection at the wire protocol level. It owns the transport layers (conn), XDR reader/writer, and tracks protocol state (version, handles, deferred responses).

func ConnectContext

func ConnectContext(ctx context.Context, cfg *ProtocolConfig) (*WireConnection, error)

ConnectContext establishes a connection honoring ctx for the TCP dial and the whole handshake (auth + crypt negotiation). Without a deadline here, a server that accepts TCP but never answers would hang Connect forever and database/sql connection timeouts would not be respected.

func (*WireConnection) AllocateAndPrepare

func (wc *WireConnection) AllocateAndPrepare(txHandle int32, sql string, bufferLength int32) (int32, []byte, error)

AllocateAndPrepare performs allocate+prepare in a single round-trip (lazy send). Returns the allocated handle and the prepare info data.

func (*WireConnection) AllocateAndPrepareWithItems

func (wc *WireConnection) AllocateAndPrepareWithItems(txHandle int32, sql string, bufferLength int32, items []byte) (int32, []byte, error)

AllocateAndPrepareWithItems performs allocate+prepare using a caller-provided info item set. If a pooled statement handle is available, skips the allocate and sends only prepare (saving 1 message + 1 response per operation).

func (*WireConnection) Cancel

func (wc *WireConnection) Cancel(kind uint32) error

Cancel sends an asynchronous op_cancel to interrupt the current operation. This is safe to call from a different goroutine.

func (*WireConnection) CancelBlob

func (wc *WireConnection) CancelBlob(blobHandle int32) error

CancelBlob sends op_cancel_blob.

func (*WireConnection) CloseBlob

func (wc *WireConnection) CloseBlob(blobHandle int32) error

CloseBlob sends op_close_blob.

func (*WireConnection) CloseTransport

func (wc *WireConnection) CloseTransport() error

CloseTransport closes the underlying socket without attempting protocol cleanup. Use this after transport failures, where detach would only add more broken writes to the same dead connection.

func (*WireConnection) Commit

func (wc *WireConnection) Commit(txHandle int32) error

Commit sends op_commit for the given transaction handle.

func (*WireConnection) CommitRetaining

func (wc *WireConnection) CommitRetaining(txHandle int32) error

CommitRetaining sends op_commit_retaining (handle remains valid).

func (*WireConnection) CompleteSQLDescribe

func (wc *WireConnection) CompleteSQLDescribe(stmtHandle int32, buf []byte, items []byte, bufferLength int32) (int32, []ColumnDescriptor, []ColumnDescriptor, error)

CompleteSQLDescribe parses statement describe data from a prepare (or op_info_sql) response and, if the buffer was truncated, keeps requesting continuations with isc_info_sql_sqlda_start until every output column and input parameter descriptor has been received. items must be the same info item list used for the original request.

func (*WireConnection) CreateBlob

func (wc *WireConnection) CreateBlob(txHandle int32, bpb []byte) (int32, int64, error)

CreateBlob sends op_create_blob2 and returns the handle and blob ID.

func (*WireConnection) Detach

func (wc *WireConnection) Detach() error

Detach sends op_detach + op_disconnect and closes the connection.

func (*WireConnection) DrainStatementPool

func (wc *WireConnection) DrainStatementPool()

DrainStatementPool drops all pooled statement handles. Called during connection close to release server resources.

func (*WireConnection) Execute

func (wc *WireConnection) Execute(stmtHandle, txHandle int32, blr, params []byte) error

Execute sends op_execute for a non-returning statement (INSERT, UPDATE, DELETE, DDL).

func (*WireConnection) Execute2

func (wc *WireConnection) Execute2(stmtHandle, txHandle int32, inBLR, params, outBLR []byte, outputs []ColumnDescriptor) (int32, []any, error)

Execute2 sends op_execute2 for a singleton returning statement (EXECUTE PROCEDURE). It returns the row carried by op_sql_response.

func (*WireConnection) ExecuteAndCommitRetaining

func (wc *WireConnection) ExecuteAndCommitRetaining(stmtHandle, txHandle int32, blr, params []byte) error

ExecuteAndCommitRetaining batches op_execute + op_commit_retaining into a single flush. The transaction handle remains valid for reuse.

func (*WireConnection) FetchRowsReuse

func (wc *WireConnection) FetchRowsReuse(
	stmtHandle int32,
	blr []byte,
	descs []ColumnDescriptor,
	fetchSize int32,
	rowsBuf [][]any,
	valuesBuf []any,
) ([][]any, []any, bool, error)

FetchRowsReuse sends op_fetch and decodes all returned rows, reusing the provided row/value buffers when they are large enough.

func (*WireConnection) FreeStatement

func (wc *WireConnection) FreeStatement(stmtHandle int32, option uint32) error

FreeStatement sends op_free_statement with the given option.

func (*WireConnection) GetSegment

func (wc *WireConnection) GetSegment(blobHandle int32, maxLength int32) (int32, []byte, error)

GetSegment sends op_get_segment and returns the packed segment data and a status (0=data, 1=partial, 2=EOF).

func (*WireConnection) InfoBlob

func (wc *WireConnection) InfoBlob(blobHandle int32, items []byte, bufferLength int32) ([]byte, error)

InfoBlob sends op_info_blob and returns the raw info buffer.

func (*WireConnection) InfoDatabase

func (wc *WireConnection) InfoDatabase(items []byte, bufferLength int32) ([]byte, error)

InfoDatabase sends op_info_database and returns the raw info buffer.

func (*WireConnection) InfoSQL

func (wc *WireConnection) InfoSQL(stmtHandle int32, items []byte, bufferLength int32) ([]byte, error)

InfoSQL sends op_info_sql and returns the raw info buffer.

func (*WireConnection) InfoTransaction

func (wc *WireConnection) InfoTransaction(txHandle int32, items []byte, bufferLength int32) ([]byte, error)

InfoTransaction sends op_info_transaction and returns the raw info buffer.

func (*WireConnection) OpenBlob

func (wc *WireConnection) OpenBlob(txHandle int32, blobID int64, bpb []byte) (int32, error)

OpenBlob sends op_open_blob2 and returns the handle.

func (*WireConnection) PrepareStatementWithItems

func (wc *WireConnection) PrepareStatementWithItems(txHandle, stmtHandle int32, sql string, bufferLength int32, items []byte) ([]byte, error)

PrepareStatementWithItems sends op_prepare_statement using a caller-provided info item set. This allows lighter describe requests for exec-only paths.

func (*WireConnection) ProtocolVersion

func (wc *WireConnection) ProtocolVersion() uint32

ProtocolVersion returns the negotiated protocol version.

func (*WireConnection) PutSegment

func (wc *WireConnection) PutSegment(blobHandle int32, data []byte) error

PutSegment sends op_put_segment with the given data.

func (*WireConnection) ReadBlobData

func (wc *WireConnection) ReadBlobData(txHandle int32, blobID int64) ([]byte, error)

ReadBlobData opens, reads, and closes a blob, returning the full content. Uses pipelining when lazy send is available: batches open + first get_segment into one flush, saving 1 round-trip for the common case of small blobs.

func (*WireConnection) Reader

func (wc *WireConnection) Reader() *Reader

Reader returns the underlying wire reader for direct row data decoding.

func (*WireConnection) RecycleStatement

func (wc *WireConnection) RecycleStatement(stmtHandle int32, hasCursor bool) error

RecycleStatement returns a statement handle to the pool for reuse, avoiding future op_allocate round-trips. If hasCursor is true, sends DSQLClose first to close the open cursor. If the pool is full, drops the handle instead.

func (*WireConnection) Rollback

func (wc *WireConnection) Rollback(txHandle int32) error

Rollback sends op_rollback for the given transaction handle.

func (*WireConnection) SetDeadline

func (wc *WireConnection) SetDeadline(t time.Time)

SetDeadline sets the read/write deadline on the underlying connection.

func (*WireConnection) SetReadDeadline

func (wc *WireConnection) SetReadDeadline(t time.Time)

SetReadDeadline sets the read deadline on the underlying connection. Setting a past time forces a blocked read to return, used to honor a cancelled context when the server can't interrupt the current operation (e.g. a lock wait). The connection must be treated as broken afterwards.

func (*WireConnection) Transaction

func (wc *WireConnection) Transaction(tpb []byte) (int32, error)

Transaction sends op_transaction with the given TPB and returns the handle.

func (*WireConnection) WriteBlobData

func (wc *WireConnection) WriteBlobData(txHandle int32, data []byte) (int64, error)

WriteBlobData creates a blob, writes data in segments, closes it, and returns the blob ID. Uses pipelining when lazy send is available to batch all operations in a single flush, reducing N+2 round-trips to 1.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer accumulates XDR-encoded data in an internal buffer. All Write methods append to the buffer without allocating. Call Flush to send the buffered data to the underlying writer.

func GetWriter

func GetWriter() *Writer

GetWriter returns a Writer from the pool, ready for use.

func NewWriter

func NewWriter() *Writer

NewWriter returns a new Writer with a 32KB initial buffer.

func (*Writer) Bytes

func (w *Writer) Bytes() []byte

Bytes returns the buffered bytes. The slice is valid until the next write operation or Reset.

func (*Writer) Flush

func (w *Writer) Flush(wr io.Writer) error

Flush writes the buffered data to wr and resets the buffer position.

func (*Writer) Len

func (w *Writer) Len() int

Len returns the number of buffered bytes.

func (*Writer) Reset

func (w *Writer) Reset()

Reset discards all buffered data without writing.

func (*Writer) ResetWriter

func (w *Writer) ResetWriter()

ResetWriter returns a Writer to a usable state with the buffer cleared. This is used by the pool to reuse writers without allocating.

func (*Writer) WriteBuffer

func (w *Writer) WriteBuffer(data []byte)

WriteBuffer writes a length-prefixed buffer: Int32(len) + data + padding(0x00).

func (*Writer) WriteInt32

func (w *Writer) WriteInt32(v int32)

WriteInt32 writes a 32-bit signed integer in big-endian byte order.

func (*Writer) WriteInt64

func (w *Writer) WriteInt64(v int64)

WriteInt64 writes a 64-bit signed integer in big-endian byte order.

func (*Writer) WriteOpaque

func (w *Writer) WriteOpaque(data []byte, n int)

WriteOpaque writes exactly n bytes of data plus padding to align to 4 bytes. No length prefix is written. The caller must ensure len(data) >= n.

func (*Writer) WriteRaw

func (w *Writer) WriteRaw(data []byte)

WriteRaw writes raw bytes without any length prefix or padding.

func (*Writer) WriteString

func (w *Writer) WriteString(s string)

WriteString writes a string as a length-prefixed buffer. Does not allocate: copies directly from string to buffer.

func (*Writer) WriteUInt32

func (w *Writer) WriteUInt32(v uint32)

WriteUInt32 writes a 32-bit unsigned integer in big-endian byte order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL