gokb

package module
v0.0.0-...-93ce9e3 Latest Latest
Warning

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

Go to latest
Published: Oct 23, 2024 License: GPL-2.0 Imports: 36 Imported by: 0

README

人大金仓 golang v9r1 驱动

所有版权归人大金仓所有

此项目目的主要是为了方便 golang 引用

Documentation

Overview

gokb包为基于database/sql包的Kingbase驱动

一般情况下需要使用database/sql而不是直接使用gokb中的接口 比如:

import (
	"database/sql"
)

func main() {
	connStr := "user=kbgotest dbname=kbgotest sslmode=verify-full"
	db, err := sql.Open("kingbase", connStr)
	if err != nil {
		log.Fatal(err)
	}

	age := 21
	rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
	…
}

也可以通过URL连接数据库 比如:

connStr := "kingbase://kbgotest:password@localhost/kbgotest?sslmode=verify-full"
db, err := sql.Open("kingbase", connStr)

与libkci类似,当建立与数据库的连接时,需要提供若干连接参数 libkci支持的连接参数gokb也均支持 此外,gokb也支持运行时参数(比如search_path等),可直接在连接串中指定

支持以下的连接参数:

  • dbname - 数据库名
  • user - 用户名
  • password - 用户的密码
  • host - 主机(默认为localhost)
  • port -端口(默认为54321)
  • sslmode - 是否使用SSL(默认为require)
  • fallback_application_name - 默认的应用名,当没有提供应用名时则使用该应用名
  • connect_timeout - 连接的最大等待时间,单位为秒。指定为0或不指定表示无限期等待
  • sslcert - ssl证书的位置
  • sslkey - ssl秘钥的位置
  • sslrootcert - 根证书的位置

sslmode的有效值:

  • disable - 不使用SSL
  • require - 总是使用SSL(跳过验证)
  • verify-ca - 使用SSL(验证证书是否为信任的CA签名)
  • verify-full - 使用SSL(验证证书是否为信任的CA签名并且主机名与证书中的匹配)

当参数值中包含空格时需要使用单引号,比如:

"user=kbgotest password='with spaces'"

使用反斜杠转义下一个字符:

"user=space\ man password='it\'s valid'"

注意: 1.连接参数client_encoding(设置文本的编码格式)必须设置为"UTF-8"

2.当连接参数binary_parameters开启时,[]bytes数据将以二进制格式发送到后端

3.gokb可能返回Error类型的错误,可通过如下方式查看错误细节:

if err, ok := err.(*kb.Error); ok {
    fmt.Println("kb error:", err.Code.Name())
}

4.CopyIn内部调用COPY FROM,不能在显示事务之外进行COPY 用法:

txn, err := db.Begin()
if err != nil {
	log.Fatal(err)
}

stmt, err := txn.Prepare(kb.CopyIn("users", "name", "age"))
if err != nil {
	log.Fatal(err)
}

for _, user := range users {
	_, err = stmt.Exec(user.Name, int64(user.Age))
	if err != nil {
		log.Fatal(err)
	}
}

_, err = stmt.Exec()
if err != nil {
	log.Fatal(err)
}

err = stmt.Close()
if err != nil {
	log.Fatal(err)
}

err = txn.Commit()
if err != nil {
	log.Fatal(err)
}

5.要开始监听通知,首先要通过调用NewListener打开一个到数据库的连接。此链接不能用于LISTEN/NOTIFY以外的任何操作 调用Listen将打开一个通知通道,在该通道上生成的通知将影响Listen上的发送 通知通道在调用Unlisten之前将一直保持打开状态,但连接丢失可能会导致某些通知丢失 为了解决这个问题,每当连接丢失后重新建立连接时,Listener都会通过通知通道发送一个nil指针 应用程序可以通过在对NewListener调用中设置事件回调来获取底层连接状态的信息

单个监听器可以安全地用于并发程序,这意味着通常不需要再应用程序中创建多个监听器。 但是监听器总是连接到单个数据库,因此需要为希望接收通知的每个数据库创建一个新的Listener实例

***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司

* 作者:KingbaseES

* 文件名:notice.go

* 功能描述:notice相关接口

* 其它说明:go1.10及以上版本可用

  • 修改记录: 1.修改时间:

    2.修改人:

    3.修改内容:

*****************************************************************************

***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司

* 作者:KingbaseES

* 文件名:ssl_permissions.go

* 功能描述:检查ssl秘钥文件权限

* 其它说明:

  • 修改记录: 1.修改时间:

    2.修改人:

    3.修改内容:

*****************************************************************************

***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司

* 作者:KingbaseES

* 文件名:user_posix.go

* 功能描述:获取当前USER环境变量值

* 其它说明:

  • 修改记录: 1.修改时间:

    2.修改人:

    3.修改内容:

*****************************************************************************

Index

Constants

View Source
const (
	Efatal   = "FATAL"
	Epanic   = "PANIC"
	Ewarning = "WARNING"
	Enotice  = "NOTICE"
	Edebug   = "DEBUG"
	Einfo    = "INFO"
	Elog     = "LOG"
)

****************error.go**************** 错误等级

View Source
const GOKB_CommitID_169f4a45 = iota
View Source
const GOKB_CompileTime_20230526_103734 = iota
View Source
const GOKB_CompilerVersion_go1_19_1_linux_amd64 = iota
View Source
const GOKB_Version_V008R006B0001 = iota

****************conn.go****************

Variables

View Source
var (
	ErrNotSupported              = errors.New("kb: Unsupported command")
	ErrInFailedTransaction       = errors.New("kb: Could not complete operation in a failed transaction")
	ErrSSLNotSupported           = errors.New("kb: SSL is not enabled on the server")
	ErrSSLKeyHasWorldPermissions = errors.New("kb: Private key file has group or world access. Permissions should be u=rw (0600) or less")
	ErrCouldNotDetectUsername    = errors.New("kb: Could not detect default username. Please provide one explicitly")
)

常见错误

View Source
var ErrChannelAlreadyOpen = errors.New("kb: channel is already open")

ErrChannelAlreadyOpen在通道打开后从Listen返回

View Source
var ErrChannelNotOpen = errors.New("kb: channel is not open")

ErrChannelNotOpen在通道未打开时从Unlisten返回

Functions

func Array

func Array(a interface{}) (result interface {
	driver.Valuer
	sql.Scanner
})

Array返回数组或切片的driver.Valuer和sql.Scanner

比如:

db.Query(`SELECT * FROM t WHERE id = ANY($1)`, kb.Array([]int{235, 401}))

var x []sql.NullInt64
db.QueryRow('SELECT ARRAY[235, 401]').Scan(kb.Array(&x))

不支持扫描多维数组 不支持数组下界不为1的情况,比如 `[0:0]={1}'

func ConnectorNoticeHandler

func ConnectorNoticeHandler(c driver.Connector) (f func(*Error))

ConnectorNoticeHandler返回当前设置的通知处理程序(如果有的话) 如果给定的connector不是ConnectorWithNoticeHandler的结果,则返回空

func CopyIn

func CopyIn(table string, columns ...string) (stmt string)

CopyIn创建一个可用Tx.Prepare()处理的'COPY FROM'预备语句 目标表需要在当前的search_path下

func CopyInSchema

func CopyInSchema(schema, table string, columns ...string) (stmt string)

CopyInSchema创建一个可用Tx.Prepare()处理的'COPY FROM'预备语句

func DialOpen

func DialOpen(d Dialer, dsn string) (dc driver.Conn, err error)

DialOpen通过dialer打开一个到数据库的新连接

func EnableInfinityTs

func EnableInfinityTs(negative time.Time, positive time.Time)

如果EnableInfinityTs没有被调用,"-infinity"和"infinity"将返回[]byte("-infinity")和[]byte("infinity") 将其传入time.Time时将导致报错"sql: Scan error on column index 0: unsupported driver -> Scanpair: []uint8 -> *time.Time"

EnableInfinityTs被调用后,所有使用该驱动的连接都将把"-infinity"和"infinity"转为"timestamp", "timestamp with time zone"和"date"类型所预指定的最小和最大时间 转换time.Time类型的值时,任何等于预指定的最小值将被转为"-infinity" 等于或大于最大值将被转为"infinity" 当negative >= positive或者被调用多次将会报错

func FormatTimestamp

func FormatTimestamp(t time.Time) (ts []byte)

FormatTimestamp将t格式化为kingbase的timestamps的文本格式

func GetPlatformBit

func GetPlatformBit() uint

func IsValue

func IsValue(v interface{}) bool

func NoticeHandler

func NoticeHandler(dc driver.Conn) (f func(*Error))

NoticeHandler返回给定连接上的通知处理程序(如果有的话) 如果c不是kb的连接则会发生pannic

func Open

func Open(dsn string) (dc driver.Conn, err error)

Open打开一个到数据库的新连接,name为连接串 一般情况下不直接使用该函数,而是通过标准库的database/sql包来使用

func ParseDate

func ParseDate(currentLocation *time.Location, str string) (dt time.Time, err error)

func ParseTime

func ParseTime(currentLocation *time.Location, str string) (pt time.Time, err error)

func ParseTimestamp

func ParseTimestamp(currentLocation *time.Location, str string) (pt time.Time, err error)

ParseTimestamp将文本格式的字符串解析为time.Time类型

func ParseURL

func ParseURL(url string) (s string, err error)

sql.Open()已经支持用户提供URL作为连接串:

sql.Open("kingbase", "kingbase://bob:secret@1.2.3.4:54321/mydb?sslmode=verify-full")

所以ParseURL一般不再被使用,但为了向后兼容所以保留

ParseURL将url转为driver.Open需要的连接串 比如:

"kingbase://bob:secret@1.2.3.4:54321/mydb?sslmode=verify-full"

转为:

"user=bob password=secret host=1.2.3.4 port=54321 dbname=mydb sslmode=verify-full"

最简短的例子:

"kingbase://"

将转为空,并使用默认的连接参数

func QuoteIdentifier

func QuoteIdentifier(name string) (s string)

QuoteIdentifier将标识引用起来作为SQL语句的一部分(比如一个表或一个列名):

tblname := "my_table"
data := "my_data"
quoted := kb.QuoteIdentifier(tblname)
err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data)

name中的所有双引号都将被转义,被引用的标识都是大小写敏感的 果输入的字符串包含0字节,结果将在此处截断

func QuoteLiteral

func QuoteLiteral(literal string) (s string)

QuoteLiteral将字符引起来作为SQL的一部分(经常被用来向DDL和其它不接收参数的语句传字符的参数):

exp_date := kb.QuoteLiteral("2023-01-05 15:00:00Z")
err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date))

引号都将被转义 反斜杠(\)都将被替换为双反斜杠(\\) C风格的转义符都将被认为是字符串

func SetNoticeHandler

func SetNoticeHandler(dc driver.Conn, handler func(*Error))

SetNoticeHandler设置指定连接上的指定的通知处理程序 如果c不是kb的连接则会发生pannic 一个空的handler可以用来进行取消设置

注意: 通知处理为同步执行,在处理程序返回之前不会继续处理命令

Types

type ArrayDelimiter

type ArrayDelimiter interface {
	// ArrayDelimiter返回当前元素类型的分隔符
	ArrayDelimiter() string
}

ArrayDelimiter可由driver.Valuer或sql.Scanner实现 通过GenericArray来重写数组分隔符

type BoolArray

type BoolArray []bool

BoolArray表示一维的布尔类型的数组

func (*BoolArray) Scan

func (boolArray *BoolArray) Scan(src interface{}) (err error)

Scan实现sql.Scanner接口

func (BoolArray) Value

func (boolArray BoolArray) Value() (dv driver.Value, err error)

Value实现driver.Valuer接口

type ByteaArray

type ByteaArray [][]byte

ByteaArray表示一维的bytea类型的数组

func (*ByteaArray) Scan

func (byteaArray *ByteaArray) Scan(src interface{}) (err error)

Scan实现sql.Scanner接口

func (ByteaArray) Value

func (a ByteaArray) Value() (value driver.Value, err error)

Value实现了driver.Valuer接口 使用"hex"格式,只在V8或更新的版本有效

type Connector

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

****************connector.go**************** 结构体表示gokb驱动的固定配置,实现database/sql/driver的Connector接口 可通过database/sql的OpenDB函数创建任意数量的Conn

func NewConnector

func NewConnector(dsn string) (conn *Connector, err error)

NewConnector返回具有给定dsn固定配置的gokb驱动的Connector 返回的Connector可用于创建任意数量的等效Conn 返回的Connector也将用于database/sql的OpenDB函数

func (*Connector) Connect

func (c *Connector) Connect(ctx context.Context) (driver.Conn, error)

Connect使用此Connector的固定配置返回到数据库的连接

func (*Connector) Driver

func (c *Connector) Driver() driver.Driver

Driver返回此Connector的底层驱动

type CursorString

type CursorString struct {
	CursorName string
}

type Dialer

type Dialer interface {
	Dial(network, address string) (net.Conn, error)
	DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
}

Dialer为dialer接口,与创建网络连接相关

type DialerContext

type DialerContext interface {
	DialContext(ctx context.Context, network, address string) (net.Conn, error)
}

DialerContext为需要上下文的dialer接口

type Driver

type Driver struct{}

Kingbase数据库驱动

func (*Driver) Open

func (d *Driver) Open(name string) (dc driver.Conn, err error)

Open打开一个到数据库的新连接,name为连接串 一般情况下不直接使用该函数,而是通过标准库的database/sql包来使用

type Error

type Error struct {
	Severity         string
	Code             ErrorCode
	Message          string
	Detail           string
	Hint             string
	Position         string
	InternalPosition string
	InternalQuery    string
	Where            string
	Schema           string
	Table            string
	Column           string
	DataTypeName     string
	Constraint       string
	File             string
	Line             string
	Routine          string
}

func (Error) Error

func (err Error) Error() (s string)

func (*Error) Fatal

func (err *Error) Fatal() bool

如果错误等级为fatal则返回true

func (*Error) Get

func (err *Error) Get(k byte) (value string)

获取Error信息

type ErrorClass

type ErrorClass string

func (ErrorClass) Name

func (ec ErrorClass) Name() string

Name返回错误类的名称,即标准错误码(最后三个字符为000的错误码)

type ErrorCode

type ErrorCode string

ErrorCode为5个字符长的错误码

func (ErrorCode) Class

func (ec ErrorCode) Class() ErrorClass

func (ErrorCode) Name

func (ec ErrorCode) Name() string

type EventCallbackType

type EventCallbackType func(event ListenerEventType, err error)

EventCallbackType为事件回调类型

type Float64Array

type Float64Array []float64

Float64Array表示一维的双精度数组

func (*Float64Array) Scan

func (a *Float64Array) Scan(src interface{}) (err error)

Scan实现了sql.Scanner接口

func (Float64Array) Value

func (a Float64Array) Value() (value driver.Value, err error)

Value实现了driver.Valuer接口

type GenericArray

type GenericArray struct{ A interface{} }

GenericArray实现了driver.Valuer和sql.Scanner接口,作为任何维数的数组或切片

func (GenericArray) Scan

func (a GenericArray) Scan(src interface{}) (err error)

Scan实现了sql.Scanner接口

func (GenericArray) Value

func (a GenericArray) Value() (value driver.Value, err error)

Value实现了driver.Valuer接口

type Int64Array

type Int64Array []int64

Int64Array表示一维的整型数组

func (*Int64Array) Scan

func (a *Int64Array) Scan(src interface{}) (err error)

Scan实现了sql.Scanner接口

func (Int64Array) Value

func (a Int64Array) Value() (value driver.Value, err error)

Value实现了driver.Valuer接口

type KBError

type KBError interface {
	Error() string
	Fatal() bool
	Get(k byte) (v string)
}

KBError为支持旧版本的接口,新版本直接使用Error type即可

type KbNumeric

type KbNumeric struct {
	Value     interface{}
	Precision int
	Scale     int
}

func NewKbNumeric

func NewKbNumeric(Value interface{}, Precision int, Scale int) KbNumeric

type Listener

type Listener struct {
	// 接收来自数据库通知的通道
	Notify chan *Notification
	// contains filtered or unexported fields
}

Listener为监听数据库的notifications提供了一个借口

func NewDialListener

func NewDialListener(d Dialer, name string, minReconnectInterval time.Duration, maxReconnectInterval time.Duration, eventCallback EventCallbackType) (l *Listener)

nNewDialListener类似NewListener,但需要一个Dialer

func NewListener

func NewListener(name string, minReconnectInterval time.Duration, maxReconnectInterval time.Duration, eventCallback EventCallbackType) (l *Listener)

NewListener创建一个用监听/通知的新数据库连接。 应该将名称设置为用于建立数据库连接的连接字符串 minReconnectInterval控制在连接丢失后重新建立数据库连接的持续时间。 每次连续故障后,此间隔将增加一倍,直到达到maxReconnectInterval。 成功地完成连接的建立程序将这个区间重新设置为minReconnectInterval。 最后一个参数eventCallback可以设置为一个函数,当底层数据库连接的状态发生变化时,监听器将调用它。 这个回调将被goroutine调用,它在通知通道上发送通知,因此您应该尽量避免从回调中进行可能耗时的操作。

func (*Listener) Close

func (listener *Listener) Close() (err error)

Close()将监听器从数据库中断开,并关闭数据库。 如果连接已经关闭则返回错误

func (*Listener) Listen

func (listener *Listener) Listen(channel string) (err error)

监听开始监听频道上的通知。调用此函数将阻塞,直到从服务器接收到确认。 注意,监听器在连接丢失后自动重新建立连接,因此如果无法重新建立连接,这个函数可能会无限期地阻塞。 监听只会在三个条件下失败: 1)频道已经打开。返回的错误将被错误地打开。 2)在远程服务器上执行查询,但是Kingbase返回错误消息以响应查询。返回的错误将是一个kb。错误包含服务器提供的信息。 3)在请求可以完成之前,请在监听器上调用Close。 通道名称是大小写敏感的。

func (*Listener) NotificationChannel

func (listener *Listener) NotificationChannel() <-chan *Notification

NotificationChannel为这个监听器返回通知通道。 这是与通知相同的通道,在监听者的生命周期内不会重新创建。

func (*Listener) Ping

func (listener *Listener) Ping() (err error)

Ping远程服务器以确保它还存在。Non-nil返回值意味着没有活跃的连接。

func (*Listener) Unlisten

func (listener *Listener) Unlisten(channel string) (err error)

从监听器的通道列表中删除一个通道。 如果没有连接,立即返回没有错误。 如果监听器不在指定通道上监听,返回ErrChannelNotOpen。

func (*Listener) UnlistenAll

func (listener *Listener) UnlistenAll() (err error)

从监听器的通道列表中删除所有的通道。 如果没有连接,立即返回没有错误。 注意,即使在不监听后,仍然可能会收到任何删除通道的通知。

type ListenerConn

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

func NewListenerConn

func NewListenerConn(name string, notificationChan chan<- *Notification) (lc *ListenerConn, err error)

NewListenerConn创建一个新的ListenerConn

func (*ListenerConn) Close

func (lc *ListenerConn) Close() (err error)

关闭连接

func (*ListenerConn) Err

func (lc *ListenerConn) Err() (err error)

Err()返回连接关闭的原因

func (*ListenerConn) ExecSimpleQuery

func (lc *ListenerConn) ExecSimpleQuery(query string) (executed bool, err error)

ExecSimpleQuery在连接上执行一个“简单查询”(即一个没有参数的查询)。可能的返回值为: 1)“执行”是正确的;在数据库服务器上完成了查询, 如果查询失败,错误将设置为数据库返回的错误,否则错误将为nil。 2)如果“执行”是错误的,则无法在远程服务器上执行查询。错误将是Non-nil。 在调用ExecSimpleQuery后返回一个已执行=false值, 连接要么关闭,要么将在此后不久关闭,所有随后执行的查询将返回一个错误。

func (*ListenerConn) Listen

func (lc *ListenerConn) Listen(channel string) (state bool, err error)

将监听器发送到服务器

func (*ListenerConn) Ping

func (lc *ListenerConn) Ping() (err error)

Ping远程服务器以确保它还存在。Non-nil错误意味着连接失败,应该被抛弃。

func (*ListenerConn) Unlisten

func (lc *ListenerConn) Unlisten(channel string) (state bool, err error)

Unlisten向服务器发送一个不监听的查询

func (*ListenerConn) UnlistenAll

func (lc *ListenerConn) UnlistenAll() (state bool, err error)

UnlistenAll向服务器发送“UNLISTEN *”查询

type ListenerEventType

type ListenerEventType int

ListenerEventType为监听器时间类型的枚举

const (
	// ListenerEventConnected在数据库连接初始化时发出
	// 错误消息总是为空
	ListenerEventConnected ListenerEventType = iota

	// ListenerEventDisconnected在出错或调用Close导致数据库连接丢失时发出
	// 错误消息为丢失连接的原因
	ListenerEventDisconnected

	// ListenerEventReconnected在数据库连接丢失并重建后发出
	// 错误信息总是为空
	// 在此时间被发送后,一个空的kb.Notification将被发送到Listener.Notify通道
	ListenerEventReconnected

	// ListenerEventConnectionAttemptFailed在尝试连接数据库但失败后被发送
	// 错误信息为连接没有成功的原因
	ListenerEventConnectionAttemptFailed
)

type NoticeHandlerConnector

type NoticeHandlerConnector struct {
	driver.Connector
	// contains filtered or unexported fields
}

NoticeHandlerConnector封装了一个常规的connector并在其上设置了一个通知处理程序

func ConnectorWithNoticeHandler

func ConnectorWithNoticeHandler(c driver.Connector, handler func(*Error)) (nhc *NoticeHandlerConnector)

ConnectorWithNoticeHandler创建或设置指定connector的指定处理程序 如果指定的connector是先前调用该函数返回的结果,则只需在指定的connector上设置并返回它即可 否则将返回一个新的connector,封装指定的connector并设置通知处理程序 可以用一个空的通知处理程序取消设置

返回的connector将用于database/sql.OpenDB.

注意:通知处理程序为同步执行,在返回之前不会继续处理命令

func (*NoticeHandlerConnector) Connect

func (n *NoticeHandlerConnector) Connect(ctx context.Context) (dc driver.Conn, err error)

Connect调用底层connector的connect方法然后设置通知处理程序

type Notification

type Notification struct {
	// 后端通知的进程ID(PID)
	BePid int
	// 发送通知的通道名
	Channel string
	// 通知内容,未指定时为空字符串
	Extra string
}

****************notify.go**************** Notification表示来自数据库的一个notification

type NullTime

type NullTime struct {
	Time  time.Time
	Valid bool // 不为空时Valid为true
}

NullTime表示一个可能为空的time.Time类型的值 NullTime实现了sql.Scanner接口,所以可被用来作为扫描后的目标结构,与sql.NullString类似

func (*NullTime) Scan

func (nt *NullTime) Scan(value interface{}) (err error)

Scan实现了Scanner接口

func (NullTime) Value

func (nt NullTime) Value() (dv driver.Value, err error)

Value实现了driver Valuer接口

type StringArray

type StringArray []string

StringArray表示一维的字符串类型的数组

func (*StringArray) Scan

func (a *StringArray) Scan(src interface{}) (err error)

Scan实现了sql.Scanner接口

func (StringArray) Value

func (a StringArray) Value() (value driver.Value, err error)

Value实现了driver.Valuer接口

Directories

Path Synopsis
oid包定义了服务端数据类型的oid
oid包定义了服务端数据类型的oid
***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司
***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司
***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司
***************************************************************************** * 版权信息:北京人大金仓信息技术股份有限公司

Jump to

Keyboard shortcuts

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