mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 04:07:47 +08:00
Feature/oracle (#1869)
This commit is contained in:
parent
0ca81bd11a
commit
ef04c8a09e
21
.github/workflows/gf.yml
vendored
21
.github/workflows/gf.yml
vendored
@ -97,10 +97,23 @@ jobs:
|
||||
- 8090:8090
|
||||
- 8091:8091
|
||||
|
||||
#oracle 11g server
|
||||
oracle-server:
|
||||
image: loads/oracle-xe-11g-r2:latest
|
||||
env:
|
||||
ORACLE_ALLOW_REMOTE: true
|
||||
ORACLE_SID: XE
|
||||
ORACLE_DB_USER_NAME: system
|
||||
ORACLE_DB_PASSWORD: oracle
|
||||
ports:
|
||||
- 1521:1521
|
||||
|
||||
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
go: ["1.15", "1.16", "1.17"]
|
||||
goarch: ["386", "amd64"]
|
||||
go: [ "1.15", "1.16", "1.17" ]
|
||||
goarch: [ "386", "amd64" ]
|
||||
|
||||
|
||||
steps:
|
||||
@ -131,7 +144,9 @@ jobs:
|
||||
dirpath=$(dirname $file)
|
||||
|
||||
if [ "oracle" = $(basename $dirpath) ]; then
|
||||
continue 1
|
||||
if ! go version|grep -q "1.17"; then
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $dirpath
|
||||
|
@ -299,6 +299,7 @@ ORDER BY a.id,a.colorder`,
|
||||
}
|
||||
fields = make(map[string]*gdb.TableField)
|
||||
for i, m := range result {
|
||||
|
||||
fields[m["Field"].String()] = &gdb.TableField{
|
||||
Index: i,
|
||||
Name: m["Field"].String(),
|
||||
|
@ -63,32 +63,42 @@ func TestTableFields(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
createTable("t_user")
|
||||
defer dropTable("t_user")
|
||||
var expect map[string]string = map[string]string{
|
||||
"ID": "numeric(10,0)",
|
||||
"PASSPORT": "VARCHAR(45)",
|
||||
"PASSWORD": "CHAR(32)",
|
||||
"NICKNAME": "VARCHAR(45)",
|
||||
"CREATE_TIME": "time",
|
||||
var expect = map[string][]interface{}{
|
||||
"ID": {"numeric(10,0)", false, "PRI", "", "", ""},
|
||||
"PASSPORT": {"varchar(45)", true, "", "", "", ""},
|
||||
"PASSWORD": {"varchar(32)", true, "", "", "", ""},
|
||||
"NICKNAME": {"varchar(45)", true, "", "", "", ""},
|
||||
"CREATE_TIME": {"datetime", true, "", "", "", ""},
|
||||
}
|
||||
|
||||
res, err := db.TableFields(context.Background(), "t_user")
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
for k, _ := range expect {
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
gtest.AssertEQ(ok, true)
|
||||
|
||||
gtest.AssertEQ(res[k].Name, k)
|
||||
gtest.AssertEQ(res[k].Type, v[0])
|
||||
gtest.AssertEQ(res[k].Null, v[1])
|
||||
gtest.AssertEQ(res[k].Key, v[2])
|
||||
gtest.AssertEQ(res[k].Default, v[3])
|
||||
gtest.AssertEQ(res[k].Extra, v[4])
|
||||
gtest.AssertEQ(res[k].Comment, v[5])
|
||||
}
|
||||
|
||||
res, err = db.TableFields(context.Background(), "t_user", "test")
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
for k, _ := range expect {
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
gtest.AssertEQ(ok, true)
|
||||
|
||||
gtest.AssertEQ(res[k].Name, k)
|
||||
gtest.AssertEQ(res[k].Type, v[0])
|
||||
gtest.AssertEQ(res[k].Null, v[1])
|
||||
gtest.AssertEQ(res[k].Key, v[2])
|
||||
gtest.AssertEQ(res[k].Default, v[3])
|
||||
gtest.AssertEQ(res[k].Extra, v[4])
|
||||
gtest.AssertEQ(res[k].Comment, v[5])
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,10 +1,36 @@
|
||||
module github.com/gogf/gf/contrib/drivers/oracle/v2
|
||||
|
||||
go 1.15
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/v2 v2.0.0
|
||||
github.com/mattn/go-oci8 v0.1.1
|
||||
github.com/sijms/go-ora/v2 v2.4.20
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.5.5 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.0.1 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
go.opentelemetry.io/otel v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.7.0 // indirect
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
||||
replace github.com/gogf/gf/v2 => ../../../
|
||||
|
@ -34,7 +34,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@ -56,8 +55,6 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-oci8 v0.1.1 h1:aEUDxNAyDG0tv8CA3TArnDQNyc4EhnWlsfxRgDHABHM=
|
||||
github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
@ -70,7 +67,6 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@ -79,6 +75,8 @@ github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sijms/go-ora/v2 v2.4.20 h1:9e3z7VLBQXRAHGiIda1GEFtRhfxata0LghyMZqvLKew=
|
||||
github.com/sijms/go-ora/v2 v2.4.20/go.mod h1:EHxlY6x7y9HAsdfumurRfTd+v8NrEOTR3Xl4FWlH6xk=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
@ -142,7 +140,6 @@ golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@ -151,7 +148,6 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -5,7 +5,7 @@
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
//
|
||||
// Note:
|
||||
// 1. It needs manually import: _ "github.com/mattn/go-oci8"
|
||||
// 1. It needs manually import: _ "github.com/sijms/go-ora/v2"
|
||||
// 2. It does not support Save/Replace features.
|
||||
// 3. It does not support LastInsertId.
|
||||
|
||||
@ -16,12 +16,7 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-oci8"
|
||||
gora "github.com/sijms/go-ora/v2"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
@ -30,6 +25,8 @@ import (
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Driver is the driver for oracle database.
|
||||
@ -65,9 +62,18 @@ func (d *Driver) New(core *gdb.Core, node *gdb.ConfigNode) (gdb.DB, error) {
|
||||
func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
|
||||
var (
|
||||
source string
|
||||
underlyingDriverName = "oci8"
|
||||
underlyingDriverName = "oracle"
|
||||
)
|
||||
// [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN]
|
||||
|
||||
options := map[string]string{
|
||||
"CONNECTION TIMEOUT": "60",
|
||||
"PREFETCH_ROWS": "25",
|
||||
}
|
||||
|
||||
if config.Debug {
|
||||
options["TRACE FILE"] = "oracle_trace.log"
|
||||
}
|
||||
// [username:[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN]
|
||||
if config.Link != "" {
|
||||
source = config.Link
|
||||
// Custom changing the schema in runtime.
|
||||
@ -75,10 +81,7 @@ func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
|
||||
source, _ = gregex.ReplaceString(`@(.+?)/([\w\.\-]+)+`, "@$1/"+config.Name, source)
|
||||
}
|
||||
} else {
|
||||
source = fmt.Sprintf(
|
||||
"%s/%s@%s:%s/%s",
|
||||
config.User, config.Pass, config.Host, config.Port, config.Name,
|
||||
)
|
||||
source = gora.BuildUrl(config.Host, gconv.Int(config.Port), config.Name, config.User, config.Pass, options)
|
||||
}
|
||||
|
||||
if db, err = sql.Open(underlyingDriverName, source); err != nil {
|
||||
@ -99,8 +102,8 @@ func (d *Driver) FilteredLink() string {
|
||||
return ""
|
||||
}
|
||||
s, _ := gregex.ReplaceString(
|
||||
`(.+?)\s*/\s*(.+)\s*@\s*(.+)\s*:\s*(\d+)\s*/\s*(.+)`,
|
||||
`$1/xxx@$3:$4/$5`,
|
||||
`(.+?)\s*:\s*(.+)\s*@\s*(.+)\s*:\s*(\d+)\s*/\s*(.+)`,
|
||||
`$1:xxx@$3:$4/$5`,
|
||||
linkInfo,
|
||||
)
|
||||
return s
|
||||
@ -124,16 +127,7 @@ func (d *Driver) DoFilter(ctx context.Context, link gdb.Link, sql string, args [
|
||||
return fmt.Sprintf(":v%d", index)
|
||||
})
|
||||
newSql, _ = gregex.ReplaceString("\"", "", newSql)
|
||||
// Handle string datetime argument.
|
||||
for i, v := range args {
|
||||
if reflect.TypeOf(v).Kind() == reflect.String {
|
||||
valueStr := gconv.String(v)
|
||||
if gregex.IsMatchString(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`, valueStr) {
|
||||
// args[i] = fmt.Sprintf(`TO_DATE('%s','yyyy-MM-dd HH:MI:SS')`, valueStr)
|
||||
args[i], _ = time.ParseInLocation("2006-01-02 15:04:05", valueStr, time.Local)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newSql = d.parseSql(newSql)
|
||||
newArgs = args
|
||||
return
|
||||
@ -168,7 +162,7 @@ func (d *Driver) parseSql(sql string) string {
|
||||
strings.EqualFold(queryExpr[3], "LIMIT") == false {
|
||||
break
|
||||
}
|
||||
first, limit := 0, 0
|
||||
page, limit := 0, 0
|
||||
for i := 1; i < len(allMatch[index]); i++ {
|
||||
if len(strings.TrimSpace(allMatch[index][i])) == 0 {
|
||||
continue
|
||||
@ -176,8 +170,16 @@ func (d *Driver) parseSql(sql string) string {
|
||||
|
||||
if strings.HasPrefix(allMatch[index][i], "LIMIT") {
|
||||
if allMatch[index][i+2] != "" {
|
||||
first, _ = strconv.Atoi(allMatch[index][i+1])
|
||||
page, _ = strconv.Atoi(allMatch[index][i+1])
|
||||
limit, _ = strconv.Atoi(allMatch[index][i+2])
|
||||
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
limit = (page/limit + 1) * limit
|
||||
|
||||
page, _ = strconv.Atoi(allMatch[index][i+1])
|
||||
} else {
|
||||
limit, _ = strconv.Atoi(allMatch[index][i+1])
|
||||
}
|
||||
@ -187,8 +189,8 @@ func (d *Driver) parseSql(sql string) string {
|
||||
sql = fmt.Sprintf(
|
||||
"SELECT * FROM "+
|
||||
"(SELECT GFORM.*, ROWNUM ROWNUM_ FROM (%s %s) GFORM WHERE ROWNUM <= %d)"+
|
||||
" WHERE ROWNUM_ >= %d",
|
||||
queryExpr[1], queryExpr[2], limit, first,
|
||||
" WHERE ROWNUM_ > %d",
|
||||
queryExpr[1], queryExpr[2], limit, page,
|
||||
)
|
||||
}
|
||||
return sql
|
||||
@ -241,7 +243,7 @@ SELECT
|
||||
CASE DATA_TYPE
|
||||
WHEN 'NUMBER' THEN DATA_TYPE||'('||DATA_PRECISION||','||DATA_SCALE||')'
|
||||
WHEN 'FLOAT' THEN DATA_TYPE||'('||DATA_PRECISION||','||DATA_SCALE||')'
|
||||
ELSE DATA_TYPE||'('||DATA_LENGTH||')' END AS TYPE
|
||||
ELSE DATA_TYPE||'('||DATA_LENGTH||')' END AS TYPE,NULLABLE
|
||||
FROM USER_TAB_COLUMNS WHERE TABLE_NAME = '%s' ORDER BY COLUMN_ID`,
|
||||
strings.ToUpper(table),
|
||||
)
|
||||
@ -256,10 +258,16 @@ FROM USER_TAB_COLUMNS WHERE TABLE_NAME = '%s' ORDER BY COLUMN_ID`,
|
||||
}
|
||||
fields = make(map[string]*gdb.TableField)
|
||||
for i, m := range result {
|
||||
fields[strings.ToLower(m["FIELD"].String())] = &gdb.TableField{
|
||||
isNull := false
|
||||
if m["NULLABLE"].String() == "Y" {
|
||||
isNull = true
|
||||
}
|
||||
|
||||
fields[m["FIELD"].String()] = &gdb.TableField{
|
||||
Index: i,
|
||||
Name: strings.ToLower(m["FIELD"].String()),
|
||||
Type: strings.ToLower(m["TYPE"].String()),
|
||||
Name: m["FIELD"].String(),
|
||||
Type: m["TYPE"].String(),
|
||||
Null: isNull,
|
||||
}
|
||||
}
|
||||
return fields
|
||||
@ -288,10 +296,10 @@ func (d *Driver) DoInsert(
|
||||
) (result sql.Result, err error) {
|
||||
switch option.InsertOption {
|
||||
case gdb.InsertOptionSave:
|
||||
return nil, gerror.NewCode(gcode.CodeNotSupported, `Save operation is not supported by mssql driver`)
|
||||
return nil, gerror.NewCode(gcode.CodeNotSupported, `Save operation is not supported by oracle driver`)
|
||||
|
||||
case gdb.InsertOptionReplace:
|
||||
return nil, gerror.NewCode(gcode.CodeNotSupported, `Replace operation is not supported by mssql driver`)
|
||||
return nil, gerror.NewCode(gcode.CodeNotSupported, `Replace operation is not supported by oracle driver`)
|
||||
}
|
||||
|
||||
var (
|
||||
|
162
contrib/drivers/oracle/oracle_init_test.go
Normal file
162
contrib/drivers/oracle/oracle_init_test.go
Normal file
@ -0,0 +1,162 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package oracle_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
_ "github.com/sijms/go-ora/v2"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
db gdb.DB
|
||||
dblink gdb.DB
|
||||
dbErr gdb.DB
|
||||
ctx context.Context
|
||||
)
|
||||
|
||||
const (
|
||||
TableSize = 10
|
||||
TableName = "t_user"
|
||||
TestSchema1 = "test1"
|
||||
TestSchema2 = "test2"
|
||||
TableNamePrefix1 = "gf_"
|
||||
TestSchema = "XE"
|
||||
)
|
||||
|
||||
const (
|
||||
TestDbIP = "127.0.0.1"
|
||||
TestDbPort = "1521"
|
||||
TestDbUser = "system"
|
||||
TestDbPass = "oracle"
|
||||
TestDbName = "XE"
|
||||
TestDbType = "oracle"
|
||||
)
|
||||
|
||||
func init() {
|
||||
node := gdb.ConfigNode{
|
||||
Host: TestDbIP,
|
||||
Port: TestDbPort,
|
||||
User: TestDbUser,
|
||||
Pass: TestDbPass,
|
||||
Name: TestDbName,
|
||||
Type: TestDbType,
|
||||
Role: "master",
|
||||
Charset: "utf8",
|
||||
Weight: 1,
|
||||
MaxIdleConnCount: 10,
|
||||
MaxOpenConnCount: 10,
|
||||
}
|
||||
|
||||
nodeLink := gdb.ConfigNode{
|
||||
Type: TestDbType,
|
||||
Name: TestDbName,
|
||||
Link: fmt.Sprintf("%s://%s:%s@%s:%s/%s",
|
||||
TestDbType, TestDbUser, TestDbPass, TestDbIP, TestDbPort, TestDbName),
|
||||
}
|
||||
|
||||
nodeErr := gdb.ConfigNode{
|
||||
Host: TestDbIP,
|
||||
Port: TestDbPort,
|
||||
User: TestDbUser,
|
||||
Pass: "1234",
|
||||
Name: TestDbName,
|
||||
Type: TestDbType,
|
||||
Role: "master",
|
||||
Charset: "utf8",
|
||||
Weight: 1,
|
||||
}
|
||||
|
||||
gdb.AddConfigNode(gdb.DefaultGroupName, node)
|
||||
if r, err := gdb.New(node); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
db = r
|
||||
}
|
||||
|
||||
gdb.AddConfigNode("dblink", nodeLink)
|
||||
if r, err := gdb.New(nodeLink); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
dblink = r
|
||||
}
|
||||
|
||||
gdb.AddConfigNode("dbErr", nodeErr)
|
||||
if r, err := gdb.New(nodeErr); err != nil {
|
||||
gtest.Fatal(err)
|
||||
} else {
|
||||
dbErr = r
|
||||
}
|
||||
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
func createTable(table ...string) (name string) {
|
||||
if len(table) > 0 {
|
||||
name = table[0]
|
||||
} else {
|
||||
name = fmt.Sprintf("user_%d", gtime.Timestamp())
|
||||
}
|
||||
|
||||
dropTable(name)
|
||||
|
||||
if _, err := db.Exec(ctx, fmt.Sprintf(`
|
||||
CREATE TABLE %s (
|
||||
ID NUMBER(10) NOT NULL,
|
||||
PASSPORT VARCHAR(45) NOT NULL,
|
||||
PASSWORD CHAR(32) NOT NULL,
|
||||
NICKNAME VARCHAR(45) NOT NULL,
|
||||
CREATE_TIME varchar(45),
|
||||
PRIMARY KEY (ID))
|
||||
`, name)); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
|
||||
//db.Schema("test")
|
||||
return
|
||||
}
|
||||
|
||||
func createInitTable(table ...string) (name string) {
|
||||
name = createTable(table...)
|
||||
array := garray.New(true)
|
||||
for i := 1; i <= TableSize; i++ {
|
||||
array.Append(g.Map{
|
||||
"id": i,
|
||||
"passport": fmt.Sprintf(`user_%d`, i),
|
||||
"password": fmt.Sprintf(`pass_%d`, i),
|
||||
"nickname": fmt.Sprintf(`name_%d`, i),
|
||||
"create_time": gtime.Now().String(),
|
||||
})
|
||||
}
|
||||
result, err := db.Insert(context.Background(), name, array.Slice())
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
n, e := result.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
gtest.Assert(n, TableSize)
|
||||
return
|
||||
}
|
||||
|
||||
func dropTable(table string) {
|
||||
count, err := db.GetCount(ctx, "SELECT COUNT(*) FROM USER_TABLES WHERE TABLE_NAME = ?", strings.ToUpper(table))
|
||||
if err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return
|
||||
}
|
||||
if _, err := db.Exec(ctx, fmt.Sprintf("DROP TABLE %s", table)); err != nil {
|
||||
gtest.Fatal(err)
|
||||
}
|
||||
}
|
665
contrib/drivers/oracle/oracle_z_basic_test.go
Normal file
665
contrib/drivers/oracle/oracle_z_basic_test.go
Normal file
@ -0,0 +1,665 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package oracle_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTables(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
tables := []string{"t_user1", "pop", "haha"}
|
||||
|
||||
for _, v := range tables {
|
||||
createTable(v)
|
||||
}
|
||||
|
||||
result, err := db.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
if strings.ToUpper(tables[i]) == result[j] {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
gtest.AssertEQ(find, true)
|
||||
}
|
||||
|
||||
result, err = db.Tables(ctx, TestSchema)
|
||||
gtest.Assert(err, nil)
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
if strings.ToUpper(tables[i]) == result[j] {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
gtest.AssertEQ(find, true)
|
||||
}
|
||||
|
||||
for _, v := range tables {
|
||||
dropTable(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestTableFields(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
createTable("t_user")
|
||||
defer dropTable("t_user")
|
||||
var expect = map[string][]interface{}{
|
||||
"ID": {"NUMBER(10,0)", false},
|
||||
"PASSPORT": {"VARCHAR2(45)", false},
|
||||
"PASSWORD": {"CHAR(32)", false},
|
||||
"NICKNAME": {"VARCHAR2(45)", false},
|
||||
"CREATE_TIME": {"VARCHAR2(45)", true},
|
||||
}
|
||||
|
||||
_, err := dbErr.TableFields(ctx, "t_user")
|
||||
gtest.AssertNE(err, nil)
|
||||
|
||||
res, err := db.TableFields(ctx, "t_user")
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
gtest.AssertEQ(ok, true)
|
||||
|
||||
gtest.AssertEQ(res[k].Name, k)
|
||||
gtest.Assert(res[k].Type, v[0])
|
||||
gtest.Assert(res[k].Null, v[1])
|
||||
}
|
||||
|
||||
res, err = db.TableFields(ctx, "t_user", TestSchema)
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
gtest.AssertEQ(ok, true)
|
||||
|
||||
gtest.AssertEQ(res[k].Name, k)
|
||||
gtest.Assert(res[k].Type, v[0])
|
||||
gtest.Assert(res[k].Null, v[1])
|
||||
}
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
_, err := db.TableFields(ctx, "t_user t_user2")
|
||||
gtest.AssertNE(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFilteredLink(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := dblink.FilteredLink()
|
||||
gtest.AssertEQ(s, "oracle:xxx@127.0.0.1:1521/XE")
|
||||
})
|
||||
|
||||
}
|
||||
func TestDoInsert(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
createTable("t_user")
|
||||
defer dropTable("t_user")
|
||||
|
||||
i := 10
|
||||
data := g.Map{
|
||||
"ID": i,
|
||||
"PASSPORT": fmt.Sprintf(`t%d`, i),
|
||||
"PASSWORD": fmt.Sprintf(`p%d`, i),
|
||||
"NICKNAME": fmt.Sprintf(`T%d`, i),
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
}
|
||||
_, err := db.Insert(ctx, "t_user", data)
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
createTable("t_user")
|
||||
defer dropTable("t_user")
|
||||
|
||||
i := 10
|
||||
data := g.Map{
|
||||
"ID": i,
|
||||
"PASSPORT": fmt.Sprintf(`t%d`, i),
|
||||
"PASSWORD": fmt.Sprintf(`p%d`, i),
|
||||
"NICKNAME": fmt.Sprintf(`T%d`, i),
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
}
|
||||
_, err := db.Save(ctx, "t_user", data, 10)
|
||||
gtest.AssertNE(err, nil)
|
||||
|
||||
_, err = db.Replace(ctx, "t_user", data, 10)
|
||||
gtest.AssertNE(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Ping(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err1 := db.PingMaster()
|
||||
err2 := db.PingSlave()
|
||||
t.Assert(err1, nil)
|
||||
t.Assert(err2, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Query(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
_, err := db.Query(ctx, "SELECT ? from dual", 1)
|
||||
t.AssertNil(err)
|
||||
|
||||
_, err = db.Query(ctx, "SELECT ?+? from dual", 1, 2)
|
||||
t.AssertNil(err)
|
||||
|
||||
_, err = db.Query(ctx, "SELECT ?+? from dual", g.Slice{1, 2})
|
||||
t.AssertNil(err)
|
||||
|
||||
_, err = db.Query(ctx, "ERROR")
|
||||
t.AssertNE(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Exec(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
_, err := db.Exec(ctx, "SELECT ? from dual", 1)
|
||||
t.AssertNil(err)
|
||||
|
||||
_, err = db.Exec(ctx, "ERROR")
|
||||
t.AssertNE(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Insert(t *testing.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
_, err := db.Insert(ctx, table, g.Map{
|
||||
"ID": 1,
|
||||
"PASSPORT": "t1",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "T1",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
|
||||
// normal map
|
||||
result, err := db.Insert(ctx, table, g.Map{
|
||||
"ID": "2",
|
||||
"PASSPORT": "t2",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "name_2",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
// struct
|
||||
type User struct {
|
||||
Id int `gconv:"ID"`
|
||||
Passport string `json:"PASSPORT"`
|
||||
Password string `gconv:"PASSWORD"`
|
||||
Nickname string `gconv:"NICKNAME"`
|
||||
CreateTime string `json:"CREATE_TIME"`
|
||||
}
|
||||
timeStr := gtime.Now().String()
|
||||
result, err = db.Insert(ctx, table, User{
|
||||
Id: 3,
|
||||
Passport: "user_3",
|
||||
Password: "25d55ad283aa400af464c76d713c07ad",
|
||||
Nickname: "name_3",
|
||||
CreateTime: timeStr,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ = result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
one, err := db.Model(table).Where("ID", 3).One()
|
||||
t.AssertNil(err)
|
||||
fmt.Println(one)
|
||||
t.Assert(one["ID"].Int(), 3)
|
||||
t.Assert(one["PASSPORT"].String(), "user_3")
|
||||
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d713c07ad")
|
||||
t.Assert(one["NICKNAME"].String(), "name_3")
|
||||
t.Assert(one["CREATE_TIME"].GTime().String(), timeStr)
|
||||
|
||||
// *struct
|
||||
timeStr = gtime.Now().String()
|
||||
result, err = db.Insert(ctx, table, &User{
|
||||
Id: 4,
|
||||
Passport: "t4",
|
||||
Password: "25d55ad283aa400af464c76d713c07ad",
|
||||
Nickname: "name_4",
|
||||
CreateTime: timeStr,
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ = result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
one, err = db.Model(table).Where("ID", 4).One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["ID"].Int(), 4)
|
||||
t.Assert(one["PASSPORT"].String(), "t4")
|
||||
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d713c07ad")
|
||||
t.Assert(one["NICKNAME"].String(), "name_4")
|
||||
t.Assert(one["CREATE_TIME"].GTime().String(), timeStr)
|
||||
|
||||
// batch with Insert
|
||||
timeStr = gtime.Now().String()
|
||||
r, err := db.Insert(ctx, table, g.Slice{
|
||||
g.Map{
|
||||
"ID": 200,
|
||||
"PASSPORT": "t200",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d71qw07ad",
|
||||
"NICKNAME": "T200",
|
||||
"CREATE_TIME": timeStr,
|
||||
},
|
||||
g.Map{
|
||||
"ID": 300,
|
||||
"PASSPORT": "t300",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "T300",
|
||||
"CREATE_TIME": timeStr,
|
||||
},
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ = r.RowsAffected()
|
||||
t.Assert(n, 2)
|
||||
|
||||
one, err = db.Model(table).Where("ID", 200).One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["ID"].Int(), 200)
|
||||
t.Assert(one["PASSPORT"].String(), "t200")
|
||||
t.Assert(one["PASSWORD"].String(), "25d55ad283aa400af464c76d71qw07ad")
|
||||
t.Assert(one["NICKNAME"].String(), "T200")
|
||||
t.Assert(one["CREATE_TIME"].GTime().String(), timeStr)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_BatchInsert(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
r, err := db.Insert(ctx, table, g.List{
|
||||
{
|
||||
"ID": 2,
|
||||
"PASSPORT": "t2",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "name_2",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
},
|
||||
{
|
||||
"ID": 3,
|
||||
"PASSPORT": "user_3",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "name_3",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
},
|
||||
}, 1)
|
||||
t.AssertNil(err)
|
||||
n, _ := r.RowsAffected()
|
||||
t.Assert(n, 2)
|
||||
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
// []interface{}
|
||||
r, err := db.Insert(ctx, table, g.Slice{
|
||||
g.Map{
|
||||
"ID": 2,
|
||||
"PASSPORT": "t2",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "name_2",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
},
|
||||
g.Map{
|
||||
"ID": 3,
|
||||
"PASSPORT": "user_3",
|
||||
"PASSWORD": "25d55ad283aa400af464c76d713c07ad",
|
||||
"NICKNAME": "name_3",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
},
|
||||
}, 1)
|
||||
t.AssertNil(err)
|
||||
n, _ := r.RowsAffected()
|
||||
t.Assert(n, 2)
|
||||
})
|
||||
|
||||
// batch insert map
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
result, err := db.Insert(ctx, table, g.Map{
|
||||
"ID": 1,
|
||||
"PASSPORT": "t1",
|
||||
"PASSWORD": "p1",
|
||||
"NICKNAME": "T1",
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
})
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_BatchInsert_Struct(t *testing.T) {
|
||||
// batch insert struct
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
table := createTable()
|
||||
defer dropTable(table)
|
||||
|
||||
type User struct {
|
||||
Id int `c:"ID"`
|
||||
Passport string `c:"PASSPORT"`
|
||||
Password string `c:"PASSWORD"`
|
||||
NickName string `c:"NICKNAME"`
|
||||
CreateTime *gtime.Time `c:"CREATE_TIME"`
|
||||
}
|
||||
user := &User{
|
||||
Id: 1,
|
||||
Passport: "t1",
|
||||
Password: "p1",
|
||||
NickName: "T1",
|
||||
CreateTime: gtime.Now(),
|
||||
}
|
||||
result, err := db.Insert(ctx, table, user)
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Update(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Update(ctx, table, "password='987654321'", "id=3")
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
t.Assert(n, 1)
|
||||
|
||||
one, err := db.Model(table).Where("ID", 3).One()
|
||||
t.AssertNil(err)
|
||||
t.Assert(one["ID"].Int(), 3)
|
||||
t.Assert(one["PASSPORT"].String(), "user_3")
|
||||
t.Assert(strings.TrimSpace(one["PASSWORD"].String()), "987654321")
|
||||
t.Assert(one["NICKNAME"].String(), "name_3")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetAll(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 1)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 1)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), g.Slice{1})
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 1)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?)", table), g.Slice{1, 2, 3})
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 3)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
t.Assert(result[1]["ID"].Int(), 2)
|
||||
t.Assert(result[2]["ID"].Int(), 3)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?,?,?)", table), g.Slice{1, 2, 3})
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 3)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
t.Assert(result[1]["ID"].Int(), 2)
|
||||
t.Assert(result[2]["ID"].Int(), 3)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id in(?,?,?)", table), g.Slice{1, 2, 3}...)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 3)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
t.Assert(result[1]["ID"].Int(), 2)
|
||||
t.Assert(result[2]["ID"].Int(), 3)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf("SELECT * FROM %s WHERE id>=? AND id <=?", table), g.Slice{1, 3})
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 3)
|
||||
t.Assert(result[0]["ID"].Int(), 1)
|
||||
t.Assert(result[1]["ID"].Int(), 2)
|
||||
t.Assert(result[2]["ID"].Int(), 3)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetOne(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
record, err := db.GetOne(ctx, fmt.Sprintf("SELECT * FROM %s WHERE passport=?", table), "user_1")
|
||||
t.AssertNil(err)
|
||||
t.Assert(record["NICKNAME"].String(), "name_1")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetValue(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
value, err := db.GetValue(ctx, fmt.Sprintf("SELECT id FROM %s WHERE passport=?", table), "user_3")
|
||||
t.AssertNil(err)
|
||||
t.Assert(value.Int(), 3)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetCount(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
count, err := db.GetCount(ctx, fmt.Sprintf("SELECT * FROM %s", table))
|
||||
t.AssertNil(err)
|
||||
t.Assert(count, TableSize)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetStruct(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.GetScan(ctx, user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.NickName, "name_3")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.GetScan(ctx, user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.NickName, "name_3")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetStructs(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), TableSize-1)
|
||||
t.Assert(users[0].Id, 2)
|
||||
t.Assert(users[1].Id, 3)
|
||||
t.Assert(users[2].Id, 4)
|
||||
t.Assert(users[0].NickName, "name_2")
|
||||
t.Assert(users[1].NickName, "name_3")
|
||||
t.Assert(users[2].NickName, "name_4")
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), TableSize-1)
|
||||
t.Assert(users[0].Id, 2)
|
||||
t.Assert(users[1].Id, 3)
|
||||
t.Assert(users[2].Id, 4)
|
||||
t.Assert(users[0].NickName, "name_2")
|
||||
t.Assert(users[1].NickName, "name_3")
|
||||
t.Assert(users[2].NickName, "name_4")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_GetScan(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.GetScan(ctx, user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.NickName, "name_3")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var user *User
|
||||
err := db.GetScan(ctx, &user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.NickName, "name_3")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
user := new(User)
|
||||
err := db.GetScan(ctx, user, fmt.Sprintf("SELECT * FROM %s WHERE id=?", table), 3)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.NickName, "name_3")
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), TableSize-1)
|
||||
t.Assert(users[0].Id, 2)
|
||||
t.Assert(users[1].Id, 3)
|
||||
t.Assert(users[2].Id, 4)
|
||||
t.Assert(users[0].NickName, "name_2")
|
||||
t.Assert(users[1].NickName, "name_3")
|
||||
t.Assert(users[2].NickName, "name_4")
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Id int
|
||||
Passport string
|
||||
Password string
|
||||
NickName string
|
||||
CreateTime *gtime.Time
|
||||
}
|
||||
var users []User
|
||||
err := db.GetScan(ctx, &users, fmt.Sprintf("SELECT * FROM %s WHERE id>?", table), 1)
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(users), TableSize-1)
|
||||
t.Assert(users[0].Id, 2)
|
||||
t.Assert(users[1].Id, 3)
|
||||
t.Assert(users[2].Id, 4)
|
||||
t.Assert(users[0].NickName, "name_2")
|
||||
t.Assert(users[1].NickName, "name_3")
|
||||
t.Assert(users[2].NickName, "name_4")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_DB_Delete(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Delete(ctx, table, "1=1")
|
||||
t.AssertNil(err)
|
||||
n, _ := result.RowsAffected()
|
||||
t.Assert(n, TableSize)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Empty_Slice_Argument(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.GetAll(ctx, fmt.Sprintf(`select * from %s where id in(?)`, table), g.Slice{})
|
||||
t.AssertNil(err)
|
||||
t.Assert(len(result), 0)
|
||||
})
|
||||
}
|
1113
contrib/drivers/oracle/oracle_z_model_test.go
Normal file
1113
contrib/drivers/oracle/oracle_z_model_test.go
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user