mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-11 01:03:51 +08:00
163 lines
4.8 KiB
Go
163 lines
4.8 KiB
Go
//go:build gonavi_full_drivers || gonavi_dameng_driver
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
type damengColumnsMetadataDriver struct{}
|
|
|
|
type damengColumnsMetadataConn struct{}
|
|
|
|
type damengColumnsMetadataRows struct {
|
|
columns []string
|
|
values [][]driver.Value
|
|
index int
|
|
}
|
|
|
|
var registerDamengColumnsMetadataDriverOnce sync.Once
|
|
|
|
var damengColumnsMetadataQueryState struct {
|
|
sync.Mutex
|
|
failAutoIncrementQuery bool
|
|
queries []string
|
|
}
|
|
|
|
func (damengColumnsMetadataDriver) Open(name string) (driver.Conn, error) {
|
|
return damengColumnsMetadataConn{}, nil
|
|
}
|
|
|
|
func (damengColumnsMetadataConn) Prepare(query string) (driver.Stmt, error) {
|
|
return nil, errors.New("prepared statements are not supported by this test driver")
|
|
}
|
|
|
|
func (damengColumnsMetadataConn) Close() error { return nil }
|
|
|
|
func (damengColumnsMetadataConn) Begin() (driver.Tx, error) {
|
|
return nil, errors.New("transactions are not supported by this test driver")
|
|
}
|
|
|
|
func (damengColumnsMetadataConn) QueryContext(_ context.Context, query string, _ []driver.NamedValue) (driver.Rows, error) {
|
|
damengColumnsMetadataQueryState.Lock()
|
|
damengColumnsMetadataQueryState.queries = append(damengColumnsMetadataQueryState.queries, query)
|
|
failAutoIncrementQuery := damengColumnsMetadataQueryState.failAutoIncrementQuery
|
|
damengColumnsMetadataQueryState.Unlock()
|
|
|
|
if strings.Contains(query, "SYS.SYSCOLUMNS") {
|
|
if failAutoIncrementQuery {
|
|
return nil, errors.New("insufficient privilege for SYS.SYSCOLUMNS")
|
|
}
|
|
return &damengColumnsMetadataRows{
|
|
columns: []string{"COLUMN_NAME"},
|
|
values: [][]driver.Value{{"ID"}},
|
|
}, nil
|
|
}
|
|
|
|
return &damengColumnsMetadataRows{
|
|
columns: []string{
|
|
"COLUMN_NAME", "DATA_TYPE", "DATA_LENGTH", "CHAR_LENGTH", "DATA_PRECISION",
|
|
"DATA_SCALE", "NULLABLE", "DATA_DEFAULT", "COL_COMMENT", "COLUMN_KEY",
|
|
},
|
|
values: [][]driver.Value{
|
|
{"ID", "NUMBER", nil, nil, int64(10), int64(0), "N", nil, "", "PRI"},
|
|
{"NAME", "VARCHAR2", int64(64), int64(64), nil, nil, "Y", nil, "", ""},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (r *damengColumnsMetadataRows) Columns() []string { return r.columns }
|
|
|
|
func (r *damengColumnsMetadataRows) Close() error { return nil }
|
|
|
|
func (r *damengColumnsMetadataRows) Next(dest []driver.Value) error {
|
|
if r.index >= len(r.values) {
|
|
return io.EOF
|
|
}
|
|
copy(dest, r.values[r.index])
|
|
r.index++
|
|
return nil
|
|
}
|
|
|
|
func openDamengColumnsMetadataDB(t *testing.T) *sql.DB {
|
|
t.Helper()
|
|
|
|
registerDamengColumnsMetadataDriverOnce.Do(func() {
|
|
sql.Register("dameng_columns_metadata", damengColumnsMetadataDriver{})
|
|
})
|
|
|
|
conn, err := sql.Open("dameng_columns_metadata", "")
|
|
if err != nil {
|
|
t.Fatalf("open dameng_columns_metadata test DB failed: %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = conn.Close()
|
|
})
|
|
return conn
|
|
}
|
|
|
|
func resetDamengColumnsMetadataQueryState(t *testing.T, failAutoIncrementQuery bool) {
|
|
t.Helper()
|
|
|
|
damengColumnsMetadataQueryState.Lock()
|
|
damengColumnsMetadataQueryState.failAutoIncrementQuery = failAutoIncrementQuery
|
|
damengColumnsMetadataQueryState.queries = nil
|
|
damengColumnsMetadataQueryState.Unlock()
|
|
t.Cleanup(func() {
|
|
damengColumnsMetadataQueryState.Lock()
|
|
damengColumnsMetadataQueryState.failAutoIncrementQuery = false
|
|
damengColumnsMetadataQueryState.queries = nil
|
|
damengColumnsMetadataQueryState.Unlock()
|
|
})
|
|
}
|
|
|
|
func damengColumnsMetadataQueries() []string {
|
|
damengColumnsMetadataQueryState.Lock()
|
|
defer damengColumnsMetadataQueryState.Unlock()
|
|
return append([]string(nil), damengColumnsMetadataQueryState.queries...)
|
|
}
|
|
|
|
func TestDamengGetColumnsMarksAutoIncrementColumns(t *testing.T) {
|
|
resetDamengColumnsMetadataQueryState(t, false)
|
|
|
|
damengDB := &DamengDB{conn: openDamengColumnsMetadataDB(t)}
|
|
columns, err := damengDB.GetColumns("biz", "orders")
|
|
if err != nil {
|
|
t.Fatalf("GetColumns returned error: %v", err)
|
|
}
|
|
if len(columns) != 2 {
|
|
t.Fatalf("unexpected column count: %d", len(columns))
|
|
}
|
|
if columns[0].Extra != "auto_increment" {
|
|
t.Fatalf("identity column should be marked as auto_increment: %+v", columns[0])
|
|
}
|
|
if columns[1].Extra != "" {
|
|
t.Fatalf("non-identity column should not be marked: %+v", columns[1])
|
|
}
|
|
|
|
queries := damengColumnsMetadataQueries()
|
|
if len(queries) != 2 || !strings.Contains(queries[1], "SYS.SYSCOLUMNS") {
|
|
t.Fatalf("expected base and system metadata queries, got=%v", queries)
|
|
}
|
|
}
|
|
|
|
func TestDamengGetColumnsKeepsBaseMetadataWhenAutoIncrementQueryFails(t *testing.T) {
|
|
resetDamengColumnsMetadataQueryState(t, true)
|
|
|
|
damengDB := &DamengDB{conn: openDamengColumnsMetadataDB(t)}
|
|
columns, err := damengDB.GetColumns("biz", "orders")
|
|
if err != nil {
|
|
t.Fatalf("GetColumns should keep base metadata when auto-increment lookup fails: %v", err)
|
|
}
|
|
if len(columns) != 2 || columns[0].Name != "ID" || columns[0].Extra != "" {
|
|
t.Fatalf("unexpected fallback columns: %+v", columns)
|
|
}
|
|
}
|