Repository: ariga/atlas
Pull request #1316 (2022-11-28 08:38:36)

sql: add driver.Version to expose the version of the connected database


Patch:
diff --git a/sql/mysql/driver.go b/sql/mysql/driver.go
index 27303eae..6d5eb8de 100644
--- a/sql/mysql/driver.go
+++ b/sql/mysql/driver.go
@@ -191,6 +191,11 @@ func (d *Driver) CheckClean(ctx context.Context, revT *migrate.TableIdent) error
 	return nil
 }
 
+// Version returns the version of the connected database.
+func (d *Driver) Version() string {
+	return string(d.conn.V)
+}
+
 func acquire(ctx context.Context, conn schema.ExecQuerier, name string, timeout time.Duration) error {
 	rows, err := conn.QueryContext(ctx, "SELECT GET_LOCK(?, ?)", name, int(timeout.Seconds()))
 	if err != nil {
diff --git a/sql/postgres/driver.go b/sql/postgres/driver.go
index 0b5a87b3..21877b44 100644
--- a/sql/postgres/driver.go
+++ b/sql/postgres/driver.go
@@ -250,6 +250,11 @@ func (d *Driver) CheckClean(ctx context.Context, revT *migrate.TableIdent) error
 	return nil
 }
 
+// Version returns the version of the connected database.
+func (d *Driver) Version() string {
+	return strconv.Itoa(d.conn.version)
+}
+
 func acquire(ctx context.Context, conn schema.ExecQuerier, id uint32, timeout time.Duration) error {
 	switch {
 	// With timeout (context-based).
diff --git a/sql/sqlite/driver.go b/sql/sqlite/driver.go
index 5d800645..e32d690a 100644
--- a/sql/sqlite/driver.go
+++ b/sql/sqlite/driver.go
@@ -153,6 +153,11 @@ func (d *Driver) Lock(_ context.Context, name string, timeout time.Duration) (sc
 	return acquireLock(path, timeout)
 }
 
+// Version returns the version of the connected database.
+func (d *Driver) Version() string {
+	return d.conn.version
+}
+
 func acquireLock(path string, timeout time.Duration) (schema.UnlockFunc, error) {
 	lock, err := os.Create(path)
 	if err != nil {


Test patch:
diff --git a/sql/mysql/driver_test.go b/sql/mysql/driver_test.go
index 610ad873..b88b6f53 100644
--- a/sql/mysql/driver_test.go
+++ b/sql/mysql/driver_test.go
@@ -171,6 +171,18 @@ func TestDriver_CheckClean(t *testing.T) {
 	require.EqualError(t, err, `sql/migrate: connected database is not clean: found multiple tables: 2`)
 }
 
+func TestDriver_Version(t *testing.T) {
+	db, m, err := sqlmock.New()
+	require.NoError(t, err)
+	mock{m}.version("8.0.13")
+	drv, err := Open(db)
+	require.NoError(t, err)
+
+	type vr interface{ Version() string }
+	require.Implements(t, (*vr)(nil), drv)
+	require.Equal(t, "8.0.13", drv.(vr).Version())
+}
+
 type mockInspector struct {
 	schema.Inspector
 	realm  *schema.Realm
diff --git a/sql/postgres/driver_test.go b/sql/postgres/driver_test.go
index 997c254a..e6286a00 100644
--- a/sql/postgres/driver_test.go
+++ b/sql/postgres/driver_test.go
@@ -144,6 +144,18 @@ func TestDriver_CheckClean(t *testing.T) {
 	require.NoError(t, err)
 }
 
+func TestDriver_Version(t *testing.T) {
+	db, m, err := sqlmock.New()
+	require.NoError(t, err)
+	mock{m}.version("130000")
+	drv, err := Open(db)
+	require.NoError(t, err)
+
+	type vr interface{ Version() string }
+	require.Implements(t, (*vr)(nil), drv)
+	require.Equal(t, "130000", drv.(vr).Version())
+}
+
 type mockInspector struct {
 	schema.Inspector
 	realm  *schema.Realm
diff --git a/sql/sqlite/driver_test.go b/sql/sqlite/driver_test.go
index 3cb0235c..adffa8a1 100644
--- a/sql/sqlite/driver_test.go
+++ b/sql/sqlite/driver_test.go
@@ -13,8 +13,9 @@ import (
 	"time"
 
 	"ariga.io/atlas/sql/migrate"
-
 	"ariga.io/atlas/sql/schema"
+
+	"github.com/DATA-DOG/go-sqlmock"
 	"github.com/stretchr/testify/require"
 )
 
@@ -76,6 +77,18 @@ func TestDriver_CheckClean(t *testing.T) {
 	require.EqualError(t, err, `sql/migrate: connected database is not clean: found multiple tables: 2`)
 }
 
+func TestDriver_Version(t *testing.T) {
+	db, m, err := sqlmock.New()
+	require.NoError(t, err)
+	mock{m}.systemVars("3.36.0")
+	drv, err := Open(db)
+	require.NoError(t, err)
+
+	type vr interface{ Version() string }
+	require.Implements(t, (*vr)(nil), drv)
+	require.Equal(t, "3.36.0", drv.(vr).Version())
+}
+
 type mockInspector struct {
 	schema.Inspector
 	realm *schema.Realm