Add oracle test
This commit is contained in:
parent
589acfff86
commit
afb3b44b83
|
@ -0,0 +1,38 @@
|
||||||
|
name: test oracle
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: test oracle
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version-file: 'go.mod'
|
||||||
|
- name: test oracle
|
||||||
|
env:
|
||||||
|
TEST_ORACLE_HOST: oracle:1521
|
||||||
|
TEST_ORACLE_DBNAME: FREEPDB1
|
||||||
|
TEST_ORACLE_USERNAME: system
|
||||||
|
TEST_ORACLE_PASSWORD: oracle
|
||||||
|
run: TEST_CACHE_ENABLE=false make test-oracle
|
||||||
|
|
||||||
|
services:
|
||||||
|
oracle:
|
||||||
|
image: gvenzl/oracle-xe:latest
|
||||||
|
env:
|
||||||
|
ORACLE_RANDOM_PASSWORD: true
|
||||||
|
APP_USER: system
|
||||||
|
APP_USER_PASSWORD: oracle
|
||||||
|
ports:
|
||||||
|
- 1521:1521
|
||||||
|
options: >-
|
||||||
|
--health-cmd healthcheck.sh
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 10
|
21
Makefile
21
Makefile
|
@ -48,6 +48,12 @@ TEST_DAMENG_HOST ?= dameng:5236
|
||||||
TEST_DAMENG_USERNAME ?= SYSDBA
|
TEST_DAMENG_USERNAME ?= SYSDBA
|
||||||
TEST_DAMENG_PASSWORD ?= SYSDBA
|
TEST_DAMENG_PASSWORD ?= SYSDBA
|
||||||
|
|
||||||
|
TEST_ORACLE_HOST ?= oracle:1521
|
||||||
|
TEST_ORACLE_SCHEMA ?=
|
||||||
|
TEST_ORACLE_DBNAME ?= xe
|
||||||
|
TEST_ORACLE_USERNAME ?= system
|
||||||
|
TEST_ORACLE_PASSWORD ?= oracle
|
||||||
|
|
||||||
TEST_CACHE_ENABLE ?= false
|
TEST_CACHE_ENABLE ?= false
|
||||||
TEST_QUOTE_POLICY ?= always
|
TEST_QUOTE_POLICY ?= always
|
||||||
|
|
||||||
|
@ -279,6 +285,21 @@ test-dameng\#%: go-check
|
||||||
-conn_str="dm://$(TEST_DAMENG_USERNAME):$(TEST_DAMENG_PASSWORD)@$(TEST_DAMENG_HOST)" \
|
-conn_str="dm://$(TEST_DAMENG_USERNAME):$(TEST_DAMENG_PASSWORD)@$(TEST_DAMENG_HOST)" \
|
||||||
-coverprofile=dameng.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
|
-coverprofile=dameng.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
|
||||||
|
|
||||||
|
.PHONY: test-oracle
|
||||||
|
test-oracle: test-goora
|
||||||
|
|
||||||
|
.PNONY: test-goora
|
||||||
|
test-goora: go-check
|
||||||
|
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=goora -schema='$(TEST_ORACLE_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
|
||||||
|
-conn_str="$(TEST_ORACLE_USERNAME):$(TEST_ORACLE_PASSWORD)@$(TEST_ORACLE_HOST)/$(TEST_ORACLE_DBNAME)" \
|
||||||
|
-coverprofile=oracle.$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||||
|
|
||||||
|
.PHONY: test-oci8\#%
|
||||||
|
test-goora\#%: go-check
|
||||||
|
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -db=goora -schema='$(TEST_PGSQL_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
|
||||||
|
-conn_str="oracle://$(TEST_ORACLE_USERNAME):$(TEST_ORACLE_PASSWORD)@$(TEST_ORACLE_HOST)/$(TEST_ORACLE_DBNAME)" \
|
||||||
|
-coverprofile=oracle.$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||||
|
|
||||||
.PHONY: vet
|
.PHONY: vet
|
||||||
vet:
|
vet:
|
||||||
$(GO) vet $(shell $(GO) list ./...)
|
$(GO) vet $(shell $(GO) list ./...)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"xorm.io/xorm/core"
|
"xorm.io/xorm/core"
|
||||||
|
"xorm.io/xorm/internal/utils"
|
||||||
"xorm.io/xorm/schemas"
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -567,11 +568,13 @@ func (db *oracle) SQLType(c *schemas.Column) string {
|
||||||
c.Default = "0"
|
c.Default = "0"
|
||||||
}
|
}
|
||||||
res = "NUMBER(1,0)"
|
res = "NUMBER(1,0)"
|
||||||
case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int, schemas.Integer, schemas.BigInt, schemas.Serial, schemas.BigSerial:
|
case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int,
|
||||||
|
schemas.Integer, schemas.BigInt, schemas.Serial, schemas.BigSerial,
|
||||||
|
schemas.UnsignedBigInt, schemas.UnsignedBit, schemas.UnsignedInt:
|
||||||
res = "NUMBER"
|
res = "NUMBER"
|
||||||
case schemas.Binary, schemas.VarBinary, schemas.Blob, schemas.TinyBlob, schemas.MediumBlob, schemas.LongBlob, schemas.Bytea:
|
case schemas.Binary, schemas.VarBinary, schemas.Blob, schemas.TinyBlob, schemas.MediumBlob, schemas.LongBlob, schemas.Bytea:
|
||||||
return schemas.Blob
|
return schemas.Blob
|
||||||
case schemas.Time, schemas.DateTime, schemas.TimeStamp:
|
case schemas.Date, schemas.Time, schemas.DateTime, schemas.TimeStamp:
|
||||||
res = schemas.TimeStamp
|
res = schemas.TimeStamp
|
||||||
case schemas.TimeStampz:
|
case schemas.TimeStampz:
|
||||||
res = "TIMESTAMP WITH TIME ZONE"
|
res = "TIMESTAMP WITH TIME ZONE"
|
||||||
|
@ -695,9 +698,29 @@ func (db *oracle) IsColumnExist(queryer core.Queryer, ctx context.Context, table
|
||||||
return db.HasRecords(queryer, ctx, query, args...)
|
return db.HasRecords(queryer, ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func QueryRowContext(ctx context.Context, queryer core.Queryer, query string, args ...interface{}) *core.Row {
|
||||||
|
rows, err := queryer.QueryContext(ctx, query, args...)
|
||||||
|
if err != nil {
|
||||||
|
return core.NewRow(nil, err)
|
||||||
|
}
|
||||||
|
return core.NewRow(rows, nil)
|
||||||
|
}
|
||||||
|
|
||||||
func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) {
|
func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) {
|
||||||
|
s := `select column_name from user_cons_columns
|
||||||
|
where constraint_name = (select constraint_name from user_constraints
|
||||||
|
where table_name = :1 and constraint_type ='P')`
|
||||||
|
var pkName string
|
||||||
|
err := QueryRowContext(ctx, queryer, s, tableName).Scan(&pkName)
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
args := []interface{}{tableName}
|
args := []interface{}{tableName}
|
||||||
s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," +
|
s = "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," +
|
||||||
"nullable FROM USER_TAB_COLUMNS WHERE table_name = :1"
|
"nullable FROM USER_TAB_COLUMNS WHERE table_name = :1"
|
||||||
|
|
||||||
rows, err := queryer.QueryContext(ctx, s, args...)
|
rows, err := queryer.QueryContext(ctx, s, args...)
|
||||||
|
@ -712,11 +735,11 @@ func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableNam
|
||||||
col := new(schemas.Column)
|
col := new(schemas.Column)
|
||||||
col.Indexes = make(map[string]int)
|
col.Indexes = make(map[string]int)
|
||||||
|
|
||||||
var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string
|
var colName, colDefault, nullable, dataType, dataPrecision, dataScale, comment *string
|
||||||
var dataLen int64
|
var dataLen int64
|
||||||
|
|
||||||
err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
|
err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
|
||||||
&dataScale, &nullable)
|
&dataScale, &nullable, &comment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -733,6 +756,21 @@ func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableNam
|
||||||
col.Nullable = false
|
col.Nullable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if comment != nil {
|
||||||
|
col.Comment = *comment
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkName != "" && pkName == col.Name {
|
||||||
|
col.IsPrimaryKey = true
|
||||||
|
has, err := db.HasRecords(queryer, ctx, "SELECT * FROM USER_SEQUENCES WHERE SEQUENCE_NAME = :1", utils.SeqName(tableName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if has {
|
||||||
|
col.IsAutoIncrement = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ignore bool
|
var ignore bool
|
||||||
|
|
||||||
var dt string
|
var dt string
|
||||||
|
@ -758,7 +796,7 @@ func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableNam
|
||||||
col.SQLType = schemas.SQLType{Name: schemas.TimeStampz, DefaultLength: 0, DefaultLength2: 0}
|
col.SQLType = schemas.SQLType{Name: schemas.TimeStampz, DefaultLength: 0, DefaultLength2: 0}
|
||||||
case "NUMBER":
|
case "NUMBER":
|
||||||
col.SQLType = schemas.SQLType{Name: schemas.Double, DefaultLength: len1, DefaultLength2: len2}
|
col.SQLType = schemas.SQLType{Name: schemas.Double, DefaultLength: len1, DefaultLength2: len2}
|
||||||
case "LONG", "LONG RAW":
|
case "LONG", "LONG RAW", "NCLOB", "CLOB":
|
||||||
col.SQLType = schemas.SQLType{Name: schemas.Text, DefaultLength: 0, DefaultLength2: 0}
|
col.SQLType = schemas.SQLType{Name: schemas.Text, DefaultLength: 0, DefaultLength2: 0}
|
||||||
case "RAW":
|
case "RAW":
|
||||||
col.SQLType = schemas.SQLType{Name: schemas.Binary, DefaultLength: 0, DefaultLength2: 0}
|
col.SQLType = schemas.SQLType{Name: schemas.Binary, DefaultLength: 0, DefaultLength2: 0}
|
||||||
|
|
|
@ -111,6 +111,35 @@ func createEngine(dbType, connStr string) error {
|
||||||
}
|
}
|
||||||
connStr = u.Path
|
connStr = u.Path
|
||||||
*ignoreSelectUpdate = true
|
*ignoreSelectUpdate = true
|
||||||
|
case schemas.ORACLE, "goora":
|
||||||
|
db, err := sql.Open("oracle", connStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, err := db.Query("SELECT 1 FROM pg_database WHERE datname = 'xorm_test'")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("db.Query: %v", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
if !rows.Next() {
|
||||||
|
if _, err = db.Exec("CREATE DATABASE xorm_test"); err != nil {
|
||||||
|
return fmt.Errorf("CREATE DATABASE: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if *schema != "" {
|
||||||
|
db.Close()
|
||||||
|
db, err = sql.Open(dbType, connStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
if _, err = db.Exec("CREATE SCHEMA IF NOT EXISTS " + *schema); err != nil {
|
||||||
|
return fmt.Errorf("CREATE SCHEMA: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.Close()
|
||||||
|
*ignoreSelectUpdate = true
|
||||||
default:
|
default:
|
||||||
*ignoreSelectUpdate = true
|
*ignoreSelectUpdate = true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue