func writeRowsFunc(w io.Writer, tree *parse.Node) { var buf1, buf2, buf3 bytes.Buffer var i int var parent = tree for _, node := range tree.Edges() { if node.Tags.Skip { continue } // temporary variable declaration switch node.Kind { case parse.Map, parse.Slice: fmt.Fprintf(&buf1, "var v%d %s\n", i, "[]byte") default: fmt.Fprintf(&buf1, "var v%d %s\n", i, node.Type) } // variable scanning fmt.Fprintf(&buf2, "&v%d,\n", i) // variable setting path := node.Path()[1:] // if the parent is a ptr struct we // need to create a new if parent != node.Parent && node.Parent.Kind == parse.Ptr { fmt.Fprintf(&buf3, "v.%s=&%s{}\n", join(path[:len(path)-1], "."), node.Parent.Type) } switch node.Kind { case parse.Map, parse.Slice, parse.Struct, parse.Ptr: fmt.Fprintf(&buf3, "json.Unmarshal(v%d, &v.%s)\n", i, join(path, ".")) default: fmt.Fprintf(&buf3, "v.%s=v%d\n", join(path, "."), i) } parent = node.Parent i++ } fmt.Fprintf(w, sScanRows, inflections.Pluralize(tree.Type), tree.Type, tree.Type, buf1.String(), buf2.String(), tree.Type, buf3.String(), ) }
func writeImports(w io.Writer, tree *parse.Node, pkgs ...string) { var pmap = map[string]struct{}{} // add default packages for _, pkg := range pkgs { pmap[pkg] = struct{}{} } // check each edge node to see if it is // encoded, which might require us to import // other packages for _, node := range tree.Edges() { if node.Tags == nil || len(node.Tags.Encode) == 0 { continue } switch node.Tags.Encode { case "json": pmap["encoding/json"] = struct{}{} // case "gzip": // pmap["compress/gzip"] = struct{}{} // case "snappy": // pmap["github.com/golang/snappy"] = struct{}{} } } if len(pmap) == 0 { return } // write the import block, including each // encoder package that was specified. fmt.Fprintln(w, "\nimport (") for pkg, _ := range pmap { fmt.Fprintf(w, "\t%q\n", pkg) } fmt.Fprintln(w, ")") }
func Load(tree *parse.Node) *Table { table := new(Table) // local map of indexes, used for quick // lookups and de-duping. indexs := map[string]*Index{} // pluralizes the table name and then // formats in snake case. table.Name = inflections.Underscore(tree.Type) table.Name = inflections.Pluralize(table.Name) // each edge node in the tree is a column // in the table. Convert each edge node to // a Field structure. for _, node := range tree.Edges() { field := new(Field) // Lookup the SQL column type // TODO: move this to a function t, ok := parse.Types[node.Type] if ok { tt, ok := types[t] if !ok { tt = BLOB } field.Type = tt } else { field.Type = BLOB } // substitute tag variables if node.Tags != nil { if node.Tags.Skip { continue } // default ID and int64 to primary key // with auto-increment if node.Name == "ID" && node.Kind == parse.Int64 { node.Tags.Primary = true node.Tags.Auto = true } field.Auto = node.Tags.Auto field.Primary = node.Tags.Primary field.Size = node.Tags.Size if node.Tags.Primary { table.Primary = append(table.Primary, field) } if node.Tags.Index != "" { index, ok := indexs[node.Tags.Index] if !ok { index = new(Index) index.Name = node.Tags.Index indexs[index.Name] = index table.Index = append(table.Index, index) } index.Fields = append(index.Fields, field) } if node.Tags.Unique != "" { index, ok := indexs[node.Tags.Index] if !ok { index = new(Index) index.Name = node.Tags.Unique index.Unique = true indexs[index.Name] = index table.Index = append(table.Index, index) } index.Fields = append(index.Fields, field) } if node.Tags.Type != "" { t, ok := sqlTypes[node.Tags.Type] if ok { field.Type = t } } } // get the full path name path := node.Path() var parts []string for _, part := range path { if part.Tags != nil && part.Tags.Name != "" { parts = append(parts, part.Tags.Name) continue } parts = append(parts, part.Name) } field.Name = strings.Join(parts, "_") field.Name = inflections.Underscore(field.Name) table.Fields = append(table.Fields, field) } return table }
func writeSliceFunc(w io.Writer, tree *parse.Node) { var buf1, buf2, buf3 bytes.Buffer var i, depth int var parent = tree for _, node := range tree.Edges() { if node.Tags.Skip { continue } // temporary variable declaration switch node.Kind { case parse.Map, parse.Slice: fmt.Fprintf(&buf1, "var v%d %s\n", i, "[]byte") default: fmt.Fprintf(&buf1, "var v%d %s\n", i, node.Type) } // variable scanning fmt.Fprintf(&buf3, "v%d,\n", i) // variable setting path := node.Path()[1:] // if the parent is a ptr struct we // need to create a new if parent != node.Parent && node.Parent.Kind == parse.Ptr { // if node.Parent != nil && node.Parent.Parent != parent { // fmt.Fprintln(&buf2, "}\n") // depth-- // } // seriously ... this works? if node.Parent != nil && node.Parent.Parent != parent { for _, p := range path { if p == parent || depth == 0 { break } fmt.Fprintln(&buf2, "}\n") depth-- } } depth++ fmt.Fprintf(&buf2, "if v.%s != nil {\n", join(path[:len(path)-1], ".")) } switch node.Kind { case parse.Map, parse.Slice, parse.Struct, parse.Ptr: fmt.Fprintf(&buf2, "v%d, _ = json.Marshal(&v.%s)\n", i, join(path, ".")) default: fmt.Fprintf(&buf2, "v%d=v.%s\n", i, join(path, ".")) } parent = node.Parent i++ } for depth != 0 { depth-- fmt.Fprintln(&buf2, "}\n") } fmt.Fprintf(w, sSliceRow, tree.Type, tree.Type, buf1.String(), buf2.String(), buf3.String(), ) }