WIP: greenplum support #1668

Closed
lunny wants to merge 2 commits from lunny/green_plum into master
9 changed files with 112 additions and 9 deletions

View File

@ -199,15 +199,16 @@ func regDrvsNDialects() bool {
getDriver func() Driver
getDialect func() Dialect
}{
"mssql": {"mssql", func() Driver { return &odbcDriver{} }, func() Dialect { return &mssql{} }},
"odbc": {"mssql", func() Driver { return &odbcDriver{} }, func() Dialect { return &mssql{} }}, // !nashtsai! TODO change this when supporting MS Access
"mysql": {"mysql", func() Driver { return &mysqlDriver{} }, func() Dialect { return &mysql{} }},
"mymysql": {"mysql", func() Driver { return &mymysqlDriver{} }, func() Dialect { return &mysql{} }},
"postgres": {"postgres", func() Driver { return &pqDriver{} }, func() Dialect { return &postgres{} }},
"pgx": {"postgres", func() Driver { return &pqDriverPgx{} }, func() Dialect { return &postgres{} }},
"sqlite3": {"sqlite3", func() Driver { return &sqlite3Driver{} }, func() Dialect { return &sqlite3{} }},
"oci8": {"oracle", func() Driver { return &oci8Driver{} }, func() Dialect { return &oracle{} }},
"goracle": {"oracle", func() Driver { return &goracleDriver{} }, func() Dialect { return &oracle{} }},
"mssql": {"mssql", func() Driver { return &odbcDriver{"mssql"} }, func() Dialect { return &mssql{} }},
"odbc": {"mssql", func() Driver { return &odbcDriver{"odbc"} }, func() Dialect { return &mssql{} }}, // !nashtsai! TODO change this when supporting MS Access
"mysql": {"mysql", func() Driver { return &mysqlDriver{} }, func() Dialect { return &mysql{} }},
"mymysql": {"mysql", func() Driver { return &mymysqlDriver{} }, func() Dialect { return &mysql{} }},
"postgres": {"postgres", func() Driver { return &pqDriver{"postgres"} }, func() Dialect { return &postgres{} }},
"pgx": {"postgres", func() Driver { return &pqDriverPgx{} }, func() Dialect { return &postgres{} }},
"sqlite3": {"sqlite3", func() Driver { return &sqlite3Driver{} }, func() Dialect { return &sqlite3{} }},
"oci8": {"oracle", func() Driver { return &oci8Driver{} }, func() Dialect { return &oracle{} }},
"goracle": {"oracle", func() Driver { return &goracleDriver{} }, func() Dialect { return &oracle{} }},
"greenplum": {schemas.GREENPLUM, func() Driver { return &pqDriver{"postgres"} }, func() Dialect { return &greenplum{} }},
}
for driverName, v := range providedDrvsNDialects {

View File

@ -8,7 +8,9 @@ import (
"fmt"
)
// Driver represents a driver interface
type Driver interface {
Name() string
Parse(string, string) (*URI, error)
}
@ -16,6 +18,7 @@ var (
drivers = map[string]Driver{}
)
// RegisterDriver register a driver
func RegisterDriver(driverName string, driver Driver) {
if driver == nil {
panic("core: Register driver is nil")

64
dialects/green_plum.go Normal file
View File

@ -0,0 +1,64 @@
// Copyright 2020 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package dialects
import (
"fmt"
"strings"
"xorm.io/xorm/schemas"
)
type greenplum struct {
postgres
}
func (db *greenplum) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) {
var sql string
sql = "CREATE TABLE IF NOT EXISTS "
if tableName == "" {
tableName = table.Name
}
quoter := db.Quoter()
sql += quoter.Quote(tableName)
sql += " ("
if len(table.ColumnsSeq()) > 0 {
var uniqueCols []string
pkList := table.PrimaryKeys
for _, colName := range table.ColumnsSeq() {
col := table.GetColumn(colName)
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1)
sql += s
sql = strings.TrimSpace(sql)
sql += ", "
for _, v := range col.Indexes {
if v == schemas.UniqueType {
uniqueCols = append(uniqueCols, colName)
break
}
}
}
if len(pkList) > 1 {
sql += "PRIMARY KEY ( "
sql += quoter.Join(pkList, ",")
sql += " ), "
}
sql = sql[:len(sql)-2]
if len(uniqueCols) > 0 {
sql += fmt.Sprintf(" distributed by (%s)", strings.Join(uniqueCols, ","))
}
}
sql += ")"
return []string{sql}, true
}

View File

@ -531,6 +531,11 @@ func (db *mssql) Filters() []Filter {
}
type odbcDriver struct {
name string
}
func (p *odbcDriver) Name() string {
return p.name
}
func (p *odbcDriver) Parse(driverName, dataSourceName string) (*URI, error) {

View File

@ -573,6 +573,10 @@ func (db *mysql) Filters() []Filter {
type mymysqlDriver struct {
}
func (d *mymysqlDriver) Name() string {
return "mymysql"
}
func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
uri := &URI{DBType: schemas.MYSQL}
@ -625,6 +629,10 @@ func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
type mysqlDriver struct {
}
func (d *mysqlDriver) Name() string {
return "mysql"
}
func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
dsnPattern := regexp.MustCompile(
`^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]

View File

@ -805,6 +805,10 @@ func (db *oracle) Filters() []Filter {
type goracleDriver struct {
}
func (d *goracleDriver) Name() string {
return "goracle"
}
func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*URI, error) {
db := &URI{DBType: schemas.ORACLE}
dsnPattern := regexp.MustCompile(
@ -831,6 +835,10 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*URI, error)
type oci8Driver struct {
}
func (d *oci8Driver) Name() string {
return "oci8"
}
// dataSourceName=user/password@ipv4:port/dbname
// dataSourceName=user/password@[ipv6]:port/dbname
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*URI, error) {

View File

@ -1241,6 +1241,11 @@ func (db *postgres) Filters() []Filter {
}
type pqDriver struct {
name string
}
func (d *pqDriver) Name() string {
return d.name
}
type values map[string]string
@ -1321,6 +1326,10 @@ type pqDriverPgx struct {
pqDriver
}
func (pgx *pqDriverPgx) Name() string {
return "pgx"
}
func (pgx *pqDriverPgx) Parse(driverName, dataSourceName string) (*URI, error) {
// Remove the leading characters for driver to work
if len(dataSourceName) >= 9 && dataSourceName[0] == 0 {

View File

@ -520,6 +520,10 @@ func (db *sqlite3) Filters() []Filter {
type sqlite3Driver struct {
}
func (p *sqlite3Driver) Name() string {
return "sqlite3"
}
func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*URI, error) {
if strings.Contains(dataSourceName, "?") {
dataSourceName = dataSourceName[:strings.Index(dataSourceName, "?")]

View File

@ -19,6 +19,7 @@ const (
MYSQL DBType = "mysql"
MSSQL DBType = "mssql"
ORACLE DBType = "oracle"
GREENPLUM DBType = "greenplum"
)
// SQLType represents SQL types