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_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_QUOTE_POLICY ?= always
|
||||
|
||||
|
@ -279,6 +285,21 @@ test-dameng\#%: go-check
|
|||
-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
|
||||
|
||||
.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
|
||||
vet:
|
||||
$(GO) vet $(shell $(GO) list ./...)
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"xorm.io/xorm/core"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
|
@ -567,11 +568,13 @@ func (db *oracle) SQLType(c *schemas.Column) string {
|
|||
c.Default = "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"
|
||||
case schemas.Binary, schemas.VarBinary, schemas.Blob, schemas.TinyBlob, schemas.MediumBlob, schemas.LongBlob, schemas.Bytea:
|
||||
return schemas.Blob
|
||||
case schemas.Time, schemas.DateTime, schemas.TimeStamp:
|
||||
case schemas.Date, schemas.Time, schemas.DateTime, schemas.TimeStamp:
|
||||
res = schemas.TimeStamp
|
||||
case schemas.TimeStampz:
|
||||
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...)
|
||||
}
|
||||
|
||||
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) {
|
||||
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}
|
||||
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"
|
||||
|
||||
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.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
|
||||
|
||||
err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
|
||||
&dataScale, &nullable)
|
||||
&dataScale, &nullable, &comment)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -733,6 +756,21 @@ func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableNam
|
|||
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 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}
|
||||
case "NUMBER":
|
||||
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}
|
||||
case "RAW":
|
||||
col.SQLType = schemas.SQLType{Name: schemas.Binary, DefaultLength: 0, DefaultLength2: 0}
|
||||
|
|
|
@ -111,6 +111,35 @@ func createEngine(dbType, connStr string) error {
|
|||
}
|
||||
connStr = u.Path
|
||||
*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:
|
||||
*ignoreSelectUpdate = true
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue