2024-01-15 11:55:59 +00:00
|
|
|
|
package oracle
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"database/sql"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"mayfly-go/internal/db/dbm/dbi"
|
2024-03-07 17:26:11 +08:00
|
|
|
|
"mayfly-go/pkg/utils/jsonx"
|
2024-01-15 11:55:59 +00:00
|
|
|
|
"strings"
|
2024-01-19 21:33:37 +08:00
|
|
|
|
|
2024-03-21 17:15:52 +08:00
|
|
|
|
"github.com/may-fly/cast"
|
2024-01-19 21:33:37 +08:00
|
|
|
|
go_ora "github.com/sijms/go-ora/v2"
|
2024-01-15 11:55:59 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2024-01-24 17:01:17 +08:00
|
|
|
|
func init() {
|
2024-10-20 03:52:23 +00:00
|
|
|
|
dbi.Register(dbi.DbTypeOracle, new(Meta))
|
2024-01-15 11:55:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-20 03:52:23 +00:00
|
|
|
|
const (
|
|
|
|
|
|
DbVersionOracle11 dbi.DbVersion = "11"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type Meta struct {
|
2024-01-15 11:55:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-20 03:52:23 +00:00
|
|
|
|
func (om *Meta) GetSqlDb(d *dbi.DbInfo) (*sql.DB, error) {
|
2024-01-15 11:55:59 +00:00
|
|
|
|
err := d.IfUseSshTunnelChangeIpPort()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
2024-03-07 17:26:11 +08:00
|
|
|
|
|
2024-01-15 11:55:59 +00:00
|
|
|
|
// 参数参考 https://github.com/sijms/go-ora?tab=readme-ov-file#other-connection-options
|
|
|
|
|
|
urlOptions := make(map[string]string)
|
|
|
|
|
|
|
|
|
|
|
|
db := d.Database
|
|
|
|
|
|
schema := ""
|
|
|
|
|
|
if db != "" {
|
|
|
|
|
|
// oracle database可以使用db/schema表示,方便连接指定schema, 若不存在schema则使用默认schema
|
|
|
|
|
|
ss := strings.Split(db, "/")
|
|
|
|
|
|
if len(ss) > 1 {
|
|
|
|
|
|
// user=hr&defaultSchema=hr
|
|
|
|
|
|
schema = ss[1]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-19 08:59:35 +00:00
|
|
|
|
// 解析参数
|
|
|
|
|
|
if d.Params != "" {
|
|
|
|
|
|
paramArr := strings.Split(d.Params, "&")
|
|
|
|
|
|
for _, param := range paramArr {
|
|
|
|
|
|
ps := strings.Split(param, "=")
|
|
|
|
|
|
if len(ps) > 1 {
|
|
|
|
|
|
if ps[0] == "clientCharset" {
|
|
|
|
|
|
urlOptions["client charset"] = ps[1]
|
|
|
|
|
|
} else {
|
|
|
|
|
|
urlOptions[ps[0]] = ps[1]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-03-07 17:26:11 +08:00
|
|
|
|
|
|
|
|
|
|
// 从extra获取sid或serviceName
|
|
|
|
|
|
serviceName := ""
|
|
|
|
|
|
if d.Extra != "" {
|
|
|
|
|
|
extraMap := jsonx.ToMap(d.Extra)
|
2024-03-21 17:15:52 +08:00
|
|
|
|
serviceName = cast.ToString(extraMap["serviceName"])
|
|
|
|
|
|
if sid := cast.ToString(extraMap["sid"]); sid != "" {
|
2024-03-07 17:26:11 +08:00
|
|
|
|
urlOptions["SID"] = sid
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-03-01 04:03:03 +00:00
|
|
|
|
urlOptions["TIMEOUT"] = "1000"
|
2024-03-07 17:26:11 +08:00
|
|
|
|
connStr := go_ora.BuildUrl(d.Host, d.Port, serviceName, d.Username, d.Password, urlOptions)
|
|
|
|
|
|
conn, err := sql.Open("oracle", connStr)
|
2024-01-15 11:55:59 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
// 目前没找到如何连接的时候就获取schema的方法,只能连接后再设置
|
|
|
|
|
|
if schema != "" {
|
|
|
|
|
|
_, err := conn.Exec(fmt.Sprintf("ALTER SESSION SET CURRENT_SCHEMA=%s", schema))
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return nil, err
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-20 03:52:23 +00:00
|
|
|
|
|
2024-01-15 11:55:59 +00:00
|
|
|
|
return conn, err
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-20 03:52:23 +00:00
|
|
|
|
func (om *Meta) GetDialect(conn *dbi.DbConn) dbi.Dialect {
|
2024-03-15 13:31:53 +08:00
|
|
|
|
return &OracleDialect{dc: conn}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-01 17:27:22 +08:00
|
|
|
|
func (om *Meta) GetMetadata(conn *dbi.DbConn) dbi.Metadata {
|
2024-10-20 03:52:23 +00:00
|
|
|
|
|
|
|
|
|
|
// 查询数据库版本信息,以做兼容性处理
|
|
|
|
|
|
if conn.Info.Version == "" && !conn.Info.DefaultVersion {
|
|
|
|
|
|
if conn.GetDb() != nil {
|
|
|
|
|
|
_, res, _ := conn.Query("select VERSION from v$instance")
|
|
|
|
|
|
if len(res) > 0 {
|
|
|
|
|
|
version := cast.ToString(res[0]["VERSION"])
|
|
|
|
|
|
// 11开头为11g版本
|
|
|
|
|
|
if strings.HasPrefix(version, "11") {
|
|
|
|
|
|
conn.Info.Version = DbVersionOracle11
|
|
|
|
|
|
conn.Info.DefaultVersion = false
|
|
|
|
|
|
} else {
|
|
|
|
|
|
conn.Info.DefaultVersion = true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if conn.Info.Version == DbVersionOracle11 {
|
2024-11-01 17:27:22 +08:00
|
|
|
|
md := &OracleMetadata11{}
|
2024-10-20 03:52:23 +00:00
|
|
|
|
md.dc = conn
|
|
|
|
|
|
md.version = DbVersionOracle11
|
2024-11-01 17:27:22 +08:00
|
|
|
|
return md
|
2024-10-20 03:52:23 +00:00
|
|
|
|
}
|
2024-11-01 17:27:22 +08:00
|
|
|
|
return &OracleMetadata{dc: conn}
|
2024-01-15 11:55:59 +00:00
|
|
|
|
}
|