Skip to content

Commit

Permalink
Merge pull request #276 from k1LoW/mariadb-version-detect
Browse files Browse the repository at this point in the history
Support MariaDB
  • Loading branch information
k1LoW authored Jan 16, 2021
2 parents 05481ab + e94d477 commit 8903026
Show file tree
Hide file tree
Showing 27 changed files with 2,078 additions and 14 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ db: db_sqlite
usql my://root:mypass@localhost:33308/testdb -f testdata/ddl/mysql.sql
usql my://root:mypass@localhost:33308/testdb -c "CREATE DATABASE IF NOT EXISTS relations;"
usql my://root:mypass@localhost:33308/relations -f testdata/ddl/detect_relations.sql
usql maria://root:mypass@localhost:33309/testdb -f testdata/ddl/mysql.sql
usql ms://SA:MSSQLServer-Passw0rd@localhost:11433/master -c "IF NOT EXISTS (SELECT * FROM sys.databases WHERE NAME = 'testdb') CREATE DATABASE testdb;"
usql ms://SA:MSSQLServer-Passw0rd@localhost:11433/testdb -f testdata/ddl/mssql.sql
./testdata/ddl/dynamodb.sh > /dev/null 2>&1
Expand All @@ -46,6 +47,7 @@ doc: build doc_sqlite
./tbls doc my://root:mypass@localhost:33306/testdb -c testdata/test_tbls.yml -f sample/mysql56
./tbls doc my://root:mypass@localhost:33308/testdb -c testdata/test_tbls.yml -f sample/mysql
./tbls doc my://root:mypass@localhost:33308/relations -c testdata/test_tbls_detect_relations.yml -f sample/detect_relations
./tbls doc maria://root:mypass@localhost:33309/testdb -c testdata/test_tbls.yml -f sample/mariadb
./tbls doc ms://SA:MSSQLServer-Passw0rd@localhost:11433/testdb -c testdata/test_tbls_mssql.yml -f sample/mssql
env AWS_ENDPOINT_URL=http://localhost:18000 ./tbls doc dynamodb://ap-northeast-1 -c testdata/test_tbls_dynamodb.yml -f sample/dynamodb
./tbls doc pg://postgres:pgpass@localhost:55413/testdb?sslmode=disable -c testdata/test_tbls_postgres.yml -j -f sample/adjust
Expand All @@ -63,6 +65,7 @@ testdoc: testdoc_sqlite
./tbls diff my://root:mypass@localhost:33306/testdb -c testdata/test_tbls.yml sample/mysql56
./tbls diff my://root:mypass@localhost:33308/testdb -c testdata/test_tbls.yml sample/mysql
./tbls diff my://root:mypass@localhost:33308/relations -c testdata/test_tbls_detect_relations.yml sample/detect_relations
./tbls diff maria://root:mypass@localhost:33309/testdb -c testdata/test_tbls.yml sample/mariadb
./tbls diff ms://SA:MSSQLServer-Passw0rd@localhost:11433/testdb -c testdata/test_tbls_mssql.yml sample/mssql
env AWS_ENDPOINT_URL=http://localhost:18000 ./tbls diff dynamodb://ap-northeast-1 -c testdata/test_tbls_dynamodb.yml sample/dynamodb
./tbls diff pg://postgres:pgpass@localhost:55413/testdb?sslmode=disable -c testdata/test_tbls_postgres.yml -j sample/adjust
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,18 @@ dsn: mysql://dbuser:dbpass@hostname:3306/dbname
dsn: my://dbuser:dbpass@hostname:3306/dbname
```

**MariaDB:**

``` yaml
# .tbls.yml
dsn: mariadb://dbuser:dbpass@hostname:3306/dbname
```

``` yaml
# .tbls.yml
dsn: maria://dbuser:dbpass@hostname:3306/dbname
```

**SQLite:**

``` yaml
Expand Down
7 changes: 6 additions & 1 deletion datasource/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/k1LoW/tbls/drivers"
"github.com/k1LoW/tbls/drivers/bq"
"github.com/k1LoW/tbls/drivers/dynamo"
"github.com/k1LoW/tbls/drivers/mariadb"
"github.com/k1LoW/tbls/drivers/mssql"
"github.com/k1LoW/tbls/drivers/mysql"
"github.com/k1LoW/tbls/drivers/postgres"
Expand Down Expand Up @@ -96,7 +97,11 @@ func Analyze(dsn config.DSN) (*schema.Schema, error) {
}
case "mysql":
s.Name = splitted[1]
driver, err = mysql.New(db, opts...)
if u.Scheme == "maria" || u.Scheme == "mariadb" {
driver, err = mariadb.New(db, opts...)
} else {
driver, err = mysql.New(db, opts...)
}
if err != nil {
return s, err
}
Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ services:
environment:
- MYSQL_DATABASE=testdb
- MYSQL_ROOT_PASSWORD=mypass
mariadb:
image: mariadb:10.5
restart: always
ports:
- "33309:3306"
environment:
- MYSQL_DATABASE=testdb
- MYSQL_ROOT_PASSWORD=mypass
mssql:
image: mcr.microsoft.com/mssql/server:2017-latest
restart: always
Expand Down
22 changes: 22 additions & 0 deletions drivers/mariadb/mariadb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package mariadb

import (
"database/sql"

"github.com/k1LoW/tbls/drivers"
"github.com/k1LoW/tbls/drivers/mysql"
)

type Mariadb struct {
mysql.Mysql
}

// New return new Mariadb
func New(db *sql.DB, opts ...drivers.Option) (*Mariadb, error) {
m, err := mysql.New(db, opts...)
if err != nil {
return nil, err
}
m.EnableMariaMode()
return &Mariadb{*m}, nil
}
84 changes: 84 additions & 0 deletions drivers/mariadb/mariadb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package mariadb

import (
"database/sql"
"os"
"testing"

_ "github.com/go-sql-driver/mysql"
"github.com/k1LoW/tbls/schema"
"github.com/xo/dburl"
)

var s *schema.Schema
var db *sql.DB

func TestMain(m *testing.M) {
s = &schema.Schema{
Name: "testdb",
}
db, _ = dburl.Open("maria://root:mypass@localhost:33309/testdb")
defer db.Close()
exit := m.Run()
if exit != 0 {
os.Exit(exit)
}
}

func TestAnalyzeView(t *testing.T) {
driver, err := New(db)
if err != nil {
t.Fatal(err)
}

err = driver.Analyze(s)
if err != nil {
t.Fatal(err)
}
view, _ := s.FindTableByName("post_comments")
if got := view.Def; got == "" {
t.Errorf("got not empty string.")
}
}

func TestExtraDef(t *testing.T) {
driver, err := New(db)
if err != nil {
t.Fatal(err)
}
if err := driver.Analyze(s); err != nil {
t.Fatal(err)
}
tbl, _ := s.FindTableByName("comments")
{
c, _ := tbl.FindColumnByName("id")
got := c.ExtraDef
if want := "auto_increment"; got != want {
t.Errorf("got %v\nwant %v", got, want)
}
}
{
c, _ := tbl.FindColumnByName("post_id_desc")
got := c.ExtraDef
if want := "GENERATED ALWAYS AS `post_id` * -1 VIRTUAL"; got != want {
t.Errorf("got %v\nwant %v", got, want)
}
}
}

func TestInfo(t *testing.T) {
driver, err := New(db)
if err != nil {
t.Fatal(err)
}
d, err := driver.Info()
if err != nil {
t.Fatal(err)
}
if d.Name != "mariadb" {
t.Errorf("got %v\nwant %v", d.Name, "mariadb")
}
if d.DatabaseVersion == "" {
t.Errorf("got not empty string.")
}
}
60 changes: 47 additions & 13 deletions drivers/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var supportGeneratedColumn = true
// Mysql struct
type Mysql struct {
db *sql.DB
mariaMode bool
showAutoIncrement bool
}

Expand Down Expand Up @@ -54,21 +55,35 @@ func (m *Mysql) Analyze(s *schema.Schema) error {
}
s.Driver = d

verGeneratedColumn, err := version.Parse("5.7.6")
if err != nil {
return err
}
v, err := version.Parse(s.Driver.DatabaseVersion)
if err != nil {
return err
}
if v.LessThan(verGeneratedColumn) {
supportGeneratedColumn = false
if m.mariaMode {
verGeneratedColumn, err := version.Parse("10.2")
if err != nil {
return err
}
splitted := strings.Split(s.Driver.DatabaseVersion, "-")
v, err := version.Parse(splitted[0])
if err != nil {
return err
}
if v.LessThan(verGeneratedColumn) {
supportGeneratedColumn = false
}
} else {
verGeneratedColumn, err := version.Parse("5.7.6")
if err != nil {
return err
}
v, err := version.Parse(s.Driver.DatabaseVersion)
if err != nil {
return err
}
if v.LessThan(verGeneratedColumn) {
supportGeneratedColumn = false
}
}

// tables and comments
tableRows, err := m.db.Query(`
SELECT table_name, table_type, table_comment FROM information_schema.tables WHERE table_schema = ?;`, s.Name)
tableRows, err := m.db.Query(m.queryForTables(), s.Name)
if err != nil {
return errors.WithStack(err)
}
Expand Down Expand Up @@ -423,13 +438,32 @@ func (m *Mysql) Info() (*schema.Driver, error) {
return nil, err
}

name := "mysql"
if m.mariaMode {
name = "mariadb"
}

d := &schema.Driver{
Name: "mysql",
Name: name,
DatabaseVersion: v,
}
return d, nil
}

// EnableMariaMode enable mariaMode
func (m *Mysql) EnableMariaMode() {
m.mariaMode = true
}

func (m *Mysql) queryForTables() string {
if m.mariaMode {
return `
SELECT table_name, table_type, table_comment FROM information_schema.tables WHERE table_schema = ? ORDER BY table_name;`
}
return `
SELECT table_name, table_type, table_comment FROM information_schema.tables WHERE table_schema = ?;`
}

func convertColumnNullable(str string) bool {
if str == "NO" {
return false
Expand Down
43 changes: 43 additions & 0 deletions sample/mariadb/CamelizeTable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# CamelizeTable

## Description

<details>
<summary><strong>Table Definition</strong></summary>

```sql
CREATE TABLE `CamelizeTable` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`created` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
```

</details>

## Columns

| Name | Type | Default | Nullable | Extra Definition | Children | Parents | Comment |
| ---- | ---- | ------- | -------- | --------------- | -------- | ------- | ------- |
| id | bigint(20) | | false | auto_increment | | | |
| created | datetime | | false | | | | |

## Constraints

| Name | Type | Definition |
| ---- | ---- | ---------- |
| PRIMARY | PRIMARY KEY | PRIMARY KEY (id) |

## Indexes

| Name | Definition |
| ---- | ---------- |
| PRIMARY | PRIMARY KEY (id) USING BTREE |

## Relations

![er](CamelizeTable.svg)

---

> Generated by [tbls](https://github.com/k1LoW/tbls)
29 changes: 29 additions & 0 deletions sample/mariadb/CamelizeTable.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions sample/mariadb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# testdb

## Description

Sample database document.

## Labels

`sample` `tbls`

## Tables

| Name | Columns | Comment | Type |
| ---- | ------- | ------- | ---- |
| [CamelizeTable](CamelizeTable.md) | 2 | | BASE TABLE |
| [comments](comments.md) | 7 | Comments<br>Multi-line<br>table<br>comment | BASE TABLE |
| [comment_stars](comment_stars.md) | 6 | | BASE TABLE |
| [hyphen-table](hyphen-table.md) | 3 | | BASE TABLE |
| [logs](logs.md) | 7 | Auditログ | BASE TABLE |
| [posts](posts.md) | 7 | Posts table | BASE TABLE |
| [post_comments](post_comments.md) | 7 | post and comments View table | VIEW |
| [users](users.md) | 6 | Users table | BASE TABLE |
| [user_options](user_options.md) | 4 | User options table | BASE TABLE |

## Relations

![er](schema.svg)

---

> Generated by [tbls](https://github.com/k1LoW/tbls)
Loading

0 comments on commit 8903026

Please # to comment.