Example #1
0
func formatEndpoint(v *registry.Value, r int) string {
	// default format is tabbed plus the value plus new line
	fparts := []string{"", "%s %s", "\n"}
	for i := 0; i < r+1; i++ {
		fparts[0] += "\t"
	}
	// its just a primitive of sorts so return
	if len(v.Values) == 0 {
		return fmt.Sprintf(strings.Join(fparts, ""), snaker.CamelToSnake(v.Name), v.Type)
	}

	// this thing has more things, it's complex
	fparts[1] += " {"

	vals := []interface{}{snaker.CamelToSnake(v.Name), v.Type}

	for _, val := range v.Values {
		fparts = append(fparts, "%s")
		vals = append(vals, formatEndpoint(val, r+1))
	}

	// at the end
	l := len(fparts) - 1
	for i := 0; i < r+1; i++ {
		fparts[l] += "\t"
	}
	fparts = append(fparts, "}\n")

	return fmt.Sprintf(strings.Join(fparts, ""), vals...)
}
func ValidateUniquenessOf(resource Resource, attribute string) {
	reflected := reflect.ValueOf(resource).Elem()

	value := reflect.Indirect(reflected).FieldByName(attribute)

	field := snaker.CamelToSnake(attribute)

	var count int

	table := DB.NewScope(resource).TableName()

	query := DB.Table(table).Where("LOWER("+field+")=?", strings.ToLower(value.String()))

	id := reflect.Indirect(reflected).FieldByName("ID").Int()

	if id > 0 {
		query = query.Not("id", id)
	}

	query.Count(&count)

	if count > 0 {
		resource.Errors().Add(attribute, "already exists")
	}
}
Example #3
0
//Generate generates a migration on the migrations folder
func Generate(c *cli.Context) {
	setupTestingEnv()
	base := os.Getenv("TRANS_TESTING_FOLDER")

	name := "migration"
	if c.App != nil && len(c.Args()) > 0 {
		name = c.Args().First()
	}

	name = snaker.CamelToSnake(name)
	identifier := time.Now().UnixNano()

	migration := MigrationData{
		Identifier: identifier,
		Name:       name,
	}

	buff := bytes.NewBufferString("")
	tmpl, _ := template.New("migration").Parse(utils.MigrationTemplate)
	_ = tmpl.Execute(buff, migration)

	fileName := strconv.FormatInt(identifier, 10) + "_" + name + ".go"
	path := filepath.Join(base, "db", "migrations", fileName)

	err := ioutil.WriteFile(path, buff.Bytes(), generatedFilePermissions)
	if err != nil {
		log.Println(err)
		log.Println("| Could not write migration file, please check db/migrations folder exists")
	}
}
Example #4
0
func (query Query) createQuery() (q *gorm.DB) {

	query.tableify()
	q = query.Context.Connection.Table(query.tableName)

	for _, ancestor := range query.Ancestors {
		filter_by_str := ancestor.primaryKey() + " = ?"
		q = q.Where(filter_by_str, ancestor.key())
	}

	for filter_by, value := range query.Filters {
		filter_by = snaker.CamelToSnake(filter_by)
		filter_by_str := filter_by + " ?"
		q = q.Where(filter_by_str, value)
	}

	if query.Limit != 0 {
		q = q.Limit(query.Limit)
	}

	if query.Offset != 0 {
		q = q.Offset(query.Offset)
	}

	if query.Order != "" {
		direction, column := order_by(query.Order)
		order_str := column + " " + direction
		q = q.Order(order_str)
	}

	return q
}
Example #5
0
// pluralCamelNameType takes a type, and returns its type converted
// to camel_case and pluralised.
func pluralCamelNameType(typ reflect.Type) string {
	t := fmt.Sprintf("%v", typ)
	a := strings.Split(t, ".")
	t1 := a[len(a)-1]
	t2 := snaker.CamelToSnake(t1)
	t3 := inflector.Pluralize(t2)
	return t3
}
Example #6
0
// pluralCamelName takes an interface, and returns its type converted
// to camel_case and pluralised. eg. pluralCamelName(ImportantPerson{})
// should return "important_people"
func pluralCamelName(i interface{}) string {
	t := fmt.Sprintf("%T", i)
	a := strings.Split(t, ".")
	t1 := a[len(a)-1]
	t2 := snaker.CamelToSnake(t1)
	t3 := inflector.Pluralize(t2)
	return t3
}
Example #7
0
func (e Errors) MarshalJSON() ([]byte, error) {
	for key, value := range e.collection {
		delete(e.collection, key)

		e.collection[snaker.CamelToSnake(key)] = value
	}

	return json.Marshal(e.collection)
}
Example #8
0
func GenerateKey(s string) string {
	key := CustomKeys[s]
	if key != "" {
		return key
	}
	key = strings.Replace(s, " ", "", -1)
	key = strings.Replace(key, "-", "", -1)
	key = snaker.CamelToSnake(key)
	return key
}
Example #9
0
func (n *Node) Render(buf *bytes.Buffer, r Renderer, nodes map[string]*Node, index int) error {
	header := fmt.Sprintf(`---
title: %s
note: Auto generated by tickdoc

menu:
  kapacitor_02:
    name: %s
    identifier: %s
    weight: %d
    parent: tick
---
`,
		n.Name,
		strings.Replace(n.Name, "Node", "", 1),
		snaker.CamelToSnake(n.Name),
		(index+1)*indexWidth,
	)

	buf.Write([]byte(header))

	renderDoc(buf, nodes, r, n.Doc)

	// Properties
	if len(n.Properties) > 0 {
		r.Header(buf, func() bool { buf.Write([]byte("Properties")); return true }, 2, "")
		r.Paragraph(buf, func() bool {
			buf.Write([]byte("Property methods modify state on the calling node. They do not add another node to the pipeline, and always return a reference to the calling node."))
			return true
		})
		renderProperties(buf, r, n.Properties, nodes, 3, "node")
	}

	// Methods
	if len(n.Methods) > 0 {
		r.Header(buf, func() bool { buf.Write([]byte("Chaining Methods")); return true }, 2, "")
		r.Paragraph(buf, func() bool {
			buf.Write([]byte("Chaining methods create a new node in the pipeline as a child of the calling node. They do not modify the calling node."))
			return true
		})
		methods := make([]string, len(n.Methods))
		i := 0
		for name, _ := range n.Methods {
			methods[i] = name
			i++
		}
		sort.Strings(methods)
		for _, name := range methods {
			n.Methods[name].Render(buf, r, nodes)
			buf.Write([]byte("\n"))
		}
	}

	return nil
}
Example #10
0
// New generates a new engine and returns it as an engine pointer
func New(driver string, dsn string) (*Engine, error) {
	conn, err := sqlx.Open(driver, dsn)
	if err != nil {
		return nil, err
	}

	// set name mapper function
	conn.MapperFunc(func(name string) string {
		return snaker.CamelToSnake(name)
	})

	return &Engine{
		dialect: NewDialect(driver),
		dsn:     dsn,
		db:      conn,
		logger:  &DefaultLogger{LDefault, log.New(os.Stdout, "", -1)},
	}, err
}
Example #11
0
File: funcs.go Project: knq/xo
// goparamlist converts a list of fields into their named Go parameters,
// skipping any Field with Name contained in ignoreNames. addType will cause
// the go Type to be added after each variable name. addPrefix will cause the
// returned string to be prefixed with ", " if the generated string is not
// empty.
//
// Any field name encountered will be checked against goReservedNames, and will
// have its name substituted by its corresponding looked up value.
//
// Used to present a comma separated list of Go variable names for use with as
// either a Go func parameter list, or in a call to another Go func.
// (ie, ", a, b, c, ..." or ", a T1, b T2, c T3, ...").
func (a *ArgType) goparamlist(fields []*Field, addPrefix bool, addType bool, ignoreNames ...string) string {
	ignore := map[string]bool{}
	for _, n := range ignoreNames {
		ignore[n] = true
	}

	i := 0
	vals := []string{}
	for _, f := range fields {
		if ignore[f.Name] {
			continue
		}

		s := "v" + strconv.Itoa(i)
		if len(f.Name) > 0 {
			n := strings.Split(snaker.CamelToSnake(f.Name), "_")
			s = strings.ToLower(n[0]) + f.Name[len(n[0]):]
		}

		// check go reserved names
		if r, ok := goReservedNames[strings.ToLower(s)]; ok {
			s = r
		}

		// add the go type
		if addType {
			s += " " + a.retype(f.Type)
		}

		// add to vals
		vals = append(vals, s)

		i++
	}

	// concat generated values
	str := strings.Join(vals, ", ")
	if addPrefix && str != "" {
		return ", " + str
	}

	return str
}
Example #12
0
// shortname checks the passed type against the ShortNameTypeMap and returns
// the value for it. If the type is not found, then the value is calculated and
// stored in the ShortNameTypeMap for use in the future.
func shortname(typ string) string {
	var v string
	var ok bool

	// check short name map
	if v, ok = ShortNameTypeMap[typ]; !ok {
		// calc the short name
		u := []string{}
		for _, s := range strings.Split(strings.ToLower(snaker.CamelToSnake(typ)), "_") {
			if len(s) > 0 && s != "id" {
				u = append(u, s[:1])
			}
		}
		v = strings.Join(u, "")

		// store back in short name map
		ShortNameTypeMap[typ] = v
	}

	return v
}
Example #13
0
func main() {
	if len(os.Args) != 4 {
		fmt.Println("Usage: tickdoc absPath path/to/golang/package output/dir")
		fmt.Println()
		fmt.Println("absPath - the absolute path of rendered documentation, used to generate links.")
		os.Exit(1)
	}

	absPath = os.Args[1]
	dir := os.Args[2]
	out := os.Args[3]

	fset := token.NewFileSet() // positions are relative to fset

	skipTest := func(fi os.FileInfo) bool {
		return !strings.HasSuffix(fi.Name(), "_test.go")
	}

	pkgs, err := parser.ParseDir(fset, dir, skipTest, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}

	nodes := make(map[string]*Node)
	for _, pkg := range pkgs {
		f := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates)
		ast.Inspect(f, func(n ast.Node) bool {
			switch decl := n.(type) {
			case *ast.GenDecl:
				handleGenDecl(nodes, decl)
			case *ast.FuncDecl:
				handleFuncDecl(nodes, decl)
			}
			return true
		})
	}

	ordered := make([]string, 0, len(nodes))
	for name, node := range nodes {
		if name == "" || !ast.IsExported(name) {
			continue
		}
		if node.Embedded {
			err := node.Embed(nodes)
			if err != nil {
				log.Fatal(err)
			}
		} else {
			ordered = append(ordered, name)
			node.Flatten(nodes)
		}
	}
	sort.Strings(ordered)

	r := markdown.NewRenderer()
	for i, name := range ordered {
		var buf bytes.Buffer
		n := nodes[name]
		n.Render(&buf, r, nodes, i)
		filename := path.Join(out, snaker.CamelToSnake(name)+".md")
		log.Println("Writing file:", filename, i)
		f, err := os.Create(filename)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		f.Write(buf.Bytes())
	}
}
Example #14
0
func nodeNameToLink(name string) string {
	return fmt.Sprintf("%s/%s/", absPath, snaker.CamelToSnake(name))
}
Example #15
0
func PropertyToField(s string) string {
	mediary := snaker.CamelToSnake(s)

	return snaker.SnakeToCamel(mediary)
}
Example #16
0
func PropertyToColumn(s string) string {
	return snaker.CamelToSnake(s)
}
Example #17
0
func underscore(s string) string {
	return snaker.CamelToSnake(s) + ".go"
}
Example #18
0
func nodeNameToLink(name string) string {
	return fmt.Sprintf("%s/%s/", config.Root, snaker.CamelToSnake(name))
}
Example #19
0
func Snakecase(s string) string {
	return snaker.CamelToSnake(s)
}
Example #20
0
// Get the information for a struct field.
//
// The format is as follows:
//
//   Field  SomeType    `form:"TYPE[,required][,autofocus][,.htmlClass][,#htmlID][,<int>][,<int>!]"`
//
// The integer tag expresses a field size. The integer tag with "!" expresses a maximum length.
//
// TYPE is the HTML field type. For non-<input/> types, use the tag name ("select", "textarea", etc.)
//
// Many HTML classes may be specified.
// If the HTML ID is not specified, the struct field name is used as the field name and HTML ID.
// Otherwise, the HTML ID is used as the field name and HTML ID.
//
// The following additional field tags are also supported:
//
//   fmsg:          Format message, shown on validation error.
//   pattern:       Regexp to enforce on client and server.
//   placeholder:   Placeholder string.
//   label:         Label string.
//   set:           <select> value set.
//
func GetFieldInfo(sf reflect.StructField) FieldInfo {
	fi := FieldInfo{
		FName: sf.Name,
	}

	tags := strings.Split(sf.Tag.Get("form"), ",")
	fi.Type = tags[0]
	for _, v := range tags[1:] {
		switch {
		case v == "required":
			fi.Required = true
		case v == "autofocus":
			fi.Autofocus = true
		case v == "":
		case v[0] == '.':
			fi.Classes = append(fi.Classes, v[1:])
		case v[0] == '#':
			fi.ID = v[1:]
		case v[0] >= '0' && v[0] <= '9':
			strict := false
			if v[len(v)-1] == '!' {
				strict = true
				v = v[0 : len(v)-1]
			} else if idx := strings.IndexByte(v, 'x'); idx >= 0 {
				v2 := v[idx+1:]
				n, err := strconv.ParseUint(v2, 10, 31)
				if err == nil {
					fi.VSize = int(n)
				}

				v = v[0:idx]
			}

			n, err := strconv.ParseUint(v, 10, 31)
			if err == nil {
				if strict {
					fi.MaxLength = int(n)
				} else {
					fi.Size = int(n)
				}
			}
		default:
			if fi.Type == "" {
				fi.Type = v
			}
		}
	}

	fi.FormatMessage = sf.Tag.Get("fmsg")
	fi.Pattern = sf.Tag.Get("pattern")
	fi.ValueSet = sf.Tag.Get("set")

	if fi.ID == "" {
		fi.Name = fi.FName
		fi.Name = snaker.CamelToSnake(fi.Name)
		fi.ID = fi.Name
	} else {
		fi.Name = fi.ID
	}

	fi.Label = sf.Tag.Get("label")
	if fi.Label == "-" {
		fi.Label = ""
	} else if fi.Label == "" {
		fi.Label = fi.FName
	}

	fi.Placeholder = sf.Tag.Get("placeholder")
	if fi.Placeholder == "-" {
		fi.Placeholder = ""
	} else if fi.Placeholder == "" {
		fi.Placeholder = fi.Label
	}

	return fi
}
Example #21
0
func main() {
	flag.Usage = usage
	flag.Parse()
	args := flag.Args()

	if len(args) != 2 {
		flag.Usage()
		os.Exit(1)
	}

	dir := args[0]
	out := args[1]
	// Decode config
	err := decodeConfig(*configPath)
	if err != nil {
		log.Fatal(err)
	}

	fset := token.NewFileSet() // positions are relative to fset

	skipTest := func(fi os.FileInfo) bool {
		return !strings.HasSuffix(fi.Name(), "_test.go")
	}

	pkgs, err := parser.ParseDir(fset, dir, skipTest, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}

	nodes := make(map[string]*Node)
	for _, pkg := range pkgs {
		f := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates)
		ast.Inspect(f, func(n ast.Node) bool {
			switch decl := n.(type) {
			case *ast.GenDecl:
				handleGenDecl(nodes, decl)
			case *ast.FuncDecl:
				handleFuncDecl(nodes, decl)
			}
			return true
		})
	}

	ordered := make([]string, 0, len(nodes))
	for name, node := range nodes {
		if name == "" || !ast.IsExported(name) || node.Name == "" {
			continue
		}
		if node.Embedded {
			err := node.Embed(nodes)
			if err != nil {
				log.Fatal(err)
			}
		} else {
			ordered = append(ordered, name)
			node.Flatten(nodes)
		}
	}
	sort.Strings(ordered)

	r := markdown.NewRenderer(nil)
	for i, name := range ordered {
		var buf bytes.Buffer
		n := nodes[name]
		weight := (i + 1) * config.IndexWidth
		if w, ok := config.Weights[name]; ok {
			weight = w
		}
		n.Render(&buf, r, nodes, weight)
		filename := path.Join(out, snaker.CamelToSnake(name)+".md")
		log.Println("Writing file:", filename, i)
		f, err := os.Create(filename)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		f.Write(buf.Bytes())
	}
}
Example #22
0
func (n *Node) Render(buf *bytes.Buffer, r Renderer, nodes map[string]*Node, weight int) error {
	info := headerInfo{
		Title:      n.Name,
		Name:       strings.Replace(n.Name, "Node", "", 1),
		Identifier: snaker.CamelToSnake(n.Name),
		Weight:     weight,
	}
	config.headerTemplate.Execute(buf, info)

	renderDoc(buf, nodes, r, n.Doc)

	properties := make([]string, len(n.Properties))
	i := 0
	for name := range n.Properties {
		properties[i] = name
		i++
	}
	sort.Strings(properties)

	methods := make([]string, len(n.Methods))
	i = 0
	for name := range n.Methods {
		methods[i] = name
		i++
	}
	sort.Strings(methods)

	// Index
	r.Header(buf, func() bool { buf.Write([]byte("Index")); return true }, 2, "")
	r.Header(buf, func() bool { buf.Write([]byte("Properties")); return true }, 3, "")
	r.List(buf, func() bool {
		for _, name := range properties {
			r.ListItem(buf, []byte(fmt.Sprintf("[%s](%s)", name, methodNameToLink(n.Name, name))), 1024)
		}
		return true
	}, 0)
	r.Header(buf, func() bool { buf.Write([]byte("Chaining Methods")); return true }, 3, "")
	r.List(buf, func() bool {
		for _, name := range methods {
			r.ListItem(buf, []byte(fmt.Sprintf("[%s](%s)", name, methodNameToLink(n.Name, name))), 1024)
		}
		return true
	}, 0)

	// Properties
	if len(n.Properties) > 0 {
		r.Header(buf, func() bool { buf.Write([]byte("Properties")); return true }, 2, "")
		r.Paragraph(buf, func() bool {
			buf.Write([]byte(config.PropertyMethodDesc))
			return true
		})
		renderProperties(buf, r, n.Properties, nodes, 3, "node", "")
	}

	// Methods
	if len(methods) > 0 {
		r.Header(buf, func() bool { buf.Write([]byte("Chaining Methods")); return true }, 2, "")
		r.Paragraph(buf, func() bool {
			buf.Write([]byte(config.ChainMethodDesc))
			return true
		})
		for _, name := range methods {
			n.Methods[name].Render(buf, r, nodes)
			buf.Write([]byte("\n"))
		}
	}

	return nil
}
Example #23
0
func (sd *SchemaDSL) Parse() (err error) {
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, sd.config.SchemaFile, nil, parser.ParseComments)
	if err != nil {
		return err
	}
	ast.FileExports(f)
SCHEMA_PARSE_LOOP:
	for _, decl := range f.Decls {
		table := ""
		fields := []*ast.Field{}

		if genDecl, ok := decl.(*ast.GenDecl); ok {
			for _, spec := range genDecl.Specs {
				if typeSpec, ok := spec.(*ast.TypeSpec); ok {
					table = snaker.CamelToSnake(typeSpec.Name.Name)

					if structType, ok := typeSpec.Type.(*ast.StructType); ok {
						fields = structType.Fields.List
					}
				}
			}

			if genDecl.Doc != nil {
				for _, doc := range genDecl.Doc.List {
					if strings.HasPrefix(doc.Text, COMMENT_IGNORE_PREFIX) {
						continue SCHEMA_PARSE_LOOP
					}

					if strings.HasPrefix(doc.Text, COMMENT_TABLE_PREFIX) {
						table = strings.TrimSpace(strings.TrimPrefix(doc.Text, COMMENT_TABLE_PREFIX))
					}
				}
			}
		}

		sd.Tables = append(sd.Tables, &Table{Name: table, AstFields: fields})
	}

	for _, table := range sd.Tables {
		var primaryKeys []string
		for _, field := range table.AstFields {
			if field.Tag == nil {
				continue
			}

			var typeName string
			tagMap := parseTag(field.Tag.Value)

			if t, ok := field.Type.(*ast.Ident); ok {
				typeName = t.Name
			}

			if t, ok := field.Type.(*ast.SelectorExpr); ok {
				x := t.X.(*ast.Ident).Name
				sel := t.Sel.Name
				typeName = fmt.Sprintf("%s.%s", x, sel)
			}

			columns, err := sd.Dialect.ConvertSql(typeName, tagMap)
			if err != nil {
				return err
			}

			table.Fields = append(table.Fields, &Field{
				Name:      tagMap["sql"],
				Attribute: strings.Join(columns, " "),
			})

			if _, ok := tagMap["primary"]; ok {
				primaryKeys = append(primaryKeys, tagMap["sql"])
			}

			if _, ok := tagMap["uniq"]; ok {
				name := tagMap["uniq"]
				if name == "" {
					name = fmt.Sprintf("`%s_%s`", table.Name, strings.Replace(tagMap["sql"], "`", "", -1))
				}

				table.ParseIndex(&table.UniqueIndexes, name, tagMap["sql"])
			}

			if _, ok := tagMap["index"]; ok {
				table.ParseIndex(&table.Indexes, tagMap["index"], tagMap["sql"])
			}
		}
		table.PrimaryKey = strings.Join(primaryKeys, ", ")
	}

	return nil
}
Example #24
0
func FieldToColumn(s string) string {
	return snaker.CamelToSnake(s)
}
Example #25
0
File: funcs.go Project: knq/xo
// shortname generates a safe Go identifier for typ. typ is first checked
// against ArgType.ShortNameTypeMap, and if not found, then the value is
// calculated and stored in the ShortNameTypeMap for future use.
//
// A shortname is the concatentation of the lowercase of the first character in
// the words comprising the name. For example, "MyCustomName" will have have
// the shortname of "mcn".
//
// If a generated shortname conflicts with a Go reserved name, then the
// corresponding value in goReservedNames map will be used.
//
// Generated shortnames that have conflicts with any scopeConflicts member will
// have ArgType.NameConflictSuffix appended.
//
// Note: recognized types for scopeConflicts are string, []*Field,
// []*QueryParam.
func (a *ArgType) shortname(typ string, scopeConflicts ...interface{}) string {
	var v string
	var ok bool

	// check short name map
	if v, ok = a.ShortNameTypeMap[typ]; !ok {
		// calc the short name
		u := []string{}
		for _, s := range strings.Split(strings.ToLower(snaker.CamelToSnake(typ)), "_") {
			if len(s) > 0 && s != "id" {
				u = append(u, s[:1])
			}
		}
		v = strings.Join(u, "")

		// check go reserved names
		if n, ok := goReservedNames[v]; ok {
			v = n
		}

		// store back to short name map
		a.ShortNameTypeMap[typ] = v
	}

	// initial conflicts are the default imported packages from
	// xo_package.go.tpl
	conflicts := map[string]bool{
		"sql":     true,
		"driver":  true,
		"csv":     true,
		"errors":  true,
		"fmt":     true,
		"regexp":  true,
		"strings": true,
		"time":    true,
	}

	// add scopeConflicts to conflicts
	for _, c := range scopeConflicts {
		switch k := c.(type) {
		case string:
			conflicts[k] = true

		case []*Field:
			for _, f := range k {
				conflicts[f.Name] = true
			}
		case []*QueryParam:
			for _, f := range k {
				conflicts[f.Name] = true
			}

		default:
			panic("not implemented")
		}
	}

	// append suffix if conflict exists
	if _, ok := conflicts[v]; ok {
		v = v + a.NameConflictSuffix
	}

	return v
}
Example #26
0
func generateModel(dbName, tName, structName string, schema drivers.TableSchema, config CodeConfig, tmpl *template.Template) error {
	snakeStructName := snaker.CamelToSnake(structName)
	file, err := os.Create(path.Join(config.packageName, snakeStructName+"_mq.go"))
	if err != nil {
		return err
	}
	w := bufio.NewWriter(file)

	defer func() {
		w.Flush()
		file.Close()
	}()

	model := ModelMeta{
		I:         string(strings.ToLower(tName)[0]),
		Name:      toCapitalCase(structName),
		SnakeName: snakeStructName,
		DbName:    dbName,
		TableName: tName,
		Fields:    make([]ModelField, len(schema)),
		Uniques:   make([]ModelField, 0, len(schema)),
		config:    config,
	}
	needTime := false
	for i, col := range schema {
		name := toCapitalCase(col.ColumnName)
		field := ModelField{
			Name:            name,
			ColumnName:      col.ColumnName,
			Type:            col.DataType,
			JsonMeta:        fmt.Sprintf("`json:\"%s\"`", snaker.CamelToSnake(col.ColumnName)),
			IsPrimaryKey:    strings.ToUpper(col.ColumnKey) == "PRI",
			IsUniqueKey:     strings.ToUpper(col.ColumnKey) == "UNI",
			IsAutoIncrement: strings.ToUpper(col.Extra) == "AUTO_INCREMENT",
			DefaultValue:    col.DefaultValue,
			Extra:           col.Extra,
			Comment:         col.Comment,
			IsNullable:      col.IsNullable,
			NullType:        col.NullType,
			IsSuper:         IsSuperField(name),
		}
		if field.Type == "time.Time" {
			needTime = true
		}
		if field.IsPrimaryKey {
			model.PrimaryFields = append(model.PrimaryFields, &field)
		}

		if field.IsUniqueKey {
			model.Uniques = append(model.Uniques, field)
		}

		model.Fields[i] = field
	}

	if err := model.GenHeader(w, tmpl, needTime); err != nil {
		return fmt.Errorf("[%s] Fail to gen model header, %s", tName, err)
	}
	if config.buildStuct {
		if err := model.GenStruct(w, tmpl); err != nil {
			return fmt.Errorf("[%s] Fail to gen model struct, %s", tName, err)
		}
	}
	if err := model.GenFindFetch(w, tmpl); err != nil {
		return fmt.Errorf("[%s] Fail to gen find fetch api, %s", tName, err)
	}
	//	if err := model.GenObjectApi(w, tmpl); err != nil {
	//		return fmt.Errorf("[%s] Fail to gen model object api, %s", tName, err)
	//	}
	//	if err := model.GenQueryApi(w, tmpl); err != nil {
	//		return fmt.Errorf("[%s] Fail to gen model query api, %s", tName, err)
	//	}
	//	if err := model.GenManagedObjApi(w, tmpl); err != nil {
	//		return fmt.Errorf("[%s] Fail to gen model managed objects api, %s", tName, err)
	//	}

	return nil
}
Example #27
0
var genFileParam = GenFileParam{}

var GenHandlerAction = func(c *cli.Context) {
	if len(c.Args()) == 0 {
		fmt.Println("| ERROR: Please specify a handler name.")
		return
	}

	genFileParam.Name = strings.Replace(c.Args()[0], " ", "", -1)

	if exists, _ := pathExists("handlers"); exists == false {
		fmt.Println("| ERROR: handlers folder does not exist in current workign directory.")
		return
	}

	fileName := snaker.CamelToSnake(genFileParam.Name)
	filePath := path.Join("handlers", fileName+".go")

	if exists, _ := pathExists(filePath); exists == true {
		fmt.Printf("| ERROR: '%s' already exists \n", filePath)
		return
	}

	file, err := os.Create(filePath)
	if err != nil {
		fmt.Println("| ERROR: Could not create file: ", err.Error())
		return
	}

	err, dat := writeTemplatedFile(handlerGenTemplate, genFileParam)
	if err != nil {
Example #28
0
File: loader.go Project: knq/xo
// ParseQuery satisfies Loader's ParseQuery.
func (tl TypeLoader) ParseQuery(args *ArgType) error {
	var err error

	// parse supplied query
	queryStr, params := args.ParseQuery(tl.Mask(), true)
	inspectStr, _ := args.ParseQuery("NULL", false)

	// split up query and inspect based on lines
	query := strings.Split(queryStr, "\n")
	inspect := strings.Split(inspectStr, "\n")

	// query comment placeholder
	queryComments := make([]string, len(query)+1)

	// trim whitespace if applicable
	if args.QueryTrim {
		for n, l := range query {
			query[n] = strings.TrimSpace(l)
			if n < len(query)-1 {
				query[n] = query[n] + " "
			}
		}

		for n, l := range inspect {
			inspect[n] = strings.TrimSpace(l)
			if n < len(inspect)-1 {
				inspect[n] = inspect[n] + " "
			}
		}
	}

	// query strip
	if args.QueryStrip && tl.QueryStrip != nil {
		tl.QueryStrip(query, queryComments)
	}

	// create template for query type
	typeTpl := &Type{
		Name:    args.QueryType,
		RelType: Table,
		Fields:  []*Field{},
		Table: &models.Table{
			TableName: "[custom " + strings.ToLower(snaker.CamelToSnake(args.QueryType)) + "]",
		},
		Comment: args.QueryTypeComment,
	}

	if args.QueryFields == "" {
		// if no query fields specified, then pass to inspector
		colList, err := tl.QueryColumnList(args, inspect)
		if err != nil {
			return err
		}

		// process columns
		for _, c := range colList {
			f := &Field{
				Name: SnakeToIdentifier(c.ColumnName),
				Col:  c,
			}
			f.Len, f.NilType, f.Type = tl.ParseType(args, c.DataType, false)
			typeTpl.Fields = append(typeTpl.Fields, f)
		}
	} else {
		// extract fields from query fields
		for _, qf := range strings.Split(args.QueryFields, ",") {
			qf = strings.TrimSpace(qf)
			colName := qf
			colType := "string"

			i := strings.Index(qf, " ")
			if i != -1 {
				colName = qf[:i]
				colType = qf[i+1:]
			}

			typeTpl.Fields = append(typeTpl.Fields, &Field{
				Name: colName,
				Type: colType,
				Col: &models.Column{
					ColumnName: snaker.CamelToSnake(colName),
				},
			})
		}
	}

	// generate query type template
	err = args.ExecuteTemplate(QueryTypeTemplate, args.QueryType, "", typeTpl)
	if err != nil {
		return err
	}

	// build func name
	funcName := args.QueryFunc
	if funcName == "" {
		// no func name specified, so generate based on type
		if args.QueryOnlyOne {
			funcName = args.QueryType
		} else {
			funcName = inflector.Pluralize(args.QueryType)
		}

		// affix any params
		if len(params) == 0 {
			funcName = "Get" + funcName
		} else {
			funcName = funcName + "By"
			for _, p := range params {
				funcName = funcName + strings.ToUpper(p.Name[:1]) + p.Name[1:]
			}
		}
	}

	// create func template
	queryTpl := &Query{
		Name:          funcName,
		Query:         query,
		QueryComments: queryComments,
		QueryParams:   params,
		OnlyOne:       args.QueryOnlyOne,
		Interpolate:   args.QueryInterpolate,
		Type:          typeTpl,
		Comment:       args.QueryFuncComment,
	}

	// generate template
	err = args.ExecuteTemplate(QueryTemplate, args.QueryType, "", queryTpl)
	if err != nil {
		return err
	}

	return nil
}