Example #1
0
func singularize(plural string) string {
	singular := inflector.Singularize(plural)
	if singular == plural {
		singular += "Item"
	}
	return singular
}
Example #2
0
func generateWhere(t *models.Table, adapter string) (string, error) {
	placeholder := getPlaceholder(adapter)
	title := strings.Title(t.Name)
	firstChar := strings.ToLower(string(t.Name[0]))
	funcPlaceholderText := FormatFunction(title, "Where", "column string, arg interface{}", fmt.Sprintf("([]*%s, error)", title))
	queryText := `"select * from %s where %s = %s;"`
	if placeholder == "?" {
		queryText = fmt.Sprintf(queryText, t.Name, placeholder, placeholder)
	} else {
		queryText = fmt.Sprintf(queryText, t.Name, placeholder, "$2")
	}
	typeName := inflector.Singularize(strings.Title(t.Name))
	srcText := fmt.Sprintf(`	%s := make([]*%s, 0)
	rows, err := db.Queryx(%s, column, arg)
	if err != nil {
		return "", err
	}
	for rows.Next() {
			%s := &%s{}
			err = rows.StructScan(%s)
			if err != nil {
				return nil, err
			}
			%s = append(%s, %s)
		}
	return %s, nil`, firstChar+"s", typeName, queryText, firstChar, typeName, firstChar, firstChar+"s", firstChar+"s", firstChar, firstChar+"s")

	functionText := fmt.Sprintf(funcPlaceholderText, srcText)
	return functionText, nil
}
Example #3
0
// PgLoadTables loads the table definitions from the database, writing the
// resulting templates to typeMap and returning the created templates.TableTemplates.
func PgLoadTables(args *internal.ArgType, db *sql.DB, typeMap map[string]*bytes.Buffer) (map[string]*templates.TableTemplate, error) {
	var err error

	// load columns
	cols, err := models.ColumnsByRelkindSchema(db, "r", args.Schema)
	if err != nil {
		return nil, err
	}

	// process columns
	fieldMap := map[string]map[string]bool{}
	tableMap := map[string]*templates.TableTemplate{}
	for _, c := range cols {
		if _, ok := fieldMap[c.TableName]; !ok {
			fieldMap[c.TableName] = map[string]bool{}
		}

		// set col info
		c.Field = snaker.SnakeToCamel(c.ColumnName)
		c.Len, c.NilType, c.Type = PgParseType(args, c.DataType, c.IsNullable)

		// set value in table map if not present
		if _, ok := tableMap[c.TableName]; !ok {
			tableMap[c.TableName] = &templates.TableTemplate{
				Type:        inflector.Singularize(snaker.SnakeToCamel(c.TableName)),
				TableSchema: args.Schema,
				TableName:   c.TableName,
				Fields:      []*models.Column{},
			}
		}

		// set primary key
		if c.IsPrimaryKey {
			tableMap[c.TableName].PrimaryKey = c.ColumnName
			tableMap[c.TableName].PrimaryKeyField = c.Field
			tableMap[c.TableName].PrimaryKeyType = c.Type
		}

		// append col to template fields
		if _, ok := fieldMap[c.TableName][c.ColumnName]; !ok {
			tableMap[c.TableName].Fields = append(tableMap[c.TableName].Fields, c)
		}

		fieldMap[c.TableName][c.ColumnName] = true
	}

	// generate table templates
	for _, t := range tableMap {
		buf := GetBuf(typeMap, strings.ToLower(t.Type))
		err = templates.Tpls["postgres.model.go.tpl"].Execute(buf, t)
		if err != nil {
			return nil, err
		}
	}

	return tableMap, nil
}
Example #4
0
func main() {
	for _, s := range singulars {
		fmt.Printf("Plural of %v = %v\n", s, inflector.Pluralize(s))
	}

	fmt.Println()

	for _, s := range plurals {
		fmt.Printf("Singular of %v = %v\n", s, inflector.Singularize(s))
	}
}
Example #5
0
// PgLoadEnums reads the enums from the database, writing the values to the
// typeMap and returning the created EnumTemplates.
func PgLoadEnums(args *internal.ArgType, db *sql.DB, typeMap map[string]*bytes.Buffer) (map[string]*templates.EnumTemplate, error) {
	var err error

	// load enums
	enums, err := models.EnumsBySchema(db, args.Schema)
	if err != nil {
		return nil, err
	}

	// process enums
	enumMap := map[string]*templates.EnumTemplate{}
	for _, e := range enums {
		// calc go type and add to known types
		goType := inflector.Singularize(snaker.SnakeToCamel(e.EnumType))
		templates.KnownTypeMap[goType] = true

		// calculate val, chopping off redundant type name if applicable
		val := snaker.SnakeToCamel(strings.ToLower(e.EnumValue))
		if strings.HasSuffix(strings.ToLower(val), strings.ToLower(goType)) {
			v := val[:len(val)-len(goType)]
			if len(v) > 0 {
				val = v
			}
		}

		// copy values back into model
		e.Value = val
		e.Type = goType

		// set value in enum map if not present
		typ := strings.ToLower(goType)
		if _, ok := enumMap[typ]; !ok {
			enumMap[typ] = &templates.EnumTemplate{
				Type:     goType,
				EnumType: e.EnumType,
				Values:   []*models.Enum{},
			}
		}

		// append enum to template vals
		enumMap[typ].Values = append(enumMap[typ].Values, e)
	}

	// generate enum templates
	for _, e := range enumMap {
		buf := GetBuf(typeMap, strings.ToLower(e.Type))
		err = templates.Tpls["postgres.enum.go.tpl"].Execute(buf, e)
		if err != nil {
			return nil, err
		}
	}

	return enumMap, nil
}
Example #6
0
func generateWhereWithMap(t *models.Table, adapter string) (string, error) {
	placeholder := getPlaceholder(adapter)
	title := strings.Title(t.Name)
	firstChar := strings.ToLower(string(t.Name[0]))
	funcPlaceholderText := FormatFunction(title, "WhereWithMap", "args map[string]interface{}", fmt.Sprintf("([]*%s, error)", title))

	typeName := inflector.Singularize(strings.Title(t.Name))
	srcText := strings.Replace(
		fmt.Sprintf(`	%s := make([]*%s, 0)
	placeholder := "%s"
	queryString := "select * from %s where "

	argsSlice := make([]interface{}, 0)
	curNum := 1
	if placeholder == "$1" {
		for k, v := range args {
			if curNum / 2 <= len(args) {
				queryString += fmt.Sprintf("$#{d}\" = \"$#{d}\" and ", curNum, curNum +1)
			} else {
				queryString += fmt.Sprintf("$#{d}\" = \"$#{d}\";", curNum, curNum +1)
			}
			argsSlice = append(argsSlice, k, v)
			curNum +=2
		}
	} else {
		for k, v := range args {
			if curNum / 2 <= len(args) {
				queryString += "? = ? and "
			} else {
				queryString += "? = ?;"
			}
			argsSlice = append(argsSlice, k, v)
			curNum +=2
		}
	}
	rows, err := db.Queryx(queryString, args)
	if err != nil {
		return "", err
	}
	for rows.Next() {
			%s := &%s{}
			err = rows.StructScan(%s)
			if err != nil {
				return nil, err
			}
			%s = append(%s, %s)
		}
	return %s, nil`, firstChar+"s", typeName, placeholder, t.Name, firstChar, typeName, firstChar, firstChar+"s", firstChar+"s", firstChar, firstChar+"s"),
		"#{d}", "%d", -1)

	functionText := fmt.Sprintf(funcPlaceholderText, srcText)
	return functionText, nil
}
Example #7
0
func generateWherein(t *models.Table, adapter string) (string, error) {
	placeholder := getPlaceholder(adapter)
	title := strings.Title(t.Name)
	firstChar := strings.ToLower(string(t.Name[0]))
	funcPlaceholderText := FormatFunction(title, "WhereIn", "column string, args ...interface{}", fmt.Sprintf("([]*%s, error)", title))
	typeName := inflector.Singularize(strings.Title(t.Name))
	srcText := strings.Replace(fmt.Sprintf(`	if len(args) == 0 {
		return nil, errors.New("Must provide at least one argument")
	}
	%s := make([]*%s, 0)
	queryString := ""
	placeholder := "%s"
	buffer := bytes.NewBuffer([]byte{})
	if placeholder == "$1" {
		queryString = "select * from %s where $1 in ("
		for i, _ := range args {
			if i < len(args) {
				buffer.WriteString("$" + fmt.Sprintf("#{d},", i+2))
			} else {
				buffer.WriteString("$" + fmt.Sprintf("#{d});", i+2))
			}
		}
	} else {
		queryString = "select * from %s where ? in ("
		for i, _ := range args {
			if i < len(args) {
				buffer.WriteString("?,")
			} else {
				buffer.WriteString("?);")
			}
		}
	}

	queryString += buffer.String()

	rows, err := db.Queryx(queryString, args)
	if err != nil {
		return "", err
	}
	for rows.Next() {
			%s := &%s{}
			err = rows.StructScan(%s)
			if err != nil {
				return nil, err
			}
			%s = append(%s, %s)
		}
	return %s, nil`, firstChar+"s", typeName, placeholder, t.Name, t.Name, firstChar, title, firstChar, firstChar+"s", firstChar+"s", firstChar, firstChar+"s"), "#{d}", "%d", -1)
	functionText := fmt.Sprintf(funcPlaceholderText, srcText)
	return functionText, nil
}
Example #8
0
func GenerateModels(s *models.Schema) (map[string][]byte, error) {
	modelSrc := make(map[string][]byte)
	for _, table := range s.Tables {
		buffer := bytes.NewBuffer([]byte{})
		structName := inflector.Singularize(strings.Title(table.Name))
		buffer.WriteString(fmt.Sprintf("\n// %s is a generated struct from a %s database. See github.com/alistanis/stg for more information.", structName, s.Adapter))
		buffer.WriteString(fmt.Sprintf("\ntype %s struct {\n", structName))
		for _, row := range table.Rows {
			buffer.WriteString(fmt.Sprintf(" %s", strings.Title(row.Field)))
			t := row.Type
			switch {
			case strings.Contains(t, "int"), strings.Contains(t, "numeric"):
				buffer.WriteString(fmt.Sprintf(" int `db:\"%s\"` \n", row.Field))
			case strings.Contains(t, "varchar"), strings.Contains(t, "text"), strings.Contains(t, "char"):
				buffer.WriteString(fmt.Sprintf(" string `db:\"%s\"` \n", row.Field))
			case strings.Contains(t, "real"), strings.Contains(t, "float"):
				buffer.WriteString(fmt.Sprintf(" float64 `db:\"%s\"` \n", row.Field))
			case strings.Contains(t, "bool"):
				buffer.WriteString(fmt.Sprintf(" bool `db:\"%s\"` \n", row.Field))
			case strings.Contains(t, "enum"):
				buffer.WriteString(fmt.Sprintf(" interface{} `db:\"%s\"` \n", row.Field))
			case strings.Contains(t, "blob"), strings.Contains(t, "binary"):
				buffer.WriteString(fmt.Sprintf(" []byte `db:\"%s\"` \n", row.Field))
			default:
				return nil, errors.New("Unsupported type")
			}

		}
		buffer.WriteString("\n}\n")

		buffer.WriteString(fmt.Sprintf(`var (
		%s = &%s{}
		)
		`, inflector.Pluralize(strings.Title(table.Name)), strings.Title(table.Name)))
		methods, err := GenerateMethods(table, s.Adapter)
		if err != nil {
			return nil, err
		}
		for _, m := range methods {
			buffer.WriteString(m)
		}
		src, err := format.Source(buffer.Bytes())
		if err != nil {
			return nil, err
		}
		buffer.Reset()
		modelSrc[strings.ToLower(table.Name)] = src
	}
	return modelSrc, nil
}
Example #9
0
func structString(schemas []ColumnSchema, table string) string {
	idColumnSchemas := primaryKey(schemas, table)
	idColumnSchema := idColumnSchemas[0] // debug
	idColumnType := idColumnSchema.GoType

	out := "type " + formatName(table) + " struct{\n"
	linkMap := make(map[string]int)
	for i, cs := range schemas {
		if cs.TableName == table {
			// fmt.Println(cs)
			if cs.ColumForeignColumn == "" {
				out = out + "\t" + formatName(cs.ColumnName) + " " + cs.GoType
				if len(config.TagLabel) > 0 {
					out = out + "\t`" + config.TagLabel + ":\"" + cs.ColumnName + "\" json:\"" + formatNameLower(cs.ColumnName) + "\"`"
				}
				out = out + "\n"
			} else {
				// fmt.Println(cs, ">"+cs.ColumForeignColumn+"<")
				// out = out + "\t" + formatName(cs.ColumnName) + " >>>> " + cs.GoType
				linkMap[cs.ColumnForeignTable] = i
			}
		}
	}
	out += "\tLinks " + formatName(table) + "Links `json:\"_links\" db:-`\n"
	out = out + "}\n\n"

	out += "type " + formatName(table) + "Links struct {\n"
	out += "\tSelf string `db:\"self\" json:\"_self\"`\n"

	for fk, _ := range linkMap {
		typeName := formatName(fk)
		if strings.HasSuffix(typeName, "Cachegroup") {
			typeName = "Cachegroup"
		}
		out += "\t\t" + formatName(fk) + "Link " + typeName + "Link `json:\"" + fk + "\" db:-`\n"
	}
	out += "} \n\n"

	for index, cs := range schemas {
		if cs.ColumnForeignTable == table {
			out += "type " + formatName(table) + "Link struct { \n"
			out += "\tID  " + idColumnType + " `db:\"" + inflector.Singularize(table) + "\" json:\"" + schemas[index].ColumForeignColumn + "\"`\n"
			out += "\tRef string `db:\"" + schemas[index].ColumnForeignTable + "_" + schemas[index].ColumForeignColumn + "_ref\" json:\"_ref\"`\n"
			out += "}\n\n"
			break
		}
	}
	return out
}
Example #10
0
func generateFind(t *models.Table, adapter string) (string, error) {
	placeholder := getPlaceholder(adapter)
	title := strings.Title(t.Name)
	firstChar := strings.ToLower(string(t.Name[0]))
	funcPlaceholderText := FormatFunction(title, "Find", "id int", fmt.Sprintf("(*%s, error)", title))
	queryText := fmt.Sprintf(`"select * from %s where id = %s;"`, t.Name, placeholder)
	typeName := inflector.Singularize(strings.Title(t.Name))
	srcText := fmt.Sprintf(`	%s := &%s{}
	err := db.Select(%s, %s, id)
	if err != nil {
		return "", err
	}
	return %s, nil`, firstChar, typeName, firstChar, queryText, firstChar)
	functionText := fmt.Sprintf(funcPlaceholderText, srcText)
	return functionText, nil
}
Example #11
0
File: loader.go Project: knq/xo
// LoadEnums loads schema enums.
func (tl TypeLoader) LoadEnums(args *ArgType) (map[string]*Enum, error) {
	var err error

	// not supplied, so bail
	if tl.EnumList == nil {
		return nil, nil
	}

	// load enums
	enumList, err := tl.EnumList(args.DB, args.Schema)
	if err != nil {
		return nil, err
	}

	// process enums
	enumMap := map[string]*Enum{}
	for _, e := range enumList {
		enumTpl := &Enum{
			Name:              inflector.Singularize(SnakeToIdentifier(e.EnumName)),
			Schema:            args.Schema,
			Values:            []*EnumValue{},
			Enum:              e,
			ReverseConstNames: args.UseReversedEnumConstNames,
		}

		err = tl.LoadEnumValues(args, enumTpl)
		if err != nil {
			return nil, err
		}

		enumMap[enumTpl.Name] = enumTpl
		args.KnownTypeMap[enumTpl.Name] = true
	}

	// generate enum templates
	for _, e := range enumMap {
		err = args.ExecuteTemplate(EnumTemplate, e.Name, "", e)
		if err != nil {
			return nil, err
		}
	}

	return enumMap, nil
}
Example #12
0
func generateWhereFirst(t *models.Table, adapter string) (string, error) {
	placeholder := getPlaceholder(adapter)
	title := strings.Title(t.Name)
	firstChar := strings.ToLower(string(t.Name[0]))
	funcPlaceholderText := FormatFunction(title, "WhereFirst", "column string, arg interface{}", fmt.Sprintf("(*%s, error)", title))
	queryText := `"select * from %s where %s = %s;"`
	if placeholder == "?" {
		queryText = fmt.Sprintf(queryText, t.Name, placeholder, placeholder)
	} else {
		queryText = fmt.Sprintf(queryText, t.Name, placeholder, "$2")
	}
	typeName := inflector.Singularize(strings.Title(t.Name))
	srcText := fmt.Sprintf(`	%s := &%s{}
	err := db.Select(%s, %s, column, arg)
	if err != nil {
		return "", err
	}
	return %s, nil`, firstChar, typeName, firstChar, queryText, firstChar)
	functionText := fmt.Sprintf(funcPlaceholderText, srcText)
	return functionText, nil
}
Example #13
0
File: loader.go Project: knq/xo
// LoadRelkind loads a schema table/view definition.
func (tl TypeLoader) LoadRelkind(args *ArgType, relType RelType) (map[string]*Type, error) {
	var err error

	// load tables
	tableList, err := tl.TableList(args.DB, args.Schema, tl.Relkind(relType))
	if err != nil {
		return nil, err
	}

	// tables
	tableMap := make(map[string]*Type)
	for _, ti := range tableList {
		// create template
		typeTpl := &Type{
			Name:    inflector.Singularize(SnakeToIdentifier(ti.TableName)),
			Schema:  args.Schema,
			RelType: relType,
			Fields:  []*Field{},
			Table:   ti,
		}

		// process columns
		err = tl.LoadColumns(args, typeTpl)
		if err != nil {
			return nil, err
		}

		tableMap[ti.TableName] = typeTpl
	}

	// generate table templates
	for _, t := range tableMap {
		err = args.ExecuteTemplate(TypeTemplate, t.Name, "", t)
		if err != nil {
			return nil, err
		}
	}

	return tableMap, nil
}
Example #14
0
func handleString(schemas []ColumnSchema, table string) string {
	pk := primaryKey(schemas, table)
	updateLastUpdated := hasLastUpdated(schemas, table)

	out := ""
	out += "// @Title get" + formatName(table) + "ById\n"
	out += "// @Description retrieves the " + table + " information for a certain id\n"
	out += "// @Accept  application/json\n"
	out += "// @Param   id              path    int     false        \"The row id\"\n"
	out += "// @Success 200 {array}    " + formatName(table) + "\n"
	out += "// @Resource /api/2.0\n"
	out += "// @Router /api/2.0/" + table + "/{id} [get]\n"
	out += "func get" + inflector.Singularize(formatName(table)) + "(" + getPkGoFuncParamString(pk) + ", db *sqlx.DB) (interface{}, error) {\n"
	out += "    ret := []" + formatName(table) + "{}\n"
	out += "    arg := " + formatName(table) + "{}\n"
	out += setStructPkFields(pk)
	out += "    queryStr := \"select *, " + selfQueryStr(pk, table) + "\"\n"
	out += setFkHALQueryStr(schemas, table)
	out += "    queryStr += \" from " + table + " " + pkWhereStr(pk) + "\"\n"
	out += "    nstmt, err := db.PrepareNamed(queryStr)\n"
	out += "    err = nstmt.Select(&ret, arg)\n"
	out += "	if err != nil {\n"
	out += "	    log.Println(err)\n"
	out += "	    return nil, err\n"
	out += "	}\n"
	out += "    nstmt.Close()\n"
	out += "	return ret, nil\n"
	out += "}\n\n"

	out += "// @Title get" + formatName(table) + "s\n"
	out += "// @Description retrieves the " + table + "\n"
	out += "// @Accept  application/json\n"
	out += "// @Success 200 {array}    " + formatName(table) + "\n"
	out += "// @Resource /api/2.0\n"
	out += "// @Router /api/2.0/" + table + " [get]\n"
	out += "func get" + inflector.Pluralize(formatName(table)) + "(db *sqlx.DB) (interface{}, error) {\n"
	out += "    ret := []" + formatName(table) + "{}\n"
	out += "    queryStr := \"select *, " + selfQueryStr(pk, table) + "\"\n"
	out += setFkHALQueryStr(schemas, table)
	out += "queryStr += \" from " + table + "\"\n"
	out += "	err := db.Select(&ret, queryStr)\n"
	out += "	if err != nil {\n"
	out += "	   log.Println(err)\n"
	out += "	   return nil, err\n"
	out += "	}\n"
	out += "	return ret, nil\n"
	out += "}\n\n"

	out += "// @Title post" + formatName(table) + "\n"
	out += "// @Description enter a new " + table + "\n"
	out += "// @Accept  application/json\n"
	out += "// @Param                 Body body     " + formatName(table) + "   true \"" + formatName(table) + " object that should be added to the table\"\n"
	out += "// @Success 200 {object}    output_format.ApiWrapper\n"
	out += "// @Resource /api/2.0\n"
	out += "// @Router /api/2.0/" + table + " [post]\n"
	out += "func post" + inflector.Singularize(formatName(table)) + "(payload []byte, db *sqlx.DB) (interface{}, error) {\n"
	out += "	var v " + formatName(table) + "\n"
	out += "	err := json.Unmarshal(payload, &v)\n"
	out += "	if err != nil {\n"
	out += "		log.Println(err)\n"
	out += "    	return nil, err\n"
	out += "	}\n"
	out += genInsertVarLines(schemas, table)
	out += "    result, err := db.NamedExec(sqlString, v)\n"
	out += "    if err != nil {\n"
	out += "        log.Println(err)\n"
	out += "    	return nil, err\n"
	out += "    }\n"
	out += "    return result, err\n"
	out += "}\n\n"

	out += "// @Title put" + formatName(table) + "\n"
	out += "// @Description modify an existing " + table + "entry\n"
	out += "// @Accept  application/json\n"
	out += "// @Param   id              path    int     true        \"The row id\"\n"
	out += "// @Param                 Body body     " + formatName(table) + "   true \"" + formatName(table) + " object that should be added to the table\"\n"
	out += "// @Success 200 {object}    output_format.ApiWrapper\n"
	out += "// @Resource /api/2.0\n"
	out += "// @Router /api/2.0/" + table + "/{id}  [put]\n"
	out += "func put" + inflector.Singularize(formatName(table)) + "(" + getPkGoFuncParamString(pk) + ", payload []byte, db *sqlx.DB) (interface{}, error) {\n"
	out += "    var arg " + formatName(table) + "\n"
	out += "    err := json.Unmarshal(payload, &arg)\n"
	out += setStructPkFields(pk)
	out += "    if err != nil {\n"
	out += "    	log.Println(err)\n"
	out += "    	return nil, err\n"
	out += "    }\n"
	if updateLastUpdated {
		out += "    arg.LastUpdated = time.Now()\n"
	}
	out += genUpdateVarLines(schemas, table)
	out += "    result, err := db.NamedExec(sqlString, arg)\n"
	out += "    if err != nil {\n"
	out += "    	log.Println(err)\n"
	out += "    	return nil, err\n"
	out += "    }\n"
	out += "    return result, err\n"
	out += "}\n\n"

	out += "// @Title del" + formatName(table) + "ById\n"
	out += "// @Description deletes " + table + " information for a certain id\n"
	out += "// @Accept  application/json\n"
	out += "// @Param   id              path    int     false        \"The row id\"\n"
	out += "// @Success 200 {array}    " + formatName(table) + "\n"
	out += "// @Resource /api/2.0\n"
	out += "// @Router /api/2.0/" + table + "/{id} [delete]\n"
	out += "func del" + inflector.Singularize(formatName(table)) + "(" + getPkGoFuncParamString(pk) + ", db *sqlx.DB) (interface{}, error) {\n"
	out += "    arg := " + formatName(table) + "{}\n"
	out += setStructPkFields(pk)
	out += "    result, err := db.NamedExec(\"DELETE FROM " + table + " " + pkWhereStr(pk) + "\", arg)\n"
	out += "    if err != nil {\n"
	out += "    	log.Println(err)\n"
	out += "    	return nil, err\n"
	out += "    }\n"
	out += "    return result, err\n"
	out += "}\n\n"
	return out
}
Example #15
0
func singularize(unit string) string {
	return inflector.Singularize(unit)
}
Example #16
0
func (n *Naming) Singularize() {
	n.ResourceName = inflector.Singularize(n.ResourceName)
}
Example #17
0
func (h HasMany) Model() string {
	return inflector.Singularize(h.Func())
}
Example #18
0
func (b BelongsTo) Model() string {
	return inflector.Singularize(b.Func())
}