codegen

package
v0.0.0-...-9522951 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 17, 2017 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package codegen provides the code-generation functionality used by the sqlrow-gen tool.

Index

Constants

This section is empty.

Variables

View Source
var DefaultTemplate = template.Must(template.New("defaultTemplate").Parse(`// Code generated by "{{.CommandLine}}"; DO NOT EDIT

package {{.Package}}

import ({{range .Imports}}
    {{.}}{{end}}
	"github.com/jjeffery/errors"
)
{{range .QueryTypes -}}
{{- if .Method.Get}}
// {{.Method.Get}} retrieves a {{.Singular}} by its primary key. Returns nil if not found.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Get}}({{.RowType.IDParams}}) (*{{.RowType.Name}}, error) {
	var row {{.RowType.Name}}
	n, err := {{.ReceiverIdent}}.{{.SchemaField}}.Select({{.ReceiverIdent}}.{{.DBField}}, &row, {{.QuotedTableName}}, {{.RowType.IDArgs}})
	if err != nil {
		return nil, errors.Wrap(err, "cannot get {{.Singular}}").With(
            {{.RowType.IDKeyvals}}
		)
	}
	if n == 0 {
		return nil, nil
	}
	return &row, nil
}
{{end -}}
{{- if .Method.Select}}
// {{.Method.Select}} returns a list of {{.Plural}} from an SQL query.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Select}}(query string, args ...interface{}) ([]*{{.RowType.Name}}, error) {
	var rows []*{{.RowType.Name}}
	_, err := {{.ReceiverIdent}}.{{.SchemaField}}.Select({{.ReceiverIdent}}.{{.DBField}}, &rows, query, args...)
	if err != nil {
		return nil, errors.Wrap(err, "cannot query {{.Plural}}").With(
			"query", query,
			"args", args,
		)
	}
	return rows, nil
}
{{end -}}
{{- if .Method.SelectOne}}
// {{.Method.SelectOne}} selects a {{.Singular}} from an SQL query. Returns nil if the query returns no rows.
// If the query returns one or more rows the value for the first is returned and any subsequent
// rows are discarded.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.SelectOne}}(query string, args ...interface{}) (*{{.RowType.Name}}, error) {
	var row {{.RowType.Name}}
	n, err := {{.ReceiverIdent}}.{{.SchemaField}}.Select({{.ReceiverIdent}}.{{.DBField}}, &row, query, args...)
	if err != nil {
		return nil, errors.Wrap(err, "cannot query one {{.Singular}}").With(
			"query", query,
			"args", args,
		)
	}
	if n == 0 {
		return nil, nil
	}
	return &row, nil
}
{{end -}}
{{- if .Method.Insert}}
// {{.Method.Insert}} inserts a {{.Singular}} row.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Insert}}(row *{{.RowType.Name}}) error {
	err := {{.ReceiverIdent}}.{{.SchemaField}}.Insert({{.ReceiverIdent}}.{{.DBField}}, row, {{.QuotedTableName}})
	if err != nil {
		return errors.Wrap(err, "cannot insert {{.Singular}}").With(
            {{range .RowType.LogProps}}"{{.}}", row.{{.}}, {{end}}
		)
	}
	return nil
}
{{end -}}
{{- if .Method.Update}}
// {{.Method.Update}} updates an existing {{.Singular}} row. Returns the number of rows updated,
// which should be zero or one.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Update}}(row *{{.RowType.Name}}) (int, error) {
	n, err := {{.ReceiverIdent}}.{{.SchemaField}}.Update({{.ReceiverIdent}}.{{.DBField}}, row, {{.QuotedTableName}})
	if err != nil {
		return 0, errors.Wrap(err, "cannot update {{.Singular}}").With(
            {{range .RowType.LogProps}}"{{.}}", row.{{.}}, {{end}}
		)
	}
	return n, nil
}
{{end -}}
{{- if .Method.Upsert}}
// {{.Method.Upsert}} attempts to update a {{.Singular}} row, and if it does not exist then insert it.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Upsert}}(row *{{.RowType.Name}}) error {
	n, err := {{.ReceiverIdent}}.{{.SchemaField}}.Update({{.ReceiverIdent}}.{{.DBField}}, row, {{.QuotedTableName}})
    if err != nil {
		return errors.Wrap(err, "cannot update {{.Singular}} for upsert").With(
            {{range .RowType.LogProps}}"{{.}}", row.{{.}}, {{end}}
        )
    }
    if n > 0 {
        // update successful, row updated
        return nil
    }
	if err := {{.ReceiverIdent}}.{{.SchemaField}}.Insert({{.ReceiverIdent}}.{{.DBField}}, row, {{.QuotedTableName}}); err != nil {
		return errors.Wrap(err, "cannot insert {{.Singular}} for upsert").With(
            {{range .RowType.LogProps}}"{{.}}", row.{{.}}, {{end}}
		)
	}
	return nil
}
{{end -}}
{{- if .Method.Delete}}
// {{.Method.Delete}} deletes a {{.Singular}} row. Returns the number of rows deleted, which should
// be zero or one.
func ({{.ReceiverIdent}} *{{.TypeName}}) {{.Method.Delete}}(row *{{.RowType.Name}}) (int, error) {
	n, err := {{.ReceiverIdent}}.{{.SchemaField}}.Delete({{.ReceiverIdent}}.{{.DBField}}, row, {{.QuotedTableName}})
	if err != nil {
		return 0, errors.Wrap(err, "cannot delete {{.Singular}}").With(
            {{range .RowType.LogProps}}"{{.}}", row.{{.}}, {{end}}
		)
	}
	return n, nil
}
{{end -}}
{{- end}}`))

DefaultTemplate is the template used by default for generating code.

Functions

func DefaultOutput

func DefaultOutput(filename string) string

DefaultOutput returns the default filename for generated output given the filename of the input file.

Types

type Import

type Import struct {
	Name string // Local name, or blank
	Path string
}

Import describes a single import line required for the generated file.

func (*Import) String

func (imp *Import) String() string

type Model

type Model struct {
	CommandLine string
	Package     string
	Imports     []*Import
	QueryTypes  []*QueryType
}

Model contains all of the information required by the template to generate code.

func Parse

func Parse(filename string) (*Model, error)

Parse the file, and any other related files and build the model, which can be used to generate the code.

type QueryType

type QueryType struct {
	TypeName        string
	QuotedTableName string // Table name in quotes
	Singular        string // Describes one instance in error msg
	Plural          string // Describes multiple instances in error msg
	DBField         string // Name of the field of type sqlrow.DB (probably db)
	SchemaField     string // Name of the schema field of type sqlrow.Schema (probably schema)
	ReceiverIdent   string // Name of the receiver identifier
	RowType         *RowType
	Method          struct {
		Get       string
		Select    string
		SelectOne string
		Insert    string
		Update    string
		Delete    string
		Upsert    string
	}
}

QueryType contains all the information the template needs about a struct type for which methods are generated for DB queries.

type RowType

type RowType struct {
	Name      string
	IDArgs    string   // for function arguments specifying primary key ID field(s)
	IDParams  string   // for function parameters specifying primary key ID field(s)
	IDKeyvals string   // for log messages specifying primary key ID field(s)
	LogProps  []string // for error messages
}

RowType contains all the information the template needs about a struct type that is used to represent a single DB table row.

Notes

Bugs

  • I have to think that there is a std library function for doing this.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL