diff --git a/_examples/config/console.yaml b/_examples/config/console.yaml deleted file mode 100644 index 7b1c14ffd866d8b665d9452b187b1138998df3f9..0000000000000000000000000000000000000000 --- a/_examples/config/console.yaml +++ /dev/null @@ -1,4 +0,0 @@ -commands: - gen:model: - options: - base-dir: "./" diff --git a/_examples/simple/app/models/registry.go b/_examples/simple/app/models/registry.go deleted file mode 100755 index 85e630637ec91f87cd8b8593dd3d604168c103f7..0000000000000000000000000000000000000000 --- a/_examples/simple/app/models/registry.go +++ /dev/null @@ -1,86 +0,0 @@ -// Do not edit this file. -// It's generated by console command at 2024-08-09T17:02:32+08:00. You can -// enter follow script on terminal like follow: -// -// cd /data/sketch -// gen:model --override --base-dir="./" --export="registry" - -package models - -import ( - "gitee.com/go-libs/db-xorm/db" -) - -// Registry -// is a model for table. -// -// Collation : utf8_general_ci -// Engine : InnoDB -// Format : Dynamic -// Table : registry -type Registry struct { - // Field count : 7 - - // Id - // PK. - // - // Extra : auto_increment - // Null : NO - // Type : int(10) unsigned - Id int `xorm:"id pk autoincr" json:"id"` - - // Status - // 状态位(0:停用,1:启用). - // - // Default : 0 - // Null : NO - // Type : tinyint(3) unsigned - Status int `xorm:"status" json:"status"` - - // TopicId - // 主题ID. - // - // Default : 0 - // Null : NO - // Type : int(10) unsigned - TopicId int `xorm:"topic_id" json:"topic_id"` - - // TopicTag - // 标签名. - // - // Collation : utf8_general_ci - // Null : NO - // Type : varchar(64) - TopicTag string `xorm:"topic_tag" json:"topic_tag"` - - // Title - // 标题. - // - // Collation : utf8_general_ci - // Null : YES - // Type : varchar(80) - Title string `xorm:"title" json:"title"` - - // CreatedAt - // 创建时间. - // - // Default : current_timestamp - // Null : NO - // Type : datetime - CreatedAt db.Datetime `xorm:"created_at" json:"created_at"` - - // UpdatedAt - // 最后更新时间. - // - // Default : current_timestamp - // Extra : on update current_timestamp - // Null : NO - // Type : datetime - UpdatedAt db.Datetime `xorm:"updated_at" json:"updated_at"` -} - -// TableName -// returns a table name. It's an optional function. -func (o *Registry) TableName() string { - return "registry" -} diff --git a/_examples/simple/app/services/registry_service.go b/_examples/simple/app/services/registry_service.go deleted file mode 100755 index 446ea3bf770177afda2b5c3dac10322f598f40cc..0000000000000000000000000000000000000000 --- a/_examples/simple/app/services/registry_service.go +++ /dev/null @@ -1,111 +0,0 @@ -// Do not edit this file. -// It's generated by console command at 2024-08-09T17:02:33+08:00. You can -// enter follow script on terminal like follow: -// -// cd /data/sketch -// gen:service --override --export="registry" - -package services - -import ( - "context" - "gitee.com/go-libs/db-xorm/_examples/simple/app/models" - "gitee.com/go-libs/db-xorm/db" -) - -// RegistryService -// is a service used to operate data for model. -type RegistryService struct{ - db.Service -} - -// NewRegistryService -// creates a model operate service. -// -// gen:service --override --export="registry" -func NewRegistryService(sess ... *db.Session) *RegistryService{ - o := &RegistryService{} - o.With(sess...) - return o -} - -// Add -// adds a new record with given param. -func (o *RegistryService) Add(ctx context.Context, req *models.Registry) (model *models.Registry, err error) { - var ( - affects int64 - sess *db.Session - ) - - // Open - // a connect session from master server. - if sess, err = o.Master(ctx); err != nil { - return - } - - // Prepare - // model fields for insert without primary key. Datetime use builtin - // methods. - model = &models.Registry{ - Status: req.Status, - TopicId: req.TopicId, - TopicTag: req.TopicTag, - Title: req.Title, - CreatedAt: db.NewDatetime(), - UpdatedAt: db.NewDatetime(), - } - - // Send data - // to master session and parse result. - if affects, err = sess.Insert(model); err != nil || affects == 0 { - model = nil - } - return -} - -// DelById -// method is generated by console command. It's deletes a record by primary key. -func (o *RegistryService) DelById(ctx context.Context, val int) (affects int64, err error) { - var ( - sess *db.Session - model = &models.Registry{} - ) - - // Open - // a connect session from master server. - if sess, err = o.Master(ctx); err != nil { - return - } - - // Send data - // to master session and return affect count. - affects, err = sess.Where("`id` = ?", val).Delete(model) - return -} - -// GetById -// method is generated by console command. It's return a model struct -// if exists otherwise nil returned. -func (o *RegistryService) GetById(ctx context.Context, val int) (model *models.Registry, err error){ - var ( - has bool - sess *db.Session - ) - - // Open - // a connect session from slave server. - if sess, err = o.Slave(ctx); err != nil { - return - } - - // Prepare - // an empty result model. - model = &models.Registry{} - - // Send data - // to slave session and get one result. - if has, err = sess.Where("`id` = ?", val).Get(model); err != nil || !has { - model = nil - } - return -} diff --git a/_examples/simple/config/console.yaml b/_examples/simple/config/console.yaml new file mode 100644 index 0000000000000000000000000000000000000000..995485294cc794fa239926e0c45130c5a7f6070e --- /dev/null +++ b/_examples/simple/config/console.yaml @@ -0,0 +1,15 @@ +commands: + gen:model: + options: + base-dir: "./" + target-path: app/models + fields: + example.status: + pkg: sketch/app + type: app.Status + types: + gen:service: + options: + base-dir: "./" + model-path: app/models + target-path: app/services diff --git a/_examples/config/db.yaml b/_examples/simple/config/db.yaml similarity index 61% rename from _examples/config/db.yaml rename to _examples/simple/config/db.yaml index f44dbb4a7733792160e997d4adc79bf79cf5ba4e..a022ee38e0d5d4b6a0fab6a432354004a36d88f2 100644 --- a/_examples/config/db.yaml +++ b/_examples/simple/config/db.yaml @@ -1,8 +1,5 @@ # Database configurations databases: db: - enable-logger: true - enable-session: true - driver: mysql dsn: - - root:PassWord@123#MySQL@tcp(127.0.0.1:3306)/test?charset=utf8 \ No newline at end of file + - root:PassWord@123#MySQL@tcp(127.0.0.1:3306)/test?charset=utf8 diff --git a/_examples/config/log.yaml b/_examples/simple/config/log.yaml similarity index 100% rename from _examples/config/log.yaml rename to _examples/simple/config/log.yaml diff --git a/_examples/simple/main.go b/_examples/simple/main.go index b1d2ae24e07280d754aa07943d6e4fb7cd081462..dbb3308316e5742191a35a608ada75cf0408096f 100644 --- a/_examples/simple/main.go +++ b/_examples/simple/main.go @@ -17,8 +17,8 @@ package main import ( "gitee.com/go-libs/console" - "gitee.com/go-libs/db-xorm/db/commands/model" - "gitee.com/go-libs/db-xorm/db/commands/service" + "gitee.com/go-libs/db-xorm/db/commands/gen_model" + "gitee.com/go-libs/db-xorm/db/commands/gen_service" "gitee.com/go-wares/log" ) @@ -26,7 +26,6 @@ func main() { defer log.Close() c := console.NewContainer() - c.Add(model.New(), service.New()) - // c.Add(db.NewGenModelCommand()) + c.Add(gen_model.New(), gen_service.New()) c.Run() } diff --git a/_examples/tem.sh b/_examples/tem.sh deleted file mode 100644 index b8c74ffb395943602791a4fa7345794d806f6814..0000000000000000000000000000000000000000 --- a/_examples/tem.sh +++ /dev/null @@ -1,12 +0,0 @@ -echo 'deb https://mirrors.aliyun.com/debian/ bullseye main non-free contrib' > /etc/apt/sources.list -echo 'deb-src https://mirrors.aliyun.com/debian/ bullseye main non-free contrib' >> /etc/apt/sources.list -echo 'deb https://mirrors.aliyun.com/debian-security/ bullseye-security main' >> /etc/apt/sources.list -echo 'deb-src https://mirrors.aliyun.com/debian-security/ bullseye-security main' >> /etc/apt/sources.list -echo 'deb https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list -echo 'deb-src https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib' >> /etc/apt/sources.list -echo 'deb https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib' >> /etc/apt/sources.list -echo 'deb-src https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib' >> /etc/apt/sources.list - - - -apt install vim \ No newline at end of file diff --git a/db/commands/base/constants.go b/db/commands/base/constants.go new file mode 100644 index 0000000000000000000000000000000000000000..7d4b01a2f821e2f99432ec48e7c75f9488a9234a --- /dev/null +++ b/db/commands/base/constants.go @@ -0,0 +1,51 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-16 + +package base + +const ( + CommandNameModel = "gen:model" + CommandNameService = "gen:service" +) + +const ( + OptBaseDir = "base-dir" + OptBaseDirDefault = "./" + OptBaseDirDesc = "Application working directory" + OptBaseDirShort = 'b' + + OptDsn = "dsn" + OptDsnDesc = "Database source name for connection, e.g. root:pass@tcp(127.0.0.1:3306)/test" + + OptExport = "export" + OptExportDesc = "Specify export names, split with comma" + OptExportShort = 'e' + + OptModelPath = "model-path" + OptModelPathDefault = "app/models" + OptModelPathDesc = "Generated model files location" + OptModelPathShort = 'm' + + OptOverride = "override" + OptOverrideDesc = "Override existing files" + + OptPrefix = "prefix" + OptPrefixDesc = "Prefix name for table" + OptPrefixShort = 'p' + + OptTargetPath = "target-path" + OptTargetPathDesc = "Generated files saved to" + OptTargetPathShort = 't' +) diff --git a/db/commands/generator_model.go b/db/commands/base/convertor.go similarity index 40% rename from db/commands/generator_model.go rename to db/commands/base/convertor.go index 3d1208d234541e7f311bd456a853703d2da96981..83cf8cf122c79c88153215da9fa76a9c52048647 100644 --- a/db/commands/generator_model.go +++ b/db/commands/base/convertor.go @@ -11,41 +11,13 @@ // limitations under the License. // // Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-12 +// Date: 2024-08-16 -package commands +package base -// +---------------------------------------------------------------------------+ -// | Model generator result | -// +---------------------------------------------------------------------------+ - -// GeneratorModel -// is a component for generate model. -type GeneratorModel struct { - GeneratorCommon -} - -// Init -// model fields. -func (o *GeneratorModel) init(g *Generator) *GeneratorModel { - // Init - // common fields. - o.GeneratorCommon.init(g) - - // Init - // field type packages. - for _, x := range o.Table.Columns { - if x.ExportPkg != "" { - o.AddPackage(x.ExportPkg) - } - } - - // Init - // export fields. - o.StructName = g.Table.Name.StructName(g.Common.Prefix) - - // Resort - // with alphabet. - o.SortPackage() - return o +// Convertor +// is a component used to defined exported type for model generator. +type Convertor struct { + Pkg string `yaml:"pkg"` + Type string `yaml:"type"` } diff --git a/db/commands/base/table.go b/db/commands/base/table.go new file mode 100644 index 0000000000000000000000000000000000000000..ffb09f156f2cdc61a8075ded7d8fda533e3ec923 --- /dev/null +++ b/db/commands/base/table.go @@ -0,0 +1,69 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-02 + +package base + +import ( + "html/template" + "sort" +) + +// Table +// is a component for table definition (DDL). +type Table struct { + // Normal fields. + Engine string `xorm:"Engine"` + Format string `xorm:"Row_format"` + Name ItemName `xorm:"Name"` + Comment ItemComment `xorm:"Comment"` + Collation ItemCollation `xorm:"Collation"` + + // Belongs to. + Columns []*Column `xorm:"-"` + PackageList []string + PackageMapper map[string]bool + + // Info fields. + CommentList []template.HTML `xorm:"-"` + Datetime template.HTML `xorm:"-"` + Script template.HTML `xorm:"-"` + + // Execution fields. + ModelName string `xorm:"-"` + ModelPkg string `xorm:"-"` + ServiceName string `xorm:"-"` + ServicePkg string `xorm:"-"` + + // Primary prop. + PrimaryName string `xorm:"-"` + PrimaryFieldName string `xorm:"-"` + PrimaryType string `xorm:"-"` +} + +func (o *Table) Add(pkg string) { + if o.PackageList == nil || o.PackageMapper == nil { + o.PackageList = make([]string, 0) + o.PackageMapper = make(map[string]bool) + } + + if _, ok := o.PackageMapper[pkg]; ok { + return + } + + o.PackageList = append(o.PackageList, pkg) + o.PackageMapper[pkg] = true + + sort.Strings(o.PackageList) +} diff --git a/db/commands/column.go b/db/commands/base/table_column.go similarity index 33% rename from db/commands/column.go rename to db/commands/base/table_column.go index 7c24b205d70fcb5a6922de17f17fc49e4a3689a5..9c8ab1a470c9e1c96cfcfb3c19495c7c92d6d49c 100644 --- a/db/commands/column.go +++ b/db/commands/base/table_column.go @@ -13,45 +13,41 @@ // Author: wsfuyibing <682805@qq.com> // Date: 2024-08-02 -package commands +package base -import "gitee.com/go-libs/console" +import ( + "html/template" +) // Column // is a component for table definition (DDL). type Column struct { - Field ItemName `xorm:"Field"` - Collation ItemCollation `xorm:"Collation"` - Comment ItemComment `xorm:"Comment"` - Type ColumnType `xorm:"Type"` - Default ColumnDefault `xorm:"Default"` - Key ColumnKey `xorm:"Key"` - Null ColumnNull `xorm:"Null"` - Extra ColumnExtra `xorm:"Extra"` - - ExportName string `xorm:"-"` // for field name. e.g. Id, UserId etc - ExportType string `xorm:"-"` // for field type. e.g. int, db.Date, db.Datetime etc - - ExportJson string `xorm:"-"` // for field tag. e.g. id, user_id etc - ExportOrm string `xorm:"-"` // for field tag. e.g. id pk autoincr, user_id etc - ExportPkg string `xorm:"-"` // for field tag. e.g. models, services etc - - IsDate bool `xorm:"-"` - IsDatetime bool `xorm:"-"` - IsDatetimeOnUpdate bool `xorm:"-"` - IsPrimaryKey bool `xorm:"-"` -} - -// Parse -// parses the result field to usage fields. -func (o *Column) Parse(command *console.Command) { - o.ExportName = o.Field.ToSame() - o.ExportPkg, o.ExportType = o.Type.Convert(command) - o.ExportOrm = o.Extra.Convert(o.Field.String()) - o.ExportJson = o.Field.ToSnake() - - o.IsDate = o.Type.IsDate() - o.IsDatetime = o.Type.IsDatetime() - o.IsDatetimeOnUpdate = o.Extra.IsDatetimeOnUpdate() - o.IsPrimaryKey = o.Key.IsPrimary() + Field ItemName `xorm:"Field"` + Collation ItemCollation `xorm:"Collation"` + Comment ItemComment `xorm:"Comment"` + Type ColumnType `xorm:"Type"` + Default ColumnDefault `xorm:"Default"` + Key ColumnKey `xorm:"Key"` + Null ColumnNull `xorm:"Null"` + Extra ColumnExtra `xorm:"Extra"` + + // Related on table. + Table *Table `xorm:"-"` + + // Info fields. + CommentList []template.HTML `xorm:"-"` + Datetime template.HTML `xorm:"-"` + Script template.HTML `xorm:"-"` + + // Name and type fields. + ExportName string `xorm:"-"` // for field name. e.g. Id, UserId etc + ExportType string `xorm:"-"` // for field type. e.g. int, db.Date, db.Datetime etc + ExportJson string `xorm:"-"` // for field tag. e.g. id, user_id etc + ExportOrm string `xorm:"-"` // for field tag. e.g. id pk autoincr, user_id etc + ExportPkg string `xorm:"-"` // for field tag. e.g. models, services etc + + IsDate bool `xorm:"-"` + IsDatetime bool `xorm:"-"` + IsDatetimeOnUpdate bool `xorm:"-"` + IsPrimaryKey bool `xorm:"-"` } diff --git a/db/commands/types.go b/db/commands/base/table_type.go similarity index 44% rename from db/commands/types.go rename to db/commands/base/table_type.go index 52340850acc9792bc2d1ba2fe1ad9cea342f6aef..a391c5ef80105dac8196f93b79763cb07dd2ef10 100644 --- a/db/commands/types.go +++ b/db/commands/base/table_type.go @@ -13,72 +13,31 @@ // Author: wsfuyibing <682805@qq.com> // Date: 2024-08-02 -package commands +package base import ( - "fmt" - "gitee.com/go-libs/console" - "regexp" - "strings" + "fmt" + "regexp" + "strings" ) var ( - RegexStartLetter = regexp.MustCompile(`^(\S)`) - RegexStartWithUnderline = regexp.MustCompile(`^_+`) - RegexMiddleWithUnderline = regexp.MustCompile(`_+(\S)`) - RegexMatchUpperLetter = regexp.MustCompile(`([A-Z])`) - RegexMatchManyUnderlines = regexp.MustCompile(`_+`) - - RegexMatchColumnExtraAutoIncrement = regexp.MustCompile(`auto_increment`) - RegexMatchColumnType = regexp.MustCompile(`^([_a-zA-Z0-9]+)`) + RegexStartLetter = regexp.MustCompile(`^(\S)`) + RegexStartWithUnderline = regexp.MustCompile(`^_+`) + RegexMiddleWithUnderline = regexp.MustCompile(`_+(\S)`) + RegexMatchUpperLetter = regexp.MustCompile(`([A-Z])`) + RegexMatchManyUnderlines = regexp.MustCompile(`_+`) + + RegexMatchColumnExtraAutoIncrement = regexp.MustCompile(`auto_increment`) + RegexMatchColumnType = regexp.MustCompile(`^([_a-zA-Z0-9]+)`) ) -var ( - convertPackage = map[string]string{ - "date": "gitee.com/go-libs/db-xorm/db", - "datetime": "gitee.com/go-libs/db-xorm/db", - } - - // Builtin - // type mapping for database. - // - // Translate database type to golang type. - convertTypes = map[string]string{ - "tinyint": "int", - "smallint": "int", - "mediumint": "int", - "int": "int", - "integer": "int", - - "bigint": "int64", - - "decimal": "float64", - "double": "float64", - "float": "float64", - - "date": "db.Date", - "datetime": "db.Datetime", - - "blob": "[]byte", - - "char": "string", - "varchar": "string", - "text": "string", - "longtext": "string", - "enum": "string", - } -) - -// +---------------------------------------------------------------------------+ -// | Type for default value of column | -// +---------------------------------------------------------------------------+ - // ColumnDefault // is a type for field name of a table. type ColumnDefault string func (o ColumnDefault) String() string { - return strings.TrimSpace(strings.ToLower(string(o))) + return strings.TrimSpace(strings.ToLower(string(o))) } // +---------------------------------------------------------------------------+ @@ -92,21 +51,21 @@ type ColumnExtra string // Convert // field name to exported orm name. // -// .Convert("id") // return "id pk autoincr" -// .Convert("user_id") // return "user_id" -func (o ColumnExtra) Convert(name string) string { - if RegexMatchColumnExtraAutoIncrement.MatchString(o.String()) { - return fmt.Sprintf(`%s pk autoincr`, name) - } - return name +// .Convert("id") // return "id pk autoincr" +// .Convert("user_id") // return "user_id" +func (o ColumnExtra) Convert(field ItemName) string { + if RegexMatchColumnExtraAutoIncrement.MatchString(o.String()) { + return fmt.Sprintf(`%s pk autoincr`, field.String()) + } + return field.String() } func (o ColumnExtra) IsDatetimeOnUpdate() bool { - return o.String() == "on update current_timestamp" + return o.String() == "on update current_timestamp" } func (o ColumnExtra) String() string { - return strings.TrimSpace(strings.ToLower(string(o))) + return strings.TrimSpace(strings.ToLower(string(o))) } // +---------------------------------------------------------------------------+ @@ -118,11 +77,11 @@ func (o ColumnExtra) String() string { type ColumnKey string func (o ColumnKey) IsPrimary() bool { - return strings.ToUpper(o.String()) == "PRI" + return strings.ToUpper(o.String()) == "PRI" } func (o ColumnKey) String() string { - return string(o) + return string(o) } // +---------------------------------------------------------------------------+ @@ -141,55 +100,30 @@ type ColumnNull string // is a type for field name of a table. type ColumnType string -func (o ColumnType) Convert(command *console.Command) (pkg, name string) { - var ( - k, s string - m []string - ok bool - ) - - // Unknown type. - if m = RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { - k = strings.ToLower(m[1]) - - // Use - // configuration of console.yaml. - if pkg, name, ok = NewMapping().Get(command.GetName(), k); ok { - return - } - - // Use builtin. - if name, ok = convertTypes[k]; ok { - if s, ok = convertPackage[k]; ok { - pkg = s - } - return - } - } - - // Any - // type. - name = "any" - return -} - func (o ColumnType) IsDate() bool { - if m := RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { - return strings.ToLower(m[1]) == "date" - } - return false + if m := RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { + return strings.ToLower(m[1]) == "date" + } + return false } func (o ColumnType) IsDatetime() bool { - if m := RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { - s := strings.ToLower(m[1]) - return s == "datetime" || s == "timestamp" - } - return false + if m := RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { + s := strings.ToLower(m[1]) + return s == "datetime" || s == "timestamp" + } + return false +} + +func (o ColumnType) Origin() string { + if m := RegexMatchColumnType.FindStringSubmatch(o.String()); len(m) > 0 { + return m[1] + } + return "" } func (o ColumnType) String() string { - return string(o) + return string(o) } // +---------------------------------------------------------------------------+ @@ -211,7 +145,13 @@ type ItemComment string // String // returns a comment string without new line. func (o ItemComment) String() string { - return strings.ReplaceAll(string(o), "\n", "") + return strings.TrimSpace(string(o)) +} + +// Strings +// returns a comment string list with new line. +func (o ItemComment) Strings() []string { + return strings.Split(o.String(), "\n") } // +---------------------------------------------------------------------------+ @@ -226,21 +166,23 @@ type ItemName string // return true if start with an a-z letter. // // Output: -// return true // user -// return false // _user +// +// return true // user +// return false // _user func (o ItemName) Allow() bool { - return regexp.MustCompile(`^[a-zA-Z][_a-zA-Z0-9]*$`).MatchString(o.String()) + return regexp.MustCompile(`^[a-zA-Z][_a-zA-Z0-9]*$`).MatchString(o.String()) } // String // returns the origin name with any formats. // // Output: -// return "user_info" -// return "UserInfo" -// return "userInfo" +// +// return "user_info" +// return "UserInfo" +// return "userInfo" func (o ItemName) String() string { - return string(o) + return string(o) } // FileName @@ -252,35 +194,36 @@ func (o ItemName) String() string { // - file name : `user_info` // // Output: -// return "user_info" +// +// return "user_info" func (o ItemName) FileName(prefix string) (name string) { - // Use - // origin name as default. - name = o.String() - - // Remove - // prefix name. - // - // Convert `cdb_user_info` as `user_info` with a prefix `cdb_`. - if prefix != "" { - name = strings.TrimPrefix(name, prefix) - } - - // Convert - // upper-case letter as underline with a lower-case letter. - // - // Convert `UserInfo` as `_user_info` - name = RegexMatchUpperLetter.ReplaceAllStringFunc(name, func(s string) string { - return fmt.Sprintf(`_%s`, strings.ToLower(s)) - }) - - // Remove - // starts with underline. - // - // Convert `_user_info` as `user_info`. - name = RegexStartWithUnderline.ReplaceAllString(name, "") - name = RegexMatchManyUnderlines.ReplaceAllString(name, "_") - return + // Use + // origin name as default. + name = o.String() + + // Remove + // prefix name. + // + // Convert `cdb_user_info` as `user_info` with a prefix `cdb_`. + if prefix != "" { + name = strings.TrimPrefix(name, prefix) + } + + // Convert + // upper-case letter as underline with a lower-case letter. + // + // Convert `UserInfo` as `_user_info` + name = RegexMatchUpperLetter.ReplaceAllStringFunc(name, func(s string) string { + return fmt.Sprintf(`_%s`, strings.ToLower(s)) + }) + + // Remove + // starts with underline. + // + // Convert `_user_info` as `user_info`. + name = RegexStartWithUnderline.ReplaceAllString(name, "") + name = RegexMatchManyUnderlines.ReplaceAllString(name, "_") + return } // StructName @@ -292,69 +235,72 @@ func (o ItemName) FileName(prefix string) (name string) { // - struct name : `UserInfo` // // Output: -// return "UserInfo" +// +// return "UserInfo" func (o ItemName) StructName(prefix string) (name string) { - // Use - // origin name as default. - name = o.String() - - // Remove - // prefix name. - // - // Example : cdb_user - // Prefix : cdb_ - // Replaced : user - if prefix != "" { - name = strings.TrimPrefix(name, prefix) - } - - // Remove - // underline start of name. - name = RegexStartWithUnderline.ReplaceAllString(name, "") - - // Convert - // underline with any letter as upper-case letter. - - name = RegexMiddleWithUnderline.ReplaceAllStringFunc(name, func(s string) string { - if m := RegexMiddleWithUnderline.FindStringSubmatch(s); len(m) > 0 { - return strings.ToUpper(m[1]) - } - return s - }) - - // Convert - // first letter as upper-case letter. - name = RegexStartLetter.ReplaceAllStringFunc(name, func(s string) string { - return strings.ToUpper(s) - }) - return + // Use + // origin name as default. + name = o.String() + + // Remove + // prefix name. + // + // Example : cdb_user + // Prefix : cdb_ + // Replaced : user + if prefix != "" { + name = strings.TrimPrefix(name, prefix) + } + + // Remove + // underline start of name. + name = RegexStartWithUnderline.ReplaceAllString(name, "") + + // Convert + // underline with any letter as upper-case letter. + name = RegexMiddleWithUnderline.ReplaceAllStringFunc(name, func(s string) string { + if m := RegexMiddleWithUnderline.FindStringSubmatch(s); len(m) > 0 { + return strings.ToUpper(m[1]) + } + return s + }) + + // Convert + // first letter as upper-case letter. + name = RegexStartLetter.ReplaceAllStringFunc(name, func(s string) string { + return strings.ToUpper(s) + }) + return } -// ToCamel -// returns a small-camel format name. +// ToLargeCamel +// returns a large camel that equals to struct name. // // Output: -// return "userInfo" -func (o ItemName) ToCamel() string { - return RegexStartLetter.ReplaceAllStringFunc(o.StructName(""), func(s string) string { - return strings.ToLower(s) - }) +// +// return "UserInfo" +func (o ItemName) ToLargeCamel() string { + return o.StructName("") } -// ToSame -// returns a name equal to struct name. +// ToSmallCamel +// returns a small-camel format name. // // Output: -// return "UserInfo" -func (o ItemName) ToSame() string { - return o.StructName("") +// +// return "userInfo" +func (o ItemName) ToSmallCamel() string { + return RegexStartLetter.ReplaceAllStringFunc(o.StructName(""), func(s string) string { + return strings.ToLower(s) + }) } // ToSnake // returns a snake format name. // // Output: -// return "user_info" +// +// return "user_info" func (o ItemName) ToSnake() string { - return o.FileName("") + return o.FileName("") } diff --git a/db/commands/target.go b/db/commands/base/target.go similarity index 94% rename from db/commands/target.go rename to db/commands/base/target.go index cb7320d77bf611798af60db72b71e4dbdc0430d5..52dbfca26885211e657ba159efb8a5d44004d994 100644 --- a/db/commands/target.go +++ b/db/commands/base/target.go @@ -13,7 +13,7 @@ // Author: wsfuyibing <682805@qq.com> // Date: 2024-08-07 -package commands +package base import ( "context" @@ -77,7 +77,7 @@ func (o Target) Save(_ context.Context, text string, result any) (err error) { if path := regexp.MustCompile(`/([^/]+)$`).ReplaceAllString(target, ""); path != target { if info, err = os.Stat(path); err != nil { if errors.Is(err, os.ErrNotExist) { - err = nil + err = os.MkdirAll(path, os.ModePerm) } else { return } @@ -89,7 +89,7 @@ func (o Target) Save(_ context.Context, text string, result any) (err error) { // Open // a file, Create new file if not exists. - if file, err = os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm); err != nil { + if file, err = os.OpenFile(target, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm); err != nil { return } diff --git a/db/commands/common.go b/db/commands/common.go index ec563ebfe4dd77f4502ef0e407948c6c871a4be4..4cc6e289dbc671eb23bb1f985829ef8a250715fd 100644 --- a/db/commands/common.go +++ b/db/commands/common.go @@ -21,19 +21,18 @@ import ( "fmt" "gitee.com/go-libs/console" "gitee.com/go-libs/db-xorm/db" + "gitee.com/go-libs/db-xorm/db/commands/base" + "gitee.com/go-libs/db-xorm/db/commands/conf" "html/template" "path/filepath" "regexp" "strings" + "time" ) -const ( - DsnKey = "_gen:commands_" -) +const DsnKey = "_gen:commands_" -var ( - RegexMatchPkg = regexp.MustCompile(`([_a-zA-Z0-9]+)$`) -) +var RegexMatchPkg = regexp.MustCompile(`([_a-zA-Z0-9]+)$`) type Common struct { BaseDir string @@ -52,27 +51,24 @@ func (o *Common) BuildModule(command *console.Command) (err error) { err = fmt.Errorf(`can not parse module name from go.mod`) return } - if o.ModuleFolder != "" { - o.ModuleFolder = fmt.Sprintf(`/%s`, - strings.TrimPrefix(o.ModuleFolder, "/"), - ) + o.ModuleFolder = fmt.Sprintf(`/%s`, strings.TrimPrefix(o.ModuleFolder, "/")) } return } // BuildScript // build command runner script. -func (o *Common) BuildScript(command *console.Command) template.HTML { - return template.HTML(fmt.Sprintf(`go run main.go %s`, command.ToScript())) +func (o *Common) BuildScript(command *console.Command) string { + return fmt.Sprintf(`go run main.go %s`, command.ToScript()) } // ListTable // returns a list for tables in a database. -func (o *Common) ListTable(ctx context.Context, command *console.Command) (tables []*Table, err error) { +func (o *Common) ListTable(ctx context.Context, command *console.Command) (tables []*base.Table, err error) { var ( all bool - list []*Table + list []*base.Table names = make(map[string]string) named = make(map[string]bool) session *db.Session @@ -98,7 +94,7 @@ func (o *Common) ListTable(ctx context.Context, command *console.Command) (table // Prepare // table list. - tables = make([]*Table, 0) + tables = make([]*base.Table, 0) // Select // all tables in database and columns of the table. @@ -126,9 +122,22 @@ func (o *Common) ListTable(ctx context.Context, command *console.Command) (table break } - // Init fields. - for _, x := range table.Columns { - x.Parse(command) + // Format + // table fields. + o.FormatTable(command, table) + for _, column := range table.Columns { + o.FormatColumn(command, table, column) + + // Bind primary on table. + if column.IsPrimaryKey { + if convertor := conf.Model.Get(fmt.Sprintf(`%s.%s`, table.Name, column.Field), column.Type.Origin()); convertor != nil { + table.PrimaryName = column.Field.ToLargeCamel() + table.PrimaryFieldName = column.Field.String() + table.PrimaryType = convertor.Type + } else { + column.IsPrimaryKey = false + } + } } // Append @@ -140,7 +149,7 @@ func (o *Common) ListTable(ctx context.Context, command *console.Command) (table // Exported // name in command argument not found. - for k, _ := range names { + for k := range names { if _, ok := named[k]; !ok { err = fmt.Errorf(`table not found: %s`, k) return @@ -154,6 +163,8 @@ func (o *Common) ListTable(ctx context.Context, command *console.Command) (table return } +// ReadBaseDir +// read absolute path of the application. func (o *Common) ReadBaseDir(command *console.Command, key, value string) (err error) { // Read // from command options. @@ -176,6 +187,8 @@ func (o *Common) ReadBaseDir(command *console.Command, key, value string) (err e return } +// ReadDsn +// read database source name. func (o *Common) ReadDsn(command *console.Command, key string) (err error) { // Read dsn // from command options. @@ -193,10 +206,13 @@ func (o *Common) ReadDsn(command *console.Command, key string) (err error) { return } + // Error read. err = fmt.Errorf(`dsn can not be blank`) return } +// ReadExport +// read export names. func (o *Common) ReadExport(command *console.Command, key string) (err error) { if opt, has := command.GetOption(key); has { if s := opt.ToString(); s != "" { @@ -206,6 +222,8 @@ func (o *Common) ReadExport(command *console.Command, key string) (err error) { return } +// ReadModelPath +// read path for model files location. func (o *Common) ReadModelPath(command *console.Command, key, value string) (err error) { // Read // from command options. @@ -226,15 +244,19 @@ func (o *Common) ReadModelPath(command *console.Command, key, value string) (err // to absolute path. o.ModelPath = value + // Read package name for model. if m := RegexMatchPkg.FindStringSubmatch(value); len(m) > 0 { o.ModelPkg = m[1] return } + // Error read. err = fmt.Errorf(`can not parse package name for target`) return } +// ReadOverride +// read override state for existing files. func (o *Common) ReadOverride(command *console.Command, key string) (err error) { if opt, has := command.GetOption(key); has { o.Override = opt.GetSpecified() @@ -242,6 +264,8 @@ func (o *Common) ReadOverride(command *console.Command, key string) (err error) return } +// ReadPrefix +// read prefix for table name. func (o *Common) ReadPrefix(command *console.Command, key string) (err error) { if opt, has := command.GetOption(key); has { if s := opt.ToString(); s != "" { @@ -251,6 +275,8 @@ func (o *Common) ReadPrefix(command *console.Command, key string) (err error) { return } +// ReadTargetPath +// read path for generated files save to. func (o *Common) ReadTargetPath(command *console.Command, key, value string) (err error) { // Read // from command options. @@ -271,20 +297,94 @@ func (o *Common) ReadTargetPath(command *console.Command, key, value string) (er // to absolute path. o.TargetPath = value + // Read package for generated files save to. if m := RegexMatchPkg.FindStringSubmatch(value); len(m) > 0 { o.TargetPkg = m[1] return } + // Error read. err = fmt.Errorf(`can not parse package name for target`) return } // RegisterDatabase -// adds a database connect configurations. +// adds a database connect configuration. func (o *Common) RegisterDatabase() error { return db.Config.Add(DsnKey, &db.Database{ Dsn: []string{o.Dsn}, Mapper: "snake", }) } + +func (o *Common) FormatColumn(command *console.Command, table *base.Table, column *base.Column) { + // Bind relation of a table. + column.Table = table + + // Build comment list of a table. + if len(column.Comment.Strings()) > 0 { + column.CommentList = make([]template.HTML, 0) + for _, s := range column.Comment.Strings() { + if s = strings.TrimSpace(s); s != "" { + column.CommentList = append(column.CommentList, template.HTML(s)) + } + } + } + + // Parse info fields. + column.Datetime = template.HTML(time.Now().Format(time.RFC3339)) + column.Script = template.HTML(o.BuildScript(command)) + + // Parse name fields. + column.ExportName = column.Field.StructName(o.Prefix) + column.ExportJson = column.Field.ToSnake() + column.ExportOrm = column.Extra.Convert(column.Field) + + // Type convert. + if convert := conf.Model.Get(fmt.Sprintf(`%s.%s`, table.Name, column.Field), column.Type.Origin()); convert != nil { + column.ExportPkg = convert.Pkg + column.ExportType = convert.Type + + // Append package. + if column.ExportPkg != "" { + table.Add(column.ExportPkg) + } + } + + column.IsDate = column.Type.IsDate() + column.IsDatetime = column.Type.IsDatetime() + column.IsDatetimeOnUpdate = column.Extra.IsDatetimeOnUpdate() + column.IsPrimaryKey = column.Key.IsPrimary() +} + +func (o *Common) FormatTable(command *console.Command, table *base.Table) { + // Build comment list of a table. + if len(table.Comment.Strings()) > 0 { + table.CommentList = make([]template.HTML, 0) + for _, s := range table.Comment.Strings() { + if s = strings.TrimSpace(s); s != "" { + table.CommentList = append(table.CommentList, template.HTML(s)) + } + } + } + + // Parse info fields. + table.Datetime = template.HTML(time.Now().Format(time.RFC3339)) + table.Script = template.HTML(o.BuildScript(command)) +} + +func (o *Common) FormatTableAsModel(table *base.Table) { + table.ModelName = table.Name.StructName(o.Prefix) + table.ModelPkg = o.TargetPkg +} + +func (o *Common) FormatTableAsService(table *base.Table) { + table.ModelName = table.Name.StructName(o.Prefix) + table.ServiceName = fmt.Sprintf(`%sService`, table.ModelName) + + table.ModelPkg = o.ModelPkg + table.ServicePkg = o.TargetPkg + + table.Add(`context`) + table.Add(`gitee.com/go-libs/db-xorm/db`) +} diff --git a/db/commands/table.go b/db/commands/conf/init.go similarity index 61% rename from db/commands/table.go rename to db/commands/conf/init.go index 9f70f2c06a84a490e446fd79b582158c9ff9f211..7abc8e629673cab5224487928425dcff2f167758 100644 --- a/db/commands/table.go +++ b/db/commands/conf/init.go @@ -11,18 +11,25 @@ // limitations under the License. // // Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-02 +// Date: 2024-08-16 -package commands +package conf -// Table -// is a component for table definition (DDL). -type Table struct { - Engine string `xorm:"Engine"` - Format string `xorm:"Row_format"` - Name ItemName `xorm:"Name"` - Comment ItemComment `xorm:"Comment"` - Collation ItemCollation `xorm:"Collation"` +import ( + "gitee.com/go-libs/db-xorm/db/commands/base" + "sync" +) - Columns []*Column `xorm:"-"` +var ( + builtinMapping Mapping + builtinUndefined *base.Convertor + once = new(sync.Once) +) + +func init() { + once.Do(func() { + builtinMapping = make(Mapping).builtin() + builtinUndefined = &base.Convertor{Type: "any"} + Model = (&model{}).init() + }) } diff --git a/db/commands/generator_common.go b/db/commands/conf/mapping.go similarity index 36% rename from db/commands/generator_common.go rename to db/commands/conf/mapping.go index e2c7110c27102e3ecf3ff3ac69d69f30b1764fdc..e5e5dfb5d441cb5d30661fc5d1880113039feea1 100644 --- a/db/commands/generator_common.go +++ b/db/commands/conf/mapping.go @@ -11,58 +11,65 @@ // limitations under the License. // // Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-08 +// Date: 2024-08-16 -package commands +package conf -import ( - "html/template" - "sort" - "time" -) +import "gitee.com/go-libs/db-xorm/db/commands/base" -// +---------------------------------------------------------------------------+ -// | Common generator result | -// +---------------------------------------------------------------------------+ - -// GeneratorCommon -// is a common component for generator. -type GeneratorCommon struct { - Datetime template.HTML - Script template.HTML - Package string - StructName string +// Mapping +// is a field type mapping to convertor. +type Mapping map[string]*base.Convertor - Packages []string - Table *Table - - packagesMapper map[string]bool +// Add +// adds a convertor for name into mapping. +func (o Mapping) Add(name string, convertor *base.Convertor) { + o[name] = convertor } -// AddPackage -// adds a package name to list. -func (o *GeneratorCommon) AddPackage(pkg string) { - if _, ok := o.packagesMapper[pkg]; !ok { - o.packagesMapper[pkg] = true - o.Packages = append(o.Packages, pkg) - } +// Get +// gets a convertor with given name from mapping. +func (o Mapping) Get(name string) *base.Convertor { + if convertor, ok := o[name]; ok { + return convertor + } + return nil } -// SortPackage -// sorts package list with alphabet. -func (o *GeneratorCommon) SortPackage() { - sort.Strings(o.Packages) -} +// +---------------------------------------------------------------------------+ +// | Hook methods | +// +---------------------------------------------------------------------------+ + +func (o Mapping) builtin() Mapping { + for name, convertor := range map[string]*base.Convertor{ + // Int + "tinyint": {Type: "int"}, + "smallint": {Type: "int"}, + "mediumint": {Type: "int"}, + "int": {Type: "int"}, + "integer": {Type: "int"}, + "bigint": {Type: "int64"}, + + // Float64 + "decimal": {Type: "float64"}, + "double": {Type: "float64"}, + "float": {Type: "float64"}, + + // String + "char": {Type: "string"}, + "varchar": {Type: "string"}, + "text": {Type: "string"}, + "longtext": {Type: "string"}, + "enum": {Type: "string"}, -// Init -// common generator fields. -func (o *GeneratorCommon) init(g *Generator) *GeneratorCommon { - o.packagesMapper = make(map[string]bool) + // Blob. + "blob": {Type: "[]byte"}, - o.Datetime = template.HTML(time.Now().Format(time.RFC3339)) - o.Package = g.Common.TargetPkg - o.Script = template.HTML(g.Command.ToScript()) - o.Packages = make([]string, 0) - o.Table = g.Table - return o + // Date & time + "date": {Pkg: "gitee.com/go-libs/db-xorm/db", Type: "db.Date"}, + "datetime": {Pkg: "gitee.com/go-libs/db-xorm/db", Type: "db.Datetime"}, + } { + o.Add(name, convertor) + } + return o } diff --git a/db/commands/generator.go b/db/commands/conf/model_command.go similarity index 40% rename from db/commands/generator.go rename to db/commands/conf/model_command.go index e5b154be8155ee2341dd60413bad44d7ec6824e0..9e6ac74f2f1a68e610f37612ea9b855902450777 100644 --- a/db/commands/generator.go +++ b/db/commands/conf/model_command.go @@ -11,44 +11,15 @@ // limitations under the License. // // Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-08 +// Date: 2024-08-16 -package commands +package conf -import ( - "context" - _ "embed" - "gitee.com/go-libs/console" -) +import "gitee.com/go-libs/db-xorm/db/commands/base" -var ( - //go:embed templates/model.tpl - TemplateModel string - - //go:embed templates/service.tpl - TemplateService string -) - -// Generator -// is a component used to generate to source files. -type Generator struct { - Common *Common - Command *console.Command - Container *console.Container - Table *Table - Target Target -} - -// Model -// generate to model source file. -func (o *Generator) Model(ctx context.Context) (err error) { - data := (&GeneratorModel{}).init(o) - return o.Target.Save(ctx, TemplateModel, data) -} - -// Service -// generate to service source file. -func (o *Generator) Service(ctx context.Context) (err error) { - data := (&GeneratorService{}).init(o) - return o.Target.Save(ctx, TemplateService, data) +// ModelCommand +// is a component for each command. +type ModelCommand struct { + Fields map[string]*base.Convertor `yaml:"fields"` + Types map[string]*base.Convertor `yaml:"types"` } diff --git a/db/commands/conf/model_config.go b/db/commands/conf/model_config.go new file mode 100644 index 0000000000000000000000000000000000000000..608932641c346857eeeeca9808f12422c5b4357d --- /dev/null +++ b/db/commands/conf/model_config.go @@ -0,0 +1,106 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-16 + +package conf + +import ( + "gitee.com/go-libs/config" + "gitee.com/go-libs/db-xorm/db/commands/base" +) + +var Model ModelConfig + +type ( + // ModelConfig + // is an interface for configuration operate. + // + // Path: + // + // config/console.yaml + // + // Example: + // + // commands: + // gen:model: + // fields: + // task.status: + // pkg: sketch/app + // type: app.Status + // task.concurrency: + // type: int32 + // task.created_at: + // pkg: gitee.com/go-libs/db-xorm/db + // type: db.Datetime + // types: + // date: + // pkg: gitee.com/go-libs/db-xorm/db + // type: db.Date + // datetime: + // pkg: gitee.com/go-libs/db-xorm/db + // type: db.Datetime + ModelConfig interface { + // Get + // returns a configured convertor in console.yaml. + Get(field, typ string) *base.Convertor + + // Mapping + // returns the builtin mapping. + Mapping() Mapping + } + + model struct { + err error + Commands map[string]*ModelCommand `yaml:"commands"` + } +) + +// Get +// returns a configured convertor in console.yaml. +func (o *model) Get(field, typ string) (convertor *base.Convertor) { + var has bool + + // Use configured convertor. + if c, ok := o.Commands[base.CommandNameModel]; ok { + // Primary for field. + if convertor, has = c.Fields[field]; has { + return + } + + // Secondary for type. + if convertor, has = c.Types[typ]; has { + return + } + } + + // For builtin mapping. + if convertor = builtinMapping.Get(typ); convertor != nil { + return + } + + // For undefined. + convertor = builtinUndefined + return +} + +// Mapping +// returns the builtin mapping. +func (o *model) Mapping() Mapping { + return builtinMapping +} + +func (o *model) init() *model { + o.err = config.Seek("console.yml", "console.yaml").ScanYaml(o) + return o +} diff --git a/db/commands/gen_model/command.go b/db/commands/gen_model/command.go new file mode 100644 index 0000000000000000000000000000000000000000..9161c788718a90aba83b01d85bd1dfdb6b18e7b3 --- /dev/null +++ b/db/commands/gen_model/command.go @@ -0,0 +1,88 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-02 + +package gen_model + +import ( + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" +) + +// New +// creates a console command. +func New() *console.Command { + // Creates + // a provider instance. + provider := &Provider{common: &commands.Common{}} + + // Creates + // a command for provider. + provider.command = console.NewCommand(Name).SetDescription(Description) + + // Append options on command. + provider.command.Add( + // Working directory. + // + // go run main.go gen:model --base-dir=/data/sketch + console.NewOption(base.OptBaseDir). + SetShortName(base.OptBaseDirShort). + SetDescription(base.OptBaseDirDesc). + SetDefaultValue(base.OptBaseDirDefault), + + // Data source name. + // + // go run main.go gen:model --dsn="root:pass@tcp(127.0.0.1:3306)/test" + console.NewOption(base.OptDsn). + SetDescription(base.OptDsnDesc), + + // Which table will be exported. + // + // go run main.go gen:model --export="user" + console.NewOption(base.OptExport). + SetShortName(base.OptExportShort). + SetDescription(base.OptExportDesc). + SetRequired(true), + + // Override existing files. + // + // go run main.go gen:model --override + console.NewNullOption(base.OptOverride). + SetDescription(base.OptOverrideDesc), + + // Which table will be exported. + // + // go run main.go gen:model --prefix="cdb_" + console.NewOption(base.OptPrefix). + SetShortName(base.OptPrefixShort). + SetDescription(base.OptPrefixDesc), + + // Target path. + // + // go run main.go gen:model --target-path=app/models + console.NewOption(base.OptTargetPath). + SetShortName(base.OptTargetPathShort). + SetDescription(base.OptTargetPathDesc). + SetDefaultValue(DefaultTargetPath), + ) + + // Bind + // provider to command. + provider.command.SetProvider(provider) + + // Returns + // a command of the provider. + return provider.command +} diff --git a/db/commands/gen_model/generator.go b/db/commands/gen_model/generator.go new file mode 100644 index 0000000000000000000000000000000000000000..9ae924dc84ec2c90346144c6886b87939d7ea181 --- /dev/null +++ b/db/commands/gen_model/generator.go @@ -0,0 +1,78 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-16 + +package gen_model + +import ( + "context" + _ "embed" + "fmt" + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" +) + +//go:embed generator.tpl +var template string + +// Generator +// is a component for generate model files. +type Generator struct { + Common *commands.Common + Command *console.Command + Container *console.Container + Table *base.Table + Target base.Target +} + +func (o *Generator) Run(ctx context.Context) (err error) { + var can bool + + // Build + // a path for service file. + o.Target = base.Target( + fmt.Sprintf(`%s/%s/%s.go`, + o.Common.BaseDir, + o.Common.TargetPath, + o.Table.Name.FileName(o.Common.Prefix), + ), + ) + + // Override + // state check for target file. + if can, err = o.Target.Can(o.Common.Override); err != nil { + return err + } + + // Return + // for service file existing and not allow override. + if !can { + o.Container.GetOutput().Info(` [ignored] %s`, o.Target) + return + } + + // Generate related fields. + o.Common.FormatTableAsModel(o.Table) + + // Save + // generated result. + if err = o.Target.Save(ctx, template, o.Table); err != nil { + return + } + + // Generate success. + o.Container.GetOutput().Info(` [succeed] %s`, o.Target) + return +} diff --git a/db/commands/templates/model.tpl b/db/commands/gen_model/generator.tpl similarity index 45% rename from db/commands/templates/model.tpl rename to db/commands/gen_model/generator.tpl index c986de6eba92dec56a2ae3e66aed82d41eee343a..a1b0800465730cf1bfec06aea46c7d987141458a 100644 --- a/db/commands/templates/model.tpl +++ b/db/commands/gen_model/generator.tpl @@ -5,56 +5,60 @@ // cd /data/sketch // {{.Script}} -package {{.Package}} +package {{.ModelPkg}} -{{- if gt (len .Packages) 0}} +{{- if gt (len .PackageList) 0}} import ( - {{- range .Packages}} + {{- range .PackageList}} "{{.}}" {{- end}} ) {{- end}} -// {{.StructName}} +// {{.ModelName}} // is a model for table. -{{- if .Table.Comment}} +{{- if gt (len .CommentList) 0}} // -// {{.Table.Comment}} +{{- range .CommentList}} +// {{.}} {{- end}} +{{- end}} +// +// Property: // -// Collation : {{.Table.Collation}} -// Engine : {{.Table.Engine}} -// Format : {{.Table.Format}} -// Table : {{.Table.Name}} -type {{.StructName}} struct{ - // Field count : {{len .Table.Columns}} +// Collation : {{.Collation}} +// Engine : {{.Engine}} +// Format : {{.Format}} +// Table : {{.Name}} +type {{.ModelName}} struct { + {{- range .Columns}} - {{- range .Table.Columns}} - {{if .Comment}} - // {{.ExportName}} - // {{.Comment}}. - {{- else}} + {{- if gt (len .CommentList) 0}} // {{.ExportName}} + {{- range .CommentList}} + // {{.}} {{- end}} // + {{- end}} + // Property: {{- if .Collation}} - // Collation : {{.Collation}} + // Collation: {{.Collation}} {{- end}} {{- if .Default}} - // Default : {{.Default}} + // Default: {{.Default}} {{- end}} {{- if .Extra}} - // Extra : {{.Extra}} + // Extra: {{.Extra}} {{- end}} - // Null : {{.Null}} - // Type : {{.Type}} + // Null: {{.Null}} + // Type: {{.Type}} {{.ExportName}} {{.ExportType}} `xorm:"{{.ExportOrm}}" json:"{{.ExportJson}}"` {{- end}} } // TableName // returns a table name. It's an optional function. -func (o *{{.StructName}}) TableName() string { - return "{{.Table.Name}}" +func (o *{{.ModelName}}) TableName() string { + return "{{.Name}}" } diff --git a/db/commands/gen_model/provider.go b/db/commands/gen_model/provider.go new file mode 100644 index 0000000000000000000000000000000000000000..e9e90720348f8c4039b470079c3d6f937878cf32 --- /dev/null +++ b/db/commands/gen_model/provider.go @@ -0,0 +1,90 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-02 + +package gen_model + +import ( + "context" + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" + "gitee.com/go-wares/log" +) + +const ( + Name = base.CommandNameModel + Description = "Generate model files" + DefaultTargetPath = "app/models" +) + +// Provider +// is a component used to generate model files. +type Provider struct { + common *commands.Common + command *console.Command +} + +// Before +// is a before runner hook handler for command. +func (o *Provider) Before(_ context.Context, _ *console.Container, command *console.Command) (err error) { + log.Config().SetLevel("error") + + // Read and validate + // options value. + // + // --base-dir + // --dsn + for _, fn := range []func() error{ + func() error { return o.common.ReadBaseDir(command, base.OptBaseDir, base.OptBaseDirDefault) }, + func() error { return o.common.BuildModule(command) }, + func() error { return o.common.ReadDsn(command, base.OptDsn) }, + func() error { return o.common.ReadExport(command, base.OptExport) }, + func() error { return o.common.ReadOverride(command, base.OptOverride) }, + func() error { return o.common.ReadPrefix(command, base.OptPrefix) }, + func() error { return o.common.ReadTargetPath(command, base.OptTargetPath, DefaultTargetPath) }, + func() error { return o.common.RegisterDatabase() }, + } { + if err = fn(); err != nil { + break + } + } + return +} + +// Run +// is a runner hook handler for command. +func (o *Provider) Run(ctx context.Context, container *console.Container, command *console.Command) (err error) { + var tables []*base.Table + + // Return error + // if tables list failed. + if tables, err = o.common.ListTable(ctx, command); err != nil { + return + } + + // Iterate + // tables and generate it. + for _, table := range tables { + if err = (&Generator{ + Common: o.common, + Command: command, + Container: container, + Table: table, + }).Run(ctx); err != nil { + break + } + } + return +} diff --git a/db/commands/gen_service/command.go b/db/commands/gen_service/command.go new file mode 100644 index 0000000000000000000000000000000000000000..c05d3bb0be8d1c054c9ac7544374fd08e44d34a8 --- /dev/null +++ b/db/commands/gen_service/command.go @@ -0,0 +1,97 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-02 + +package gen_service + +import ( + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" +) + +// New +// creates a console command. +func New() *console.Command { + // Creates + // a provider instance. + provider := &Provider{common: &commands.Common{}} + + // Creates + // a command for provider. + provider.command = console.NewCommand(Name). + SetDescription(Description) + + // Append options on command. + provider.command.Add( + // Working directory. + // + // go run main.go gen:service --base-dir=/data/sketch + console.NewOption(base.OptBaseDir). + SetShortName(base.OptBaseDirShort). + SetDescription(base.OptBaseDirDesc). + SetDefaultValue(base.OptBaseDirDefault), + + // Data source name. + // + // go run main.go gen:service --dsn="root:pass@tcp(127.0.0.1:3306)/test" + console.NewOption(base.OptDsn). + SetDescription(base.OptDsnDesc), + + // Which table will be exported. + // + // go run main.go gen:service --export="user" + console.NewOption(base.OptExport). + SetShortName(base.OptExportShort). + SetDescription(base.OptExportDesc). + SetRequired(true), + + // Model path. + // + // go run main.go gen:service --model-path=app/models + console.NewOption(base.OptModelPath). + SetShortName(base.OptModelPathShort). + SetDescription(base.OptModelPathDesc). + SetDefaultValue(base.OptModelPathDefault), + + // Override existing files. + // + // go run main.go gen:service --override + console.NewNullOption(base.OptOverride). + SetDescription(base.OptOverrideDesc), + + // Which table will be exported. + // + // go run main.go gen:service --prefix="cdb_" + console.NewOption(base.OptPrefix). + SetShortName(base.OptPrefixShort). + SetDescription(base.OptPrefixDesc), + + // Target path. + // + // go run main.go gen:service --target-path=app/services + console.NewOption(base.OptTargetPath). + SetShortName(base.OptTargetPathShort). + SetDescription(base.OptTargetPathDesc). + SetDefaultValue(DefaultTargetPath), + ) + + // Bind + // provider to command. + provider.command.SetProvider(provider) + + // Returns + // a command of the provider. + return provider.command +} diff --git a/db/commands/gen_service/generator.go b/db/commands/gen_service/generator.go new file mode 100644 index 0000000000000000000000000000000000000000..1d321b801a373793fbe6a51f052de127bd11aa2e --- /dev/null +++ b/db/commands/gen_service/generator.go @@ -0,0 +1,78 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-16 + +package gen_service + +import ( + "context" + _ "embed" + "fmt" + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" +) + +//go:embed generator.tpl +var template string + +// Generator +// is a component for generate model files. +type Generator struct { + Common *commands.Common + Command *console.Command + Container *console.Container + Table *base.Table + Target base.Target // /data/sketch/app/service/example_service.go +} + +func (o *Generator) Run(ctx context.Context) (err error) { + var can bool + + // Build + // a path for service file. + o.Target = base.Target( + fmt.Sprintf(`%s/%s/%s_service.go`, + o.Common.BaseDir, + o.Common.TargetPath, + o.Table.Name.FileName(o.Common.Prefix), + ), + ) + + // Override + // state check for target file. + if can, err = o.Target.Can(o.Common.Override); err != nil { + return err + } + + // Return + // for service file existing and not allow override. + if !can { + o.Container.GetOutput().Info(` [ignored] %s`, o.Target) + return + } + + // Generate related fields. + o.Common.FormatTableAsService(o.Table) + + // Save + // generated result. + if err = o.Target.Save(ctx, template, o.Table); err != nil { + return + } + + // Generate success. + o.Container.GetOutput().Info(` [succeed] %s`, o.Target) + return +} diff --git a/db/commands/templates/service.tpl b/db/commands/gen_service/generator.tpl similarity index 70% rename from db/commands/templates/service.tpl rename to db/commands/gen_service/generator.tpl index 7b798dcc618081ec875dad4754b93b8d326dafd5..63ffaf12652f6efb8288789baad16abe0a58f0ac 100644 --- a/db/commands/templates/service.tpl +++ b/db/commands/gen_service/generator.tpl @@ -5,36 +5,34 @@ // cd /data/sketch // {{.Script}} -package {{.Package}} +package {{.ServicePkg}} -{{- if gt (len .Packages) 0}} +{{- if gt (len .PackageList) 0}} import ( - {{- range .Packages}} + {{- range .PackageList}} "{{.}}" {{- end}} ) {{- end}} -// {{.StructName}} -// is a service used to operate data for model. -type {{.StructName}} struct{ +// {{.ServiceName}} +// is a database operator for {{.Name}} table. +type {{.ServiceName}} struct { db.Service } -// New{{.StructName}} -// creates a model operate service. -// -// {{.Script}} -func New{{.StructName}}(sess ... *db.Session) *{{.StructName}}{ - o := &{{.StructName}}{} - o.With(sess...) - return o +// New{{.ServiceName}} +// creates a database operator service for {{.Name}} table. +func New{{.ServiceName}}(sess ... *db.Session) *{{.ServiceName}}{ + o := &{{.ServiceName}}{} + o.With(sess...) + return o } // Add // adds a new record with given param. -func (o *{{.StructName}}) Add(ctx context.Context, req *{{.ModelPkg}}.{{.ModelName}}) (model *{{.ModelPkg}}.{{.ModelName}}, err error) { +func (o *{{.ServiceName}}) Add(ctx context.Context, req *{{.ModelPkg}}.{{.ModelName}}) (model *{{.ModelPkg}}.{{.ModelName}}, err error) { var ( affects int64 sess *db.Session @@ -50,7 +48,7 @@ func (o *{{.StructName}}) Add(ctx context.Context, req *{{.ModelPkg}}.{{.ModelNa // model fields for insert without primary key. Datetime use builtin // methods. model = &{{.ModelPkg}}.{{.ModelName}}{ - {{- range .Table.Columns}} + {{- range .Columns}} {{- if not .IsPrimaryKey}} {{- if .IsDate}} {{.ExportName}}: db.NewDate(), @@ -74,7 +72,7 @@ func (o *{{.StructName}}) Add(ctx context.Context, req *{{.ModelPkg}}.{{.ModelNa // DelBy{{.PrimaryName}} // method is generated by console command. It's deletes a record by primary key. -func (o *{{.StructName}}) DelBy{{.PrimaryName}}(ctx context.Context, val {{.PrimaryType}}) (affects int64, err error) { +func (o *{{.ServiceName}}) DelBy{{.PrimaryName}}(ctx context.Context, val {{.PrimaryType}}) (affects int64, err error) { var ( sess *db.Session model = &{{.ModelPkg}}.{{.ModelName}}{} @@ -88,16 +86,14 @@ func (o *{{.StructName}}) DelBy{{.PrimaryName}}(ctx context.Context, val {{.Prim // Send data // to master session and return affect count. - affects, err = sess.Where("`id` = ?", val).Delete(model) + affects, err = sess.Where("`{{.PrimaryFieldName}}` = ?", val).Delete(model) return } -{{- end}} -{{- if .PrimaryName}} // GetBy{{.PrimaryName}} // method is generated by console command. It's return a model struct // if exists otherwise nil returned. -func (o *{{.StructName}}) GetBy{{.PrimaryName}}(ctx context.Context, val {{.PrimaryType}}) (model *{{.ModelPkg}}.{{.ModelName}}, err error){ +func (o *{{.ServiceName}}) GetBy{{.PrimaryName}}(ctx context.Context, val {{.PrimaryType}}) (model *{{.ModelPkg}}.{{.ModelName}}, err error){ var ( has bool sess *db.Session @@ -120,4 +116,4 @@ func (o *{{.StructName}}) GetBy{{.PrimaryName}}(ctx context.Context, val {{.Prim } return } -{{- end}} +{{- end}} \ No newline at end of file diff --git a/db/commands/gen_service/provider.go b/db/commands/gen_service/provider.go new file mode 100644 index 0000000000000000000000000000000000000000..6226681159ea24d2b30ea5cf8fd9c06b9de256e8 --- /dev/null +++ b/db/commands/gen_service/provider.go @@ -0,0 +1,91 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: wsfuyibing <682805@qq.com> +// Date: 2024-08-02 + +package gen_service + +import ( + "context" + "gitee.com/go-libs/console" + "gitee.com/go-libs/db-xorm/db/commands" + "gitee.com/go-libs/db-xorm/db/commands/base" + "gitee.com/go-wares/log" +) + +const ( + Name = base.CommandNameService + Description = "Generate service files" + DefaultTargetPath = "app/services" +) + +// Provider +// is a component used to generate service files. +type Provider struct { + common *commands.Common + command *console.Command +} + +// Before +// is a before runner hook handler for command. +func (o *Provider) Before(_ context.Context, _ *console.Container, command *console.Command) (err error) { + log.Config().SetLevel("error") + + // Read and validate + // options value. + // + // --base-dir + // --dsn + for _, fn := range []func() error{ + func() error { return o.common.ReadBaseDir(command, base.OptBaseDir, base.OptBaseDirDefault) }, + func() error { return o.common.BuildModule(command) }, + func() error { return o.common.ReadDsn(command, base.OptDsn) }, + func() error { return o.common.ReadExport(command, base.OptExport) }, + func() error { return o.common.ReadModelPath(command, base.OptModelPath, base.OptModelPathDefault) }, + func() error { return o.common.ReadOverride(command, base.OptOverride) }, + func() error { return o.common.ReadPrefix(command, base.OptPrefix) }, + func() error { return o.common.ReadTargetPath(command, base.OptTargetPath, DefaultTargetPath) }, + func() error { return o.common.RegisterDatabase() }, + } { + if err = fn(); err != nil { + break + } + } + return +} + +// Run +// is a runner hook handler for command. +func (o *Provider) Run(ctx context.Context, container *console.Container, command *console.Command) (err error) { + var tables []*base.Table + + // Return error + // if tables list failed. + if tables, err = o.common.ListTable(ctx, command); err != nil { + return + } + + // Iterate + // tables and generate it. + for _, table := range tables { + if err = (&Generator{ + Common: o.common, + Command: command, + Container: container, + Table: table, + }).Run(ctx); err != nil { + break + } + } + return +} diff --git a/db/commands/generator_service.go b/db/commands/generator_service.go deleted file mode 100644 index 32b6b066129eba0f2f887b230c1cc58e5889a6e3..0000000000000000000000000000000000000000 --- a/db/commands/generator_service.go +++ /dev/null @@ -1,63 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-12 - -package commands - -import "fmt" - -// +---------------------------------------------------------------------------+ -// | Service generator result | -// +---------------------------------------------------------------------------+ - -// GeneratorService -// is a component for generate service. -type GeneratorService struct { - GeneratorCommon - ModelName, ModelPkg string - - PrimaryName, PrimaryType, PrimaryFieldName string -} - -func (o *GeneratorService) init(g *Generator) *GeneratorService { - // Init - // common fields. - o.GeneratorCommon.init(g) - - // Init - // field type packages. - o.AddPackage("context") - o.AddPackage("gitee.com/go-libs/db-xorm/db") - o.AddPackage(fmt.Sprintf(`%s%s/%s`, g.Common.ModuleName, g.Common.ModuleFolder, g.Common.ModelPath)) - - // Init - // export fields. - o.ModelName = g.Table.Name.StructName(g.Common.Prefix) - o.ModelPkg = g.Common.ModelPkg - o.StructName = fmt.Sprintf(`%sService`, o.ModelName) - - // Check primary key. - for _, x := range g.Table.Columns { - if x.Key.IsPrimary() { - o.PrimaryName = x.Field.ToSame() - o.PrimaryFieldName = x.Field.String() - _, o.PrimaryType = x.Type.Convert(g.Command) - } - } - - // Resort - // with alphabet. - o.SortPackage() - return o -} diff --git a/db/commands/mapping.go b/db/commands/mapping.go deleted file mode 100644 index e3b619c0a19c8c26f0aebb6ec459629c0feff149..0000000000000000000000000000000000000000 --- a/db/commands/mapping.go +++ /dev/null @@ -1,95 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-07 - -package commands - -import ( - "gitee.com/go-libs/config" - "strings" - "sync" -) - -var ( - once = new(sync.Once) - typeMapping *TypeMapping -) - -type ( - TypeMapping struct { - err error - Commands map[string]*TypeMappingCommand `yaml:"commands"` - } - TypeMappingCommand struct { - Packages map[string]string `yaml:"packages"` - Types map[string]string `yaml:"types"` - } -) - -func NewMapping() *TypeMapping { - return typeMapping -} - -func (o *TypeMapping) After() { - if o.Commands == nil { - o.Commands = make(map[string]*TypeMappingCommand) - } -} - -// Get -// returns library package and type name for field type if defined by config file. -// -// Config in console.yml: -// -// commands: -// gen:model: -// packages: -// datetime: "gitee.com/go-libs/db-xorm" -// types: -// datetime: "db.Datetime" -// -// Example: -// -// pkg, name, exists := NewMapping().Get("gen:model", "datetime") -// // Output: "xorm", "Time", true -// // "gitee.com/go-libs/db-xorm", "db.Datetime", true -func (o *TypeMapping) Get(cn, tn string) (pkg, name string, exists bool) { - if c, cok := o.Commands[cn]; cok { - if t, tok := c.Types[tn]; tok { - if t = strings.TrimSpace(t); t != "" { - exists = true - name = t - - // Custom package. - if k, kok := c.Packages[tn]; kok { - if k = strings.TrimSpace(k); k != "" { - pkg = k - } - } - } - } - } - return -} - -func (o *TypeMapping) init() *TypeMapping { - o.err = config.Seek("console.yml", "console.yaml").ScanYaml(o) - return o -} - -func init() { - once.Do(func() { - typeMapping = (&TypeMapping{}).init() - }) -} diff --git a/db/commands/model/command.go b/db/commands/model/command.go deleted file mode 100644 index 0faf54d476f4784e457101a43e5e85190eabf72a..0000000000000000000000000000000000000000 --- a/db/commands/model/command.go +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-02 - -package model - -import ( - "gitee.com/go-libs/console" - "gitee.com/go-libs/db-xorm/db/commands" -) - -// New -// creates a console command. -func New() *console.Command { - // Creates - // a provider instance. - provider := &Provider{common: &commands.Common{}} - - // Creates - // a command for provider. - provider.command = console.NewCommand(Name). - SetDescription(Description) - - // Append options on command. - provider.command.Add( - // Working directory. - // - // go run main.go gen:model --base-dir=/data/sketch - console.NewOption(OptBaseDir). - SetShortName(OptBaseDirShort). - SetDescription(OptBaseDirDesc). - SetDefaultValue(OptBaseDirDefault), - - // Data source name. - // - // go run main.go gen:model --dsn="root:pass@tcp(127.0.0.1:3306)/test" - console.NewOption(OptDsn). - SetDescription(OptDsnDesc), - - // Which table will be exported. - // - // go run main.go gen:model --export="user" - console.NewOption(OptExport). - SetShortName(OptExportShort). - SetDescription(OptExportDesc). - SetRequired(true), - - // Override existing files. - // - // go run main.go gen:model --override - console.NewNullOption(OptOverride). - SetDescription(OptOverrideDesc), - - // Which table will be exported. - // - // go run main.go gen:model --prefix="cdb_" - console.NewOption(OptPrefix). - SetShortName(OptPrefixShort). - SetDescription(OptPrefixDesc), - - // Target path. - // - // go run main.go gen:model --target-path=app/models - console.NewOption(OptTargetPath). - SetShortName(OptTargetPathShort). - SetDescription(OptTargetPathDesc). - SetDefaultValue(OptTargetPathDefault), - ) - - // Bind - // provider to command. - provider.command.SetProvider(provider) - - // Returns - // a command of the provider. - return provider.command -} diff --git a/db/commands/model/provider.go b/db/commands/model/provider.go deleted file mode 100644 index 31cdc9f0b76fb3c97c64260474667d1e6ba2d59e..0000000000000000000000000000000000000000 --- a/db/commands/model/provider.go +++ /dev/null @@ -1,143 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-02 - -package model - -import ( - "context" - "fmt" - "gitee.com/go-libs/console" - "gitee.com/go-libs/db-xorm/db/commands" - "gitee.com/go-wares/log" -) - -const ( - Name = "gen:model" - Description = "Generate model files" - - OptBaseDir = "base-dir" - OptBaseDirDefault = "./" - OptBaseDirDesc = "Application working directory" - OptBaseDirShort = 'b' - - OptDsn = "dsn" - OptDsnDesc = "Database source name for connection, e.g. root:pass@tcp(127.0.0.1:3306)/test" - - OptExport = "export" - OptExportDesc = "Which tables will be exported" - OptExportShort = 'e' - - OptOverride = "override" - OptOverrideDesc = "Override existing model files" - - OptPrefix = "prefix" - OptPrefixDesc = "Prefix name for table" - OptPrefixShort = 'p' - - OptTargetPath = "target-path" - OptTargetPathDefault = "app/models" - OptTargetPathDesc = "Generated model files saved to" - OptTargetPathShort = 't' -) - -// Provider -// is a component used to generate model files. -type Provider struct { - common *commands.Common - command *console.Command -} - -// Before -// is a before runner hook handler for command. -func (o *Provider) Before(_ context.Context, _ *console.Container, command *console.Command) (err error) { - log.Config().SetLevel("error") - - // Read and validate - // options value. - // - // --base-dir - // --dsn - for _, fn := range []func() error{ - func() error { return o.common.ReadBaseDir(command, OptBaseDir, OptBaseDirDefault) }, - func() error { return o.common.BuildModule(command) }, - func() error { return o.common.ReadDsn(command, OptDsn) }, - func() error { return o.common.ReadExport(command, OptExport) }, - func() error { return o.common.ReadOverride(command, OptOverride) }, - func() error { return o.common.ReadPrefix(command, OptPrefix) }, - func() error { return o.common.ReadTargetPath(command, OptTargetPath, OptTargetPathDefault) }, - func() error { return o.common.RegisterDatabase() }, - } { - if err = fn(); err != nil { - break - } - } - return -} - -// Run -// is a runner hook handler for command. -func (o *Provider) Run(ctx context.Context, container *console.Container, command *console.Command) (err error) { - var tables []*commands.Table - - // Return error - // if tables list failed. - if tables, err = o.common.ListTable(ctx, command); err != nil { - return - } - - // Iterate - // tables and generate it. - for _, table := range tables { - if err = o.generate(ctx, container, command, table); err != nil { - break - } - } - return -} - -// generate table to target file. -func (o *Provider) generate(ctx context.Context, container *console.Container, command *console.Command, table *commands.Table) (err error) { - var ( - can bool - name = fmt.Sprintf(`%s.go`, table.Name.FileName(o.common.Prefix)) - target = commands.Target(fmt.Sprintf(`%s/%s/%s`, o.common.BaseDir, o.common.TargetPath, name)) - ) - - // Check - // target file can override or not. - if can, err = target.Can(o.common.Override); err != nil { - return - } - - // Ignore - // if target exists and override not enabled. - if !can { - container.GetOutput().Info(` [ignored] target file found: table="%s", target="%s"`, table.Name, target) - return - } - - // Store - // model file. - if err = (&commands.Generator{ - Command: command, - Container: container, - Common: o.common, - Table: table, - Target: target, - }).Model(ctx); err == nil { - container.GetOutput().Info(` [succeed] target file saved: table="%s", target="%s"`, table.Name, target) - } - return -} diff --git a/db/commands/service/command.go b/db/commands/service/command.go deleted file mode 100644 index d4bc786e6c26e9dfe1e8bbabb91960d41ae5181f..0000000000000000000000000000000000000000 --- a/db/commands/service/command.go +++ /dev/null @@ -1,96 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-02 - -package service - -import ( - "gitee.com/go-libs/console" - "gitee.com/go-libs/db-xorm/db/commands" -) - -// New -// creates a console command. -func New() *console.Command { - // Creates - // a provider instance. - provider := &Provider{common: &commands.Common{}} - - // Creates - // a command for provider. - provider.command = console.NewCommand(Name). - SetDescription(Description) - - // Append options on command. - provider.command.Add( - // Working directory. - // - // go run main.go gen:service --base-dir=/data/sketch - console.NewOption(OptBaseDir). - SetShortName(OptBaseDirShort). - SetDescription(OptBaseDirDesc). - SetDefaultValue(OptBaseDirDefault), - - // Data source name. - // - // go run main.go gen:service --dsn="root:pass@tcp(127.0.0.1:3306)/test" - console.NewOption(OptDsn). - SetDescription(OptDsnDesc), - - // Which table will be exported. - // - // go run main.go gen:service --export="user" - console.NewOption(OptExport). - SetShortName(OptExportShort). - SetDescription(OptExportDesc). - SetRequired(true), - - // Model path. - // - // go run main.go gen:service --model-path=app/models - console.NewOption(OptModelPath). - SetShortName(OptModelPathShort). - SetDescription(OptModelPathDesc). - SetDefaultValue(OptModelPathDefault), - - // Override existing files. - // - // go run main.go gen:service --override - console.NewNullOption(OptOverride). - SetDescription(OptOverrideDesc), - - // Which table will be exported. - // - // go run main.go gen:service --prefix="cdb_" - console.NewOption(OptPrefix). - SetShortName(OptPrefixShort). - SetDescription(OptPrefixDesc), - - // Target path. - // - // go run main.go gen:service --target-path=app/services - console.NewOption(OptTargetPath). - SetShortName(OptTargetPathShort). - SetDescription(OptTargetPathDesc). - SetDefaultValue(OptTargetPathDefault), - ) - - // Bind - // provider to command. - provider.command.SetProvider(provider) - - // Returns - // a command of the provider. - return provider.command -} diff --git a/db/commands/service/provider.go b/db/commands/service/provider.go deleted file mode 100644 index 72eda42c88f971ce20c6fe9195a86c6da0a61030..0000000000000000000000000000000000000000 --- a/db/commands/service/provider.go +++ /dev/null @@ -1,149 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Author: wsfuyibing <682805@qq.com> -// Date: 2024-08-02 - -package service - -import ( - "context" - "fmt" - "gitee.com/go-libs/console" - "gitee.com/go-libs/db-xorm/db/commands" - "gitee.com/go-wares/log" -) - -const ( - Name = "gen:service" - Description = "Generate service files" - - OptBaseDir = "base-dir" - OptBaseDirDefault = "./" - OptBaseDirDesc = "Application working directory" - OptBaseDirShort = 'b' - - OptDsn = "dsn" - OptDsnDesc = "Database source name for connection, e.g. root:pass@tcp(127.0.0.1:3306)/test" - - OptExport = "export" - OptExportDesc = "Which tables will be exported" - OptExportShort = 'e' - - OptModelPath = "model-path" - OptModelPathDefault = "app/models" - OptModelPathDesc = "Generated model files location" - OptModelPathShort = 'm' - - OptOverride = "override" - OptOverrideDesc = "Override existing service files" - - OptPrefix = "prefix" - OptPrefixDesc = "Prefix name for table" - OptPrefixShort = 'p' - - OptTargetPath = "target-path" - OptTargetPathDefault = "app/services" - OptTargetPathDesc = "Generated service files saved to" - OptTargetPathShort = 't' -) - -// Provider -// is a component used to generate service files. -type Provider struct { - common *commands.Common - command *console.Command -} - -// Before -// is a before runner hook handler for command. -func (o *Provider) Before(_ context.Context, _ *console.Container, command *console.Command) (err error) { - log.Config().SetLevel("error") - - // Read and validate - // options value. - // - // --base-dir - // --dsn - for _, fn := range []func() error{ - func() error { return o.common.ReadBaseDir(command, OptBaseDir, OptBaseDirDefault) }, - func() error { return o.common.BuildModule(command) }, - func() error { return o.common.ReadDsn(command, OptDsn) }, - func() error { return o.common.ReadExport(command, OptExport) }, - func() error { return o.common.ReadModelPath(command, OptModelPath, OptModelPathDefault) }, - func() error { return o.common.ReadOverride(command, OptOverride) }, - func() error { return o.common.ReadPrefix(command, OptPrefix) }, - func() error { return o.common.ReadTargetPath(command, OptTargetPath, OptTargetPathDefault) }, - func() error { return o.common.RegisterDatabase() }, - } { - if err = fn(); err != nil { - break - } - } - return -} - -// Run -// is a runner hook handler for command. -func (o *Provider) Run(ctx context.Context, container *console.Container, command *console.Command) (err error) { - var tables []*commands.Table - - // Return error - // if tables list failed. - if tables, err = o.common.ListTable(ctx, command); err != nil { - return - } - - // Iterate - // tables and generate it. - for _, table := range tables { - if err = o.generate(ctx, container, command, table); err != nil { - break - } - } - return -} - -// generate table to target file. -func (o *Provider) generate(ctx context.Context, container *console.Container, command *console.Command, table *commands.Table) (err error) { - var ( - can bool - name = fmt.Sprintf(`%s_service.go`, table.Name.FileName(o.common.Prefix)) - target = commands.Target(fmt.Sprintf(`%s/%s/%s`, o.common.BaseDir, o.common.TargetPath, name)) - ) - - // Check - // target file can override or not. - if can, err = target.Can(o.common.Override); err != nil { - return - } - - // Ignore - // if target exists and override not enabled. - if !can { - container.GetOutput().Info(` [ignored] target file found: table="%s", target="%s"`, table.Name, target) - return - } - - // Store - // model file. - if err = (&commands.Generator{ - Command: command, - Container: container, - Common: o.common, - Table: table, - Target: target, - }).Service(ctx); err == nil { - container.GetOutput().Info(` [succeed] target file saved: table="%s", target="%s"`, table.Name, target) - } - return -}