godatabend

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2022 License: Apache-2.0 Imports: 27 Imported by: 0

README

godatabend

Golang driver for databend cloud

Key features

  • Supports native Databend HTTP client-server protocol
  • Compatibility with database/sql

Examples

Connecting

Connection can be achieved either via a DSN string with the format http://user:password@/database?<query_option>= and sql/Open method such as https://username:password@app.databend.com:443/test?&org=databend&warehouse=bl.

func ConnectDSN() error {
    dsn, cfg, err := getDSN()
    if err != nil {
    log.Fatalf("failed to create DSN from Config: %v, err: %v", cfg, err)
    }
    conn, err := sql.Open("databend", dsn)
    if err != nil {
        return err
    }
    return conn.Ping()
}

Connection Settings

  • host - the server host
  • username/password - auth credentials
  • database - select the current default database
  • org - the org of your databend cloud account
  • warehouse - the warehouse you want to use

Execution

Once a connection has been obtained, users can issue sql statements for execution via the Exec method.

    dsn, cfg, err := getDSN()
    if err != nil {
    log.Fatalf("failed to create DSN from Config: %v, err: %v", cfg, err)
        }
		conn, err := sql.Open("databend", dsn)
    if err != nil {
        return err
	    }
    conn.Exec(`DROP TABLE IF EXISTS data`)
    _, err = conn.Exec(`
    CREATE TABLE IF NOT EXISTS  data(
        Col1 UInt8,
        Col2 String
    ) 
    `)
    if err != nil {
        return err
    }
    _, err = conn.Exec("INSERT INTO data VALUES (1, 'test-1')")

Querying Row/s

Querying a single row can be achieved using the QueryRow method. This returns a *sql.Row, on which Scan can be invoked with pointers to variables into which the columns should be marshaled.

row := conn.QueryRow("SELECT * FROM data")
var (
    col1             uint8
    col2, col3, col4 string
    col5            []string
    col6             time.Time
)
if err := row.Scan(&col1, &col2, &col3, &col4, &col5, &col6); err != nil {
    return err
}

Iterating multiple rows requires the Query method. This returns a *sql.Rows struct on which Next can be invoked to iterate through the rows. QueryContext equivalent allows passing of a context.

row := conn.QueryRow("SELECT * FROM data")
var (
    col1             uint8
    col2, col3, col4 string
    col5            []string
    col6             time.Time
)
for rows.Next() {
    if err := row.Scan(&col1, &col2, &col3, &col4, &col5, &col6); err != nil {
    return err
    }
    fmt.Printf("row: col1=%d, col2=%s, col3=%s, col4=%s, col5=%v, col6=%v\n", col1, col2, col3, col4, col5, col6)
}

Documentation

Index

Constants

View Source
const DBSessionIDKey contextKey = "LOG_SESSION_ID"

DBSessionIDKey is context key of session id

View Source
const SFSessionUserKey contextKey = "LOG_USER"

SFSessionUserKey is context key of user id of a session

Variables

View Source
var (
	ErrPlaceholderCount = errors.New("databend: wrong placeholder count")
	ErrNoLastInsertID   = errors.New("no LastInsertId available")
	ErrNoRowsAffected   = errors.New("no RowsAffected available")
)
View Source
var LogKeys = [...]contextKey{DBSessionIDKey, SFSessionUserKey}

LogKeys these keys in context should be included in logging messages when using logger.WithContext

Functions

func Array

func Array(v interface{}) driver.Valuer

Array wraps slice or array into driver.Valuer interface to allow pass through it from database/sql

func DBCallerPrettyfier

func DBCallerPrettyfier(frame *runtime.Frame) (string, string)

DBCallerPrettyfier to provide base file name and function name from calling frame used in SFLogger

func Date

func Date(t time.Time) driver.Valuer

Date returns date for t

func Decimal128

func Decimal128(v interface{}, s int32) driver.Valuer

Decimal128 converts value to Decimal128 of precision S. The value can be a number or a string. The S (scale) parameter specifies the number of decimal places.

func Decimal32

func Decimal32(v interface{}, s int32) driver.Valuer

Decimal32 converts value to Decimal32 of precision S. The value can be a number or a string. The S (scale) parameter specifies the number of decimal places.

func Decimal64

func Decimal64(v interface{}, s int32) driver.Valuer

Decimal64 converts value to Decimal64 of precision S. The value can be a number or a string. The S (scale) parameter specifies the number of decimal places.

func DeregisterTLSConfig

func DeregisterTLSConfig(key string)

DeregisterTLSConfig removes the tls.Config associated with key.

func IP

func IP(i net.IP) driver.Valuer

IP returns compatible database format for net.IP

func Map

func Map(v interface{}) driver.Valuer

func RegisterTLSConfig

func RegisterTLSConfig(key string, config *tls.Config) error

RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.

func SetLogger

func SetLogger(inLogger *DBLogger)

SetLogger set a new logger of SFLogger interface for godatabend

func Tuple

func Tuple(v interface{}) driver.Valuer

Tuple converts a struct into a tuple struct{A string, B int}{"a", 1} -> ("a", 1)

func UInt64

func UInt64(u uint64) driver.Valuer

UInt64 returns uint64

Types

type APIClient

type APIClient struct {
	UserEmail        string
	Password         string
	AccessToken      string
	RefreshToken     string
	ApiEndpoint      string
	Host             string
	CurrentOrgSlug   string
	CurrentWarehouse string
	AccountID        uint64
}

func (*APIClient) CheckQueryStatus

func (c *APIClient) CheckQueryStatus(queryId string) (*QueryResponse, error)

func (*APIClient) DoQuery

func (c *APIClient) DoQuery(ctx context.Context, query string, args []driver.Value) (*QueryResponse, error)

func (*APIClient) DoRequest

func (c *APIClient) DoRequest(method, path string, headers http.Header, req interface{}, resp interface{}) error

func (*APIClient) Login

func (c *APIClient) Login() error

func (*APIClient) QueryPage

func (c *APIClient) QueryPage(queryId, path string) (*QueryResponse, error)

func (*APIClient) QuerySync

func (c *APIClient) QuerySync(ctx context.Context, query string, args []driver.Value, respCh chan QueryResponse) error

func (*APIClient) RefreshTokens added in v0.0.2

func (c *APIClient) RefreshTokens() error

type Config

type Config struct {
	Org             string // Org name
	User            string // Username
	Password        string // Password (requires User)
	Database        string // Database name
	Warehouse       string // Warehouse
	AccessToken     string `json:"accessToken"`
	RefreshToken    string `json:"refreshToken"`
	Scheme          string
	Host            string
	Timeout         time.Duration
	IdleTimeout     time.Duration
	ReadTimeout     time.Duration
	WriteTimeout    time.Duration
	Location        *time.Location
	Debug           bool
	UseDBLocation   bool
	GzipCompression bool
	Params          map[string]string
	TLSConfig       string
}

Config is a set of configuration parameters

func NewConfig

func NewConfig() *Config

NewConfig creates a new config with default values

func ParseDSN

func ParseDSN(dsn string) (*Config, error)

ParseDSN parses the DSN string to a Config

func (*Config) FormatDSN

func (cfg *Config) FormatDSN() string

FormatDSN formats the given Config into a DSN string which can be passed to the driver.

type DBLogger

type DBLogger interface {
	rlog.Ext1FieldLogger
	SetLogLevel(level string) error
	WithContext(ctx context.Context) *rlog.Entry
	SetOutput(output io.Writer)
}

DBLogger Databend logger interface to expose FieldLogger defined in logrus

func CreateDefaultLogger

func CreateDefaultLogger() DBLogger

CreateDefaultLogger return a new instance of SFLogger with default config

func GetLogger

func GetLogger() DBLogger

GetLogger return logger that is not public

type DataField

type DataField struct {
	Name     string     `json:"name"`
	DataType TypeDetail `json:"data_type"`
}

type DataParser

type DataParser interface {
	Parse(io.RuneScanner) (driver.Value, error)
	Type() reflect.Type
}

DataParser implements parsing of a driver value and reporting its type.

func NewDataParser

func NewDataParser(t *TypeDesc, opt *DataParserOptions) (DataParser, error)

NewDataParser creates a new DataParser based on the given TypeDesc.

type DataParserOptions

type DataParserOptions struct {
	// Location describes default location for DateTime and Date field without Timezone argument.
	Location *time.Location
	// UseDBLocation if false: always use Location, ignore DateTime argument.
	UseDBLocation bool
}

DataParserOptions describes DataParser options. Ex.: Fields Location and UseDBLocation specify timezone options.

type DataSchema

type DataSchema struct {
	Fields []DataField `json:"fields"`
}

type DatabendConn

type DatabendConn struct {
	SQLState string
	// contains filtered or unexported fields
}

func (*DatabendConn) Begin

func (dc *DatabendConn) Begin() (driver.Tx, error)

func (*DatabendConn) BeginTx

func (dc *DatabendConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error)

func (*DatabendConn) Close

func (dc *DatabendConn) Close() error

Close invalidates and potentially stops any current prepared statements and transactions, marking this connection as no longer in use.

func (*DatabendConn) Commit

func (dc *DatabendConn) Commit() (err error)

Commit applies prepared statement if it exists

func (*DatabendConn) Exec

func (dc *DatabendConn) Exec(query string, args []driver.Value) (driver.Result, error)

func (*DatabendConn) Prepare

func (dc *DatabendConn) Prepare(query string) (driver.Stmt, error)

func (*DatabendConn) PrepareContext

func (dc *DatabendConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error)

func (*DatabendConn) Query

func (dc *DatabendConn) Query(query string, args []driver.Value) (driver.Rows, error)

func (*DatabendConn) Rollback

func (dc *DatabendConn) Rollback() error

Rollback cleans prepared statement

type DatabendDriver

type DatabendDriver struct{}

DatabendDriver is a context of Go Driver

func (DatabendDriver) Open

func (d DatabendDriver) Open(dsn string) (driver.Conn, error)

Open creates a new connection.

func (DatabendDriver) OpenWithConfig

func (d DatabendDriver) OpenWithConfig(
	ctx context.Context,
	config Config) (
	driver.Conn, error)

OpenWithConfig creates a new connection with the given Config.

type Error

type Error struct {
	Code    int
	Message string
}

Error contains parsed information about server error

func (*Error) Error

func (e *Error) Error() string

Error implements the interface error

type QueryError

type QueryError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Kind    string `json:"kind"`
}

type QueryProgress

type QueryProgress struct {
	Bytes uint64 `json:"bytes"`
	Rows  uint64 `json:"rows"`
}

type QueryRequest

type QueryRequest struct {
	SQL string `json:"sql"`
}

type QueryResponse

type QueryResponse struct {
	Data     [][]interface{} `json:"data"`
	Error    *QueryError     `json:"error"`
	FinalURI string          `json:"final_uri"`
	Id       string          `json:"id"`
	NextURI  string          `json:"next_uri"`
	Schema   DataSchema      `json:"schema,omitempty"`
	State    string          `json:"state"`
	Stats    QueryStats      `json:"stats"`
	StatsURI string          `json:"stats_uri"`
}

type QueryStats

type QueryStats struct {
	RunningTimeMS float64       `json:"running_time_ms"`
	ScanProgress  QueryProgress `json:"scan_progress"`
}

type TypeDesc

type TypeDesc struct {
	Name string
	Args []*TypeDesc
}

TypeDesc describes a (possibly nested) data type returned by ClickHouse.

func ParseTypeDesc

func ParseTypeDesc(s string) (*TypeDesc, error)

ParseTypeDesc parses the type description that ClickHouse provides.

The grammar is quite simple:

desc
    name
    name()
    name(args)
args
    desc
    desc, args

Examples:

String
Nullable(Nothing)
Array(Tuple(Tuple(String, String), Tuple(String, UInt64)))

type TypeDetail

type TypeDetail struct {
	Type string `json:"type"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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