Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
urionz committed Apr 14, 2021
1 parent eca3db7 commit a4c5f82
Show file tree
Hide file tree
Showing 14 changed files with 561 additions and 33 deletions.
1 change: 0 additions & 1 deletion _examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/mvc"
"github.com/urionz/goofy"
_ "github.com/urionz/goofy/_examples/database/migrations"
"github.com/urionz/goofy/contracts"
"github.com/urionz/goofy/log"
"github.com/urionz/goofy/web"
Expand Down
4 changes: 3 additions & 1 deletion command/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ package command
import "github.com/gookit/gcli/v3"

type (
Command = gcli.Command
Command = gcli.Command
Argument = gcli.Argument
Arguments = gcli.Arguments
)
2 changes: 1 addition & 1 deletion contracts/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Application interface {
ProvideValue(value di.Value, options ...di.ProvideOption) error
Provide(constructor di.Constructor, options ...di.ProvideOption) error
Resolve(ptr di.Pointer, options ...di.ResolveOption) error
Call(args ...string) int
Call(name string, args ...string) error

Workspace() string
Dir() string
Expand Down
9 changes: 6 additions & 3 deletions db/migrate/migrate_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,17 @@ func Make(app contracts.Application) *command.Command {
Config: func(c *command.Command) {
c.StrOpt(&tableName, "table", "t", "", "The table to migrate")
c.StrOpt(&create, "create", "c", "", "The table to be created")
c.BindArg(&command.Argument{
Name: "name", Desc: "迁移文件名称",
})
},
Func: func(c *command.Command, args []string) error {
var prompt *survey.Input
var name string
var isCreate bool
if len(args) > 0 {
name = args[0]
}
for {
if name != "" || len(args) >= 1 {
break
Expand All @@ -371,9 +377,6 @@ func Make(app contracts.Application) *command.Command {
}
survey.AskOne(prompt, &name)
}
if name == "" {
name = args[0]
}

if err := os.MkdirAll(path.Join(app.Database(), "migrations"), os.ModePerm); err != nil {
color.Errorln(err)
Expand Down
109 changes: 89 additions & 20 deletions db/model/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package model

import (
"bytes"
"fmt"
"os"
"path"
"strings"
"text/template"

"github.com/AlecAivazis/survey/v2"
"github.com/gookit/gcli/v3"
"github.com/jinzhu/inflection"
"github.com/urionz/color"
"github.com/urionz/goofy/command"
"github.com/urionz/goofy/contracts"
"github.com/urionz/goutil"
"github.com/urionz/goutil/fsutil"
"github.com/urionz/goutil/strutil"
)

Expand Down Expand Up @@ -39,13 +42,38 @@ var (
migration bool
repository bool
service bool
mvcPath string
modName string
)

func Make(app contracts.Application) *gcli.Command {
command := &gcli.Command{
func resolveConf(app contracts.Application) error {
var conf contracts.Config
if err := app.Resolve(&conf); err != nil {
color.Errorln(err)
return err
}
mvcPath = conf.String("app.mvc_path")
modName = goutil.GetModName(app.Workspace())
return nil
}

func Make(app contracts.Application) *command.Command {
cmd := &command.Command{
Name: "make-model",
Desc: "创建数据模型",
Func: func(c *gcli.Command, args []string) error {
Config: func(c *command.Command) {
c.BoolOpt(&migration, "migration", "m", false, "同时创建迁移文件")
c.BoolOpt(&repository, "repo", "r", false, "同时创建repo文件")
c.BoolOpt(&service, "service", "s", false, "同时创建service文件")
},
Func: func(c *command.Command, args []string) error {
if err := resolveConf(app); err != nil {
color.Errorln(err)
return nil
}
if len(args) > 0 {
name = args[0]
}
var prompt *survey.Input
for {
if name != "" || len(args) >= 1 {
Expand All @@ -56,58 +84,99 @@ func Make(app contracts.Application) *gcli.Command {
}
survey.AskOne(prompt, &name)
}
if name == "" {
name = args[0]
}
tableName := strutil.ToSnake(inflection.Plural(name))

if err := os.MkdirAll(path.Join(app.Workspace(), mvcPath, "models"), os.ModePerm); err != nil {
color.Errorln(err)
return nil
}

if !migration {
migrateConfirm := &survey.Confirm{
Message: "是否同时创建迁移文件?",
}
survey.AskOne(migrateConfirm, &migration)
}

if migration {
if err := createMigration(app, tableName); err != nil {
color.Errorln(err)
return err
return nil
}
}

if err := createModel(name, tableName, app.Workspace()); err != nil {
color.Errorln(err)
return err
return nil
}

if !repository {
repoConfirm := &survey.Confirm{
Message: "是否同时创建repo文件?",
}
survey.AskOne(repoConfirm, &repository)
}

if repository {
if err := createRepository(app, name); err != nil {
color.Errorln(err)
return err
return nil
}
}

if !service {
serviceConfirm := &survey.Confirm{
Message: "是否同时创建service文件?",
}
survey.AskOne(serviceConfirm, &service)
}

if service {
if err := createService(app, name); err != nil {
color.Errorln(err)
return err
return nil
}
}
return nil
},
}
return command
return cmd
}

func createModel(name, tableName, root string) error {
var fHandle *os.File
var err error
var stubString string
fileName := strings.ToLower(strutil.ToSnake(name))

structName := strutil.ToCamel(name)

filePath := path.Join(root, "models", fileName+".go")
filePath := path.Join(root, mvcPath, "models", fileName+".go")

var cover bool

stubString, err := modelPopulateStub(structName, tableName, modelStub)
if fsutil.FileExists(filePath) {
confirm := &survey.Confirm{
Message: "此文件已存在,是否覆盖?",
}
survey.AskOne(confirm, &cover)
}

if cover {
fHandle, err = os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
} else {
fHandle, err = os.OpenFile(filePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666)
}

if err != nil {
return err
}

if f, err := os.OpenFile(filePath, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0666); err == nil {
f.WriteString(stubString)
} else {
if stubString, err = modelPopulateStub(structName, tableName, modelStub); err != nil {
return err
}

if _, err = fHandle.WriteString(stubString); err != nil {
return err
}

Expand All @@ -132,16 +201,16 @@ func modelPopulateStub(structName, tableName, stub string) (string, error) {
}

func createMigration(app contracts.Application, tableName string) error {
// _, _, err := app.Call("make:migration", fmt.Sprintf("create_%s_table", tableName))
app.Call("make-migration", fmt.Sprintf("create_%s_table", tableName))
return nil
}

func createRepository(app contracts.Application, name string) error {
// _, _, err := app.Call("make:repository", name)
app.Call("make-repo", name)
return nil
}

func createService(app contracts.Application, name string) error {
// _, _, err := app.Call("make:service", name)
app.Call("make-service", name)
return nil
}
54 changes: 54 additions & 0 deletions db/model/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package model

import (
"io/ioutil"
"regexp"
"strings"

"github.com/urionz/goutil/arrutil"
)

var (
blankReg = regexp.MustCompile("\\s?")
multiLineCommentReg = regexp.MustCompile("/\\*+\\s?.*?\\s?\\*+/")
singleCommentReg = regexp.MustCompile("//[^\\r\\n]*")
structReg = regexp.MustCompile("type\\s+\\w+\\s+struct\\s+{\\s+[\\w.]+BaseModel\\s+([\\w\\s`\\[\\]{:\"_.;*|,]+)\\s+}")
fieldReg = regexp.MustCompile("\\s?(\\w+)\\s+([\\w*\\[\\].]+)\\s+.*")
)

func ParseGoFileStruct(filepath string) map[string]string {
result := make(map[string]string)
b, err := ioutil.ReadFile(filepath)
if err != nil {
return result
}
content := string(b)
content = multiLineCommentReg.ReplaceAllString(content, "")
content = singleCommentReg.ReplaceAllString(content, "")

structMatch := structReg.FindStringSubmatch(content)
fieldMatch := strings.TrimSpace(fieldReg.ReplaceAllString(structMatch[1], "$1"))
typeMatch := strings.TrimSpace(fieldReg.ReplaceAllString(structMatch[1], "$2"))

fields := strings.Split(fieldMatch, "\n")
types := strings.Split(typeMatch, "\n")

for index, field := range fields {
typ := blankReg.ReplaceAllString(types[index], "")

if strings.Contains(typ, "*") {
typ = "ptr"
} else if strings.Contains(typ, "[") {
typ = "array"
} else if strings.Contains(typ, "JSON") {
typ = "ptr"
} else if arrutil.StringsHas([]string{
"int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64",
"float32", "float64"}, typ) {
typ = "number"
}
result[blankReg.ReplaceAllString(field, "")] = typ
}
return result
}
Loading

0 comments on commit a4c5f82

Please sign in to comment.