table

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2022 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddColumn

func AddColumn(ctx context.Context, db wrapper.Querier, col Column) error

AddColumn add a column by Column

func ChangeColumn

func ChangeColumn(ctx context.Context, db wrapper.Querier, col Column) error

ChangeColumn change a column definition by Column

func CheckAutoSet

func CheckAutoSet(defaultVal string) bool

CheckAutoSet check a column is auto generated by database or not

func CheckAutoincrement

func CheckAutoincrement(extra string) bool

CheckAutoincrement check a column is auto increment or not

func CheckNull

func CheckNull(null nullenum.Null) bool

CheckNull check a column is nullable or not

func CheckPk

func CheckPk(key keyenum.Key) bool

CheckPk check key is primary key or not

func CheckUnsigned

func CheckUnsigned(dbColType string) bool

CheckUnsigned check a column is unsigned or not

func CreateTable

func CreateTable(ctx context.Context, db wrapper.Querier, t Table) error

CreateTable create table from Table

Example
terminator, db, err := Setup()
if err != nil {
	panic(err)
}
defer terminator()
defer db.Close()

expectjson := `{"Name":"user_createtable","Columns":[{"Table":"user","Name":"id","Type":"INT","Default":null,"Pk":true,"Nullable":false,"Unsigned":false,"Autoincrement":true,"Extra":"","Meta":{"Name":"ID","Type":"int","Tag":"dd:\"pk;auto\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"name","Type":"VARCHAR(255)","Default":"'jack'","Pk":false,"Nullable":false,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"Name","Type":"string","Tag":"dd:\"index:name_phone_idx,2;default:'jack'\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"phone","Type":"VARCHAR(255)","Default":"'13552053960'","Pk":false,"Nullable":false,"Unsigned":false,"Autoincrement":false,"Extra":"comment '手机号'","Meta":{"Name":"Phone","Type":"string","Tag":"dd:\"index:name_phone_idx,1;default:'13552053960';extra:comment '手机号'\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"age","Type":"INT","Default":null,"Pk":false,"Nullable":false,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"Age","Type":"int","Tag":"dd:\"index\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"no","Type":"INT","Default":null,"Pk":false,"Nullable":false,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"No","Type":"int","Tag":"dd:\"unique\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"school","Type":"VARCHAR(255)","Default":"'harvard'","Pk":false,"Nullable":true,"Unsigned":false,"Autoincrement":false,"Extra":"comment '学校'","Meta":{"Name":"School","Type":"string","Tag":"dd:\"null;default:'harvard';extra:comment '学校'\"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"is_student","Type":"TINYINT","Default":null,"Pk":false,"Nullable":false,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"IsStudent","Type":"bool","Tag":"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"delete_at","Type":"DATETIME","Default":null,"Pk":false,"Nullable":true,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"DeleteAt","Type":"*time.Time","Tag":"","Comments":null},"AutoSet":false,"Indexes":null},{"Table":"user","Name":"create_at","Type":"DATETIME","Default":"CURRENT_TIMESTAMP","Pk":false,"Nullable":true,"Unsigned":false,"Autoincrement":false,"Extra":"","Meta":{"Name":"CreateAt","Type":"*time.Time","Tag":"dd:\"default:CURRENT_TIMESTAMP\"","Comments":null},"AutoSet":true,"Indexes":null},{"Table":"user","Name":"update_at","Type":"DATETIME","Default":"CURRENT_TIMESTAMP","Pk":false,"Nullable":true,"Unsigned":false,"Autoincrement":false,"Extra":"ON UPDATE CURRENT_TIMESTAMP","Meta":{"Name":"UpdateAt","Type":"*time.Time","Tag":"dd:\"default:CURRENT_TIMESTAMP;extra:ON UPDATE CURRENT_TIMESTAMP\"","Comments":null},"AutoSet":true,"Indexes":null}],"Pk":"id","Indexes":[{"Unique":false,"Name":"name_phone_idx","Items":[{"Unique":false,"Name":"","Column":"phone","Order":1,"Sort":"asc"},{"Unique":false,"Name":"","Column":"name","Order":2,"Sort":"asc"}]},{"Unique":false,"Name":"age_idx","Items":[{"Unique":false,"Name":"","Column":"age","Order":1,"Sort":"asc"}]},{"Unique":true,"Name":"no_idx","Items":[{"Unique":false,"Name":"","Column":"no","Order":1,"Sort":"asc"}]}],"Meta":{"Name":"User","Fields":[{"Name":"ID","Type":"int","Tag":"dd:\"pk;auto\"","Comments":null},{"Name":"Name","Type":"string","Tag":"dd:\"index:name_phone_idx,2;default:'jack'\"","Comments":null},{"Name":"Phone","Type":"string","Tag":"dd:\"index:name_phone_idx,1;default:'13552053960';extra:comment '手机号'\"","Comments":null},{"Name":"Age","Type":"int","Tag":"dd:\"index\"","Comments":null},{"Name":"No","Type":"int","Tag":"dd:\"unique\"","Comments":null},{"Name":"School","Type":"string","Tag":"dd:\"null;default:'harvard';extra:comment '学校'\"","Comments":null},{"Name":"IsStudent","Type":"bool","Tag":"","Comments":null},{"Name":"DeleteAt","Type":"*time.Time","Tag":"","Comments":null},{"Name":"CreateAt","Type":"*time.Time","Tag":"dd:\"default:CURRENT_TIMESTAMP\"","Comments":null},{"Name":"UpdateAt","Type":"*time.Time","Tag":"dd:\"default:CURRENT_TIMESTAMP;extra:ON UPDATE CURRENT_TIMESTAMP\"","Comments":null}],"Comments":["dd:table"],"Methods":null}}`
var table Table
if err = json.Unmarshal([]byte(expectjson), &table); err != nil {
	panic(err)
}
if err := CreateTable(context.Background(), db, table); (err != nil) != false {
	panic(fmt.Sprintf("CreateTable() error = %v, wantErr %v", err, false))
}
Output:

CREATE TABLE `user_createtable` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT 'jack',
`phone` VARCHAR(255) NOT NULL DEFAULT '13552053960' comment '手机号',
`age` INT NOT NULL,
`no` INT NOT NULL,
`school` VARCHAR(255) NULL DEFAULT 'harvard' comment '学校',
`is_student` TINYINT NOT NULL,
`delete_at` DATETIME NULL,
`create_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`update_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `name_phone_idx` (`phone` asc,`name` asc),
INDEX `age_idx` (`age` asc),
UNIQUE INDEX `no_idx` (`no` asc))

func NewFieldFromColumn

func NewFieldFromColumn(col Column) astutils.FieldMeta

NewFieldFromColumn creates an astutils.FieldMeta instance from col

func Setup

func Setup() (func(), *sqlx.DB, error)

Types

type Column

type Column struct {
	Table         string
	Name          string
	Type          columnenum.ColumnType
	Default       string
	Pk            bool
	Nullable      bool
	Unsigned      bool
	Autoincrement bool
	Extra         extraenum.Extra
	Meta          astutils.FieldMeta
	AutoSet       bool
	Indexes       []IndexItem
	Fk            ForeignKey
}

Column define a column

func (*Column) AddColumnSql

func (c *Column) AddColumnSql() (string, error)

AddColumnSql return add column sql

func (*Column) ChangeColumnSql

func (c *Column) ChangeColumnSql() (string, error)

ChangeColumnSql return change column sql

type DbAction

type DbAction struct {
	TableName           string `db:"TABLE_NAME"`
	ConstraintName      string `db:"CONSTRAINT_NAME"`
	ReferencedTableName string `db:"REFERENCED_TABLE_NAME"`
	UpdateRule          string `db:"UPDATE_RULE"`
	DeleteRule          string `db:"DELETE_RULE"`
}

DbAction from information_schema.REFERENTIAL_CONSTRAINTS

type DbColumn

type DbColumn struct {
	Field   string        `db:"Field"`
	Type    string        `db:"Type"`
	Null    nullenum.Null `db:"Null"`
	Key     keyenum.Key   `db:"Key"`
	Default *string       `db:"Default"`
	Extra   string        `db:"Extra"`
	Comment string        `db:"Comment"`
}

DbColumn defines a column

type DbForeignKey

type DbForeignKey struct {
	TableName            string `db:"TABLE_NAME"`
	ColumnName           string `db:"COLUMN_NAME"`
	ConstraintName       string `db:"CONSTRAINT_NAME"`
	ReferencedTableName  string `db:"REFERENCED_TABLE_NAME"`
	ReferencedColumnName string `db:"REFERENCED_COLUMN_NAME"`
}

DbForeignKey from INFORMATION_SCHEMA.KEY_COLUMN_USAGE

type DbIndex

type DbIndex struct {
	Table      string `db:"Table"`        // The name of the table
	NonUnique  bool   `db:"Non_unique"`   // 1 if the index can contain duplicates, 0 if it cannot.
	KeyName    string `db:"Key_name"`     // The name of the index. The primary key index always has the name of PRIMARY.
	SeqInIndex int    `db:"Seq_in_index"` // The column sequence number in the index. The first column sequence number starts from 1.
	ColumnName string `db:"Column_name"`  // The column name
	Collation  string `db:"Collation"`    // Collation represents how the column is sorted in the index. A means ascending, B means descending, or NULL means not sorted.
}

DbIndex defines an index refer to https://www.mysqltutorial.org/mysql-index/mysql-show-indexes/

type ForeignKey

type ForeignKey struct {
	// Table the child table
	Table string
	// Constraint name of foreign key constraint
	Constraint string
	// Fk foreign key
	Fk string
	// ReferencedTable the referenced table
	ReferencedTable string
	// ReferencedCol the referenced column of ReferencedTable
	ReferencedCol string
	UpdateRule    string
	DeleteRule    string
	FullRule      string
}

func (*ForeignKey) AddFkSql

func (fk *ForeignKey) AddFkSql() (string, error)

func (*ForeignKey) DropFkSql

func (fk *ForeignKey) DropFkSql() (string, error)

type Index

type Index struct {
	Table  string
	Unique bool
	Name   string
	Items  []IndexItem
}

Index define an index

func NewIndexFromDbIndexes

func NewIndexFromDbIndexes(dbIndexes []DbIndex) Index

func (*Index) AddIndexSql

func (idx *Index) AddIndexSql() (string, error)

func (*Index) DropIndexSql

func (idx *Index) DropIndexSql() (string, error)

type IndexItem

type IndexItem struct {
	Unique bool
	Name   string
	Column string
	Order  int
	Sort   sortenum.Sort
}

IndexItem define an index item

type IndexItems

type IndexItems []IndexItem

IndexItems slice type alias for IndexItem

func (IndexItems) Len

func (it IndexItems) Len() int

Len return length of IndexItems

func (IndexItems) Less

func (it IndexItems) Less(i, j int) bool

Less define asc or desc order

func (IndexItems) Swap

func (it IndexItems) Swap(i, j int)

Swap change position of elements at i and j

type Table

type Table struct {
	Name    string
	Columns []Column
	Pk      string
	Indexes []Index
	Meta    astutils.StructMeta
	Fks     []ForeignKey
}

Table defines a table

func NewTableFromStruct

func NewTableFromStruct(structMeta astutils.StructMeta, prefix ...string) Table

NewTableFromStruct creates a Table instance from structMeta

Example
testDir := pathutils.Abs("../testdata/domain")
var files []string
var err error
err = filepath.Walk(testDir, astutils.Visit(&files))
if err != nil {
	panic(err)
}
sc := astutils.NewStructCollector(astutils.ExprString)
for _, file := range files {
	fset := token.NewFileSet()
	root, err := parser.ParseFile(fset, file, nil, parser.ParseComments)
	if err != nil {
		panic(err)
	}
	ast.Walk(sc, root)
}
flattened := ddlast.FlatEmbed(sc.Structs)

for _, sm := range flattened {
	tab := NewTableFromStruct(sm)
	fmt.Println(len(tab.Indexes))
	var statement string
	if statement, err = tab.CreateSql(); err != nil {
		panic(err)
	}
	fmt.Println(statement)
}
Output:

0
CREATE TABLE `order` (
`id` INT NOT NULL AUTO_INCREMENT,
`amount` BIGINT NOT NULL,
`user_id` int NOT NULL,
`create_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`delete_at` DATETIME NULL,
`update_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
CONSTRAINT `fk_ddl_user` FOREIGN KEY (`user_id`)
REFERENCES `ddl_user`(`id`)
ON DELETE CASCADE ON UPDATE NO ACTION)
5
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT 'jack',
`phone` VARCHAR(255) NOT NULL DEFAULT '13552053960' comment '手机号',
`age` INT NOT NULL,
`no` int NOT NULL,
`unique_col` int NOT NULL,
`unique_col_2` int NOT NULL,
`school` VARCHAR(255) NULL DEFAULT 'harvard' comment '学校',
`is_student` TINYINT NOT NULL,
`rule` varchar(255) NOT NULL comment '链接匹配规则,匹配的链接采用该css规则来爬',
`rule_type` varchar(45) NOT NULL comment '链接匹配规则类型,支持prefix前缀匹配和regex正则匹配',
`arrive_at` datetime NULL comment '到货时间',
`status` tinyint(4) NOT NULL comment '0进行中
1完结
2取消',
`create_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`delete_at` DATETIME NULL,
`update_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `age_idx` (`age` asc),
INDEX `name_phone_idx` (`phone` asc,`name` asc),
UNIQUE INDEX `no_idx` (`no` asc),
UNIQUE INDEX `rule_idx` (`rule` asc),
UNIQUE INDEX `unique_col_idx` (`unique_col` asc,`unique_col_2` asc))

func Struct2Table

func Struct2Table(ctx context.Context, dir, pre string, existTables []string, db *sqlx.DB, schema string) (tables []Table)
Example
terminator, db, err := Setup()
if err != nil {
	panic(err)
}
defer terminator()
defer db.Close()

_ = Struct2Table(context.Background(), "../testdata/domain", "ddl_", []string{"ddl_user", "ddl_book"}, db, "test")
Output:

CREATE TABLE `ddl_order` (
`id` INT NOT NULL AUTO_INCREMENT,
`amount` BIGINT NOT NULL,
`user_id` int NOT NULL,
`create_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
`delete_at` DATETIME NULL,
`update_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
CONSTRAINT `fk_ddl_user` FOREIGN KEY (`user_id`)
REFERENCES `ddl_user`(`id`)
ON DELETE CASCADE ON UPDATE NO ACTION)
ALTER TABLE `ddl_user`
CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT;
ALTER TABLE `ddl_user`
CHANGE COLUMN `name` `name` VARCHAR(255) NOT NULL DEFAULT 'jack';
ALTER TABLE `ddl_user`
CHANGE COLUMN `phone` `phone` VARCHAR(255) NOT NULL DEFAULT '13552053960' comment '手机号';
ALTER TABLE `ddl_user`
CHANGE COLUMN `age` `age` INT NOT NULL;
ALTER TABLE `ddl_user`
CHANGE COLUMN `no` `no` int NOT NULL;
ALTER TABLE `ddl_user`
ADD COLUMN `unique_col` int NOT NULL;
ALTER TABLE `ddl_user`
ADD COLUMN `unique_col_2` int NOT NULL;
ALTER TABLE `ddl_user`
CHANGE COLUMN `school` `school` VARCHAR(255) NULL DEFAULT 'harvard' comment '学校';
ALTER TABLE `ddl_user`
CHANGE COLUMN `is_student` `is_student` TINYINT NOT NULL;
ALTER TABLE `ddl_user`
ADD COLUMN `rule` varchar(255) NOT NULL comment '链接匹配规则,匹配的链接采用该css规则来爬';
ALTER TABLE `ddl_user`
ADD COLUMN `rule_type` varchar(45) NOT NULL comment '链接匹配规则类型,支持prefix前缀匹配和regex正则匹配';
ALTER TABLE `ddl_user`
ADD COLUMN `arrive_at` datetime NULL comment '到货时间';
ALTER TABLE `ddl_user`
ADD COLUMN `status` tinyint(4) NOT NULL comment '0进行中
1完结
2取消';
ALTER TABLE `ddl_user`
CHANGE COLUMN `create_at` `create_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE `ddl_user`
CHANGE COLUMN `delete_at` `delete_at` DATETIME NULL;
ALTER TABLE `ddl_user`
CHANGE COLUMN `update_at` `update_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
ALTER TABLE `ddl_user` ADD UNIQUE INDEX `rule_idx` (`rule` asc);
ALTER TABLE `ddl_user` ADD UNIQUE INDEX `unique_col_idx` (`unique_col` asc,`unique_col_2` asc);

func Table2struct

func Table2struct(ctx context.Context, pre, schema string, existTables []string, db *sqlx.DB) (tables []Table)

func (*Table) CreateSql

func (t *Table) CreateSql() (string, error)

CreateSql return create table sql

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL