데이터베이스에서 테이블 정보를 가져와 Go 코드로 변환하는 도구
$ go install github.com/smallnest/gen@latest
$ go mod init goproj
$ sqlite3 sqlite.db
sqlite> CREATE TABLE human ( id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, age INT NOT NULL, description TEXT NULL );
sqlite> INSERT INTO human ( id, name, age ) VALUES ( 1, 'James', 25 );
sqlite> SELECT * FROM human;
1|James|25|
sqlite> .exit
$ gen --sqltype=sqlite3 --connstr "./sqlite.db" --database main --json --overwrite --gorm
Generating code for the following tables (1)
[0] human
$ go mod tidy
go: finding module for package github.com/satori/go.uuid
go: finding module for package github.com/guregu/null
go: found github.com/guregu/null in github.com/guregu/null v4.0.0+incompatible
go: found github.com/satori/go.uuid in github.com/satori/go.uuid v1.2.0
go: finding module for package gopkg.in/check.v1
go: found gopkg.in/check.v1 in gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
model
디렉터리가 생성되고 그 아래 model_base.go
, human.go
파일이 생성됨$ tree
.
├── go.mod
├── go.sum
├── model
│ ├── human.go
│ └── model_base.go
└── sqlite.db
1 directory, 5 files
model_base.go
파일내용 확인package model
import "fmt"
// Action CRUD actions
type Action int32
var (
// Create action when record is created
Create = Action(0)
// RetrieveOne action when a record is retrieved from db
RetrieveOne = Action(1)
// RetrieveMany action when record(s) are retrieved from db
RetrieveMany = Action(2)
// Update action when record is updated in db
Update = Action(3)
// Delete action when record is deleted in db
Delete = Action(4)
// FetchDDL action when fetching ddl info from db
FetchDDL = Action(5)
tables map[string]*TableInfo
)
func init() {
tables = make(map[string]*TableInfo)
tables["human"] = humanTableInfo
}
// String describe the action
func (i Action) String() string {
switch i {
case Create:
return "Create"
case RetrieveOne:
return "RetrieveOne"
case RetrieveMany:
return "RetrieveMany"
case Update:
return "Update"
case Delete:
return "Delete"
case FetchDDL:
return "FetchDDL"
default:
return fmt.Sprintf("unknown action: %d", int(i))
}
}
// Model interface methods for database structs generated
type Model interface {
TableName() string
BeforeSave() error
Prepare()
Validate(action Action) error
TableInfo() *TableInfo
}
// TableInfo describes a table in the database
type TableInfo struct {
Name string `json:"name"`
Columns []*ColumnInfo `json:"columns"`
}
// ColumnInfo describes a column in the database table
type ColumnInfo struct {
Index int `json:"index"`
GoFieldName string `json:"go_field_name"`
GoFieldType string `json:"go_field_type"`
JSONFieldName string `json:"json_field_name"`
ProtobufFieldName string `json:"protobuf_field_name"`
ProtobufType string `json:"protobuf_field_type"`
ProtobufPos int `json:"protobuf_field_pos"`
Comment string `json:"comment"`
Notes string `json:"notes"`
Name string `json:"name"`
Nullable bool `json:"is_nullable"`
DatabaseTypeName string `json:"database_type_name"`
DatabaseTypePretty string `json:"database_type_pretty"`
IsPrimaryKey bool `json:"is_primary_key"`
IsAutoIncrement bool `json:"is_auto_increment"`
IsArray bool `json:"is_array"`
ColumnType string `json:"column_type"`
ColumnLength int64 `json:"column_length"`
DefaultValue string `json:"default_value"`
}
// GetTableInfo retrieve TableInfo for a table
func GetTableInfo(name string) (*TableInfo, bool) {
val, ok := tables[name]
return val, ok
}
human.go
내용 확인package model
import (
"database/sql"
"time"
"github.com/guregu/null"
"github.com/satori/go.uuid"
)
var (
_ = time.Second
_ = sql.LevelDefault
_ = null.Bool{}
_ = uuid.UUID{}
)
/*
DB Table Details
-------------------------------------
CREATE TABLE human ( id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, age INT NOT NULL, description TEXT NULL )
JSON Sample
-------------------------------------
{ "id": 24, "name": "AqVvPIytUihPNkKQpRCulFhGd", "age": 86, "description": "oaAyfCaKfIZpgLEIpmyununQE"}
*/
// Human struct is a row record of the human table in the main database
type Human struct {
//[ 0] id int null: false primary: true isArray: false auto: false col: int len: -1 default: []
ID int32 `gorm:"primary_key;column:id;type:int;" json:"id"`
//[ 1] name varchar(255) null: false primary: false isArray: false auto: false col: varchar len: 255 default: []
Name string `gorm:"column:name;type:varchar;size:255;" json:"name"`
//[ 2] age int null: false primary: false isArray: false auto: false col: int len: -1 default: []
Age int32 `gorm:"column:age;type:int;" json:"age"`
//[ 3] description text null: true primary: false isArray: false auto: false col: text len: -1 default: []
Description sql.NullString `gorm:"column:description;type:text;" json:"description"`
}
var humanTableInfo = &TableInfo{
Name: "human",
Columns: []*ColumnInfo{
&ColumnInfo{
Index: 0,
Name: "id",
Comment: ``,
Notes: ``,
Nullable: false,
DatabaseTypeName: "int",
DatabaseTypePretty: "int",
IsPrimaryKey: true,
IsAutoIncrement: false,
IsArray: false,
ColumnType: "int",
ColumnLength: -1,
GoFieldName: "ID",
GoFieldType: "int32",
JSONFieldName: "id",
ProtobufFieldName: "id",
ProtobufType: "int32",
ProtobufPos: 1,
},
&ColumnInfo{
Index: 1,
Name: "name",
Comment: ``,
Notes: ``,
Nullable: false,
DatabaseTypeName: "varchar",
DatabaseTypePretty: "varchar(255)",
IsPrimaryKey: false,
IsAutoIncrement: false,
IsArray: false,
ColumnType: "varchar",
ColumnLength: 255,
GoFieldName: "Name",
GoFieldType: "string",
JSONFieldName: "name",
ProtobufFieldName: "name",
ProtobufType: "string",
ProtobufPos: 2,
},
&ColumnInfo{
Index: 2,
Name: "age",
Comment: ``,
Notes: ``,
Nullable: false,
DatabaseTypeName: "int",
DatabaseTypePretty: "int",
IsPrimaryKey: false,
IsAutoIncrement: false,
IsArray: false,
ColumnType: "int",
ColumnLength: -1,
GoFieldName: "Age",
GoFieldType: "int32",
JSONFieldName: "age",
ProtobufFieldName: "age",
ProtobufType: "int32",
ProtobufPos: 3,
},
&ColumnInfo{
Index: 3,
Name: "description",
Comment: ``,
Notes: ``,
Nullable: true,
DatabaseTypeName: "text",
DatabaseTypePretty: "text",
IsPrimaryKey: false,
IsAutoIncrement: false,
IsArray: false,
ColumnType: "text",
ColumnLength: -1,
GoFieldName: "Description",
GoFieldType: "sql.NullString",
JSONFieldName: "description",
ProtobufFieldName: "description",
ProtobufType: "string",
ProtobufPos: 4,
},
},
}
// TableName sets the insert table name for this struct type
func (h *Human) TableName() string {
return "human"
}
// BeforeSave invoked before saving, return an error if field is not populated.
func (h *Human) BeforeSave() error {
return nil
}
// Prepare invoked before saving, can be used to populate fields etc.
func (h *Human) Prepare() {
}
// Validate invoked before performing action, return an error if field is not populated.
func (h *Human) Validate(action Action) error {
return nil
}
// TableInfo return table meta data
func (h *Human) TableInfo() *TableInfo {
return humanTableInfo
}