-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9149ab0
Showing
11 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: tests | ||
|
||
on: | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: tidbcloud/wait-for-tidbcloud-branch@v0 | ||
id: wait-for-branch | ||
with: | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
public-key: ${{ secrets.TIDB_CLOUD_PUBLIC_KEY }} | ||
private-key: ${{ secrets.TIDB_CLOUD_PRIVATE_KEY }} | ||
timeout-seconds: 600 | ||
|
||
- name: Set up Go 1.19 | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: 1.19 | ||
|
||
- name: go mod pakcage cache | ||
uses: actions/cache@v2 | ||
with: | ||
path: ~/go/pkg/mod | ||
key: ubuntu-latest-go-1.19-${{ hashFiles('go.mod') }} | ||
|
||
- name: Tests | ||
run: | | ||
GORM_ENABLE_CACHE=true GORM_DIALECT=tidb GORM_DSN="${{ steps.wait-for-branch.outputs.username }}:${{ steps.wait-for-branch.outputs.password }}@tcp(${{ steps.wait-for-branch.outputs.host }}:${{ steps.wait-for-branch.outputs.port }})/test?parseTime=true&tls=tidb" ./test.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
gorm | ||
go.sum | ||
*.db | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2013-NOW Jinzhu <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# branching-gorm-example | ||
|
||
> **Warning:** This repo is only for testing. Please don't use it in production. | ||
This repo is a gorm example of CI/CD workflow powered by the TiDB Serverless branching. From this repo, you can learn: | ||
|
||
- How to connect to TiDB Serverless in gorm. | ||
- How to use branching GitHub integration. | ||
|
||
## About this repo | ||
|
||
This repo is based on [gorm playground](https://github.com/go-gorm/playground), with some changes: | ||
|
||
- A tidb dialect is added to the repo to test the TiDB Cloud. | ||
- The [gormigrate](https://github.com/go-gormigrate/gormigrate) is used in `RunMigrations` to help migration. | ||
- Delete some useless files like GitHub actions, docker-compose, etc. | ||
|
||
## Connect to TiDB Serverless in gorm | ||
|
||
> Make sure you have installed the go environment. | ||
1. clone the code | ||
|
||
``` | ||
git clone [email protected]:shiyuhang0/branching-gorm-example.git | ||
cd branching-gorm-example | ||
``` | ||
|
||
2. Fill in the following environment variable. You can find the information in the TiDB Serverless console. | ||
|
||
``` | ||
export GORM_ENABLE_CACHE=true | ||
export GORM_DIALECT=tidb | ||
export GORM_DSN="${{ username }}:${{ password }}@tcp(${{ host }}:${{ port }})/test?parseTime=true&tls=tidb" | ||
``` | ||
|
||
3. Connect to the TiDB Serverless (migration will be executed automatically) | ||
|
||
``` | ||
./test.sh | ||
``` | ||
|
||
## Use branching GitHub integration | ||
|
||
This repo has been connected to a TiDB Serverless using the [Branching GitHub integration](https://docs.pingcap.com/tidbcloud/branch-github-integration). This brings database branches to your GitHub workflows, and a TiDB Cloud App will automatically manage database branches for you in the pull request. | ||
|
||
**CI workflow** | ||
|
||
The repo has a [Test GitHub Action](./.github/workflows/tests.yml) to run the test on the created TiDB Serverless branch. This action uses the [wait-for-tidbcloud-branch](https://github.com/tidbcloud/wait-for-tidbcloud-branch) to get branch connection information and pass it by environment variables. We can do it because the repo accepts the `GORM_DSN` environment variable as connection information. See the [code](https://github.com/shiyuhang0/branching-gorm-example/blob/9639f553418456fd1ebb1d933923fba131c98b6b/db.go#L52) for more details. | ||
|
||
Check the [pull request](https://github.com/shiyuhang0/branching-gorm-example/pulls) to see how we use the CI workflow! | ||
|
||
**CD workflow** | ||
|
||
The CD workflow works well with native frameworks. | ||
|
||
Take DDL as an example, you can use the [gormigrate](https://github.com/go-gormigrate/gormigrate) to manage your database migrations. Any DDL changes can be applied to the production cluster when the PR is merged. Don't worry about the influence of production business, the TiDB Serverless cluster supports online DDL without blocking your business. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"errors" | ||
"github.com/go-gormigrate/gormigrate/v2" | ||
mysql2 "github.com/go-sql-driver/mysql" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"regexp" | ||
|
||
"gorm.io/driver/mysql" | ||
"gorm.io/driver/postgres" | ||
"gorm.io/driver/sqlite" | ||
"gorm.io/driver/sqlserver" | ||
"gorm.io/gorm" | ||
"gorm.io/gorm/logger" | ||
) | ||
|
||
var DB *gorm.DB | ||
|
||
func init() { | ||
var err error | ||
if DB, err = OpenTestConnection(); err != nil { | ||
log.Printf("failed to connect database, got error %v\n", err) | ||
os.Exit(1) | ||
} else { | ||
sqlDB, err := DB.DB() | ||
if err == nil { | ||
err = sqlDB.Ping() | ||
} | ||
|
||
if err != nil { | ||
log.Printf("failed to connect database, got error %v\n", err) | ||
} | ||
|
||
RunMigrations() | ||
|
||
if DB.Dialector.Name() == "sqlite" { | ||
DB.Exec("PRAGMA foreign_keys = ON") | ||
} | ||
|
||
DB.Logger = DB.Logger.LogMode(logger.Info) | ||
} | ||
} | ||
|
||
func OpenTestConnection() (db *gorm.DB, err error) { | ||
dbDSN := os.Getenv("GORM_DSN") | ||
switch os.Getenv("GORM_DIALECT") { | ||
case "tidb": | ||
log.Println("testing tidb...") | ||
if dbDSN == "" { | ||
dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" | ||
} | ||
|
||
re := regexp.MustCompile(`(?m)tcp\((\S+):\d+\)`) | ||
match := re.FindStringSubmatch(dbDSN) | ||
|
||
if len(match) <= 1 { | ||
return nil, errors.New("invaild dsn") | ||
} | ||
|
||
mysql2.RegisterTLSConfig("tidb", &tls.Config{ | ||
MinVersion: tls.VersionTLS12, | ||
ServerName: match[1], | ||
}) | ||
db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) | ||
case "mysql": | ||
log.Println("testing mysql...") | ||
if dbDSN == "" { | ||
dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" | ||
} | ||
db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) | ||
case "postgres": | ||
log.Println("testing postgres...") | ||
if dbDSN == "" { | ||
dbDSN = "user=gorm password=gorm host=localhost dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" | ||
} | ||
db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{}) | ||
case "sqlserver": | ||
// CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86'; | ||
// CREATE DATABASE gorm; | ||
// USE gorm; | ||
// CREATE USER gorm FROM LOGIN gorm; | ||
// sp_changedbowner 'gorm'; | ||
log.Println("testing sqlserver...") | ||
if dbDSN == "" { | ||
dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" | ||
} | ||
db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{}) | ||
default: | ||
log.Println("testing sqlite3...") | ||
db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) | ||
} | ||
|
||
if debug := os.Getenv("DEBUG"); debug == "true" { | ||
db.Logger = db.Logger.LogMode(logger.Info) | ||
} else if debug == "false" { | ||
db.Logger = db.Logger.LogMode(logger.Silent) | ||
} | ||
|
||
return | ||
} | ||
|
||
func RunMigrations() { | ||
var err error | ||
allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} | ||
m := gormigrate.New(DB, gormigrate.DefaultOptions, []*gormigrate.Migration{{ | ||
// create tables | ||
ID: "202307101821", | ||
Migrate: func(tx *gorm.DB) error { | ||
if err = DB.AutoMigrate(allModels...); err != nil { | ||
log.Printf("Failed to auto migrate, but got error %v\n", err) | ||
return err | ||
} | ||
return nil | ||
}, | ||
}}) | ||
|
||
if err = m.Migrate(); err != nil { | ||
log.Fatalf("Migration failed: %v", err) | ||
os.Exit(1) | ||
} | ||
log.Println("Migration did run successfully") | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module gorm.io/playground | ||
|
||
go 1.16 | ||
|
||
require ( | ||
github.com/go-gormigrate/gormigrate/v2 v2.1.0 | ||
github.com/go-sql-driver/mysql v1.7.1 | ||
github.com/jackc/pgx/v5 v5.4.3 // indirect | ||
github.com/microsoft/go-mssqldb v1.6.0 // indirect | ||
golang.org/x/crypto v0.13.0 // indirect | ||
gorm.io/driver/mysql v1.5.1 | ||
gorm.io/driver/postgres v1.5.2 | ||
gorm.io/driver/sqlite v1.5.3 | ||
gorm.io/driver/sqlserver v1.5.1 | ||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 | ||
) | ||
|
||
replace gorm.io/gorm => ./gorm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package main | ||
|
||
import "fmt" | ||
|
||
func main() { | ||
fmt.Println("vim-go") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
// GORM_REPO: https://github.com/go-gorm/gorm.git | ||
// GORM_BRANCH: master | ||
// TEST_DRIVERS: sqlite, mysql, postgres, sqlserver, tidb | ||
|
||
func TestGORM(t *testing.T) { | ||
user := User{Name: "jinzhu"} | ||
|
||
DB.Create(&user) | ||
|
||
var result User | ||
if err := DB.First(&result, user.ID).Error; err != nil { | ||
t.Errorf("Failed, got error: %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package main | ||
|
||
import ( | ||
"database/sql" | ||
"time" | ||
|
||
"gorm.io/gorm" | ||
) | ||
|
||
// User has one `Account` (has one), many `Pets` (has many) and `Toys` (has many - polymorphic) | ||
// He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table) | ||
// He speaks many languages (many to many) and has many friends (many to many - single-table) | ||
// His pet also has one Toy (has one - polymorphic) | ||
type User struct { | ||
gorm.Model | ||
Name string | ||
Age uint | ||
Birthday *time.Time | ||
Account Account | ||
Pets []*Pet | ||
Toys []Toy `gorm:"polymorphic:Owner"` | ||
CompanyID *int | ||
Company Company | ||
ManagerID *uint | ||
Manager *User | ||
Team []User `gorm:"foreignkey:ManagerID"` | ||
Languages []Language `gorm:"many2many:UserSpeak"` | ||
Friends []*User `gorm:"many2many:user_friends"` | ||
Active bool | ||
} | ||
|
||
type Account struct { | ||
gorm.Model | ||
UserID sql.NullInt64 | ||
Number string | ||
} | ||
|
||
type Pet struct { | ||
gorm.Model | ||
UserID *uint | ||
Name string | ||
Toy Toy `gorm:"polymorphic:Owner;"` | ||
} | ||
|
||
type Toy struct { | ||
gorm.Model | ||
Name string | ||
OwnerID string | ||
OwnerType string | ||
} | ||
|
||
type Company struct { | ||
ID int | ||
Name string | ||
} | ||
|
||
type Language struct { | ||
Code string `gorm:"primarykey"` | ||
Name string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/bin/bash -e | ||
|
||
dialects=("sqlite" "mysql" "postgres" "sqlserver" "tidb") | ||
|
||
if [ "$GORM_ENABLE_CACHE" = "" ] | ||
then | ||
rm -rf gorm | ||
fi | ||
|
||
[ -d gorm ] || (echo "git clone --depth 1 -b $(cat main_test.go | grep GORM_BRANCH | awk '{print $3}') $(cat main_test.go | grep GORM_REPO | awk '{print $3}')"; git clone --depth 1 -b $(cat main_test.go | grep GORM_BRANCH | awk '{print $3}') $(cat main_test.go | grep GORM_REPO | awk '{print $3}')) | ||
|
||
go get -u -t ./... | ||
|
||
for dialect in "${dialects[@]}" ; do | ||
if [ "$GORM_DIALECT" = "" ] || [ "$GORM_DIALECT" = "${dialect}" ] | ||
then | ||
if [[ $(grep TEST_DRIVER main_test.go) =~ "${dialect}" ]] | ||
then | ||
echo "testing ${dialect}..." | ||
GORM_DIALECT=${dialect} go test -race -count=1 -v ./... | ||
else | ||
echo "skip ${dialect}..." | ||
fi | ||
fi | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
github: | ||
branch: | ||
allowList: | ||
- "ci_example" |