<commit_before>package generator

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"text/template"
	"unicode"

	"github.com/gedex/inflector"
)

func writeToFile(file string, structs structs) error {
	f, err := os.Create(file)
	if err != nil {
		return err
	}

	w := bufio.NewWriter(f)
	defer w.Flush()

	return write(w, structs)
}

func write(w io.Writer, structs structs) error {

	const tplText = `package {{.Package}}

import (
	"database/sql"

	"github.com/monochromegane/goar"
)

var db *sql.DB

func Use(DB *sql.DB) {
	db = DB
}
{{range .}}
func (m {{.Name}}) Find(id {{.PrimaryKeyType}}) (*{{.Name}}, error) {
	r := m.newRelation()
        q, b := r.Select.Where("{{.PrimaryKeyColumn}}", id).Build()
        row := &{{.Name}}{}
        if err := db.QueryRow(q, b...).Scan({{.FieldNames "&row."| joinField}}); err != nil {
                return nil, err
        }
        return row, nil
}

func (m {{.Name}}) Where(cond string, args ...interface{}) *{{.Name}}Relation {
	r := m.newRelation()
        return r.Where(cond, args...)
}

func (m *{{.Name}}) newRelation() *{{.Name}}Relation {
	sel := &goar.Select{}
	sel.Table("{{.Name}}").Columns({{.ColumnNames | joinColumn}})
	return &{{.Name}}Relation{sel}
}

type {{.Name}}Relation struct {
	*goar.Select
}

func (r *{{.Name}}Relation) Query() ([]*{{.Name}}, error) {
        q, b := r.Build()
        rows, err := db.Query(q, b...)
        if err != nil {
                return nil, err
        }
        defer rows.Close()

	results := []*{{.Name}}{}
        for rows.Next() {
                row := &{{.Name}}{}
		if err := rows.Scan({{.FieldNames "&row."| joinField}}); err != nil {
                        return nil, err
                }
                results = append(results, row)
        }
        return results, nil
}

func (r *{{.Name}}Relation) First() (*{{.Name}}, error) {
	q, b := r.OrderBy("{{.PrimaryKeyColumn}}", goar.ASC).Limit(1).Build()
        row := &{{.Name}}{}
        if err := db.QueryRow(q, b...).Scan({{.FieldNames "&row."| joinField}}); err != nil {
                return nil, err
        }
        return row, nil
}

func (r *{{.Name}}Relation) Where(cond string, args ...interface{}) *{{.Name}}Relation {
        r.Select.Where(cond, args...)
        return r
}

func (r *{{.Name}}Relation) And(cond string, args ...interface{}) *{{.Name}}Relation {
        r.Select.And(cond, args...)
        return r
}
{{$model := .}}
{{range .Anotations}}
{{if .BelongsTo}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() (*{{.Arg | capitalize}}, error) {
	return {{.Arg | capitalize}}{}.Where("{{$model.PrimaryKeyColumn}}", m.{{.Arg | capitalize}}ID).First()
}
{{else if .HasOne}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() ([]*{{.Arg | capitalize}}, error) {
	return {{.Arg | capitalize | singularize}}{}.Where("{{$model.TableName}}_id", m.{{$model.PrimaryKeyField}}).First()
}
{{else if .HasMany}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() ([]*{{.Arg | capitalize | singularize}}, error) {
	return {{.Arg | capitalize | singularize}}{}.Where("{{$model.TableName}}_id", m.{{$model.PrimaryKeyField}}).Query()
}
{{end}}
{{end}}
{{end}}
`
	t := template.New("t")
	t.Funcs(template.FuncMap{
		"capitalize":  capitalize,
		"joinColumn":  joinColumn,
		"joinField":   joinField,
		"singularize": inflector.Singularize,
		"pluralize":   inflector.Pluralize,
	})
	tpl := template.Must(t.Parse(tplText))
	if err := tpl.Execute(w, structs); err != nil {
		return err
	}
	return nil
}

func capitalize(s string) string {
	c := []rune(s)
	c[0] = unicode.ToUpper(c[0])
	return string(c)
}

func joinColumn(s []string) string {
	return fmt.Sprintf("\"%s\"", strings.Join(s, "\", \""))
}

func joinField(s []string) string {
	return strings.Join(s, ", ")
}
<commit_msg>Add last to template.<commit_after>package generator

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
	"text/template"
	"unicode"

	"github.com/gedex/inflector"
)

func writeToFile(file string, structs structs) error {
	f, err := os.Create(file)
	if err != nil {
		return err
	}

	w := bufio.NewWriter(f)
	defer w.Flush()

	return write(w, structs)
}

func write(w io.Writer, structs structs) error {

	const tplText = `package {{.Package}}

import (
	"database/sql"

	"github.com/monochromegane/goar"
)

var db *sql.DB

func Use(DB *sql.DB) {
	db = DB
}
{{range .}}
func (m {{.Name}}) Find(id {{.PrimaryKeyType}}) (*{{.Name}}, error) {
	r := m.newRelation()
        q, b := r.Select.Where("{{.PrimaryKeyColumn}}", id).Build()
        row := &{{.Name}}{}
        if err := db.QueryRow(q, b...).Scan({{.FieldNames "&row."| joinField}}); err != nil {
                return nil, err
        }
        return row, nil
}

func (m {{.Name}}) Where(cond string, args ...interface{}) *{{.Name}}Relation {
	r := m.newRelation()
        return r.Where(cond, args...)
}

func (m *{{.Name}}) newRelation() *{{.Name}}Relation {
	sel := &goar.Select{}
	sel.Table("{{.Name}}").Columns({{.ColumnNames | joinColumn}})
	return &{{.Name}}Relation{sel}
}

type {{.Name}}Relation struct {
	*goar.Select
}

func (r *{{.Name}}Relation) Query() ([]*{{.Name}}, error) {
        q, b := r.Build()
        rows, err := db.Query(q, b...)
        if err != nil {
                return nil, err
        }
        defer rows.Close()

	results := []*{{.Name}}{}
        for rows.Next() {
                row := &{{.Name}}{}
		if err := rows.Scan({{.FieldNames "&row."| joinField}}); err != nil {
                        return nil, err
                }
                results = append(results, row)
        }
        return results, nil
}

func (r *{{.Name}}Relation) First() (*{{.Name}}, error) {
	q, b := r.OrderBy("{{.PrimaryKeyColumn}}", goar.ASC).Limit(1).Build()
        row := &{{.Name}}{}
        if err := db.QueryRow(q, b...).Scan({{.FieldNames "&row."| joinField}}); err != nil {
                return nil, err
        }
        return row, nil
}

func (r *{{.Name}}Relation) Last() (*{{.Name}}, error) {
	q, b := r.OrderBy("{{.PrimaryKeyColumn}}", goar.DESC).Limit(1).Build()
        row := &{{.Name}}{}
        if err := db.QueryRow(q, b...).Scan({{.FieldNames "&row."| joinField}}); err != nil {
                return nil, err
        }
        return row, nil
}

func (r *{{.Name}}Relation) Where(cond string, args ...interface{}) *{{.Name}}Relation {
        r.Select.Where(cond, args...)
        return r
}

func (r *{{.Name}}Relation) And(cond string, args ...interface{}) *{{.Name}}Relation {
        r.Select.And(cond, args...)
        return r
}
{{$model := .}}
{{range .Anotations}}
{{if .BelongsTo}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() (*{{.Arg | capitalize}}, error) {
	return {{.Arg | capitalize}}{}.Where("{{$model.PrimaryKeyColumn}}", m.{{.Arg | capitalize}}ID).First()
}
{{else if .HasOne}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() ([]*{{.Arg | capitalize}}, error) {
	return {{.Arg | capitalize | singularize}}{}.Where("{{$model.TableName}}_id", m.{{$model.PrimaryKeyField}}).First()
}
{{else if .HasMany}}
func (m *{{$model.Name}}) {{.Arg | capitalize}}() ([]*{{.Arg | capitalize | singularize}}, error) {
	return {{.Arg | capitalize | singularize}}{}.Where("{{$model.TableName}}_id", m.{{$model.PrimaryKeyField}}).Query()
}
{{end}}
{{end}}
{{end}}
`
	t := template.New("t")
	t.Funcs(template.FuncMap{
		"capitalize":  capitalize,
		"joinColumn":  joinColumn,
		"joinField":   joinField,
		"singularize": inflector.Singularize,
		"pluralize":   inflector.Pluralize,
	})
	tpl := template.Must(t.Parse(tplText))
	if err := tpl.Execute(w, structs); err != nil {
		return err
	}
	return nil
}

func capitalize(s string) string {
	c := []rune(s)
	c[0] = unicode.ToUpper(c[0])
	return string(c)
}

func joinColumn(s []string) string {
	return fmt.Sprintf("\"%s\"", strings.Join(s, "\", \""))
}

func joinField(s []string) string {
	return strings.Join(s, ", ")
}
<|endoftext|>


<commit_before>package form

import (
	"errors"
	"fmt"
	"log"
	"net/url"
	"reflect"
	"strconv"
	"strings"
)

var LogDebug = false

// ValidationError indicates that a field was not valid.
type ValidationError struct {
	Field, Message string
}

// Invalid constructs a ValidationError.
func Invalid(field, msg string, v ...interface{}) *ValidationError {
	return &ValidationError{Field: field, Message: fmt.Sprintf(msg, v...)}
}

func (e ValidationError) Error() string {
	return e.Message
}

// CompoundValidationError represents a list of validation errors.
type CompoundValidationError struct {
	errs []*ValidationError
}

// Len returns the count of validation errors
func (c CompoundValidationError) Len() int {
	return len(c.errs)
}

// Errors returns all validation errors
func (c CompoundValidationError) Errors() []*ValidationError {
	return c.errs
}

func (c CompoundValidationError) Error() string {
	msg := []string{}
	for _, e := range c.errs {
		msg = append(msg, e.Error())
	}
	return fmt.Sprintf("validation errors occurred: %s", strings.Join(msg, "; "))
}

// Validator indicates whether a form field is valid.
type Validator func(value []string) *ValidationError

// Setter decodes a value for a field.
type Setter func(value []string) error

// FieldUnmarshaler unmarshals a specific field.
type FieldUnmarshaler func(field string, value []string) (interface{}, error)

// Unmarshal unmarshals values into the given interface{}.
//
// This walks the values and copies each value into the matching field on the
// interface. It is recommended that o be a pointer to a struct.
//
// Structs may be annotated with tags:
//
//	type Person struct {
//		First string `form:"first_name"`
//		Last string `form:"last_name"`
//	}
//
// Additionally, if a field has a matching Validator or Setter, that function
// will also be called. Validators and Setters are matched based on name.
// For example, given the First field above, the validators and setters would
// be:
//
//	func(p *Person) FormValidateFirst(v []string) *form.ValidationError {}
//	func(p *Person) FormSetFirst(v []string) error {}
//
// A Validator should not alter v or store any part of v.
//
// A Setter may set the field. If it does not, the field will remain unset.
//
// If a Validator fails, the field will not be set, but processing will continue.
// If a Setter fails, the field will not be set, and unmarshaling will be halter.
func Unmarshal(v url.Values, o interface{}) error {
	val := reflect.ValueOf(o)
	if val.Kind() != reflect.Ptr || val.IsNil() {
		return errors.New("unmarshal requires a pointer to a receiver")
	}

	return walk(val, v)
}

// Tags returns the tags on all of the fields on the struct that have 'form' annotations.
func Tags(o interface{}) []*Tag {
	tt := reflect.Indirect(reflect.ValueOf(o)).Type()
	if tt.Kind() != reflect.Struct {
		return []*Tag{}
	}
	tags := []*Tag{}

	// Look for a Field on struct that matches the key name.
	for i := 0; i < tt.NumField(); i++ {
		f := tt.Field(i)
		tag := parseTag(f.Tag.Get("form"))
		if !tag.Ignore && tag.Name == "" {
			tag.Name = f.Name
		}
		tags = append(tags, tag)
	}
	return tags
}

func walk(val reflect.Value, v url.Values) error {
	// Loop through values, top-down specificity
	verrs := []*ValidationError{}
	for key, vals := range v {
		e := findIn(val, key, vals)
		if e == nil {
			continue
		} else if ve, ok := e.(*ValidationError); ok {
			verrs = append(verrs, ve)
			continue
		}
		return e
	}
	if len(verrs) > 0 {
		return CompoundValidationError{errs: verrs}
	}
	return nil
}

func findIn(rv reflect.Value, key string, values []string) error {
	switch reflect.Indirect(rv).Kind() {
	case reflect.Map:
		// The map must take string keys.
		if _, ok := rv.Interface().(map[string]interface{}); ok {
			return assignToMap(rv, key, values)
		}
	case reflect.Struct:
		// Look for struct field named 'key'.
		//return assignToStruct(reflect.Indirect(rv), key, values)
		return assignToStruct(rv, key, values)
	}
	return fmt.Errorf("object %s cannot be used to store values", rv.Type().Name())
}

func assignToMap(rv reflect.Value, key string, values []string) error {
	var err error
	defer func() {
		if e := recover(); e != nil {
			fmt.Printf("Failed map assignment: %v\n", e)
			// FIXME: can't modify err in recover.
			err = fmt.Errorf("failed map assignment: %s", e)
		}
	}()
	// FIXME: There must be a way to find the destination type of a map and
	// appropriately convert to it.
	switch l := len(values); {
	case l == 1:
		rv.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(values[0]))
	case l > 1:
		rv.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(values))
	}
	return err
}

func assignToStruct(rval reflect.Value, key string, values []string) error {
	ptrt := rval.Type()
	rv := reflect.Indirect(rval)
	rt := rv.Type()
	// Look for a Field on struct that matches the key name.
	for i := 0; i < rt.NumField(); i++ {
		f := rt.Field(i)
		tag := parseTag(f.Tag.Get("form"))
		if !tag.Ignore && tag.Name == "" {
			tag.Name = f.Name
		}
		if tag.Name == key {
			validator := "FormValidate" + f.Name
			setter := "FormSet" + f.Name

			// If there is a validator, call it.
			if m, ok := ptrt.MethodByName(validator); ok {
				if LogDebug {
					log.Printf("Validating %s against %v\n", key, m)
				}
				if err := callFormMethod(m, rval, values); err != nil {
					return err
				}
			}

			// For assignment, if there is a setter, use it. Otherwise, do a
			// raw assignment.
			if m, ok := ptrt.MethodByName(setter); ok {
				if LogDebug {
					log.Printf("Setting %s with %v\n", key, m)
				}
				return callFormMethod(m, rval, values)
			} else {
				if LogDebug {
					log.Printf("Assigning %s value %v", key, values)
				}
				err := assignToStructField(rv.FieldByName(f.Name), values)
				if LogDebug && err != nil {
					log.Printf("Error assigning %s value %v: %s", key, values, err)
				}
				return nil
			}
		}
	}
	fmt.Printf("Skipped key %q", key)
	return nil
}

func callFormMethod(method reflect.Method, target reflect.Value, values []string) error {
	retvals := method.Func.Call([]reflect.Value{target, reflect.ValueOf(values)})
	if !retvals[0].IsNil() {
		// An error occurred
		return retvals[0].Interface().(error)
	}
	return nil
}

func assignToStructField(rv reflect.Value, val []string) error {
	// Basically, we need to convert from a string to the appropriate underlying
	// kind, then assign.
	switch rv.Kind() {
	case reflect.String:
		rv.Set(reflect.ValueOf(val[0]))
		return nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToInt(rv, vv)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToUint(rv, vv)
	case reflect.Float32, reflect.Float64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToFloat(rv, vv)
	case reflect.Bool:
		b, err := strconv.ParseBool(val[0])
		reflect.Indirect(rv).Set(reflect.ValueOf(b))
		return err
	case reflect.Slice:
		if _, ok := rv.Interface().([]string); ok {
			reflect.Indirect(rv).Set(reflect.ValueOf(val))
			return nil
		}
		return fmt.Errorf("Only string slices are supported.")
	default:
		return fmt.Errorf("Unsupported kind")
	}
}

func assignToInt(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseInt(val, 0, 0)
	if err != nil {
		return err
	}
	rvv.SetInt(ival)
	return nil
}
func assignToUint(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseUint(val, 0, 0)
	if err != nil {
		return err
	}
	rvv.SetUint(ival)
	return nil
}
func assignToFloat(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseFloat(val, 64)
	if err != nil {
		return err
	}
	rvv.SetFloat(ival)
	return nil
}

func parseTag(str string) *Tag {
	parts := strings.Split(str, ",")
	if len(parts) == 1 && parts[0] == "" {
		return &Tag{}
	}
	t := &Tag{}
	switch n := parts[0]; n {
	case "+":
		t.Group = true
	case "-":
		t.Ignore = true
	default:
		t.Name = n
	}

	for _, p := range parts[1:] {
		switch {
		case p == "omitempty":
			t.Omit = true
		case strings.HasPrefix(p, "prefix="):
			t.Prefix = strings.TrimPrefix(p, "prefix=")
		case strings.HasPrefix(p, "suffix="):
			t.Suffix = strings.TrimPrefix(p, "suffix=")
		}
	}
	return t
}

// tag represents a 'form' tag.
//
//	Name string `form:name`
//	Date time.Time `form:date,omitempty`
//	Address *Address `form:+,omitempty,prefix=addr_
type Tag struct {
	Name           string
	Prefix, Suffix string //prefix=, suffix=
	Omit           bool   // omitempty
	Ignore         bool   // -
	Group          bool   // +
	validator      Validator
	unmarshaler    FieldUnmarshaler
}
<commit_msg>Add debug message for validation failure<commit_after>package form

import (
	"errors"
	"fmt"
	"log"
	"net/url"
	"reflect"
	"strconv"
	"strings"
)

var LogDebug = false

// ValidationError indicates that a field was not valid.
type ValidationError struct {
	Field, Message string
}

// Invalid constructs a ValidationError.
func Invalid(field, msg string, v ...interface{}) *ValidationError {
	return &ValidationError{Field: field, Message: fmt.Sprintf(msg, v...)}
}

func (e ValidationError) Error() string {
	return e.Message
}

// CompoundValidationError represents a list of validation errors.
type CompoundValidationError struct {
	errs []*ValidationError
}

// Len returns the count of validation errors
func (c CompoundValidationError) Len() int {
	return len(c.errs)
}

// Errors returns all validation errors
func (c CompoundValidationError) Errors() []*ValidationError {
	return c.errs
}

func (c CompoundValidationError) Error() string {
	msg := []string{}
	for _, e := range c.errs {
		msg = append(msg, e.Error())
	}
	return fmt.Sprintf("validation errors occurred: %s", strings.Join(msg, "; "))
}

// Validator indicates whether a form field is valid.
type Validator func(value []string) *ValidationError

// Setter decodes a value for a field.
type Setter func(value []string) error

// FieldUnmarshaler unmarshals a specific field.
type FieldUnmarshaler func(field string, value []string) (interface{}, error)

// Unmarshal unmarshals values into the given interface{}.
//
// This walks the values and copies each value into the matching field on the
// interface. It is recommended that o be a pointer to a struct.
//
// Structs may be annotated with tags:
//
//	type Person struct {
//		First string `form:"first_name"`
//		Last string `form:"last_name"`
//	}
//
// Additionally, if a field has a matching Validator or Setter, that function
// will also be called. Validators and Setters are matched based on name.
// For example, given the First field above, the validators and setters would
// be:
//
//	func(p *Person) FormValidateFirst(v []string) *form.ValidationError {}
//	func(p *Person) FormSetFirst(v []string) error {}
//
// A Validator should not alter v or store any part of v.
//
// A Setter may set the field. If it does not, the field will remain unset.
//
// If a Validator fails, the field will not be set, but processing will continue.
// If a Setter fails, the field will not be set, and unmarshaling will be halter.
func Unmarshal(v url.Values, o interface{}) error {
	val := reflect.ValueOf(o)
	if val.Kind() != reflect.Ptr || val.IsNil() {
		return errors.New("unmarshal requires a pointer to a receiver")
	}

	return walk(val, v)
}

// Tags returns the tags on all of the fields on the struct that have 'form' annotations.
func Tags(o interface{}) []*Tag {
	tt := reflect.Indirect(reflect.ValueOf(o)).Type()
	if tt.Kind() != reflect.Struct {
		return []*Tag{}
	}
	tags := []*Tag{}

	// Look for a Field on struct that matches the key name.
	for i := 0; i < tt.NumField(); i++ {
		f := tt.Field(i)
		tag := parseTag(f.Tag.Get("form"))
		if !tag.Ignore && tag.Name == "" {
			tag.Name = f.Name
		}
		tags = append(tags, tag)
	}
	return tags
}

func walk(val reflect.Value, v url.Values) error {
	// Loop through values, top-down specificity
	verrs := []*ValidationError{}
	for key, vals := range v {
		e := findIn(val, key, vals)
		if e == nil {
			continue
		} else if ve, ok := e.(*ValidationError); ok {
			verrs = append(verrs, ve)
			continue
		}
		return e
	}
	if len(verrs) > 0 {
		return CompoundValidationError{errs: verrs}
	}
	return nil
}

func findIn(rv reflect.Value, key string, values []string) error {
	switch reflect.Indirect(rv).Kind() {
	case reflect.Map:
		// The map must take string keys.
		if _, ok := rv.Interface().(map[string]interface{}); ok {
			return assignToMap(rv, key, values)
		}
	case reflect.Struct:
		// Look for struct field named 'key'.
		//return assignToStruct(reflect.Indirect(rv), key, values)
		return assignToStruct(rv, key, values)
	}
	return fmt.Errorf("object %s cannot be used to store values", rv.Type().Name())
}

func assignToMap(rv reflect.Value, key string, values []string) error {
	var err error
	defer func() {
		if e := recover(); e != nil {
			fmt.Printf("Failed map assignment: %v\n", e)
			// FIXME: can't modify err in recover.
			err = fmt.Errorf("failed map assignment: %s", e)
		}
	}()
	// FIXME: There must be a way to find the destination type of a map and
	// appropriately convert to it.
	switch l := len(values); {
	case l == 1:
		rv.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(values[0]))
	case l > 1:
		rv.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(values))
	}
	return err
}

func assignToStruct(rval reflect.Value, key string, values []string) error {
	ptrt := rval.Type()
	rv := reflect.Indirect(rval)
	rt := rv.Type()
	// Look for a Field on struct that matches the key name.
	for i := 0; i < rt.NumField(); i++ {
		f := rt.Field(i)
		tag := parseTag(f.Tag.Get("form"))
		if !tag.Ignore && tag.Name == "" {
			tag.Name = f.Name
		}
		if tag.Name == key {
			validator := "FormValidate" + f.Name
			setter := "FormSet" + f.Name

			// If there is a validator, call it.
			if m, ok := ptrt.MethodByName(validator); ok {
				if LogDebug {
					log.Printf("Validating %s against %v\n", key, m)
				}
				if err := callFormMethod(m, rval, values); err != nil {
					if LogDebug {
						log.Printf("Validation of %s=%v failed: %s", key, values, err)
					}
					return err
				}
			}

			// For assignment, if there is a setter, use it. Otherwise, do a
			// raw assignment.
			if m, ok := ptrt.MethodByName(setter); ok {
				if LogDebug {
					log.Printf("Setting %s with %v\n", key, m)
				}
				return callFormMethod(m, rval, values)
			} else {
				if LogDebug {
					log.Printf("Assigning %s value %v", key, values)
				}
				err := assignToStructField(rv.FieldByName(f.Name), values)
				if LogDebug && err != nil {
					log.Printf("Error assigning %s value %v: %s", key, values, err)
				}
				return nil
			}
		}
	}
	fmt.Printf("Skipped key %q", key)
	return nil
}

func callFormMethod(method reflect.Method, target reflect.Value, values []string) error {
	retvals := method.Func.Call([]reflect.Value{target, reflect.ValueOf(values)})
	if !retvals[0].IsNil() {
		// An error occurred
		return retvals[0].Interface().(error)
	}
	return nil
}

func assignToStructField(rv reflect.Value, val []string) error {
	// Basically, we need to convert from a string to the appropriate underlying
	// kind, then assign.
	switch rv.Kind() {
	case reflect.String:
		rv.Set(reflect.ValueOf(val[0]))
		return nil
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToInt(rv, vv)
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToUint(rv, vv)
	case reflect.Float32, reflect.Float64:
		vv := "0"
		if len(val) > 0 {
			vv = val[0]
		}
		return assignToFloat(rv, vv)
	case reflect.Bool:
		b, err := strconv.ParseBool(val[0])
		reflect.Indirect(rv).Set(reflect.ValueOf(b))
		return err
	case reflect.Slice:
		if _, ok := rv.Interface().([]string); ok {
			reflect.Indirect(rv).Set(reflect.ValueOf(val))
			return nil
		}
		return fmt.Errorf("Only string slices are supported.")
	default:
		return fmt.Errorf("Unsupported kind")
	}
}

func assignToInt(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseInt(val, 0, 0)
	if err != nil {
		return err
	}
	rvv.SetInt(ival)
	return nil
}
func assignToUint(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseUint(val, 0, 0)
	if err != nil {
		return err
	}
	rvv.SetUint(ival)
	return nil
}
func assignToFloat(rv reflect.Value, val string) error {
	rvv := reflect.Indirect(rv)
	if !rvv.CanSet() {
		return fmt.Errorf("cannot set %q (%s)", rv.Type().Name(), rv.Kind().String())
	}
	ival, err := strconv.ParseFloat(val, 64)
	if err != nil {
		return err
	}
	rvv.SetFloat(ival)
	return nil
}

func parseTag(str string) *Tag {
	parts := strings.Split(str, ",")
	if len(parts) == 1 && parts[0] == "" {
		return &Tag{}
	}
	t := &Tag{}
	switch n := parts[0]; n {
	case "+":
		t.Group = true
	case "-":
		t.Ignore = true
	default:
		t.Name = n
	}

	for _, p := range parts[1:] {
		switch {
		case p == "omitempty":
			t.Omit = true
		case strings.HasPrefix(p, "prefix="):
			t.Prefix = strings.TrimPrefix(p, "prefix=")
		case strings.HasPrefix(p, "suffix="):
			t.Suffix = strings.TrimPrefix(p, "suffix=")
		}
	}
	return t
}

// tag represents a 'form' tag.
//
//	Name string `form:name`
//	Date time.Time `form:date,omitempty`
//	Address *Address `form:+,omitempty,prefix=addr_
type Tag struct {
	Name           string
	Prefix, Suffix string //prefix=, suffix=
	Omit           bool   // omitempty
	Ignore         bool   // -
	Group          bool   // +
	validator      Validator
	unmarshaler    FieldUnmarshaler
}
<|endoftext|>


<commit_before>package newapp

import (
	"github.com/gobuffalo/makr"
	sg "github.com/markbates/pop/soda/cmd/generate"
)

func newSodaGenerator() *makr.Generator {
	g := makr.New()

	should := func(data makr.Data) bool {
		if _, ok := data["withPop"]; ok {
			return ok
		}
		return false
	}

	f := makr.NewFile("models/models.go", nModels)
	f.Should = should
	g.Add(f)

	f = makr.NewFile("models/models_test.go", nModelsTest)
	f.Should = should
	g.Add(f)

	c := makr.NewCommand(makr.GoGet("github.com/markbates/pop/..."))
	c.Should = should
	g.Add(c)

	c = makr.NewCommand(makr.GoInstall("github.com/markbates/pop/soda"))
	c.Should = should
	g.Add(c)

	g.Add(&makr.Func{
		Should: should,
		Runner: func(rootPath string, data makr.Data) error {
			data["dialect"] = data["dbType"]
			return sg.GenerateConfig("./database.yml", data)
		},
	})

	return g
}

const nModels = `package models

import (
	"log"
	"os"

	"github.com/markbates/going/defaults"
	"github.com/markbates/pop"
)

// DB is a connection to your database to be used
// throughout your application.
var DB *pop.Connection

func init() {
	var err error
	env := defaults.String(os.Getenv("GO_ENV"), "development")
	DB, err = pop.Connect(env)
	if err != nil {
		log.Fatal(err)
	}
	pop.Debug = env == "development"
}
`

const nModelsTest = `package models_test

import (
	"testing"

	"github.com/gobuffalo/suite"
)

type ModelSuite struct {
	*suite.Model
}

func Test_ModelSuite(t *testing.T) {
	as := &ModelSuite{suite.NewModel()}
	suite.Run(t, as)
}`
<commit_msg>the generated models/models.go file should use envy to look for the GO_ENV<commit_after>package newapp

import (
	"github.com/gobuffalo/makr"
	sg "github.com/markbates/pop/soda/cmd/generate"
)

func newSodaGenerator() *makr.Generator {
	g := makr.New()

	should := func(data makr.Data) bool {
		if _, ok := data["withPop"]; ok {
			return ok
		}
		return false
	}

	f := makr.NewFile("models/models.go", nModels)
	f.Should = should
	g.Add(f)

	f = makr.NewFile("models/models_test.go", nModelsTest)
	f.Should = should
	g.Add(f)

	c := makr.NewCommand(makr.GoGet("github.com/markbates/pop/..."))
	c.Should = should
	g.Add(c)

	c = makr.NewCommand(makr.GoInstall("github.com/markbates/pop/soda"))
	c.Should = should
	g.Add(c)

	g.Add(&makr.Func{
		Should: should,
		Runner: func(rootPath string, data makr.Data) error {
			data["dialect"] = data["dbType"]
			return sg.GenerateConfig("./database.yml", data)
		},
	})

	return g
}

const nModels = `package models

import (
	"log"

	"github.com/gobuffalo/envy"
	"github.com/markbates/pop"
)

// DB is a connection to your database to be used
// throughout your application.
var DB *pop.Connection

func init() {
	var err error
	env := envy.Get("GO_ENV", "development")
	DB, err = pop.Connect(env)
	if err != nil {
		log.Fatal(err)
	}
	pop.Debug = env == "development"
}
`

const nModelsTest = `package models_test

import (
	"testing"

	"github.com/gobuffalo/suite"
)

type ModelSuite struct {
	*suite.Model
}

func Test_ModelSuite(t *testing.T) {
	as := &ModelSuite{suite.NewModel()}
	suite.Run(t, as)
}`
<|endoftext|>


<commit_before>package middleware

import (
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/buro9/microcosm/web/opts"
)

var (
	forceSSLHosts     map[string]struct{}
	forceSSLHostsLock sync.RWMutex
)

// ForceSSL is a middleware that looks at the request scheme and host to
// determine whether this is over http and should be redirected over https.
//
// The rules for this are:
// 1. If req.URL.Scheme == https do nothing.
// 2. If req.URL.Host == *.apidomain, redirect to https.
// 3. If req.URL.Host exists in forceSSLHosts, redirect to https.
//
// forceSSLHosts is loaded by virtue of the session middleware fetching
// knowledge of the site and then populating the forceSSLHosts if
// Site.ForceSSL is true
func ForceSSL(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, req *http.Request) {
		if req.TLS == nil {
			if strings.HasSuffix(req.Host, *opts.APIDomain) {
				http.Redirect(
					w,
					req,
					redirectURLtoTLS(req),
					http.StatusMovedPermanently,
				)
				return
			}

			forceSSLHostsLock.RLock()
			_, ok := forceSSLHosts[req.Host]
			forceSSLHostsLock.RUnlock()

			if ok {
				http.Redirect(
					w,
					req,
					redirectURLtoTLS(req),
					http.StatusMovedPermanently,
				)
				return
			}
		}

		// SSL not being forced, serve the content
		h.ServeHTTP(w, req)
	}

	return http.HandlerFunc(fn)
}

func redirectURLtoTLS(req *http.Request) string {
	if req.TLS != nil {
		return req.URL.String()
	}

	if strings.Contains(*opts.TLSListen, ":443") {
		return fmt.Sprintf(
			"https://%s%s",
			req.Host,
			req.URL.RequestURI(),
		)
	}

	addrPort := strings.Split(*opts.TLSListen, ":")
	if len(addrPort) != 2 || addrPort[1] == "443" {
		return fmt.Sprintf(
			"https://%s%s",
			req.Host,
			req.URL.RequestURI(),
		)
	}

	return fmt.Sprintf(
		"https://%s:%d%s",
		req.Host,
		addrPort[1],
		req.URL.RequestURI(),
	)
}
<commit_msg>Fixed bad sprintf<commit_after>package middleware

import (
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/buro9/microcosm/web/opts"
)

var (
	forceSSLHosts     map[string]struct{}
	forceSSLHostsLock sync.RWMutex
)

// ForceSSL is a middleware that looks at the request scheme and host to
// determine whether this is over http and should be redirected over https.
//
// The rules for this are:
// 1. If req.URL.Scheme == https do nothing.
// 2. If req.URL.Host == *.apidomain, redirect to https.
// 3. If req.URL.Host exists in forceSSLHosts, redirect to https.
//
// forceSSLHosts is loaded by virtue of the session middleware fetching
// knowledge of the site and then populating the forceSSLHosts if
// Site.ForceSSL is true
func ForceSSL(h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, req *http.Request) {
		if req.TLS == nil {
			if strings.HasSuffix(req.Host, *opts.APIDomain) {
				http.Redirect(
					w,
					req,
					redirectURLtoTLS(req),
					http.StatusMovedPermanently,
				)
				return
			}

			forceSSLHostsLock.RLock()
			_, ok := forceSSLHosts[req.Host]
			forceSSLHostsLock.RUnlock()

			if ok {
				http.Redirect(
					w,
					req,
					redirectURLtoTLS(req),
					http.StatusMovedPermanently,
				)
				return
			}
		}

		// SSL not being forced, serve the content
		h.ServeHTTP(w, req)
	}

	return http.HandlerFunc(fn)
}

func redirectURLtoTLS(req *http.Request) string {
	if req.TLS != nil {
		return req.URL.String()
	}

	if strings.Contains(*opts.TLSListen, ":443") {
		return fmt.Sprintf(
			"https://%s%s",
			req.Host,
			req.URL.RequestURI(),
		)
	}

	addrPort := strings.Split(*opts.TLSListen, ":")
	if len(addrPort) != 2 || addrPort[1] == "443" {
		return fmt.Sprintf(
			"https://%s%s",
			req.Host,
			req.URL.RequestURI(),
		)
	}

	return fmt.Sprintf(
		"https://%s:%s%s",
		req.Host,
		addrPort[1],
		req.URL.RequestURI(),
	)
}
<|endoftext|>


<commit_before><commit_msg>remove limits to concurrent writers<commit_after><|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/gitstore"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/timer"
)

// btgit is a script that queries a BigTable based GitStore.

func main() {
	// Define the flags and parse them.
	var (
		btInstanceID = flag.String("bt_instance", "production", "Big Table instance")
		btTableID    = flag.String("bt_table", "git-repos", "BigTable table ID")
		listBranches = flag.Bool("list", false, "List all branches and quit")
		listRepos    = flag.Bool("list_repos", false, "List all repositories quit")
		loadGraph    = flag.Bool("load_graph", false, "Load the entire commit graph. For performance check only.")
		projectID    = flag.String("project", "skia-public", "ID of the GCP project")
		branch       = flag.String("branch", "", "Name of the branch to list. Empty means all commits across all branches.")
		limit        = flag.Int("limit", 100, "Number of commits to show. 0 means no limit")
		repoURL      = flag.String("repo_url", "", "URL of the git repo.")
		verbose      = flag.Bool("verbose", false, "Indicate whether to log the commits we find.")
	)
	common.Init()

	// Configure the bigtable instance.
	config := &gitstore.BTConfig{
		ProjectID:  *projectID,
		InstanceID: *btInstanceID,
		TableID:    *btTableID,
	}

	// Normalize the URL as GitStore does.
	normURL, err := git.NormalizeURL(*repoURL)
	if err != nil {
		sklog.Fatalf("Error getting normalized URL for %s:  %s", *repoURL, err)
	}

	ctx := context.Background()

	// Get all repos and find the one we want plus the branch we want.
	allRepoInfos, err := gitstore.AllRepos(ctx, config)
	if err != nil {
		sklog.Fatalf("Error retrieving lists of repositories: %s", err)
	}
	sklog.Infof("Got all repo info: %d", len(allRepoInfos))

	if *listRepos {
		for _, repo := range allRepoInfos {
			sklog.Infof("Repo: %s ", repo.RepoURL)
			if *verbose {
				logBranches("    ", repo.Branches)
			}
		}
		return
	}

	// Make sure our repoURL exists.
	repoInfo, ok := allRepoInfos[normURL]
	if !ok {
		sklog.Fatalf("Repo %s could not found in BigTable", normURL)
	}
	sklog.Infof("Found repo for %s", repoInfo.RepoURL)

	if *listBranches {
		logBranches("", repoInfo.Branches)
		return
	}

	// Make sure the target branch exists
	foundBranch, ok := repoInfo.Branches[*branch]
	if !ok {
		sklog.Fatalf("Error, branch %q does not exist in BigTable git", *branch)
	}
	sklog.Infof("Found branch %q in repo for %s", *branch, repoInfo.RepoURL)

	// Create a new BT based GitStore.
	gitStore, err := gitstore.NewBTGitStore(ctx, config, *repoURL)
	if err != nil {
		sklog.Fatalf("Error instantiating git store: %s", err)
	}
	sklog.Infof("Opened gitstore")

	// Determine how many commits we fetch.
	startIndex := 0
	branchLength := foundBranch.Index + 1
	if *limit > 0 {
		startIndex = branchLength - *limit
	}

	// Fetch the graph of the repository to see if it performs well enough.
	if *loadGraph {
		ggt := timer.New("Getting graph")
		commitGraph, err := gitStore.GetGraph(ctx)
		if err != nil {
			sklog.Fatalf("Error retrieving graph: %s", err)
		}
		ggt.Stop()
		sklog.Infof("Loaded graph with %d nodes", len(commitGraph.Nodes))
	}

	// Retrieve the index commits we are interested in.
	indexCommits, err := gitStore.RangeN(ctx, startIndex, branchLength, *branch)
	if err != nil {
		sklog.Fatalf("Error retrieving branch %q: %s", *branch, err)
	}

	// Isolate the hashes and retrieve the LongCommits.
	hashes := make([]string, 0, len(indexCommits))
	for _, commit := range indexCommits {
		hashes = append(hashes, commit.Hash)
	}

	tlc := timer.New("Long commits")
	longCommits, err := gitStore.Get(ctx, hashes)
	if err != nil {
		sklog.Fatalf("Error retrieving long commits: %s", err)
	}
	tlc.Stop()
	sklog.Infof("Long commits loaded: %d", len(longCommits))

	for idx := len(longCommits) - 1; idx >= 0; idx-- {
		c := longCommits[idx]
		if c == nil {
			sklog.Fatalf("Programming error: Unable to retrieve long commit for hash %s", hashes[idx])
		}
		if *verbose {
			sklog.Infof("%s %40s %v %s", c.Hash, c.Author, c.Timestamp, c.Subject)
		}
	}
}

func logBranches(indent string, branches map[string]*gitstore.BranchPointer) {
	for branchName, branch := range branches {
		sklog.Infof("Branch %s @ %s with index %d", branchName, branch.Head, branch.Index)
	}
}
<commit_msg>btgit - Actually produce output.<commit_after>package main

import (
	"context"
	"flag"
	"fmt"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/gitstore"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/timer"
)

// btgit is a script that queries a BigTable based GitStore.

func main() {
	// Define the flags and parse them.
	var (
		btInstanceID = flag.String("bt_instance", "production", "Big Table instance")
		btTableID    = flag.String("bt_table", "git-repos", "BigTable table ID")
		listBranches = flag.Bool("list", false, "List all branches and quit")
		listRepos    = flag.Bool("list_repos", false, "List all repositories quit")
		loadGraph    = flag.Bool("load_graph", false, "Load the entire commit graph. For performance check only.")
		projectID    = flag.String("project", "skia-public", "ID of the GCP project")
		branch       = flag.String("branch", "", "Name of the branch to list. Empty means all commits across all branches.")
		limit        = flag.Int("limit", 100, "Number of commits to show. 0 means no limit")
		repoURL      = flag.String("repo_url", "", "URL of the git repo.")
		verbose      = flag.Bool("verbose", false, "Indicate whether to log the commits we find.")
	)
	common.Init()

	// Configure the bigtable instance.
	config := &gitstore.BTConfig{
		ProjectID:  *projectID,
		InstanceID: *btInstanceID,
		TableID:    *btTableID,
	}

	// Normalize the URL as GitStore does.
	normURL, err := git.NormalizeURL(*repoURL)
	if err != nil {
		sklog.Fatalf("Error getting normalized URL for %s:  %s", *repoURL, err)
	}

	ctx := context.Background()

	// Get all repos and find the one we want plus the branch we want.
	allRepoInfos, err := gitstore.AllRepos(ctx, config)
	if err != nil {
		sklog.Fatalf("Error retrieving lists of repositories: %s", err)
	}
	sklog.Infof("Got all repo info: %d", len(allRepoInfos))

	if *listRepos {
		for _, repo := range allRepoInfos {
			fmt.Printf("Repo: %s ", repo.RepoURL)
			if *verbose {
				logBranches("    ", repo.Branches)
			}
		}
		return
	}

	// Make sure our repoURL exists.
	repoInfo, ok := allRepoInfos[normURL]
	if !ok {
		sklog.Fatalf("Repo %s could not found in BigTable", normURL)
	}
	sklog.Infof("Found repo for %s", repoInfo.RepoURL)

	if *listBranches {
		logBranches("", repoInfo.Branches)
		return
	}

	// Make sure the target branch exists
	foundBranch, ok := repoInfo.Branches[*branch]
	if !ok {
		sklog.Fatalf("Error, branch %q does not exist in BigTable git", *branch)
	}
	sklog.Infof("Found branch %q in repo for %s", *branch, repoInfo.RepoURL)

	// Create a new BT based GitStore.
	gitStore, err := gitstore.NewBTGitStore(ctx, config, *repoURL)
	if err != nil {
		sklog.Fatalf("Error instantiating git store: %s", err)
	}
	sklog.Infof("Opened gitstore")

	// Determine how many commits we fetch.
	startIndex := 0
	branchLength := foundBranch.Index + 1
	if *limit > 0 {
		startIndex = branchLength - *limit
	}

	// Fetch the graph of the repository to see if it performs well enough.
	if *loadGraph {
		ggt := timer.New("Getting graph")
		commitGraph, err := gitStore.GetGraph(ctx)
		if err != nil {
			sklog.Fatalf("Error retrieving graph: %s", err)
		}
		ggt.Stop()
		sklog.Infof("Loaded graph with %d nodes", len(commitGraph.Nodes))
	}

	// Retrieve the index commits we are interested in.
	indexCommits, err := gitStore.RangeN(ctx, startIndex, branchLength, *branch)
	if err != nil {
		sklog.Fatalf("Error retrieving branch %q: %s", *branch, err)
	}

	// Isolate the hashes and retrieve the LongCommits.
	hashes := make([]string, 0, len(indexCommits))
	for _, commit := range indexCommits {
		hashes = append(hashes, commit.Hash)
	}

	tlc := timer.New("Long commits")
	longCommits, err := gitStore.Get(ctx, hashes)
	if err != nil {
		sklog.Fatalf("Error retrieving long commits: %s", err)
	}
	tlc.Stop()
	sklog.Infof("Long commits loaded: %d", len(longCommits))

	for idx := len(longCommits) - 1; idx >= 0; idx-- {
		c := longCommits[idx]
		if c == nil {
			sklog.Fatalf("Programming error: Unable to retrieve long commit for hash %s", hashes[idx])
		}
		if *verbose {
			fmt.Printf("%s %40s %v %s", c.Hash, c.Author, c.Timestamp, c.Subject)
		}
	}
}

func logBranches(indent string, branches map[string]*gitstore.BranchPointer) {
	for branchName, branch := range branches {
		fmt.Printf("Branch %s @ %s with index %d\n", branchName, branch.Head, branch.Index)
	}
}
<|endoftext|>


<commit_before>package _1_sorts

func BubbleSort(a []int) {
	arrLen := len(a)
	if arrLen <= 1 {
		return
	}
	for i := arrLen - 1; i > 0; i-- {
		for j := 0; j < i; j++ {
			if a[j] > a[j+1] {
				tmp := a[j+1]
				a[j+1] = a[j]
				a[j] = tmp
			}
		}
	}
}

func InsertSort(a []int) {
	arrLen := len(a)
	if arrLen <= 1 {
		return
	}
	for i := 1; i < arrLen; i++ {
		v := a[i]
		j := i - 1
		for ; j >= 0; j-- {
			if a[j] > v {
				a[j+1] = a[j]
			}
		}
		a[j+1] = v
	}
}

func SelectionSort(a []int) {
	arrLen := len(a)
	if arrLen <= 1 {
		return
	}
	for i := 0; i < arrLen; i++ {
		minIndex := i
		for j := i + 1; j < arrLen; j++ {
			if a[j] < a[minIndex] {
				minIndex = j
			}
		}
		if minIndex != i {
			tmp := a[minIndex]
			a[minIndex] = a[i]
			a[i] = tmp
		}
	}
}
<commit_msg>Update Sort.go<commit_after>package _1_sorts

/*
冒泡排序、插入排序、选择排序
 */

//冒泡排序，a是数组，n表示数组大小
func BubbleSort(a []int, n int) {
	if n <= 1 {
		return
	}
	for i := 0; i < n; i++ {
		// 提前退出标志
		flag := false
		for j := 0; j < n-i-1; j++ {
			if a[j] > a[j+1] {
				a[j], a[j+1] = a[j+1], a[j]
				//此次冒泡有数据交换
				flag = true
			}
		}
		// 如果没有交换数据，提前退出
		if !flag {
			break
		}
	}
}

// 插入排序，a表示数组，n表示数组大小
func InsertionSort(a []int, n int) {
	if n <= 1 {
		return
	}
	for i := 1; i < n; i++ {
		value := a[i]
		j := i - 1
		//查找要插入的位置并移动数据
		for ; j >= 0; j-- {
			if a[j] > value {
				a[j+1] = a[j]
			} else {
				break
			}
		}
		a[j+1] = value
	}
}

// 选择排序，a表示数组，n表示数组大小
func SelectionSort(a []int, n int) {
	if n <= 1 {
		return
	}
	for i := 0; i < n; i++ {
		// 查找最小值
		minIndex := i
		for j := i + 1; j < n; j++ {
			if a[j] < a[minIndex] {
				minIndex = j
			}
		}
		// 交换
		a[i], a[minIndex] = a[minIndex],a[i]

	}
}
<|endoftext|>


<commit_before>package envplate

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"

	"github.com/yawn/envmap"
)

const (
	noDefaultDefined    = ""
	notAnEscapeSequence = ""
)

type Handler struct {
	Backup bool
	DryRun bool
	Strict bool
}

var exp = regexp.MustCompile(`(\\*)\$\{(.+?)(?:(\:\-)(.*?))?\}`)

func (h *Handler) Apply(globs []string) error {

	matches := false

	for _, pattern := range globs {

		files, err := filepath.Glob(pattern)

		if err != nil {
			return err
		}

		for _, name := range files {

			if info, _ := os.Stat(name); info.IsDir() {
				continue
			}

			matches = true

			if err := h.parse(name); err != nil {
				return Log(ERROR, "Error while parsing '%s': %v", name, err)
			}

		}

	}

	if !matches {
		return Log(ERROR, "Zero files matched passed globs '%v'", globs)
	}

	return nil

}

func (h *Handler) parse(file string) error {

	env := envmap.Import()
	content, err := ioutil.ReadFile(file)

	if err != nil {
		return Log(ERROR, "Cannot open %s: %v", file, err)
	}

	Log(DEBUG, "Parsing environment references in '%s'", file)

	var errors []error

	parsed := exp.ReplaceAllStringFunc(string(content), func(match string) string {

		var (
			esc, key, sep, def = capture(match)
			value, keyDefined  = env[key]
		)

		if len(esc)%2 == 1 {

			escaped := escape(match)

			if escaped == notAnEscapeSequence {
				errors = append(errors, Log(ERROR, "Tried to escape '%s', but was no escape sequence", content))
			}

			return escaped

		}

		if !keyDefined {

			if sep == noDefaultDefined {
				errors = append(errors, Log(ERROR, "'%s' requires undeclared environment variable '%s', no default is given", file, key))
			} else {

				if h.Strict {
					errors = append(errors, Log(ERROR, "'%s' requires undeclared environment variable '%s', but cannot use default '%s' (strict-mode)", file, key, def))
				} else {
					Log(DEBUG, "'%s' requires undeclared environment variable '%s', using default '%s'", file, key, def)
					value = def
				}

			}

		} else {
			Log(DEBUG, "Expanding reference to '%s' to value '%s'", key, value)
		}

		if len(esc) > 0 {
			value = esc[:len(esc)/2] + value
		}

		return value

	})

	if h.DryRun {
		Log(INFO, "Expanding all references in '%s' without doing anything (dry-run)", file)
		Log(RAW, parsed)
	} else {

		if h.Backup {

			Log(DEBUG, "Creating backup of '%s'", file)

			if err := createBackup(file); err != nil {
				return err
			}

		}

		mode, err := filemode(file)

		if err != nil {
			return err
		}

		if err := ioutil.WriteFile(file, []byte(parsed), mode); err != nil {
			return err
		}

	}

	if len(errors) > 0 {
		return errors[0]
	}

	return nil

}

func capture(s string) (esc, key, sep, def string) {

	matches := exp.FindStringSubmatch(s)

	esc = matches[1]
	key = matches[2]
	sep = matches[3]
	def = matches[4]

	return esc, key, sep, def

}

func escape(s string) (escaped string) {

	expEscaped := regexp.MustCompile(`(\\+)(.*)`)
	matches := expEscaped.FindStringSubmatch(s)

	if matches == nil {
		return notAnEscapeSequence
	}

	bss := matches[1]

	if len(bss)%2 != 1 {
		return notAnEscapeSequence
	}

	parsedBss := bss[:len(bss)-1][:(len(bss)-1)/2]

	escaped = parsedBss + matches[2]

	Log(DEBUG, "Substituting escaped sequence '%s' with '%s'", s, escaped)

	return escaped

}
<commit_msg>Changed log level for a message<commit_after>package envplate

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"

	"github.com/yawn/envmap"
)

const (
	noDefaultDefined    = ""
	notAnEscapeSequence = ""
)

type Handler struct {
	Backup bool
	DryRun bool
	Strict bool
}

var exp = regexp.MustCompile(`(\\*)\$\{(.+?)(?:(\:\-)(.*?))?\}`)

func (h *Handler) Apply(globs []string) error {

	matches := false

	for _, pattern := range globs {

		files, err := filepath.Glob(pattern)

		if err != nil {
			return err
		}

		for _, name := range files {

			if info, _ := os.Stat(name); info.IsDir() {
				continue
			}

			matches = true

			if err := h.parse(name); err != nil {
				return Log(ERROR, "Error while parsing '%s': %v", name, err)
			}

		}

	}

	if !matches {
		return Log(ERROR, "Zero files matched passed globs '%v'", globs)
	}

	return nil

}

func (h *Handler) parse(file string) error {

	env := envmap.Import()
	content, err := ioutil.ReadFile(file)

	if err != nil {
		return Log(ERROR, "Cannot open %s: %v", file, err)
	}

	Log(DEBUG, "Parsing environment references in '%s'", file)

	var errors []error

	parsed := exp.ReplaceAllStringFunc(string(content), func(match string) string {

		var (
			esc, key, sep, def = capture(match)
			value, keyDefined  = env[key]
		)

		if len(esc)%2 == 1 {

			escaped := escape(match)

			if escaped == notAnEscapeSequence {
				errors = append(errors, Log(ERROR, "Tried to escape '%s', but was no escape sequence", content))
			}

			return escaped

		}

		if !keyDefined {

			if sep == noDefaultDefined {
				errors = append(errors, Log(ERROR, "'%s' requires undeclared environment variable '%s', no default is given", file, key))
			} else {

				if h.Strict {
					errors = append(errors, Log(ERROR, "'%s' requires undeclared environment variable '%s', but cannot use default '%s' (strict-mode)", file, key, def))
				} else {
					Log(DEBUG, "'%s' requires undeclared environment variable '%s', using default '%s'", file, key, def)
					value = def
				}

			}

		} else {
			Log(DEBUG, "Expanding reference to '%s' to value '%s'", key, value)
		}

		if len(esc) > 0 {
			value = esc[:len(esc)/2] + value
		}

		return value

	})

	if h.DryRun {
		Log(DEBUG, "Expanding all references in '%s' without doing anything (dry-run)", file)
		Log(RAW, parsed)
	} else {

		if h.Backup {

			Log(DEBUG, "Creating backup of '%s'", file)

			if err := createBackup(file); err != nil {
				return err
			}

		}

		mode, err := filemode(file)

		if err != nil {
			return err
		}

		if err := ioutil.WriteFile(file, []byte(parsed), mode); err != nil {
			return err
		}

	}

	if len(errors) > 0 {
		return errors[0]
	}

	return nil

}

func capture(s string) (esc, key, sep, def string) {

	matches := exp.FindStringSubmatch(s)

	esc = matches[1]
	key = matches[2]
	sep = matches[3]
	def = matches[4]

	return esc, key, sep, def

}

func escape(s string) (escaped string) {

	expEscaped := regexp.MustCompile(`(\\+)(.*)`)
	matches := expEscaped.FindStringSubmatch(s)

	if matches == nil {
		return notAnEscapeSequence
	}

	bss := matches[1]

	if len(bss)%2 != 1 {
		return notAnEscapeSequence
	}

	parsedBss := bss[:len(bss)-1][:(len(bss)-1)/2]

	escaped = parsedBss + matches[2]

	Log(DEBUG, "Substituting escaped sequence '%s' with '%s'", s, escaped)

	return escaped

}
<|endoftext|>


<commit_before>package otgrpc

import (
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// A Class is a set of types of outcomes (including errors) that will often
// be handled in the same way.
type Class string

const (
	Unknown Class = "0xx"
	// Success represents outcomes that achieved the desired results.
	Success Class = "2xx"
	// ClientError represents errors that were the client's fault.
	ClientError Class = "4xx"
	// ServerError represents errors that were the server's fault.
	ServerError Class = "5xx"
)

// ErrorClass returns the class of the given error
func ErrorClass(err error) Class {
	if s, ok := status.FromError(err); ok {
		switch s.Code() {
		// Success or "success"
		case codes.OK, codes.Canceled:
			return Success

		// Client errors
		case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists,
			codes.PermissionDenied, codes.Unauthenticated, codes.FailedPrecondition,
			codes.OutOfRange:
			return ClientError

		// Server errors
		case codes.DeadlineExceeded, codes.ResourceExhausted, codes.Aborted,
			codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss:
			return ServerError

		// Not sure
		case codes.Unknown:
			fallthrough
		default:
			return Unknown
		}
	}
	return Unknown
}

// SetSpanTags sets one or more tags on the given span according to the
// error.
func SetSpanTags(span opentracing.Span, err error, client bool) {
	c := ErrorClass(err)
	code := codes.Unknown
	if s, ok := status.FromError(err); ok {
		code = s.Code()
	}
	span.SetTag("response_code", code)
	span.SetTag("response_class", c)
	if client || c == ServerError {
		ext.Error.Set(span, true)
	}
}
<commit_msg>address PR comment<commit_after>package otgrpc

import (
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// A Class is a set of types of outcomes (including errors) that will often
// be handled in the same way.
type Class string

const (
	Unknown Class = "0xx"
	// Success represents outcomes that achieved the desired results.
	Success Class = "2xx"
	// ClientError represents errors that were the client's fault.
	ClientError Class = "4xx"
	// ServerError represents errors that were the server's fault.
	ServerError Class = "5xx"
)

// ErrorClass returns the class of the given error
func ErrorClass(err error) Class {
	if s, ok := status.FromError(err); ok {
		switch s.Code() {
		// Success or "success"
		case codes.OK, codes.Canceled:
			return Success

		// Client errors
		case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists,
			codes.PermissionDenied, codes.Unauthenticated, codes.FailedPrecondition,
			codes.OutOfRange:
			return ClientError

		// Server errors
		case codes.DeadlineExceeded, codes.ResourceExhausted, codes.Aborted,
			codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss:
			return ServerError

		// Not sure
		case codes.Unknown:
			fallthrough
		default:
			return Unknown
		}
	}
	return Unknown
}

// SetSpanTags sets one or more tags on the given span according to the
// error.
func SetSpanTags(span opentracing.Span, err error, client bool) {
	c := ErrorClass(err)
	code := codes.Unknown
	if s, ok := status.FromError(err); ok {
		code = s.Code()
	}
	span.SetTag("response_code", code)
	span.SetTag("response_class", c)
    if err == nil {
        return
    }
	if client || c == ServerError {
		ext.Error.Set(span, true)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go-SQLite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlite3

/*
#include "sqlite3.h"

int shell_main(int, void*);
*/
import "C"

import (
	"bytes"
	"fmt"
	"os"
	"reflect"
	"unsafe"
)

// NamedArgs is a name/value map of arguments passed to a prepared statement
// that uses ?NNN, :AAA, @AAA, and/or $AAA parameter formats. Name matching is
// case-sensitive and the prefix character (one of [?:@$]) must be included in
// the name. Names that are missing from the map are treated as NULL. Names that
// are not used in the prepared statement are ignored.
//
// It is not possible to mix named and anonymous ("?") parameters in the same
// statement.
// [http://www.sqlite.org/lang_expr.html#varparam]
type NamedArgs map[string]interface{}

// RowMap may be passed as the last (or only) argument to Stmt.Scan to create a
// map of all remaining column/value pairs in the current row. The map is not
// cleared before being populated with new column values. Assignment is
// performed in left-to-right column order, and values may be overwritten if the
// query returns two or more columns with identical names.
type RowMap map[string]interface{}

// RawString and RawBytes are special string and []byte types that may be used
// for database input and output without the cost of an extra copy operation.
//
// When used as an argument to a statement, the contents are bound using
// SQLITE_STATIC instead of SQLITE_TRANSIENT flag. This requires the contents to
// remain valid and unmodified until the end of statement execution. In
// particular, the caller must keep a reference to the value to prevent it from
// being garbage collected.
//
// When used for retrieving query output, the internal string/[]byte pointer is
// set to reference memory belonging to SQLite. The memory remains valid until
// another method is called on the Stmt object and should not be modified.
type (
	RawString string
	RawBytes  []byte
)

// ZeroBlob is a special argument type used to allocate a zero-filled BLOB of
// the specified length. The BLOB can then be opened for incremental I/O to
// efficiently transfer a large amount of data. The maximum BLOB size can be
// queried with Conn.Limit(LIMIT_LENGTH, -1).
type ZeroBlob int

// BusyFunc is a callback function invoked by SQLite when it is unable to
// acquire a lock on a table. Count is the number of times that the callback has
// been invoked for this locking event so far. If the function returns false,
// then the operation is aborted. Otherwise, the function should block for a
// while before returning true and letting SQLite make another locking attempt.
type BusyFunc func(count int) (retry bool)

// CommitFunc is a callback function invoked by SQLite before a transaction is
// committed. If the function returns true, the transaction is rolled back.
type CommitFunc func() (abort bool)

// RollbackFunc is a callback function invoked by SQLite when a transaction is
// rolled back.
type RollbackFunc func()

// UpdateFunc is a callback function invoked by SQLite when a row is updated,
// inserted, or deleted.
type UpdateFunc func(op int, db, tbl RawString, row int64)

// Error is returned for all SQLite API result codes other than OK, ROW, and
// DONE.
type Error struct {
	rc  int
	msg string
}

// libErr reports an error originating in SQLite. The error message is obtained
// from the database connection when possible, which may include some additional
// information. Otherwise, the result code is translated to a generic message.
func libErr(rc C.int, db *C.sqlite3) error {
	if db != nil && rc == C.sqlite3_errcode(db) {
		return &Error{int(rc), C.GoString(C.sqlite3_errmsg(db))}
	}
	return &Error{int(rc), C.GoString(C.sqlite3_errstr(rc))}
}

// pkgErr reports an error originating in this package.
func pkgErr(rc int, msg string, v ...interface{}) error {
	if len(v) == 0 {
		return &Error{rc, msg}
	}
	return &Error{rc, fmt.Sprintf(msg, v...)}
}

// Code returns the SQLite extended result code.
func (err *Error) Code() int {
	return err.rc
}

// Error implements the error interface.
func (err *Error) Error() string {
	return fmt.Sprintf("sqlite3: %s [%d]", err.msg, err.rc)
}

// Errors returned for access attempts to closed or invalid objects.
var (
	ErrBadConn   = &Error{MISUSE, "closed or invalid connection"}
	ErrBadStmt   = &Error{MISUSE, "closed or invalid statement"}
	ErrBadIO     = &Error{MISUSE, "closed or invalid incremental I/O operation"}
	ErrBadBackup = &Error{MISUSE, "closed or invalid backup operation"}
)

// Shell is deprecated and will be removed in the near future. Don't use it!
func Shell(args ...string) int {
	if initErr != nil {
		return 127
	}
	args = append([]string{os.Args[0]}, args...)

	// Copy all arguments into a single []byte, terminating each one with '\0'
	buf := make([]byte, 0, 256)
	for _, arg := range args {
		buf = append(append(buf, arg...), 0)
	}

	// Fill argv with pointers to the start of each null-terminated string
	argv := make([]uintptr, len(args))
	base := uintptr(cBytes(buf))
	for i, arg := range args {
		argv[i] = base
		base += uintptr(len(arg)) + 1
	}
	return int(C.shell_main(C.int(len(args)), unsafe.Pointer(&argv[0])))
}

// Complete returns true if sql appears to contain a complete statement that is
// ready to be parsed. This does not validate the statement syntax.
// [http://www.sqlite.org/c3ref/complete.html]
func Complete(sql string) bool {
	if initErr != nil {
		return false
	}
	sql += "\x00"
	return C.sqlite3_complete(cStr(sql)) == 1
}

// ReleaseMemory attempts to free n bytes of heap memory by deallocating
// non-essential memory held by the SQLite library. It returns the number of
// bytes actually freed.
//
// This function is currently a no-op because SQLite is not compiled with the
// SQLITE_ENABLE_MEMORY_MANAGEMENT option.
// [http://www.sqlite.org/c3ref/release_memory.html]
func ReleaseMemory(n int) int {
	if initErr != nil {
		return 0
	}
	return int(C.sqlite3_release_memory(C.int(n)))
}

// SingleThread returns true if the SQLite library was compiled with
// -DSQLITE_THREADSAFE=0. With this threading mode, all mutex code is omitted
// and this package becomes unsafe for concurrent access, even to separate
// database connections.
//
// This function was needed in Go 1.0 when the package was dynamically linked
// with the system's SQLite library on *nix. As of Go 1.1, the SQLite
// amalgamation is compiled into the package with -DSQLITE_THREADSAFE=2, so this
// function always returns false and is kept only for backward compatibility.
// [http://www.sqlite.org/threadsafe.html]
func SingleThread() bool {
	return initErr == nil && C.sqlite3_threadsafe() == 0
}

// SoftHeapLimit sets and/or queries the soft limit on the amount of heap memory
// that may be allocated by SQLite. A negative value for n keeps the current
// limit, while 0 removes the limit. The previous limit value is returned, with
// negative values indicating an error.
// [http://www.sqlite.org/c3ref/soft_heap_limit64.html]
func SoftHeapLimit(n int64) int64 {
	if initErr != nil {
		return -1
	}
	return int64(C.sqlite3_soft_heap_limit64(C.sqlite3_int64(n)))
}

// SourceId returns the check-in identifier of SQLite within its configuration
// management system (e.g. "2013-01-09 11:53:05
// c0e09560d26f0a6456be9dd3447f5311eb4f238f").
// [http://www.sqlite.org/c3ref/c_source_id.html]
func SourceId() string {
	if initErr != nil {
		return ""
	}
	return C.GoString(C.sqlite3_sourceid())
}

// Status returns the current and peak values of a core performance
// counter, specified by one of the STATUS constants. If reset is true, the peak
// value is reset back down to the current value after retrieval.
// [http://www.sqlite.org/c3ref/status.html]
func Status(op int, reset bool) (cur, peak int, err error) {
	if initErr != nil {
		return 0, 0, initErr
	}
	var cCur, cPeak C.int
	rc := C.sqlite3_status(C.int(op), &cCur, &cPeak, cBool(reset))
	if rc != OK {
		return 0, 0, pkgErr(MISUSE, "invalid status op (%d)", op)
	}
	return int(cCur), int(cPeak), nil
}

// Version returns the SQLite version as a string in the format "X.Y.Z[.N]".
// [http://www.sqlite.org/c3ref/libversion.html]
func Version() string {
	if initErr != nil {
		return ""
	}
	return C.GoString(C.sqlite3_libversion())
}

// VersionNum returns the SQLite version as an integer in the format X*1000000 +
// Y*1000 + Z, where X is the major version, Y is the minor version, and Z is
// the release number.
func VersionNum() int {
	if initErr != nil {
		return 0
	}
	return int(C.sqlite3_libversion_number())
}

// Print prints out all rows returned by a query. This function is intended as a
// debugging aid and may be removed or altered in the future. Do not use it in
// production applications.
func Print(s *Stmt) error {
	if s == nil || s.NumColumns() == 0 {
		return nil
	}
	var err error
	if !s.Busy() {
		if err = s.Query(); err != nil {
			return err
		}
	}
	cols := s.Columns()
	buf := bytes.NewBuffer(make([]byte, 0, len(cols)*10))
	row := make(RowMap, len(cols))

	buf.WriteByte('~')
	for _, col := range cols {
		fmt.Fprintf(buf, " %s ~", col)
	}
	fmt.Println(buf)
	for ; err == nil; err = s.Next() {
		if err = s.Scan(row); err != nil {
			return err
		}
		buf.Reset()
		buf.WriteByte('|')
		for _, col := range cols {
			fmt.Fprintf(buf, " %*v |", len(col), row[col])
		}
		fmt.Println(buf)
	}
	return err
}

// cStr returns a pointer to the first byte in s, which must be a
// null-terminated string.
func cStr(s string) *C.char {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	return (*C.char)(unsafe.Pointer(h.Data))
}

// cStrOffset returns the offset of p in s, which must be a null-terminated
// string. It panics if p is not a pointer into s.
func cStrOffset(s string, p *C.char) int {
	start := (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
	if n := uintptr(unsafe.Pointer(p)) - start; n < uintptr(len(s)) {
		return int(n)
	}
	panic("sqlite3: p is not a pointer into s")
}

// cBytes returns a pointer to the first byte in b.
func cBytes(b []byte) unsafe.Pointer {
	return unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&b)).Data)
}

// cBool returns an integer representation of a bool (false = 0, true = 1).
func cBool(b bool) C.int {
	if b {
		return 1
	}
	return 0
}

// goStr returns a Go string representation of a null-terminated C string.
func goStr(p *C.char) (s string) {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	h.Data = uintptr(unsafe.Pointer(p))
	h.Len = int(^uint(0) >> 1)
	n := 0
	for s[n] != 0 {
		n++
	}
	if n == 0 {
		return "" // Don't keep a pointer to an unused string
	}
	h.Len = n
	return
}

// goStrN returns a Go string representation of an n-byte C string.
func goStrN(p *C.char, n C.int) (s string) {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	h.Data = uintptr(unsafe.Pointer(p))
	h.Len = int(n)
	return
}

// goBytes returns a []byte representation of an n-byte C array.
func goBytes(p unsafe.Pointer, n C.int) (b []byte) {
	h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	h.Data = uintptr(p)
	h.Len = int(n)
	h.Cap = int(n)
	return
}

//export go_busy_handler
func go_busy_handler(conn unsafe.Pointer, count C.int) C.int {
	retry := false
	if c := (*Conn)(conn); c != nil && c.db != nil && c.busy != nil {
		retry = c.busy(int(count))
	}
	return cBool(retry)
}

//export go_commit_hook
func go_commit_hook(conn unsafe.Pointer) C.int {
	abort := false
	if c := (*Conn)(conn); c != nil && c.db != nil && c.commit != nil {
		abort = c.commit()
	}
	return cBool(abort)
}

//export go_rollback_hook
func go_rollback_hook(conn unsafe.Pointer) {
	if c := (*Conn)(conn); c != nil && c.db != nil && c.rollback != nil {
		c.rollback()
	}
}

//export go_update_hook
func go_update_hook(conn unsafe.Pointer, op C.int, db, tbl *C.char, row C.sqlite3_int64) {
	if c := (*Conn)(conn); c != nil && c.db != nil && c.update != nil {
		c.update(int(op), RawString(goStr(db)), RawString(goStr(tbl)), int64(row))
	}
}
<commit_msg>Add Copy methods for RawString and RawBytes.<commit_after>// Copyright 2013 The Go-SQLite Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlite3

/*
#include "sqlite3.h"

int shell_main(int, void*);
*/
import "C"

import (
	"bytes"
	"fmt"
	"os"
	"reflect"
	"unsafe"
)

// NamedArgs is a name/value map of arguments passed to a prepared statement
// that uses ?NNN, :AAA, @AAA, and/or $AAA parameter formats. Name matching is
// case-sensitive and the prefix character (one of [?:@$]) must be included in
// the name. Names that are missing from the map are treated as NULL. Names that
// are not used in the prepared statement are ignored.
//
// It is not possible to mix named and anonymous ("?") parameters in the same
// statement.
// [http://www.sqlite.org/lang_expr.html#varparam]
type NamedArgs map[string]interface{}

// RowMap may be passed as the last (or only) argument to Stmt.Scan to create a
// map of all remaining column/value pairs in the current row. The map is not
// cleared before being populated with new column values. Assignment is
// performed in left-to-right column order, and values may be overwritten if the
// query returns two or more columns with identical names.
type RowMap map[string]interface{}

// RawString and RawBytes are special string and []byte types that may be used
// for database input and output without the cost of an extra copy operation.
//
// When used as an argument to a statement, the contents are bound using
// SQLITE_STATIC instead of SQLITE_TRANSIENT flag. This requires the contents to
// remain valid and unmodified until the end of statement execution. In
// particular, the caller must keep a reference to the value to prevent it from
// being garbage collected.
//
// When used for retrieving query output, the internal string/[]byte pointer is
// set to reference memory belonging to SQLite. The memory remains valid until
// another method is called on the Stmt object and should not be modified.
type (
	RawString string
	RawBytes  []byte
)

// Copy returns a Go-owned copy of s.
func (s RawString) Copy() string {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	return C.GoStringN((*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len))
}

// Copy returns a Go-owned copy of b.
func (b RawBytes) Copy() []byte {
	h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	return C.GoBytes(unsafe.Pointer(h.Data), C.int(h.Len))
}

// ZeroBlob is a special argument type used to allocate a zero-filled BLOB of
// the specified length. The BLOB can then be opened for incremental I/O to
// efficiently transfer a large amount of data. The maximum BLOB size can be
// queried with Conn.Limit(LIMIT_LENGTH, -1).
type ZeroBlob int

// BusyFunc is a callback function invoked by SQLite when it is unable to
// acquire a lock on a table. Count is the number of times that the callback has
// been invoked for this locking event so far. If the function returns false,
// then the operation is aborted. Otherwise, the function should block for a
// while before returning true and letting SQLite make another locking attempt.
type BusyFunc func(count int) (retry bool)

// CommitFunc is a callback function invoked by SQLite before a transaction is
// committed. If the function returns true, the transaction is rolled back.
type CommitFunc func() (abort bool)

// RollbackFunc is a callback function invoked by SQLite when a transaction is
// rolled back.
type RollbackFunc func()

// UpdateFunc is a callback function invoked by SQLite when a row is updated,
// inserted, or deleted.
type UpdateFunc func(op int, db, tbl RawString, row int64)

// Error is returned for all SQLite API result codes other than OK, ROW, and
// DONE.
type Error struct {
	rc  int
	msg string
}

// libErr reports an error originating in SQLite. The error message is obtained
// from the database connection when possible, which may include some additional
// information. Otherwise, the result code is translated to a generic message.
func libErr(rc C.int, db *C.sqlite3) error {
	if db != nil && rc == C.sqlite3_errcode(db) {
		return &Error{int(rc), C.GoString(C.sqlite3_errmsg(db))}
	}
	return &Error{int(rc), C.GoString(C.sqlite3_errstr(rc))}
}

// pkgErr reports an error originating in this package.
func pkgErr(rc int, msg string, v ...interface{}) error {
	if len(v) == 0 {
		return &Error{rc, msg}
	}
	return &Error{rc, fmt.Sprintf(msg, v...)}
}

// Code returns the SQLite extended result code.
func (err *Error) Code() int {
	return err.rc
}

// Error implements the error interface.
func (err *Error) Error() string {
	return fmt.Sprintf("sqlite3: %s [%d]", err.msg, err.rc)
}

// Errors returned for access attempts to closed or invalid objects.
var (
	ErrBadConn   = &Error{MISUSE, "closed or invalid connection"}
	ErrBadStmt   = &Error{MISUSE, "closed or invalid statement"}
	ErrBadIO     = &Error{MISUSE, "closed or invalid incremental I/O operation"}
	ErrBadBackup = &Error{MISUSE, "closed or invalid backup operation"}
)

// Shell is deprecated and will be removed in the near future. Don't use it!
func Shell(args ...string) int {
	if initErr != nil {
		return 127
	}
	args = append([]string{os.Args[0]}, args...)

	// Copy all arguments into a single []byte, terminating each one with '\0'
	buf := make([]byte, 0, 256)
	for _, arg := range args {
		buf = append(append(buf, arg...), 0)
	}

	// Fill argv with pointers to the start of each null-terminated string
	argv := make([]uintptr, len(args))
	base := uintptr(cBytes(buf))
	for i, arg := range args {
		argv[i] = base
		base += uintptr(len(arg)) + 1
	}
	return int(C.shell_main(C.int(len(args)), unsafe.Pointer(&argv[0])))
}

// Complete returns true if sql appears to contain a complete statement that is
// ready to be parsed. This does not validate the statement syntax.
// [http://www.sqlite.org/c3ref/complete.html]
func Complete(sql string) bool {
	if initErr != nil {
		return false
	}
	sql += "\x00"
	return C.sqlite3_complete(cStr(sql)) == 1
}

// ReleaseMemory attempts to free n bytes of heap memory by deallocating
// non-essential memory held by the SQLite library. It returns the number of
// bytes actually freed.
//
// This function is currently a no-op because SQLite is not compiled with the
// SQLITE_ENABLE_MEMORY_MANAGEMENT option.
// [http://www.sqlite.org/c3ref/release_memory.html]
func ReleaseMemory(n int) int {
	if initErr != nil {
		return 0
	}
	return int(C.sqlite3_release_memory(C.int(n)))
}

// SingleThread returns true if the SQLite library was compiled with
// -DSQLITE_THREADSAFE=0. With this threading mode, all mutex code is omitted
// and this package becomes unsafe for concurrent access, even to separate
// database connections.
//
// This function was needed in Go 1.0 when the package was dynamically linked
// with the system's SQLite library on *nix. As of Go 1.1, the SQLite
// amalgamation is compiled into the package with -DSQLITE_THREADSAFE=2, so this
// function always returns false and is kept only for backward compatibility.
// [http://www.sqlite.org/threadsafe.html]
func SingleThread() bool {
	return initErr == nil && C.sqlite3_threadsafe() == 0
}

// SoftHeapLimit sets and/or queries the soft limit on the amount of heap memory
// that may be allocated by SQLite. A negative value for n keeps the current
// limit, while 0 removes the limit. The previous limit value is returned, with
// negative values indicating an error.
// [http://www.sqlite.org/c3ref/soft_heap_limit64.html]
func SoftHeapLimit(n int64) int64 {
	if initErr != nil {
		return -1
	}
	return int64(C.sqlite3_soft_heap_limit64(C.sqlite3_int64(n)))
}

// SourceId returns the check-in identifier of SQLite within its configuration
// management system (e.g. "2013-01-09 11:53:05
// c0e09560d26f0a6456be9dd3447f5311eb4f238f").
// [http://www.sqlite.org/c3ref/c_source_id.html]
func SourceId() string {
	if initErr != nil {
		return ""
	}
	return C.GoString(C.sqlite3_sourceid())
}

// Status returns the current and peak values of a core performance
// counter, specified by one of the STATUS constants. If reset is true, the peak
// value is reset back down to the current value after retrieval.
// [http://www.sqlite.org/c3ref/status.html]
func Status(op int, reset bool) (cur, peak int, err error) {
	if initErr != nil {
		return 0, 0, initErr
	}
	var cCur, cPeak C.int
	rc := C.sqlite3_status(C.int(op), &cCur, &cPeak, cBool(reset))
	if rc != OK {
		return 0, 0, pkgErr(MISUSE, "invalid status op (%d)", op)
	}
	return int(cCur), int(cPeak), nil
}

// Version returns the SQLite version as a string in the format "X.Y.Z[.N]".
// [http://www.sqlite.org/c3ref/libversion.html]
func Version() string {
	if initErr != nil {
		return ""
	}
	return C.GoString(C.sqlite3_libversion())
}

// VersionNum returns the SQLite version as an integer in the format X*1000000 +
// Y*1000 + Z, where X is the major version, Y is the minor version, and Z is
// the release number.
func VersionNum() int {
	if initErr != nil {
		return 0
	}
	return int(C.sqlite3_libversion_number())
}

// Print prints out all rows returned by a query. This function is intended as a
// debugging aid and may be removed or altered in the future. Do not use it in
// production applications.
func Print(s *Stmt) error {
	if s == nil || s.NumColumns() == 0 {
		return nil
	}
	var err error
	if !s.Busy() {
		if err = s.Query(); err != nil {
			return err
		}
	}
	cols := s.Columns()
	buf := bytes.NewBuffer(make([]byte, 0, len(cols)*10))
	row := make(RowMap, len(cols))

	buf.WriteByte('~')
	for _, col := range cols {
		fmt.Fprintf(buf, " %s ~", col)
	}
	fmt.Println(buf)
	for ; err == nil; err = s.Next() {
		if err = s.Scan(row); err != nil {
			return err
		}
		buf.Reset()
		buf.WriteByte('|')
		for _, col := range cols {
			fmt.Fprintf(buf, " %*v |", len(col), row[col])
		}
		fmt.Println(buf)
	}
	return err
}

// cStr returns a pointer to the first byte in s, which must be a
// null-terminated string.
func cStr(s string) *C.char {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	return (*C.char)(unsafe.Pointer(h.Data))
}

// cStrOffset returns the offset of p in s, which must be a null-terminated
// string. It panics if p is not a pointer into s.
func cStrOffset(s string, p *C.char) int {
	start := (*reflect.StringHeader)(unsafe.Pointer(&s)).Data
	if n := uintptr(unsafe.Pointer(p)) - start; n < uintptr(len(s)) {
		return int(n)
	}
	panic("sqlite3: p is not a pointer into s")
}

// cBytes returns a pointer to the first byte in b.
func cBytes(b []byte) unsafe.Pointer {
	return unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&b)).Data)
}

// cBool returns an integer representation of a bool (false = 0, true = 1).
func cBool(b bool) C.int {
	if b {
		return 1
	}
	return 0
}

// goStr returns a Go string representation of a null-terminated C string.
func goStr(p *C.char) (s string) {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	h.Data = uintptr(unsafe.Pointer(p))
	h.Len = int(^uint(0) >> 1)
	n := 0
	for s[n] != 0 {
		n++
	}
	if n == 0 {
		return "" // Don't keep a pointer to an unused string
	}
	h.Len = n
	return
}

// goStrN returns a Go string representation of an n-byte C string.
func goStrN(p *C.char, n C.int) (s string) {
	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
	h.Data = uintptr(unsafe.Pointer(p))
	h.Len = int(n)
	return
}

// goBytes returns a []byte representation of an n-byte C array.
func goBytes(p unsafe.Pointer, n C.int) (b []byte) {
	h := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	h.Data = uintptr(p)
	h.Len = int(n)
	h.Cap = int(n)
	return
}

//export go_busy_handler
func go_busy_handler(conn unsafe.Pointer, count C.int) C.int {
	retry := false
	if c := (*Conn)(conn); c != nil && c.db != nil && c.busy != nil {
		retry = c.busy(int(count))
	}
	return cBool(retry)
}

//export go_commit_hook
func go_commit_hook(conn unsafe.Pointer) C.int {
	abort := false
	if c := (*Conn)(conn); c != nil && c.db != nil && c.commit != nil {
		abort = c.commit()
	}
	return cBool(abort)
}

//export go_rollback_hook
func go_rollback_hook(conn unsafe.Pointer) {
	if c := (*Conn)(conn); c != nil && c.db != nil && c.rollback != nil {
		c.rollback()
	}
}

//export go_update_hook
func go_update_hook(conn unsafe.Pointer, op C.int, db, tbl *C.char, row C.sqlite3_int64) {
	if c := (*Conn)(conn); c != nil && c.db != nil && c.update != nil {
		c.update(int(op), RawString(goStr(db)), RawString(goStr(tbl)), int64(row))
	}
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package device

import (
	"flag"
	"fmt"
	"io"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/vmware/govmomi/govc/cli"
	"github.com/vmware/govmomi/govc/flags"
	"github.com/vmware/govmomi/object"
	"github.com/vmware/govmomi/vim25/types"
	"golang.org/x/net/context"
)

type info struct {
	*flags.VirtualMachineFlag
	*flags.OutputFlag
}

func init() {
	cli.Register("device.info", &info{})
}

func (cmd *info) Register(f *flag.FlagSet) {}

func (cmd *info) Process() error { return nil }

func (cmd *info) Usage() string {
	return "[DEVICE]..."
}

func (cmd *info) Run(f *flag.FlagSet) error {
	vm, err := cmd.VirtualMachine()
	if err != nil {
		return err
	}

	if vm == nil {
		return flag.ErrHelp
	}

	devices, err := vm.Device(context.TODO())
	if err != nil {
		return err
	}

	res := infoResult{
		list: devices,
	}

	if f.NArg() == 0 {
		res.Devices = devices
	} else {
		for _, name := range f.Args() {
			device := devices.Find(name)
			if device == nil {
				return fmt.Errorf("device '%s' not found", name)
			}

			res.Devices = append(res.Devices, device)
		}
	}

	return cmd.WriteResult(&res)
}

type infoResult struct {
	Devices object.VirtualDeviceList
	// need the full list of devices to lookup attached devices and controllers
	list object.VirtualDeviceList
}

func (r *infoResult) Write(w io.Writer) error {
	tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)

	for _, device := range r.Devices {
		d := device.GetVirtualDevice()
		info := d.DeviceInfo.GetDescription()

		fmt.Fprintf(tw, "Name:\t%s\n", r.Devices.Name(device))
		fmt.Fprintf(tw, "  Type:\t%s\n", r.Devices.TypeName(device))
		fmt.Fprintf(tw, "  Label:\t%s\n", info.Label)
		fmt.Fprintf(tw, "  Summary:\t%s\n", info.Summary)
		fmt.Fprintf(tw, "  Key:\t%d\n", d.Key)

		if c, ok := device.(types.BaseVirtualController); ok {
			var attached []string
			for _, key := range c.GetVirtualController().Device {
				attached = append(attached, r.Devices.Name(r.list.FindByKey(key)))
			}
			fmt.Fprintf(tw, "  Devices:\t%s\n", strings.Join(attached, ", "))
		} else {
			if c := r.list.FindByKey(d.ControllerKey); c != nil {
				fmt.Fprintf(tw, "  Controller:\t%s\n", r.Devices.Name(c))
				fmt.Fprintf(tw, "  Unit number:\t%d\n", d.UnitNumber)
			}
		}

		if ca := d.Connectable; ca != nil {
			fmt.Fprintf(tw, "  Connected:\t%t\n", ca.Connected)
			fmt.Fprintf(tw, "  Start connected:\t%t\n", ca.StartConnected)
			fmt.Fprintf(tw, "  Guest control:\t%t\n", ca.AllowGuestControl)
			fmt.Fprintf(tw, "  Status:\t%s\n", ca.Status)
		}

		switch md := device.(type) {
		case types.BaseVirtualEthernetCard:
			fmt.Fprintf(tw, "  MAC Address:\t%s\n", md.GetVirtualEthernetCard().MacAddress)
			fmt.Fprintf(tw, "  Address type:\t%s\n", md.GetVirtualEthernetCard().AddressType)
		case *types.VirtualDisk:
			if b, ok := md.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok {
				fmt.Fprintf(tw, "  File:\t%s\n", b.GetVirtualDeviceFileBackingInfo().FileName)
			}
			if b, ok := md.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok && b.Parent != nil {
				fmt.Fprintf(tw, "  Parent:\t%s\n", b.Parent.GetVirtualDeviceFileBackingInfo().FileName)
			}
		}
	}

	return tw.Flush()
}
<commit_msg>Add serial port URI info to device.info output<commit_after>/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package device

import (
	"flag"
	"fmt"
	"io"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/vmware/govmomi/govc/cli"
	"github.com/vmware/govmomi/govc/flags"
	"github.com/vmware/govmomi/object"
	"github.com/vmware/govmomi/vim25/types"
	"golang.org/x/net/context"
)

type info struct {
	*flags.VirtualMachineFlag
	*flags.OutputFlag
}

func init() {
	cli.Register("device.info", &info{})
}

func (cmd *info) Register(f *flag.FlagSet) {}

func (cmd *info) Process() error { return nil }

func (cmd *info) Usage() string {
	return "[DEVICE]..."
}

func (cmd *info) Run(f *flag.FlagSet) error {
	vm, err := cmd.VirtualMachine()
	if err != nil {
		return err
	}

	if vm == nil {
		return flag.ErrHelp
	}

	devices, err := vm.Device(context.TODO())
	if err != nil {
		return err
	}

	res := infoResult{
		list: devices,
	}

	if f.NArg() == 0 {
		res.Devices = devices
	} else {
		for _, name := range f.Args() {
			device := devices.Find(name)
			if device == nil {
				return fmt.Errorf("device '%s' not found", name)
			}

			res.Devices = append(res.Devices, device)
		}
	}

	return cmd.WriteResult(&res)
}

type infoResult struct {
	Devices object.VirtualDeviceList
	// need the full list of devices to lookup attached devices and controllers
	list object.VirtualDeviceList
}

func (r *infoResult) Write(w io.Writer) error {
	tw := tabwriter.NewWriter(os.Stdout, 2, 0, 2, ' ', 0)

	for _, device := range r.Devices {
		d := device.GetVirtualDevice()
		info := d.DeviceInfo.GetDescription()

		fmt.Fprintf(tw, "Name:\t%s\n", r.Devices.Name(device))
		fmt.Fprintf(tw, "  Type:\t%s\n", r.Devices.TypeName(device))
		fmt.Fprintf(tw, "  Label:\t%s\n", info.Label)
		fmt.Fprintf(tw, "  Summary:\t%s\n", info.Summary)
		fmt.Fprintf(tw, "  Key:\t%d\n", d.Key)

		if c, ok := device.(types.BaseVirtualController); ok {
			var attached []string
			for _, key := range c.GetVirtualController().Device {
				attached = append(attached, r.Devices.Name(r.list.FindByKey(key)))
			}
			fmt.Fprintf(tw, "  Devices:\t%s\n", strings.Join(attached, ", "))
		} else {
			if c := r.list.FindByKey(d.ControllerKey); c != nil {
				fmt.Fprintf(tw, "  Controller:\t%s\n", r.Devices.Name(c))
				fmt.Fprintf(tw, "  Unit number:\t%d\n", d.UnitNumber)
			}
		}

		if ca := d.Connectable; ca != nil {
			fmt.Fprintf(tw, "  Connected:\t%t\n", ca.Connected)
			fmt.Fprintf(tw, "  Start connected:\t%t\n", ca.StartConnected)
			fmt.Fprintf(tw, "  Guest control:\t%t\n", ca.AllowGuestControl)
			fmt.Fprintf(tw, "  Status:\t%s\n", ca.Status)
		}

		switch md := device.(type) {
		case types.BaseVirtualEthernetCard:
			fmt.Fprintf(tw, "  MAC Address:\t%s\n", md.GetVirtualEthernetCard().MacAddress)
			fmt.Fprintf(tw, "  Address type:\t%s\n", md.GetVirtualEthernetCard().AddressType)
		case *types.VirtualDisk:
			if b, ok := md.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok {
				fmt.Fprintf(tw, "  File:\t%s\n", b.GetVirtualDeviceFileBackingInfo().FileName)
			}
			if b, ok := md.Backing.(*types.VirtualDiskFlatVer2BackingInfo); ok && b.Parent != nil {
				fmt.Fprintf(tw, "  Parent:\t%s\n", b.Parent.GetVirtualDeviceFileBackingInfo().FileName)
			}
		case *types.VirtualSerialPort:
			if b, ok := md.Backing.(*types.VirtualSerialPortURIBackingInfo); ok {
				fmt.Fprintf(tw, "  Direction:\t%s\n", b.Direction)
				fmt.Fprintf(tw, "  Service URI:\t%s\n", b.ServiceURI)
				fmt.Fprintf(tw, "  Proxy URI:\t%s\n", b.ProxyURI)
			}
		}
	}

	return tw.Flush()
}
<|endoftext|>


<commit_before>package arraylist

import (
    "errors"
)

const DEFAULT_CAPACITY int = 10

type List interface {
	Size() int
	Get(index int) (item interface, err error)
	Set(index int, newVal interface) (oldItem interface, err error)
    Insert(index int, val interface)
    Append(val interface)
    Remove(index int)
    Clear()
}

type ArrayList struct {
    dataStore = make([]interface, 0, DEFAULT_CAPACITY)
}

func (list *ArrayList) Size() int {
    return len(list.dataStore)
}

func (list *ArrayList) Get(index int) (item interface, err error) {
    if index < 0 || index >= len(list.dataStore) {
        return nil, errors.New("Index out of range.")
    }
    return &list.dataStore[index], nil
}

func (list *ArrayList) Set(index int, newVal interface) (oldItem interface, err error) {
    if index < 0 || index >= len(list.dataStore) {
        return nil, errors.New("Index out of range.")
    }
    oldItem = &list.dataStore[index]
    &list.dataStore[index] = newVal

    return oldITem, nil
}
<commit_msg>add go arraylist<commit_after>package arraylist

import (
    "error"
)

const DEFAULT_CAPACITY int = 10

type List interface {
    Size() int
    Get(index int) (item interface, err error)
    Set(index int, newVal interface) (oldItem interface, err error)
    Insert(index int, val interface)
    Append(val interface)
    Remove(index int)
    Clear()
}

type ArrayList struct {
    dataStore = make([]interface, 0, DEFAULT_CAPACITY)
}

func (list *ArrayList) Size() int {
    return len(list.dataStore)
}

func (list *ArrayList) Get(index int) (item interface, err error) {
    if index < 0 || index >= len(list.dataStore) {
        return nil, errors.New("Index out of range.")
    }
    return &list.dataStore[index], nil
}

func (list *ArrayList) Set(index int, newVal interface) (oldItem interface, err error) {
    if index < 0 || index >= len(list.dataStore) {
        return nil, errors.New("Index out of range.")
    }
    oldItem = &list.dataStore[index]
    &list.dataStore[index] = newVal

    return oldITem, nil
}
<|endoftext|>