Add DBVersion #1723

Merged
lunny merged 7 commits from lunny/version into master 2021-06-12 07:06:06 +00:00
10 changed files with 165 additions and 9 deletions

View File

@ -44,6 +44,7 @@ type Dialect interface {
URI() *URI
SQLType(*schemas.Column) string
FormatBytes(b []byte) string
Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error)
IsReserved(string) bool
Quoter() schemas.Quoter

View File

@ -253,6 +253,31 @@ func (db *mssql) SetParams(params map[string]string) {
}
}
func (db *mssql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx,
"SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel') AS ProductLevel, SERVERPROPERTY ('edition') AS ProductEdition")
if err != nil {
return nil, err
}
defer rows.Close()
var version, level, edition string
if !rows.Next() {
return nil, errors.New("unknow version")
}
if err := rows.Scan(&version, &level, &edition); err != nil {
return nil, err
}
// MSSQL: Microsoft SQL Server 2017 (RTM-CU13) (KB4466404) - 14.0.3048.4 (X64) Nov 30 2018 12:57:58 Copyright (C) 2017 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
return &schemas.Version{
Number: version,
Level: level,
Edition: edition,
}, nil
}
func (db *mssql) SQLType(c *schemas.Column) string {
var res string
switch t := c.SQLType.Name; t {

View File

@ -188,6 +188,43 @@ func (db *mysql) Init(uri *URI) error {
return db.Base.Init(db, uri)
}
func (db *mysql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx, "SELECT @@VERSION")
if err != nil {
return nil, err
}
defer rows.Close()
var version string
if !rows.Next() {
return nil, errors.New("Unknow version")
}
if err := rows.Scan(&version); err != nil {
return nil, err
}
fields := strings.Split(version, "-")
lunny marked this conversation as resolved Outdated
Outdated
Review

make sure with regex, strings.Split do have 3 items or we could get out of range exeptions

and use it to make sure its TiDB in the same time :)

make sure with regex, strings.Split do have 3 items or we could get out of range exeptions and use it to make sure its TiDB in the same time :)
Outdated
Review

The rule is simple, three fields with -. So I don't think we need regex here.

The rule is simple, three fields with `-`. So I don't think we need regex here.
if len(fields) == 3 && fields[1] == "TiDB" {
// 5.7.25-TiDB-v3.0.3
return &schemas.Version{
Number: strings.TrimPrefix(fields[2], "v"),
Level: fields[0],
Edition: fields[1],
}, nil
}
var edition string
if len(fields) == 2 {
edition = fields[1]
}
return &schemas.Version{
Number: fields[0],
Edition: edition,
}, nil
}
func (db *mysql) SetParams(params map[string]string) {
rowFormat, ok := params["rowFormat"]
if ok {

View File

@ -515,6 +515,26 @@ func (db *oracle) Init(uri *URI) error {
return db.Base.Init(db, uri)
}
func (db *oracle) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx, "select * from v$version where banner like 'Oracle%'")
if err != nil {
return nil, err
}
defer rows.Close()
var version string
if !rows.Next() {
return nil, errors.New("unknow version")
}
if err := rows.Scan(&version); err != nil {
return nil, err
}
return &schemas.Version{
Number: version,
}, nil
}
func (db *oracle) SQLType(c *schemas.Column) string {
var res string
switch t := c.SQLType.Name; t {

View File

@ -788,6 +788,42 @@ func (db *postgres) Init(uri *URI) error {
return db.Base.Init(db, uri)
}
func (db *postgres) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx, "SELECT version()")
if err != nil {
return nil, err
}
defer rows.Close()
var version string
if !rows.Next() {
return nil, errors.New("Unknow version")
}
if err := rows.Scan(&version); err != nil {
return nil, err
}
// Postgres: 9.5.22 on x86_64-pc-linux-gnu (Debian 9.5.22-1.pgdg90+1), compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit
// CockroachDB CCL v19.2.4 (x86_64-unknown-linux-gnu, built
if strings.HasPrefix(version, "CockroachDB") {
versions := strings.Split(strings.TrimPrefix(version, "CockroachDB CCL "), " ")
return &schemas.Version{
Number: strings.TrimPrefix(versions[0], "v"),
Edition: "CockroachDB",
}, nil
} else if strings.HasPrefix(version, "PostgreSQL") {
versions := strings.Split(strings.TrimPrefix(version, "PostgreSQL "), " on ")
return &schemas.Version{
Number: versions[0],
Level: versions[1],
Edition: "PostgreSQL",
}, nil
}
return nil, errors.New("unknow database version")
}
func (db *postgres) getSchema() string {
if db.uri.Schema != "" {
return db.uri.Schema

View File

@ -160,6 +160,27 @@ func (db *sqlite3) Init(uri *URI) error {
return db.Base.Init(db, uri)
}
func (db *sqlite3) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx, "SELECT sqlite_version()")
if err != nil {
return nil, err
}
defer rows.Close()
var version string
if !rows.Next() {
return nil, errors.New("Unknow version")
}
if err := rows.Scan(&version); err != nil {
return nil, err
}
return &schemas.Version{
Number: version,
Edition: "sqlite",
}, nil
}
func (db *sqlite3) SetQuotePolicy(quotePolicy QuotePolicy) {
switch quotePolicy {
case QuotePolicyNone:

View File

@ -925,15 +925,9 @@ func (engine *Engine) Having(conditions string) *Session {
return session.Having(conditions)
}
// Table table struct
type Table struct {
*schemas.Table
Name string
}
// IsValid if table is valid
func (t *Table) IsValid() bool {
return t.Table != nil && len(t.Name) > 0
// DBVersion returns the database version
func (engine *Engine) DBVersion() (*schemas.Version, error) {
return engine.dialect.Version(engine.defaultContext, engine.db)
}
// TableInfo get table info according to bean's content

View File

@ -200,3 +200,12 @@ func TestImport(t *testing.T) {
assert.NoError(t, err)
assert.NoError(t, sess.Commit())
}
func TestDBVersion(t *testing.T) {
assert.NoError(t, PrepareEngine())
version, err := testEngine.DBVersion()
assert.NoError(t, err)
fmt.Println(testEngine.Dialect().URI().DBType, "version is", version)
}

View File

@ -83,6 +83,7 @@ type EngineInterface interface {
Context(context.Context) *Session
CreateTables(...interface{}) error
DBMetas() ([]*schemas.Table, error)
DBVersion() (*schemas.Version, error)
Dialect() dialects.Dialect
DriverName() string
DropTables(...interface{}) error

12
schemas/version.go Normal file
View File

@ -0,0 +1,12 @@
// Copyright 2021 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 schemas
// Version represents a database version
type Version struct {
Number string // the version number which could be compared
Level string
Edition string
}