Skip to content

Commit 2200bd0

Browse files
committed
clean README
1 parent 347ad93 commit 2200bd0

File tree

2 files changed

+147
-339
lines changed

2 files changed

+147
-339
lines changed

README.md

+73-170
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,9 @@
44

55
English | [中文](README_zh.md)
66

7-
SQLize is a powerful SQL toolkit for Golang, offering parsing, building, and migration capabilities.
8-
9-
## Features
10-
11-
- SQL parsing and building for multiple databases:
12-
- MySQL
13-
- PostgreSQL
14-
- SQLite
15-
16-
- SQL migration generation:
17-
- Create migrations from Golang models and current SQL schema
18-
- Generate migration versions compatible with `golang-migrate/migrate`
19-
- Export ERD (MermaidJs)
20-
- Export Arvo Schema
21-
22-
- Advanced functionalities:
23-
- Support for embedded structs
24-
- Avro schema generation (MySQL only)
25-
- Compatibility with `gorm` tags (default tag is `sql`)
7+
SQLize is a powerful migration generation tool that detects differences between two SQL state sources. It simplifies migration creation by comparing an existing SQL schema with Go models, ensuring seamless database updates.
8+
Designed for flexibility, SQLize supports `MySQL`, `PostgreSQL`, and `SQLite` and integrates well with popular Go ORM and migration tools like `gorm` (gorm tag), `golang-migrate/migrate` (migration version), and more.
9+
Additionally, SQLize offers advanced features, including `Avro Schema` export (MySQL only) and `ERD` diagram generation (`MermaidJS`).
2610

2711
## Conventions
2812

@@ -72,176 +56,95 @@ SQLize is a powerful SQL toolkit for Golang, offering parsing, building, and mig
7256
BIGINT => bigint(20)
7357
```
7458

75-
### Important Notes
76-
77-
- Pointer values must be declared in the struct
78-
79-
### Examples
80-
81-
1. Using pointer values:
59+
- Pointer values must be declared in the struct or predefined data types.
8260

8361
```golang
84-
type sample struct {
85-
ID int32 `sql:"primary_key"`
62+
// your struct
63+
type Record struct {
64+
ID int
8665
DeletedAt *time.Time
8766
}
8867

68+
// =>
69+
// the struct is declared with a value
8970
now := time.Now()
90-
newMigration.FromObjects(sample{DeletedAt: &now})
91-
```
92-
93-
2. Embedded struct:
94-
95-
```golang
96-
type Base struct {
97-
ID int32 `sql:"primary_key"`
98-
CreatedAt time.Time
99-
}
100-
type sample struct {
101-
Base `sql:"embedded"`
102-
User string
103-
}
104-
105-
newMigration.FromObjects(sample{})
106-
107-
/*
108-
CREATE TABLE sample (
109-
id int(11) PRIMARY KEY,
110-
user text,
111-
created_at datetime
112-
);
113-
*/
114-
```
115-
116-
3. Comparing SQL schema with Go struct:
117-
118-
```go
119-
package main
120-
121-
import (
122-
"time"
123-
124-
"github.com/sunary/sqlize"
125-
)
71+
Record{DeletedAt: &now}
12672

127-
type user struct {
128-
ID int32 `sql:"primary_key;auto_increment"`
129-
Alias string `sql:"type:VARCHAR(64)"`
130-
Name string `sql:"type:VARCHAR(64);unique;index_columns:name,age"`
131-
Age int
132-
Bio string
133-
IgnoreMe string `sql:"-"`
134-
AcceptTncAt *time.Time `sql:"index:idx_accept_tnc_at"`
135-
CreatedAt time.Time `sql:"default:CURRENT_TIMESTAMP"`
136-
UpdatedAt time.Time `sql:"default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index:idx_updated_at"`
73+
// or predefined data type
74+
type Record struct {
75+
ID int
76+
DeletedAt *time.Time `sql:"type:DATETIME"`
13777
}
13878

139-
func (user) TableName() string {
140-
return "user"
141-
}
142-
143-
var createStm = `
144-
CREATE TABLE user (
145-
id INT AUTO_INCREMENT PRIMARY KEY,
146-
name VARCHAR(64),
147-
age INT,
148-
bio TEXT,
149-
gender BOOL,
150-
accept_tnc_at DATETIME NULL,
151-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
152-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
153-
);
154-
CREATE UNIQUE INDEX idx_name_age ON user(name, age);
155-
CREATE INDEX idx_updated_at ON user(updated_at);`
156-
157-
func main() {
158-
n := time.Now()
159-
newMigration := sqlize.NewSqlize(sqlize.WithSqlTag("sql"), sqlize.WithMigrationFolder(""))
160-
_ = newMigration.FromObjects(user{AcceptTncAt: &n})
161-
162-
println(newMigration.StringUp())
163-
//CREATE TABLE `user` (
164-
// `id` int(11) AUTO_INCREMENT PRIMARY KEY,
165-
// `alias` varchar(64),
166-
// `name` varchar(64),
167-
// `age` int(11),
168-
// `bio` text,
169-
// `accept_tnc_at` datetime NULL,
170-
// `created_at` datetime DEFAULT CURRENT_TIMESTAMP(),
171-
// `updated_at` datetime DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()
172-
//);
173-
//CREATE UNIQUE INDEX `idx_name_age` ON `user`(`name`, `age`);
174-
//CREATE INDEX `idx_accept_tnc_at` ON `user`(`accept_tnc_at`);
175-
//CREATE INDEX `idx_updated_at` ON `user`(`updated_at`);
176-
177-
println(newMigration.StringDown())
178-
//DROP TABLE IF EXISTS `user`;
179-
180-
oldMigration := sqlize.NewSqlize(sqlize.WithMigrationFolder(""))
181-
//_ = oldMigration.FromMigrationFolder()
182-
_ = oldMigration.FromString(createStm)
183-
184-
newMigration.Diff(*oldMigration)
185-
186-
println(newMigration.StringUp())
187-
//ALTER TABLE `user` ADD COLUMN `alias` varchar(64) AFTER `id`;
188-
//ALTER TABLE `user` DROP COLUMN `gender`;
189-
//CREATE INDEX `idx_accept_tnc_at` ON `user`(`accept_tnc_at`);
190-
191-
println(newMigration.StringDown())
192-
//ALTER TABLE `user` DROP COLUMN `alias`;
193-
//ALTER TABLE `user` ADD COLUMN `gender` tinyint(1) AFTER `age`;
194-
//DROP INDEX `idx_accept_tnc_at` ON `user`;
195-
196-
println(newMigration.MermaidJsLive())
197-
println(newMigration.ArvoSchema())
198-
//...
199-
200-
_ = newMigration.WriteFiles("demo migration")
79+
// or using struct supported by "database/sql"
80+
type Record struct {
81+
ID int
82+
DeletedAt sql.NullTime
20183
}
20284
```
20385

204-
4. Comparing Two SQL Schemas:
86+
## Usage
20587

206-
```go
88+
- Add the following code to your project as a command.
89+
- Implement `YourModels()` to return the Go models affected by the migration.
90+
- Run the command whenever you need to generate a migration.
91+
92+
```golang
20793
package main
20894

20995
import (
96+
"fmt"
97+
"log"
98+
"os"
99+
210100
"github.com/sunary/sqlize"
211101
)
212102

213103
func main() {
214-
sql1 := sqlize.NewSqlize()
215-
sql1.FromString(`
216-
CREATE TABLE user (
217-
id INT AUTO_INCREMENT PRIMARY KEY,
218-
name VARCHAR(64),
219-
age INT,
220-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
221-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
222-
);
223-
CREATE UNIQUE INDEX idx_name_age ON user(name, age);
224-
`)
225-
226-
sql2 := sqlize.NewSqlize()
227-
sql2.FromString(`
228-
CREATE TABLE user (
229-
id INT,
230-
name VARCHAR(64),
231-
age INT,
232-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
233-
updated_at DATETIME
234-
);`)
235-
236-
sql1.Diff(*sql2)
237-
println(sql1.StringUp())
238-
//ALTER TABLE `user` MODIFY COLUMN `id` int(11) AUTO_INCREMENT PRIMARY KEY;
239-
//ALTER TABLE `user` MODIFY COLUMN `updated_at` datetime DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP();
240-
//CREATE UNIQUE INDEX `idx_name_age` ON `user`(`name`, `age`);
241-
242-
println(sql1.StringDown())
243-
//ALTER TABLE `user` MODIFY COLUMN `id` int(11);
244-
//ALTER TABLE `user` MODIFY COLUMN `updated_at` datetime;
245-
//DROP INDEX `idx_name_age` ON `user`;
104+
migrationFolder := "migrations/"
105+
sqlLatest := sqlize.NewSqlize(sqlize.WithSqlTag("sql"),
106+
sqlize.WithMigrationFolder(migrationFolder),
107+
sqlize.WithCommentGenerate())
108+
109+
ms := YourModels() // TODO: implement YourModels() function
110+
err := sqlLatest.FromObjects(ms...)
111+
if err != nil {
112+
log.Fatal("sqlize FromObjects", err)
113+
}
114+
sqlVersion := sqlLatest.HashValue()
115+
116+
sqlMigrated := sqlize.NewSqlize(sqlize.WithMigrationFolder(migrationFolder))
117+
err = sqlMigrated.FromMigrationFolder()
118+
if err != nil {
119+
log.Fatal("sqlize FromMigrationFolder", err)
120+
}
121+
122+
sqlLatest.Diff(*sqlMigrated)
123+
124+
fmt.Println("sql version", sqlVersion)
125+
126+
fmt.Println("\n\n### migration up")
127+
migrationUp := sqlLatest.StringUp()
128+
fmt.Println(migrationUp)
129+
130+
fmt.Println("\n\n### migration down")
131+
fmt.Println(sqlLatest.StringDown())
132+
133+
initVersion := false
134+
if initVersion {
135+
log.Println("write to init version")
136+
err = sqlLatest.WriteFilesVersion("new version", 0, false)
137+
if err != nil {
138+
log.Fatal("sqlize WriteFilesVersion", err)
139+
}
140+
}
141+
142+
if len(os.Args) > 1 {
143+
log.Println("write to file", os.Args[1])
144+
err = sqlLatest.WriteFilesWithVersion(os.Args[1], sqlVersion, false)
145+
if err != nil {
146+
log.Fatal("sqlize WriteFilesWithVersion", err)
147+
}
148+
}
246149
}
247150
```

0 commit comments

Comments
 (0)