<commit_before>package mage

// this template uses the "data"

// var only for tests
var mageMainfileTplString = `// +build ignore

package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
	{{range .Imports}}{{.UniqueName}} "{{.Path}}"
	{{end}}
)

func main() {
	// Use local types and functions in order to avoid name conflicts with additional magefiles.
	type arguments struct {
		Verbose       bool          // print out log statements
		List          bool          // print out a list of targets
		Help          bool          // print out help for a specific target
		Timeout       time.Duration // set a timeout to running the targets
		Args          []string      // args contain the non-flag command-line arguments
	}

	parseBool := func(env string) bool {
		val := os.Getenv(env)
		if val == "" {
			return false
		}
		b, err := strconv.ParseBool(val)
		if err != nil {
			log.Printf("warning: environment variable %s is not a valid bool value: %v", env, val)
			return false
		}
		return b
	}

	parseDuration := func(env string) time.Duration {
		val := os.Getenv(env)
		if val == "" {
			return 0
		}
		d, err := time.ParseDuration(val)
		if err != nil {
			log.Printf("warning: environment variable %s is not a valid duration value: %v", env, val)
			return 0
		}
		return d
	}
	args := arguments{}
	fs := flag.FlagSet{}
	fs.SetOutput(os.Stdout)

	// default flag set with ExitOnError and auto generated PrintDefaults should be sufficient
	fs.BoolVar(&args.Verbose, "v", parseBool("MAGEFILE_VERBOSE"), "show verbose output when running targets")
	fs.BoolVar(&args.List, "l", parseBool("MAGEFILE_LIST"), "list targets for this binary")
	fs.BoolVar(&args.Help, "h", parseBool("MAGEFILE_HELP"), "print out help for a specific target")
	fs.DurationVar(&args.Timeout, "t", parseDuration("MAGEFILE_TIMEOUT"), "timeout in duration parsable format (e.g. 5m30s)")
	fs.Usage = func() {
		fmt.Fprintf(os.Stdout, ` + "`" + `
%s [options] [target]

Commands:
  -l    list targets in this binary
  -h    show this help

Options:
  -h    show description of a target
  -t <string>
        timeout in duration parsable format (e.g. 5m30s)
  -v    show verbose output when running targets
 ` + "`" + `[1:], filepath.Base(os.Args[0]))
	}
	if err := fs.Parse(os.Args[1:]); err != nil {
		// flag will have printed out an error already.
		return
	}
	args.Args = fs.Args()
	if args.Help && len(args.Args) == 0 {
		fs.Usage()
		return
	}

	list := func() error {
		{{with .Description}}fmt.Println(` + "`{{.}}\n`" + `)
		{{- end}}
		{{- $default := .DefaultFunc}}
		targets := map[string]string{
		{{- range .Funcs}}
			"{{lowerFirst .TargetName}}{{if and (eq .Name $default.Name) (eq .Receiver $default.Receiver)}}*{{end}}": {{printf "%q" .Synopsis}},
		{{- end}}
		{{- range .Imports}}{{$imp := .}}
			{{- range .Info.Funcs}}
			"{{lowerFirst .TargetName}}{{if and (eq .Name $default.Name) (eq .Receiver $default.Receiver)}}*{{end}}": {{printf "%q" .Synopsis}},
			{{- end}}
		{{- end}}
		}

		keys := make([]string, 0, len(targets))
		for name := range targets {
			keys = append(keys, name)
		}
		sort.Strings(keys)

		fmt.Println("Targets:")
		w := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
		for _, name := range keys {
			fmt.Fprintf(w, "  %v\t%v\n", name, targets[name])
		}
		err := w.Flush()
		{{- if .DefaultFunc.Name}}
			if err == nil {
				fmt.Println("\n* default target")
			}
		{{- end}}
		return err
	}

	var ctx context.Context
	var ctxCancel func()

	getContext := func() (context.Context, func()) {
		if ctx != nil {
			return ctx, ctxCancel
		}

		if args.Timeout != 0 {
			ctx, ctxCancel = context.WithTimeout(context.Background(), args.Timeout)
		} else {
			ctx = context.Background()
			ctxCancel = func() {}
		}
		return ctx, ctxCancel
	}

	runTarget := func(fn func(context.Context) error) interface{} {
		var err interface{}
		ctx, cancel := getContext()
		d := make(chan interface{})
		go func() {
			defer func() {
				err := recover()
				d <- err
			}()
			err := fn(ctx)
			d <- err
		}()
		select {
		case <-ctx.Done():
			cancel()
			e := ctx.Err()
			fmt.Printf("ctx err: %v\n", e)
			return e
		case err = <-d:
			cancel()
			return err
		}
	}
	// This is necessary in case there aren't any targets, to avoid an unused
	// variable error.
	_ = runTarget

	handleError := func(logger *log.Logger, err interface{}) {
		if err != nil {
			logger.Printf("Error: %v\n", err)
			type code interface {
				ExitStatus() int
			}
			if c, ok := err.(code); ok {
				os.Exit(c.ExitStatus())
			}
			os.Exit(1)
		}
	}
	_ = handleError

	log.SetFlags(0)
	if !args.Verbose {
		log.SetOutput(ioutil.Discard)
	}
	logger := log.New(os.Stderr, "", 0)
	if args.List {
		if err := list(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
		return
	}

	targets := map[string]bool {
		{{range $alias, $funci := .Aliases}}"{{lower $alias}}": true,
		{{end}}
		{{range .Funcs}}"{{lower .TargetName}}": true,
		{{end}}
		{{range .Imports}}
			{{$imp := .}}
			{{range $alias, $funci := .Info.Aliases}}"{{if ne $imp.Alias "."}}{{lower $imp.Alias}}:{{end}}{{lower $alias}}": true,
			{{end}}
			{{range .Info.Funcs}}"{{lower .TargetName}}": true,
			{{end}}
		{{end}}
	}

	var unknown []string
	for _, arg := range args.Args {
		if !targets[strings.ToLower(arg)] {
			unknown = append(unknown, arg)
		}
	}
	if len(unknown) == 1 {
		logger.Println("Unknown target specified:", unknown[0])
		os.Exit(2)
	}
	if len(unknown) > 1 {
		logger.Println("Unknown targets specified:", strings.Join(unknown, ", "))
		os.Exit(2)
	}

	if args.Help {
		if len(args.Args) < 1 {
			logger.Println("no target specified")
			os.Exit(1)
		}
		switch strings.ToLower(args.Args[0]) {
			{{range .Funcs}}case "{{lower .TargetName}}":
				fmt.Print("{{$.BinaryName}} {{lower .TargetName}}:\n\n")
				{{if ne .Comment "" -}}
				fmt.Println({{printf "%q" .Comment}})
				fmt.Println()
				{{end}}
				var aliases []string
				{{- $name := .Name -}}
				{{- $recv := .Receiver -}}
				{{range $alias, $func := $.Aliases}}
				{{if and (eq $name $func.Name) (eq $recv $func.Receiver)}}aliases = append(aliases, "{{$alias}}"){{end -}}
				{{- end}}
				if len(aliases) > 0 {
					fmt.Printf("Aliases: %s\n\n", strings.Join(aliases, ", "))
				}
				return
			{{end}}
			default:
				logger.Printf("Unknown target: %q\n", args.Args[0])
				os.Exit(1)
		}
	}
	if len(args.Args) < 1 {
	{{- if .DefaultFunc.Name}}
		ignoreDefault, _ := strconv.ParseBool(os.Getenv("MAGEFILE_IGNOREDEFAULT"))
		if ignoreDefault {
			if err := list(); err != nil {
				logger.Println("Error:", err)
				os.Exit(1)
			}
			return
		}
		{{.DefaultFunc.ExecCode}}
		handleError(logger, err)
		return
	{{- else}}
		if err := list(); err != nil {
			logger.Println("Error:", err)
			os.Exit(1)
		}
		return
	{{- end}}
	}
	for _, target := range args.Args {
		switch strings.ToLower(target) {
		{{range $alias, $func := .Aliases}}
			case "{{lower $alias}}":
				target = "{{$func.TargetName}}"
		{{- end}}
		}
		switch strings.ToLower(target) {
		{{range .Funcs }}
			case "{{lower .TargetName}}":
				if args.Verbose {
					logger.Println("Running target:", "{{.TargetName}}")
				}
				{{.ExecCode}}
				handleError(logger, err)
		{{- end}}
		{{range .Imports}}
		{{$imp := .}}
			{{range .Info.Funcs }}
				case "{{lower .TargetName}}":
					if args.Verbose {
						logger.Println("Running target:", "{{.TargetName}}")
					}
					{{.ExecCode}}
					handleError(logger, err)
			{{- end}}
		{{- end}}
		default:
			// should be impossible since we check this above.
			logger.Printf("Unknown target: %q\n", args.Args[0])
			os.Exit(1)
		}
	}
}

`
<commit_msg>enable detail/stack printing for the Go 2 proposal for error values (#259)<commit_after>package mage

// this template uses the "data"

// var only for tests
var mageMainfileTplString = `// +build ignore

package main

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
	{{range .Imports}}{{.UniqueName}} "{{.Path}}"
	{{end}}
)

func main() {
	// Use local types and functions in order to avoid name conflicts with additional magefiles.
	type arguments struct {
		Verbose       bool          // print out log statements
		List          bool          // print out a list of targets
		Help          bool          // print out help for a specific target
		Timeout       time.Duration // set a timeout to running the targets
		Args          []string      // args contain the non-flag command-line arguments
	}

	parseBool := func(env string) bool {
		val := os.Getenv(env)
		if val == "" {
			return false
		}
		b, err := strconv.ParseBool(val)
		if err != nil {
			log.Printf("warning: environment variable %s is not a valid bool value: %v", env, val)
			return false
		}
		return b
	}

	parseDuration := func(env string) time.Duration {
		val := os.Getenv(env)
		if val == "" {
			return 0
		}
		d, err := time.ParseDuration(val)
		if err != nil {
			log.Printf("warning: environment variable %s is not a valid duration value: %v", env, val)
			return 0
		}
		return d
	}
	args := arguments{}
	fs := flag.FlagSet{}
	fs.SetOutput(os.Stdout)

	// default flag set with ExitOnError and auto generated PrintDefaults should be sufficient
	fs.BoolVar(&args.Verbose, "v", parseBool("MAGEFILE_VERBOSE"), "show verbose output when running targets")
	fs.BoolVar(&args.List, "l", parseBool("MAGEFILE_LIST"), "list targets for this binary")
	fs.BoolVar(&args.Help, "h", parseBool("MAGEFILE_HELP"), "print out help for a specific target")
	fs.DurationVar(&args.Timeout, "t", parseDuration("MAGEFILE_TIMEOUT"), "timeout in duration parsable format (e.g. 5m30s)")
	fs.Usage = func() {
		fmt.Fprintf(os.Stdout, ` + "`" + `
%s [options] [target]

Commands:
  -l    list targets in this binary
  -h    show this help

Options:
  -h    show description of a target
  -t <string>
        timeout in duration parsable format (e.g. 5m30s)
  -v    show verbose output when running targets
 ` + "`" + `[1:], filepath.Base(os.Args[0]))
	}
	if err := fs.Parse(os.Args[1:]); err != nil {
		// flag will have printed out an error already.
		return
	}
	args.Args = fs.Args()
	if args.Help && len(args.Args) == 0 {
		fs.Usage()
		return
	}

	list := func() error {
		{{with .Description}}fmt.Println(` + "`{{.}}\n`" + `)
		{{- end}}
		{{- $default := .DefaultFunc}}
		targets := map[string]string{
		{{- range .Funcs}}
			"{{lowerFirst .TargetName}}{{if and (eq .Name $default.Name) (eq .Receiver $default.Receiver)}}*{{end}}": {{printf "%q" .Synopsis}},
		{{- end}}
		{{- range .Imports}}{{$imp := .}}
			{{- range .Info.Funcs}}
			"{{lowerFirst .TargetName}}{{if and (eq .Name $default.Name) (eq .Receiver $default.Receiver)}}*{{end}}": {{printf "%q" .Synopsis}},
			{{- end}}
		{{- end}}
		}

		keys := make([]string, 0, len(targets))
		for name := range targets {
			keys = append(keys, name)
		}
		sort.Strings(keys)

		fmt.Println("Targets:")
		w := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
		for _, name := range keys {
			fmt.Fprintf(w, "  %v\t%v\n", name, targets[name])
		}
		err := w.Flush()
		{{- if .DefaultFunc.Name}}
			if err == nil {
				fmt.Println("\n* default target")
			}
		{{- end}}
		return err
	}

	var ctx context.Context
	var ctxCancel func()

	getContext := func() (context.Context, func()) {
		if ctx != nil {
			return ctx, ctxCancel
		}

		if args.Timeout != 0 {
			ctx, ctxCancel = context.WithTimeout(context.Background(), args.Timeout)
		} else {
			ctx = context.Background()
			ctxCancel = func() {}
		}
		return ctx, ctxCancel
	}

	runTarget := func(fn func(context.Context) error) interface{} {
		var err interface{}
		ctx, cancel := getContext()
		d := make(chan interface{})
		go func() {
			defer func() {
				err := recover()
				d <- err
			}()
			err := fn(ctx)
			d <- err
		}()
		select {
		case <-ctx.Done():
			cancel()
			e := ctx.Err()
			fmt.Printf("ctx err: %v\n", e)
			return e
		case err = <-d:
			cancel()
			return err
		}
	}
	// This is necessary in case there aren't any targets, to avoid an unused
	// variable error.
	_ = runTarget

	handleError := func(logger *log.Logger, err interface{}) {
		if err != nil {
			logger.Printf("Error: %+v\n", err)
			type code interface {
				ExitStatus() int
			}
			if c, ok := err.(code); ok {
				os.Exit(c.ExitStatus())
			}
			os.Exit(1)
		}
	}
	_ = handleError

	log.SetFlags(0)
	if !args.Verbose {
		log.SetOutput(ioutil.Discard)
	}
	logger := log.New(os.Stderr, "", 0)
	if args.List {
		if err := list(); err != nil {
			log.Println(err)
			os.Exit(1)
		}
		return
	}

	targets := map[string]bool {
		{{range $alias, $funci := .Aliases}}"{{lower $alias}}": true,
		{{end}}
		{{range .Funcs}}"{{lower .TargetName}}": true,
		{{end}}
		{{range .Imports}}
			{{$imp := .}}
			{{range $alias, $funci := .Info.Aliases}}"{{if ne $imp.Alias "."}}{{lower $imp.Alias}}:{{end}}{{lower $alias}}": true,
			{{end}}
			{{range .Info.Funcs}}"{{lower .TargetName}}": true,
			{{end}}
		{{end}}
	}

	var unknown []string
	for _, arg := range args.Args {
		if !targets[strings.ToLower(arg)] {
			unknown = append(unknown, arg)
		}
	}
	if len(unknown) == 1 {
		logger.Println("Unknown target specified:", unknown[0])
		os.Exit(2)
	}
	if len(unknown) > 1 {
		logger.Println("Unknown targets specified:", strings.Join(unknown, ", "))
		os.Exit(2)
	}

	if args.Help {
		if len(args.Args) < 1 {
			logger.Println("no target specified")
			os.Exit(1)
		}
		switch strings.ToLower(args.Args[0]) {
			{{range .Funcs}}case "{{lower .TargetName}}":
				fmt.Print("{{$.BinaryName}} {{lower .TargetName}}:\n\n")
				{{if ne .Comment "" -}}
				fmt.Println({{printf "%q" .Comment}})
				fmt.Println()
				{{end}}
				var aliases []string
				{{- $name := .Name -}}
				{{- $recv := .Receiver -}}
				{{range $alias, $func := $.Aliases}}
				{{if and (eq $name $func.Name) (eq $recv $func.Receiver)}}aliases = append(aliases, "{{$alias}}"){{end -}}
				{{- end}}
				if len(aliases) > 0 {
					fmt.Printf("Aliases: %s\n\n", strings.Join(aliases, ", "))
				}
				return
			{{end}}
			default:
				logger.Printf("Unknown target: %q\n", args.Args[0])
				os.Exit(1)
		}
	}
	if len(args.Args) < 1 {
	{{- if .DefaultFunc.Name}}
		ignoreDefault, _ := strconv.ParseBool(os.Getenv("MAGEFILE_IGNOREDEFAULT"))
		if ignoreDefault {
			if err := list(); err != nil {
				logger.Println("Error:", err)
				os.Exit(1)
			}
			return
		}
		{{.DefaultFunc.ExecCode}}
		handleError(logger, err)
		return
	{{- else}}
		if err := list(); err != nil {
			logger.Println("Error:", err)
			os.Exit(1)
		}
		return
	{{- end}}
	}
	for _, target := range args.Args {
		switch strings.ToLower(target) {
		{{range $alias, $func := .Aliases}}
			case "{{lower $alias}}":
				target = "{{$func.TargetName}}"
		{{- end}}
		}
		switch strings.ToLower(target) {
		{{range .Funcs }}
			case "{{lower .TargetName}}":
				if args.Verbose {
					logger.Println("Running target:", "{{.TargetName}}")
				}
				{{.ExecCode}}
				handleError(logger, err)
		{{- end}}
		{{range .Imports}}
		{{$imp := .}}
			{{range .Info.Funcs }}
				case "{{lower .TargetName}}":
					if args.Verbose {
						logger.Println("Running target:", "{{.TargetName}}")
					}
					{{.ExecCode}}
					handleError(logger, err)
			{{- end}}
		{{- end}}
		default:
			// should be impossible since we check this above.
			logger.Printf("Unknown target: %q\n", args.Args[0])
			os.Exit(1)
		}
	}
}

`
<|endoftext|>


<commit_before>package felixcheck

import (
	"fmt"
	"net"
	"time"

	"net/http"

	"github.com/aleasoluciones/gosnmpquerier"
	"github.com/aleasoluciones/simpleamqp"
	"github.com/tatsushid/go-fastping"
)

const (
	sysName     = "1.3.6.1.2.1.1.5.0"
	maxPingTime = 4 * time.Second
)

type CheckFunction func() (bool, error, float32)

func NewPingChecker(ip string) CheckFunction {
	return func() (bool, error, float32) {
		var retRtt time.Duration = 0
		var isUp bool = false

		p := fastping.NewPinger()
		p.MaxRTT = maxPingTime
		ra, err := net.ResolveIPAddr("ip4:icmp", ip)

		if err != nil {
			return false, err, 0
		}

		p.AddIPAddr(ra)
		p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
			isUp = true
			retRtt = rtt
		}

		err = p.Run()
		if err != nil {
			return false, err, 0
		}

		return isUp, nil, float32(retRtt.Nanoseconds() / 1e6)
	}
}

type TcpCheckerConf struct {
	retries   int
	timeout   time.Duration
	retrytime time.Duration
}

var DefaultTcpCheckConf = TcpCheckerConf{
	retries:   3,
	timeout:   2 * time.Second,
	retrytime: 1 * time.Second,
}

func NewTcpPortChecker(ip string, port int, conf TcpCheckerConf) CheckFunction {
	return func() (bool, error, float32) {
		var err error
		var conn net.Conn

		for attempt := 0; attempt < conf.retries; attempt++ {
			conn, err = net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), conf.timeout)
			if err == nil {
				conn.Close()
				return true, nil, 0
			}
			time.Sleep(conf.retrytime)
		}
		return false, err, 0
	}
}

func NewHttpChecker(url string, expectedStatusCode int) CheckFunction {
	return func() (bool, error, float32) {
		var t1 = time.Now()
		response, err := http.Get(url)
		milliseconds := float32((time.Now().Sub(t1)).Nanoseconds() / 1e6)
		if err != nil {
			return false, err, milliseconds
		} else {
			defer response.Body.Close()
			if response.StatusCode == expectedStatusCode {
				return true, nil, milliseconds
			}
		}
		return false, err, milliseconds
	}
}

type SnmpCheckerConf struct {
	retries    int
	timeout    time.Duration
	oidToCheck string
}

var DefaultSnmpCheckConf = SnmpCheckerConf{
	retries:    1,
	timeout:    1 * time.Second,
	oidToCheck: sysName,
}

func NewSnmpChecker(ip, community string, conf SnmpCheckerConf, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		_, err := snmpQuerier.Get(ip, community, []string{conf.oidToCheck}, conf.timeout, conf.retries)
		if err == nil {
			return true, nil, 0
		} else {
			return false, err, 0
		}
	}
}

func NewC4CMTSTempChecker(ip, community string, maxAllowedTemp int, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		result, err := snmpQuerier.Walk(ip, community, "1.3.6.1.4.1.4998.1.1.10.1.4.2.1.29", 2*time.Second, 1)

		if err == nil {
			max := 0
			for _, r := range result {
				if r.Value.(int) != 999 && r.Value.(int) > max {
					max = r.Value.(int)
				}
			}
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func getMaxValueFromSnmpWalk(oid, ip, community string, snmpQuerier gosnmpquerier.SyncQuerier) (uint, error) {
	result, err := snmpQuerier.Walk(ip, community, oid, 2*time.Second, 1)
	if err == nil {
		max := uint(0)
		for _, r := range result {
			if r.Value.(uint) > max {
				max = r.Value.(uint)
			}
		}
		return max, nil
	} else {
		return 0, err
	}
}

func NewJuniperTempChecker(ip, community string, maxAllowedTemp uint, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		max, err := getMaxValueFromSnmpWalk("1.3.6.1.4.1.2636.3.1.13.1.7", ip, community, snmpQuerier)
		if err == nil {
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func NewJuniperCpuChecker(ip, community string, maxAllowedTemp uint, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		max, err := getMaxValueFromSnmpWalk("1.3.6.1.4.1.2636.3.1.13.1.8", ip, community, snmpQuerier)
		if err == nil {
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func NewRabbitMQQueueLenCheck(amqpuri, queue string, max int) CheckFunction {
	return func() (bool, error, float32) {
		queueInfo, err := simpleamqp.NewAmqpManagement(amqpuri).QueueInfo(queue)
		if err == nil {
			return queueInfo.Messages < max, nil, float32(queueInfo.Messages)
		} else {
			return false, nil, float32(0)
		}
	}
}
<commit_msg>Check for mysql connection<commit_after>package felixcheck

import (
	"fmt"
	"net"
	"strings"
	"time"

	"net/http"
	"net/url"

	"github.com/aleasoluciones/gosnmpquerier"
	"github.com/aleasoluciones/simpleamqp"
	"github.com/tatsushid/go-fastping"
)

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

const (
	sysName     = "1.3.6.1.2.1.1.5.0"
	maxPingTime = 4 * time.Second
)

type CheckFunction func() (bool, error, float32)

func NewPingChecker(ip string) CheckFunction {
	return func() (bool, error, float32) {
		var retRtt time.Duration = 0
		var isUp bool = false

		p := fastping.NewPinger()
		p.MaxRTT = maxPingTime
		ra, err := net.ResolveIPAddr("ip4:icmp", ip)

		if err != nil {
			return false, err, 0
		}

		p.AddIPAddr(ra)
		p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
			isUp = true
			retRtt = rtt
		}

		err = p.Run()
		if err != nil {
			return false, err, 0
		}

		return isUp, nil, float32(retRtt.Nanoseconds() / 1e6)
	}
}

type TcpCheckerConf struct {
	retries   int
	timeout   time.Duration
	retrytime time.Duration
}

var DefaultTcpCheckConf = TcpCheckerConf{
	retries:   3,
	timeout:   2 * time.Second,
	retrytime: 1 * time.Second,
}

func NewTcpPortChecker(ip string, port int, conf TcpCheckerConf) CheckFunction {
	return func() (bool, error, float32) {
		var err error
		var conn net.Conn

		for attempt := 0; attempt < conf.retries; attempt++ {
			conn, err = net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), conf.timeout)
			if err == nil {
				conn.Close()
				return true, nil, 0
			}
			time.Sleep(conf.retrytime)
		}
		return false, err, 0
	}
}

func NewHttpChecker(url string, expectedStatusCode int) CheckFunction {
	return func() (bool, error, float32) {
		var t1 = time.Now()
		response, err := http.Get(url)
		milliseconds := float32((time.Now().Sub(t1)).Nanoseconds() / 1e6)
		if err != nil {
			return false, err, milliseconds
		} else {
			defer response.Body.Close()
			if response.StatusCode == expectedStatusCode {
				return true, nil, milliseconds
			}
		}
		return false, err, milliseconds
	}
}

type SnmpCheckerConf struct {
	retries    int
	timeout    time.Duration
	oidToCheck string
}

var DefaultSnmpCheckConf = SnmpCheckerConf{
	retries:    1,
	timeout:    1 * time.Second,
	oidToCheck: sysName,
}

func NewSnmpChecker(ip, community string, conf SnmpCheckerConf, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		_, err := snmpQuerier.Get(ip, community, []string{conf.oidToCheck}, conf.timeout, conf.retries)
		if err == nil {
			return true, nil, 0
		} else {
			return false, err, 0
		}
	}
}

func NewC4CMTSTempChecker(ip, community string, maxAllowedTemp int, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		result, err := snmpQuerier.Walk(ip, community, "1.3.6.1.4.1.4998.1.1.10.1.4.2.1.29", 2*time.Second, 1)

		if err == nil {
			max := 0
			for _, r := range result {
				if r.Value.(int) != 999 && r.Value.(int) > max {
					max = r.Value.(int)
				}
			}
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func getMaxValueFromSnmpWalk(oid, ip, community string, snmpQuerier gosnmpquerier.SyncQuerier) (uint, error) {
	result, err := snmpQuerier.Walk(ip, community, oid, 2*time.Second, 1)
	if err == nil {
		max := uint(0)
		for _, r := range result {
			if r.Value.(uint) > max {
				max = r.Value.(uint)
			}
		}
		return max, nil
	} else {
		return 0, err
	}
}

func NewJuniperTempChecker(ip, community string, maxAllowedTemp uint, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		max, err := getMaxValueFromSnmpWalk("1.3.6.1.4.1.2636.3.1.13.1.7", ip, community, snmpQuerier)
		if err == nil {
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func NewJuniperCpuChecker(ip, community string, maxAllowedTemp uint, snmpQuerier gosnmpquerier.SyncQuerier) CheckFunction {
	return func() (bool, error, float32) {
		max, err := getMaxValueFromSnmpWalk("1.3.6.1.4.1.2636.3.1.13.1.8", ip, community, snmpQuerier)
		if err == nil {
			return max < maxAllowedTemp, nil, float32(max)
		} else {
			return false, err, 0
		}
	}
}

func NewRabbitMQQueueLenCheck(amqpuri, queue string, max int) CheckFunction {
	return func() (bool, error, float32) {
		queueInfo, err := simpleamqp.NewAmqpManagement(amqpuri).QueueInfo(queue)
		if err == nil {
			return queueInfo.Messages < max, nil, float32(queueInfo.Messages)
		} else {
			return false, nil, float32(0)
		}
	}
}

func NewMysqlConnectionCheck(mysqluri string) CheckFunction {
	return func() (bool, error, float32) {
		u, err := url.Parse(mysqluri)
		if err != nil {
			return false, err, float32(0)
		}

		password, _ := u.User.Password()
		hostAndPort := u.Host
		if !strings.Contains(hostAndPort, ":") {
			hostAndPort = hostAndPort + ":3306"
		}
		con, err := sql.Open("mysql", u.User.Username()+":"+password+"@"+"tcp("+hostAndPort+")"+u.Path)
		defer con.Close()
		if err != nil {
			return false, err, float32(0)
		}
		q := `select CURTIME()`
		row := con.QueryRow(q)
		var date string
		err = row.Scan(&date)
		if err != nil {
			return false, err, float32(0)
		}
		return true, nil, float32(0)
	}
}
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package models

import (
	"github.com/bboozzoo/q3stats/models/test"
	"testing"
)

func TestNewPlayerMatchStat(t *testing.T) {
	store := test.GetStore(t)

	db := store.Conn()
	defer db.Close()

	CreateSchema(store)

	pms := PlayerMatchStat{
		Score:   10,
		Kills:   10,
		AliasID: 2,
		MatchID: 3,
	}

	pmsid := NewPlayerMatchStat(store, pms)

	var fpms PlayerMatchStat
	nf := db.Find(&fpms, pmsid).RecordNotFound()
	if nf == true {
		t.Fatalf("expected to find player-match stat of ID %u", pmsid)
	}

	if pms.AliasID != fpms.AliasID || pms.MatchID != fpms.MatchID ||
		pms.Score != fpms.Score {
		t.Fatalf("found data mismatch in player-match stat data")
	}
}
<commit_msg>models/playermatch: use assert pacakge in tests<commit_after>// The MIT License (MIT)

// Copyright (c) 2016 Maciej Borzecki

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package models

import (
	"github.com/bboozzoo/q3stats/models/test"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestNewPlayerMatchStat(t *testing.T) {
	store := test.GetStore(t)

	db := store.Conn()
	defer db.Close()

	CreateSchema(store)

	pms := PlayerMatchStat{
		Score:   10,
		Kills:   10,
		AliasID: 2,
		MatchID: 3,
	}

	pmsid := NewPlayerMatchStat(store, pms)

	var fpms PlayerMatchStat
	nf := db.Find(&fpms, pmsid).RecordNotFound()
	assert.False(t, nf, "expected to find player-match stat of ID %u", pmsid)

	assert.Equal(t, pms.AliasID, fpms.AliasID)
	assert.Equal(t, pms.MatchID, fpms.MatchID)
	assert.Equal(t, pms.Score, fpms.Score)
}
<|endoftext|>


<commit_before>package sqlread

import (
	"log"
	"unicode"
)

func startState(l *lexer) state {
	l.accept(sep)

	if l.hasPrefix("--") {
		return doubleDashCommentState(l, startState)
	}

	if l.hasPrefix("/*") {
		return blockCommentState(l, startState)
	}

	if l.hasPrefix("DROP TABLE ") {
		return dropTableState(l)
	}

	if l.hasPrefix("LOCK TABLES ") {
		return lockTableState(l)
	}

	if l.hasPrefix("UNLOCK TABLES") {
		return unlockTableState(l)
	}

	if l.hasPrefix("CREATE TABLE ") {
		return createTableState(l)
	}

	if l.hasPrefix("INSERT INTO ") {
		return insertIntoTableState(l)
	}

	if l.hasPrefix("SET ") {
		return setState
	}

	n, p := l.peek(10)
	log.Println("peak ahead", string(p), n, p)

	return nil
}

func insertIntoTableState(l *lexer) state {
	l.start = l.pos
	l.pos += 12

	l.emit(TInsertInto)
	return identifierStateAction(insertValuesState)
}

func insertValuesState(l *lexer) state {
	l.start = l.pos
	l.accept(whitespace)
	if l.hasPrefix("VALUES ") {
		l.pos += 7
		l.emit(TInsertValues)
	} else {
		l.emit(TIllegal)
		return nil
	}

	l.accept(whitespace)

	return insertRowsState
}

func insertRowsState(l *lexer) state {
	l.start = l.pos

	e := l.next()
	if e == lprn {
		return insertRowState
	}
	// _, pp := l.peak(5)
	// log.Println(string(e), string(pp))
	if e == coma && l.hasPrefix("(") {
		l.emit(TComma)
		l.pos++
		return insertRowState
	}

	if e == semi {
		l.emit(TSemi)
		return startState
	}

	l.emit(TIllegal)
	return nil
}

func insertRowState(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if in(c, numbers) {
			l.rewind()
			if eatNumber(l) {
				l.emit(TNumber)
				break
			}
		} else if c == sq || c == dq {
			l.rewind()
			if eatString(l) {
				l.emit(TString)
				break
			}
		} else if c == letN && l.hasPrefix("ULL") {
			l.pos += 3
			l.emit(TNull)
			break
		}

		l.emit(TIllegal)
		return nil
	}

	d := l.next()

	if d == rprn {
		// l.rewind()
		// l.emit(TInsertRow)
		return insertRowsState
	}

	if d == coma {
		return insertRowState
	}

	l.emit(TIllegal)
	return nil
}

func doubleDashCommentState(l *lexer, ret state) state {
	l.start = l.pos + 3
	s := ""
	for {
		b := l.next()
		if b == eof || b == lf {
			break
		}
		s += string(b)
	}

	l.emit(TComment)

	return ret
}

func blockCommentState(l *lexer, ret state) state {
	l.pos += 2
	l.start = l.pos

	for {
		if l.hasPrefix("*/") {
			l.emit(TComment)
			l.pos += 2
			break
		}
		l.next()
	}

	return ret
}

func dropTableState(l *lexer) state {
	l.start = l.pos

	if l.until(semi) {
		l.rewind()
		l.emit(TDropTableFullStmt)
		l.start = l.pos
		l.pos++
		l.emit(TSemi)
	} else {
		l.emit(TIllegal)
		return nil
	}

	return startState
}

func lockTableState(l *lexer) state {
	l.start = l.pos

	if l.until(semi) {
		l.rewind()
		l.emit(TLockTableFullStmt)
		l.start = l.pos
		l.pos++
		l.emit(TSemi)
	} else {
		l.emit(TIllegal)
		return nil
	}

	return startState
}

func unlockTableState(l *lexer) state {
	l.start = l.pos

	if l.until(semi) {
		l.rewind()
		l.emit(TUnlockTablesFullStmt)
		l.start = l.pos
		l.pos++
		l.emit(TSemi)
	} else {
		l.emit(TIllegal)
		return nil
	}

	return startState
}

func setState(l *lexer) state {
	l.start = l.pos

	if l.until(semi) {
		l.rewind()
		l.emit(TSetFullStmt)
		l.start = l.pos
		l.pos++
		l.emit(TSemi)
	} else {
		l.emit(TIllegal)
		return nil
	}

	return startState
}

func createTableState(l *lexer) state {
	l.start = l.pos
	l.pos += 13
	l.emit(TCreateTable)

	return identifierStateAction(createTableParamsState)
}

func createTableParamsState(l *lexer) state {
	l.start = l.pos
	l.accept(whitespace)

	if l.next() == lprn {
		l.emit(TLParen)
		return createTableParamState
	}

	l.emit(TIllegal)
	return nil
}

func createTableParamState(l *lexer) state {
	l.accept(whitespace)

	if l.hasPrefix("PRIMARY KEY ") || l.hasPrefix("KEY ") || l.hasPrefix("CONSTRAINT ") || l.hasPrefix("UNIQUE KEY") || l.hasPrefix(")") {
		return createTableDetailState
	}

	return identifierStateAction(createTableParamTypeState)
}

func createTableDetailState(l *lexer) state {
	l.start = l.pos
	o := 0
	for {
		c := l.next()

		if c == lprn {
			o++
		} else if c == rprn {
			o--
		}

		if o < 0 {
			l.rewind()
			l.emit(TCreateTableDetail)

			l.start = l.pos

			l.next()
			l.emit(TRParen)
			return createTableExtra
		}
	}
}

func createTableExtra(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if l.hasPrefix("COMMENT=") {
			l.pos += 8
			if !eatString(l) {
				l.emit(TIllegal)
				return nil
			}
		}

		if c == semi {
			return startState
		}
	}
}

func createTableParamTypeState(l *lexer) state {
	l.accept(whitespace)
	l.start = l.pos

	for {
		c := l.next()
		r := rune(c)

		if !unicode.IsLetter(r) {
			if l.start == l.pos-1 {
				l.emit(TIllegal)
				return nil
			}

			l.rewind()
			li := l.emit(TColumnType)

			if c == lprn {
				if li.Val == "enum" {
					return createTableParamTypeEnumValuesState
				}

				return createTableParamTypeSizeState
			}

			return createTableParamDetailsState
		}
	}
}

func createTableParamTypeEnumValuesState(l *lexer) state {
	if l.accept([]byte{lprn}) != 1 {
		l.emit(TIllegal)
		return nil
	}

	l.start = l.pos
	for {
		if eatString(l) {
			l.emit(TColumnEnumVal)
		}

		c := l.next()
		if c == rprn {
			return createTableParamDetailsState
		}

		if c != coma {
			l.emit(TIllegal)
			return nil
		}

		l.start = l.pos
	}
}

func createTableParamTypeSizeState(l *lexer) state {
	if l.accept([]byte{lprn}) != 1 {
		l.emit(TIllegal)
		return nil
	}

	l.start = l.pos

	for {
		c := l.next()

		if c == rprn {
			if l.start == l.pos-1 {
				l.emit(TIllegal)
				return nil
			}

			l.rewind()
			l.emit(TColumnSize)
			l.next()

			return createTableParamDetailsState
		}

		if c != coma {
			r := rune(c)

			if !unicode.IsNumber(r) {
				l.emit(TIllegal)
				return nil
			}
		}
	}
}

func createTableParamDetailsState(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if c == coma || c == rprn {
			l.rewind()
			l.emit(TColumnDetails)
			if c == coma {
				l.next()
			}

			return createTableParamState
		}

		if l.hasPrefix("COMMENT ") {
			l.pos += 7
			l.accept(whitespace)
			if !eatString(l) {
				l.emit(TIllegal)
				return nil
			}
		}

		if l.hasPrefix("DEFAULT ") {
			l.pos += 7
			l.accept(whitespace)
			eatString(l)
		}
	}
	return nil
}

func eatNumber(l *lexer) bool {
	n1 := l.accept(numbers)
	n2 := 0

	p := l.next()
	if p == dot {
		n2 = l.accept(numbers)
		if n2 == 0 {
			return false
		}
	} else {
		l.rewind()
	}

	return n1+n2 > 0
}

func eatString(l *lexer) bool {
	delim := l.next()
	l.rewind()

	if delim != sq && delim != dq {
		return false
	}

	return eatDelimStr(l, delim)
}

func eatDelimStr(l *lexer, delim byte) bool {
	first := l.next()
	if first != delim {
		l.rewind()
		return false
	}

	for {
		c := l.next()

		if c == eof {
			return false
		}

		if c == bs {
			_, p := l.peek(1)
			if p[0] == delim || p[0] == bs {
				l.next()
			}
		} else if c == delim {
			_, p := l.peek(1)
			if p[0] == delim {
				l.next()
			} else {
				break
			}

		}
	}

	return true
}

func eatIdentifier(l *lexer) bool {
	b := l.next()
	l.rewind()

	if b == bt {
		return eatDelimStr(l, bt)
	}

	log.Fatal("non-backtick identifiers not implemented yet at:", l.pos)

	return false
}

func identifierStateAction(ret state) state {
	return func(l *lexer) state {
		l.start = l.pos

		if eatIdentifier(l) {
			l.start++
			l.pos--
			l.emit(TIdentifier)
			l.pos++
		} else {
			l.emit(TIllegal)
		}

		return ret
	}
}
<commit_msg>Cleans up some duplication I’ve intended to clean up<commit_after>package sqlread

import (
	"log"
	"unicode"
)

func startState(l *lexer) state {
	l.accept(sep)

	if l.hasPrefix("--") {
		return doubleDashCommentState(l, startState)
	}

	if l.hasPrefix("/*") {
		return blockCommentState(l, startState)
	}

	if l.hasPrefix("DROP TABLE ") {
		return untilSemiState(TDropTableFullStmt)
	}

	if l.hasPrefix("LOCK TABLES ") {
		return untilSemiState(TLockTableFullStmt)
	}

	if l.hasPrefix("UNLOCK TABLES") {
		return untilSemiState(TUnlockTablesFullStmt)
	}

	if l.hasPrefix("CREATE TABLE ") {
		return createTableState(l)
	}

	if l.hasPrefix("INSERT INTO ") {
		return insertIntoTableState(l)
	}

	if l.hasPrefix("SET ") {
		return untilSemiState(TSetFullStmt)
	}

	n, p := l.peek(10)
	log.Println("peak ahead", string(p), n, p)

	return nil
}

func insertIntoTableState(l *lexer) state {
	l.start = l.pos
	l.pos += 12

	l.emit(TInsertInto)
	return identifierStateAction(insertValuesState)
}

func insertValuesState(l *lexer) state {
	l.start = l.pos
	l.accept(whitespace)
	if l.hasPrefix("VALUES ") {
		l.pos += 7
		l.emit(TInsertValues)
	} else {
		l.emit(TIllegal)
		return nil
	}

	l.accept(whitespace)

	return insertRowsState
}

func insertRowsState(l *lexer) state {
	l.start = l.pos

	e := l.next()
	if e == lprn {
		return insertRowState
	}
	// _, pp := l.peak(5)
	// log.Println(string(e), string(pp))
	if e == coma && l.hasPrefix("(") {
		l.emit(TComma)
		l.pos++
		return insertRowState
	}

	if e == semi {
		l.emit(TSemi)
		return startState
	}

	l.emit(TIllegal)
	return nil
}

func insertRowState(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if in(c, numbers) {
			l.rewind()
			if eatNumber(l) {
				l.emit(TNumber)
				break
			}
		} else if c == sq || c == dq {
			l.rewind()
			if eatString(l) {
				l.emit(TString)
				break
			}
		} else if c == letN && l.hasPrefix("ULL") {
			l.pos += 3
			l.emit(TNull)
			break
		}

		l.emit(TIllegal)
		return nil
	}

	d := l.next()

	if d == rprn {
		// l.rewind()
		// l.emit(TInsertRow)
		return insertRowsState
	}

	if d == coma {
		return insertRowState
	}

	l.emit(TIllegal)
	return nil
}

func doubleDashCommentState(l *lexer, ret state) state {
	l.start = l.pos + 3
	s := ""
	for {
		b := l.next()
		if b == eof || b == lf {
			break
		}
		s += string(b)
	}

	l.emit(TComment)

	return ret
}

func blockCommentState(l *lexer, ret state) state {
	l.pos += 2
	l.start = l.pos

	for {
		if l.hasPrefix("*/") {
			l.emit(TComment)
			l.pos += 2
			break
		}
		l.next()
	}

	return ret
}

func untilSemiState(emit lexItemType) state {
	return func(l *lexer) state {
		l.start = l.pos

		if l.until(semi) {
			l.rewind()
			l.emit(emit)
			l.start = l.pos
			l.pos++
			l.emit(TSemi)
		} else {
			l.emit(TIllegal)
			return nil
		}

		return startState
	}
}

func createTableState(l *lexer) state {
	l.start = l.pos
	l.pos += 13
	l.emit(TCreateTable)

	return identifierStateAction(createTableParamsState)
}

func createTableParamsState(l *lexer) state {
	l.start = l.pos
	l.accept(whitespace)

	if l.next() == lprn {
		l.emit(TLParen)
		return createTableParamState
	}

	l.emit(TIllegal)
	return nil
}

func createTableParamState(l *lexer) state {
	l.accept(whitespace)

	if l.hasPrefix("PRIMARY KEY ") || l.hasPrefix("KEY ") || l.hasPrefix("CONSTRAINT ") || l.hasPrefix("UNIQUE KEY") || l.hasPrefix(")") {
		return createTableDetailState
	}

	return identifierStateAction(createTableParamTypeState)
}

func createTableDetailState(l *lexer) state {
	l.start = l.pos
	o := 0
	for {
		c := l.next()

		if c == lprn {
			o++
		} else if c == rprn {
			o--
		}

		if o < 0 {
			l.rewind()
			l.emit(TCreateTableDetail)

			l.start = l.pos

			l.next()
			l.emit(TRParen)
			return createTableExtra
		}
	}
}

func createTableExtra(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if l.hasPrefix("COMMENT=") {
			l.pos += 8
			if !eatString(l) {
				l.emit(TIllegal)
				return nil
			}
		}

		if c == semi {
			return startState
		}
	}
}

func createTableParamTypeState(l *lexer) state {
	l.accept(whitespace)
	l.start = l.pos

	for {
		c := l.next()
		r := rune(c)

		if !unicode.IsLetter(r) {
			if l.start == l.pos-1 {
				l.emit(TIllegal)
				return nil
			}

			l.rewind()
			li := l.emit(TColumnType)

			if c == lprn {
				if li.Val == "enum" {
					return createTableParamTypeEnumValuesState
				}

				return createTableParamTypeSizeState
			}

			return createTableParamDetailsState
		}
	}
}

func createTableParamTypeEnumValuesState(l *lexer) state {
	if l.accept([]byte{lprn}) != 1 {
		l.emit(TIllegal)
		return nil
	}

	l.start = l.pos
	for {
		if eatString(l) {
			l.emit(TColumnEnumVal)
		}

		c := l.next()
		if c == rprn {
			return createTableParamDetailsState
		}

		if c != coma {
			l.emit(TIllegal)
			return nil
		}

		l.start = l.pos
	}
}

func createTableParamTypeSizeState(l *lexer) state {
	if l.accept([]byte{lprn}) != 1 {
		l.emit(TIllegal)
		return nil
	}

	l.start = l.pos

	for {
		c := l.next()

		if c == rprn {
			if l.start == l.pos-1 {
				l.emit(TIllegal)
				return nil
			}

			l.rewind()
			l.emit(TColumnSize)
			l.next()

			return createTableParamDetailsState
		}

		if c != coma {
			r := rune(c)

			if !unicode.IsNumber(r) {
				l.emit(TIllegal)
				return nil
			}
		}
	}
}

func createTableParamDetailsState(l *lexer) state {
	l.start = l.pos
	for {
		c := l.next()

		if c == coma || c == rprn {
			l.rewind()
			l.emit(TColumnDetails)
			if c == coma {
				l.next()
			}

			return createTableParamState
		}

		if l.hasPrefix("COMMENT ") {
			l.pos += 7
			l.accept(whitespace)
			if !eatString(l) {
				l.emit(TIllegal)
				return nil
			}
		}

		if l.hasPrefix("DEFAULT ") {
			l.pos += 7
			l.accept(whitespace)
			eatString(l)
		}
	}
	return nil
}

func eatNumber(l *lexer) bool {
	n1 := l.accept(numbers)
	n2 := 0

	p := l.next()
	if p == dot {
		n2 = l.accept(numbers)
		if n2 == 0 {
			return false
		}
	} else {
		l.rewind()
	}

	return n1+n2 > 0
}

func eatString(l *lexer) bool {
	delim := l.next()
	l.rewind()

	if delim != sq && delim != dq {
		return false
	}

	return eatDelimStr(l, delim)
}

func eatDelimStr(l *lexer, delim byte) bool {
	first := l.next()
	if first != delim {
		l.rewind()
		return false
	}

	for {
		c := l.next()

		if c == eof {
			return false
		}

		if c == bs {
			_, p := l.peek(1)
			if p[0] == delim || p[0] == bs {
				l.next()
			}
		} else if c == delim {
			_, p := l.peek(1)
			if p[0] == delim {
				l.next()
			} else {
				break
			}

		}
	}

	return true
}

func eatIdentifier(l *lexer) bool {
	b := l.next()
	l.rewind()

	if b == bt {
		return eatDelimStr(l, bt)
	}

	log.Fatal("non-backtick identifiers not implemented yet at:", l.pos)

	return false
}

func identifierStateAction(ret state) state {
	return func(l *lexer) state {
		l.start = l.pos

		if eatIdentifier(l) {
			l.start++
			l.pos--
			l.emit(TIdentifier)
			l.pos++
		} else {
			l.emit(TIllegal)
		}

		return ret
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 The Cockroach Authors.
//
// 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. See the AUTHORS file
// for names of contributors.
//
// Author: Peter Mattis (peter@cockroachlabs.com)

package cli

import (
	"bytes"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/cockroachdb/cockroach/client"
	"github.com/cockroachdb/cockroach/keys"
	"github.com/cockroachdb/cockroach/proto"

	"github.com/spf13/cobra"
)

var osExit = os.Exit
var osStderr = os.Stderr

func makeDBClient() *client.DB {
	// TODO(pmattis): Initialize the user to something more
	// reasonable. Perhaps Context.Addr should be considered a URL.
	db, err := client.Open(Context.RequestScheme() +
		"://root@" + Context.Addr +
		"?certs=" + Context.Certs)
	if err != nil {
		fmt.Fprintf(osStderr, "failed to initialize KV client: %s\n", err)
		osExit(1)
	}
	return db
}

// unquoteArg unquotes the provided argument using Go double-quoted
// string literal rules.
func unquoteArg(arg string, disallowSystem bool) string {
	s, err := strconv.Unquote(`"` + arg + `"`)
	if err != nil {
		fmt.Fprintf(osStderr, "invalid argument %q: %s\n", arg, err)
		osExit(1)
	}
	if disallowSystem && strings.HasPrefix(s, "\x00") {
		fmt.Fprintf(osStderr, "cannot specify system key %q\n", s)
		osExit(1)
	}
	return s
}

// A getCmd gets the value for the specified key.
var getCmd = &cobra.Command{
	Use:   "get [options] <key>",
	Short: "gets the value for a key",
	Long: `
Fetches and displays the value for <key>.
`,
	Run: runGet,
}

func runGet(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	key := proto.Key(unquoteArg(args[0], false))
	r, err := kvDB.Get(key)
	if err != nil {
		fmt.Fprintf(osStderr, "get failed: %s\n", err)
		osExit(1)
		return
	}
	if !r.Exists() {
		fmt.Fprintf(osStderr, "%s not found\n", key)
		osExit(1)
		return
	}
	fmt.Printf("%q\n", r.Value)
}

// A putCmd sets the value for one or more keys.
var putCmd = &cobra.Command{
	Use:   "put [options] <key> <value> [<key2> <value2>...]",
	Short: "sets the value for one or more keys",
	Long: `
Sets the value for one or more keys. Keys and values must be provided
in pairs on the command line.
`,
	Run: runPut,
}

func runPut(cmd *cobra.Command, args []string) {
	if len(args) == 0 || len(args)%2 == 1 {
		cmd.Usage()
		return
	}

	var b client.Batch
	for i := 0; i < len(args); i += 2 {
		b.Put(
			unquoteArg(args[i], true /* disallow system keys */),
			unquoteArg(args[i+1], false),
		)
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.Run(&b); err != nil {
		fmt.Fprintf(osStderr, "put failed: %s\n", err)
		osExit(1)
		return
	}
}

// A cPutCmd command conditionally sets a value for a key.
var cPutCmd = &cobra.Command{
	Use:   "cput [options] <key> <value> [<expValue>]",
	Short: "conditionally sets a value for a key",
	Long: `
Conditionally sets a value for a key if the existing value is equal
to expValue. To conditionally set a value only if there is no existing entry
pass nil for expValue. The expValue defaults to 1 if not specified.
`,
	Run: runCPut,
}

func runCPut(cmd *cobra.Command, args []string) {
	if len(args) != 2 && len(args) != 3 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	key := unquoteArg(args[0], true /* disallow system keys */)
	value := unquoteArg(args[1], false)
	var err error
	if len(args) == 3 {
		err = kvDB.CPut(key, value, unquoteArg(args[2], false))
	} else {
		err = kvDB.CPut(key, value, nil)
	}

	if err != nil {
		fmt.Fprintf(osStderr, "conditionally put failed: %s\n", err)
		osExit(1)
	}
}

// A incCmd command increments the value for a key.
var incCmd = &cobra.Command{
	Use:   "inc [options] <key> [<amount>]",
	Short: "increments the value for a key",
	Long: `
Increments the value for a key. The increment amount defaults to 1 if
not specified. Displays the incremented value upon success.
Negative values need to be prefixed with -- to not get interpreted as
flags.
`,
	Run: runInc,
}

func runInc(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	amount := 1
	if len(args) >= 2 {
		var err error
		if amount, err = strconv.Atoi(args[1]); err != nil {
			fmt.Fprintf(osStderr, "invalid increment: %s: %s\n", args[1], err)
			osExit(1)
			return
		}
	}

	key := proto.Key(unquoteArg(args[0], true /* disallow system keys */))
	if r, err := kvDB.Inc(key, int64(amount)); err != nil {
		fmt.Fprintf(osStderr, "increment failed: %s\n", err)
		osExit(1)
	} else {
		fmt.Printf("%d\n", r.ValueInt())
	}
}

// A delCmd deletes the values of one or more keys.
var delCmd = &cobra.Command{
	Use:   "del [options] <key> [<key2>...]",
	Short: "deletes the values of one or more keys",
	Long: `
Deletes the values of one or more keys.
`,
	Run: runDel,
}

func runDel(cmd *cobra.Command, args []string) {
	if len(args) == 0 {
		cmd.Usage()
		return
	}

	var b client.Batch
	for _, arg := range args {
		b.Del(unquoteArg(arg, true /* disallow system keys */))
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.Run(&b); err != nil {
		fmt.Fprintf(osStderr, "delete failed: %s\n", err)
		osExit(1)
		return
	}
}

// A delRangeCmd deletes the values for a range of keys.
// [startKey, endKey).
var delRangeCmd = &cobra.Command{
	Use:   "delrange [options] <startKey> <endKey>",
	Short: "deletes the values for a range of keys",
	Long: `
Deletes the values for the range of keys [startKey, endKey).
`,
	Run: runDelRange,
}

func runDelRange(cmd *cobra.Command, args []string) {
	if len(args) == 0 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.DelRange(
		unquoteArg(args[0], true /* disallow system keys */),
		unquoteArg(args[1], true /* disallow system keys */),
	); err != nil {
		fmt.Fprintf(osStderr, "delrange failed: %s\n", err)
		osExit(1)
	}
}

// A scanCmd fetches the key/value pairs for a specified
// range.
var scanCmd = &cobra.Command{
	Use:   "scan [options] [<start-key> [<end-key>]]",
	Short: "scans a range of keys",
	Long: `
Fetches and display the key/value pairs for a range. If no <start-key>
is specified then all (non-system) key/value pairs are retrieved. If no
<end-key> is specified then all keys greater than or equal to <start-key>
are retrieved.
`,
	Run: runScan,
}

func runScan(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}
	startKey, endKey := initScanArgs(args)

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	rows, err := kvDB.Scan(startKey, endKey, maxResults)
	if err != nil {
		fmt.Fprintf(osStderr, "scan failed: %s\n", err)
		osExit(1)
		return
	}
	showResult(rows)
}

// A reverseScanCmd fetches the key/value pairs for a specified
// range.
var reverseScanCmd = &cobra.Command{
	Use:   "revscan [options] [<start-key> [<end-key>]]",
	Short: "scans a range of keys in reverse order",
	Long: `
Fetches and display the key/value pairs for a range. If no <start-key>
is specified then all (non-system) key/value pairs are retrieved. If no
<end-key> is specified then all keys greater than or equal to <start-key>
are retrieved.
`,
	Run: runReverseScan,
}

func runReverseScan(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}
	startKey, endKey := initScanArgs(args)
	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	rows, err := kvDB.ReverseScan(startKey, endKey, maxResults)
	if err != nil {
		fmt.Fprintf(osStderr, "reverse scan failed: %s\n", err)
		osExit(1)
		return
	}
	showResult(rows)
}

func initScanArgs(args []string) (startKey, endKey proto.Key) {
	if len(args) >= 1 {
		startKey = proto.Key(unquoteArg(args[0], false))
	} else {
		// Start with the first key after the system key range.
		startKey = keys.SystemMax
	}
	if len(args) >= 2 {
		endKey = proto.Key(unquoteArg(args[1], false))
	} else {
		// Exclude table data keys by default. The user can explicitly request them
		// by passing \xff\xff for the end key.
		endKey = keys.TableDataPrefix
	}
	return startKey, endKey
}

func showResult(rows []client.KeyValue) {
	for _, row := range rows {
		if bytes.HasPrefix(row.Key, []byte{0}) {
			// TODO(pmattis): Pretty-print system keys.
			fmt.Printf("%s\n", row.Key)
			continue
		}

		key := proto.Key(row.Key)
		fmt.Printf("%s\t%q\n", key, row.Value)
	}
	fmt.Printf("%d result(s)\n", len(rows))
}

var kvCmds = []*cobra.Command{
	getCmd,
	putCmd,
	cPutCmd,
	incCmd,
	delCmd,
	delRangeCmd,
	scanCmd,
	reverseScanCmd,
}

var kvCmd = &cobra.Command{
	Use:   "kv",
	Short: "get, put, conditional put, increment, delete, scan, and reverse scan key/value pairs",
	Long: `
Special characters in keys or values should be specified according to
the double-quoted Go string literal rules (see
https://golang.org/ref/spec#String_literals).
`,
	Run: func(cmd *cobra.Command, args []string) {
		cmd.Usage()
	},
}

func init() {
	kvCmd.AddCommand(kvCmds...)
}
<commit_msg>Fix comment<commit_after>// Copyright 2015 The Cockroach Authors.
//
// 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. See the AUTHORS file
// for names of contributors.
//
// Author: Peter Mattis (peter@cockroachlabs.com)

package cli

import (
	"bytes"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/cockroachdb/cockroach/client"
	"github.com/cockroachdb/cockroach/keys"
	"github.com/cockroachdb/cockroach/proto"

	"github.com/spf13/cobra"
)

var osExit = os.Exit
var osStderr = os.Stderr

func makeDBClient() *client.DB {
	// TODO(pmattis): Initialize the user to something more
	// reasonable. Perhaps Context.Addr should be considered a URL.
	db, err := client.Open(Context.RequestScheme() +
		"://root@" + Context.Addr +
		"?certs=" + Context.Certs)
	if err != nil {
		fmt.Fprintf(osStderr, "failed to initialize KV client: %s\n", err)
		osExit(1)
	}
	return db
}

// unquoteArg unquotes the provided argument using Go double-quoted
// string literal rules.
func unquoteArg(arg string, disallowSystem bool) string {
	s, err := strconv.Unquote(`"` + arg + `"`)
	if err != nil {
		fmt.Fprintf(osStderr, "invalid argument %q: %s\n", arg, err)
		osExit(1)
	}
	if disallowSystem && strings.HasPrefix(s, "\x00") {
		fmt.Fprintf(osStderr, "cannot specify system key %q\n", s)
		osExit(1)
	}
	return s
}

// A getCmd gets the value for the specified key.
var getCmd = &cobra.Command{
	Use:   "get [options] <key>",
	Short: "gets the value for a key",
	Long: `
Fetches and displays the value for <key>.
`,
	Run: runGet,
}

func runGet(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		return
	}
	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	key := proto.Key(unquoteArg(args[0], false))
	r, err := kvDB.Get(key)
	if err != nil {
		fmt.Fprintf(osStderr, "get failed: %s\n", err)
		osExit(1)
		return
	}
	if !r.Exists() {
		fmt.Fprintf(osStderr, "%s not found\n", key)
		osExit(1)
		return
	}
	fmt.Printf("%q\n", r.Value)
}

// A putCmd sets the value for one or more keys.
var putCmd = &cobra.Command{
	Use:   "put [options] <key> <value> [<key2> <value2>...]",
	Short: "sets the value for one or more keys",
	Long: `
Sets the value for one or more keys. Keys and values must be provided
in pairs on the command line.
`,
	Run: runPut,
}

func runPut(cmd *cobra.Command, args []string) {
	if len(args) == 0 || len(args)%2 == 1 {
		cmd.Usage()
		return
	}

	var b client.Batch
	for i := 0; i < len(args); i += 2 {
		b.Put(
			unquoteArg(args[i], true /* disallow system keys */),
			unquoteArg(args[i+1], false),
		)
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.Run(&b); err != nil {
		fmt.Fprintf(osStderr, "put failed: %s\n", err)
		osExit(1)
		return
	}
}

// A cPutCmd conditionally sets a value for a key.
var cPutCmd = &cobra.Command{
	Use:   "cput [options] <key> <value> [<expValue>]",
	Short: "conditionally sets a value for a key",
	Long: `
Conditionally sets a value for a key if the existing value is equal
to expValue. To conditionally set a value only if there is no existing entry
pass nil for expValue. The expValue defaults to 1 if not specified.
`,
	Run: runCPut,
}

func runCPut(cmd *cobra.Command, args []string) {
	if len(args) != 2 && len(args) != 3 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	key := unquoteArg(args[0], true /* disallow system keys */)
	value := unquoteArg(args[1], false)
	var err error
	if len(args) == 3 {
		err = kvDB.CPut(key, value, unquoteArg(args[2], false))
	} else {
		err = kvDB.CPut(key, value, nil)
	}

	if err != nil {
		fmt.Fprintf(osStderr, "conditionally put failed: %s\n", err)
		osExit(1)
	}
}

// A incCmd command increments the value for a key.
var incCmd = &cobra.Command{
	Use:   "inc [options] <key> [<amount>]",
	Short: "increments the value for a key",
	Long: `
Increments the value for a key. The increment amount defaults to 1 if
not specified. Displays the incremented value upon success.
Negative values need to be prefixed with -- to not get interpreted as
flags.
`,
	Run: runInc,
}

func runInc(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	amount := 1
	if len(args) >= 2 {
		var err error
		if amount, err = strconv.Atoi(args[1]); err != nil {
			fmt.Fprintf(osStderr, "invalid increment: %s: %s\n", args[1], err)
			osExit(1)
			return
		}
	}

	key := proto.Key(unquoteArg(args[0], true /* disallow system keys */))
	if r, err := kvDB.Inc(key, int64(amount)); err != nil {
		fmt.Fprintf(osStderr, "increment failed: %s\n", err)
		osExit(1)
	} else {
		fmt.Printf("%d\n", r.ValueInt())
	}
}

// A delCmd deletes the values of one or more keys.
var delCmd = &cobra.Command{
	Use:   "del [options] <key> [<key2>...]",
	Short: "deletes the values of one or more keys",
	Long: `
Deletes the values of one or more keys.
`,
	Run: runDel,
}

func runDel(cmd *cobra.Command, args []string) {
	if len(args) == 0 {
		cmd.Usage()
		return
	}

	var b client.Batch
	for _, arg := range args {
		b.Del(unquoteArg(arg, true /* disallow system keys */))
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.Run(&b); err != nil {
		fmt.Fprintf(osStderr, "delete failed: %s\n", err)
		osExit(1)
		return
	}
}

// A delRangeCmd deletes the values for a range of keys.
// [startKey, endKey).
var delRangeCmd = &cobra.Command{
	Use:   "delrange [options] <startKey> <endKey>",
	Short: "deletes the values for a range of keys",
	Long: `
Deletes the values for the range of keys [startKey, endKey).
`,
	Run: runDelRange,
}

func runDelRange(cmd *cobra.Command, args []string) {
	if len(args) == 0 {
		cmd.Usage()
		return
	}

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}

	if err := kvDB.DelRange(
		unquoteArg(args[0], true /* disallow system keys */),
		unquoteArg(args[1], true /* disallow system keys */),
	); err != nil {
		fmt.Fprintf(osStderr, "delrange failed: %s\n", err)
		osExit(1)
	}
}

// A scanCmd fetches the key/value pairs for a specified
// range.
var scanCmd = &cobra.Command{
	Use:   "scan [options] [<start-key> [<end-key>]]",
	Short: "scans a range of keys",
	Long: `
Fetches and display the key/value pairs for a range. If no <start-key>
is specified then all (non-system) key/value pairs are retrieved. If no
<end-key> is specified then all keys greater than or equal to <start-key>
are retrieved.
`,
	Run: runScan,
}

func runScan(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}
	startKey, endKey := initScanArgs(args)

	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	rows, err := kvDB.Scan(startKey, endKey, maxResults)
	if err != nil {
		fmt.Fprintf(osStderr, "scan failed: %s\n", err)
		osExit(1)
		return
	}
	showResult(rows)
}

// A reverseScanCmd fetches the key/value pairs for a specified
// range.
var reverseScanCmd = &cobra.Command{
	Use:   "revscan [options] [<start-key> [<end-key>]]",
	Short: "scans a range of keys in reverse order",
	Long: `
Fetches and display the key/value pairs for a range. If no <start-key>
is specified then all (non-system) key/value pairs are retrieved. If no
<end-key> is specified then all keys greater than or equal to <start-key>
are retrieved.
`,
	Run: runReverseScan,
}

func runReverseScan(cmd *cobra.Command, args []string) {
	if len(args) > 2 {
		cmd.Usage()
		return
	}
	startKey, endKey := initScanArgs(args)
	kvDB := makeDBClient()
	if kvDB == nil {
		return
	}
	rows, err := kvDB.ReverseScan(startKey, endKey, maxResults)
	if err != nil {
		fmt.Fprintf(osStderr, "reverse scan failed: %s\n", err)
		osExit(1)
		return
	}
	showResult(rows)
}

func initScanArgs(args []string) (startKey, endKey proto.Key) {
	if len(args) >= 1 {
		startKey = proto.Key(unquoteArg(args[0], false))
	} else {
		// Start with the first key after the system key range.
		startKey = keys.SystemMax
	}
	if len(args) >= 2 {
		endKey = proto.Key(unquoteArg(args[1], false))
	} else {
		// Exclude table data keys by default. The user can explicitly request them
		// by passing \xff\xff for the end key.
		endKey = keys.TableDataPrefix
	}
	return startKey, endKey
}

func showResult(rows []client.KeyValue) {
	for _, row := range rows {
		if bytes.HasPrefix(row.Key, []byte{0}) {
			// TODO(pmattis): Pretty-print system keys.
			fmt.Printf("%s\n", row.Key)
			continue
		}

		key := proto.Key(row.Key)
		fmt.Printf("%s\t%q\n", key, row.Value)
	}
	fmt.Printf("%d result(s)\n", len(rows))
}

var kvCmds = []*cobra.Command{
	getCmd,
	putCmd,
	cPutCmd,
	incCmd,
	delCmd,
	delRangeCmd,
	scanCmd,
	reverseScanCmd,
}

var kvCmd = &cobra.Command{
	Use:   "kv",
	Short: "get, put, conditional put, increment, delete, scan, and reverse scan key/value pairs",
	Long: `
Special characters in keys or values should be specified according to
the double-quoted Go string literal rules (see
https://golang.org/ref/spec#String_literals).
`,
	Run: func(cmd *cobra.Command, args []string) {
		cmd.Usage()
	},
}

func init() {
	kvCmd.AddCommand(kvCmds...)
}
<|endoftext|>


<commit_before>package fasthttp

import (
	"bufio"
	"io"
	"runtime/debug"
	"sync"
)

// StreamWriter must write data to w.
//
// Usually StreamWriter writes data to w in a loop (aka 'data streaming').
//
// StreamWriter must return immediately if w returns error.
//
// Since the written data is buffered, do not forget calling w.Flush
// when the data must be propagated to reader.
type StreamWriter func(w *bufio.Writer)

// NewStreamReader returns a reader, which replays all the data generated by sw.
//
// The returned reader may be passed to Response.SetBodyStream.
//
// See also Response.SetBodyWriter.
func NewStreamReader(sw StreamWriter) io.Reader {
	pr, pw := io.Pipe()

	var bw *bufio.Writer
	bwv := streamWriterBufPool.Get()
	if bwv == nil {
		bw = bufio.NewWriter(pw)
		bwv = bw
	} else {
		bw = bwv.(*bufio.Writer)
		bw.Reset(pw)
	}

	go func() {
		defer func() {
			if r := recover(); r != nil {
				defaultLogger.Printf("panic in StreamWriter: %s\nStack trace:\n%s", r, debug.Stack())
			}
		}()

		sw(bw)
		bw.Flush()
		pw.Close()

		bw.Reset(nil)
		streamWriterBufPool.Put(bwv)
	}()

	return pr
}

var streamWriterBufPool sync.Pool
<commit_msg>typo fix<commit_after>package fasthttp

import (
	"bufio"
	"io"
	"runtime/debug"
	"sync"
)

// StreamWriter must write data to w.
//
// Usually StreamWriter writes data to w in a loop (aka 'data streaming').
//
// StreamWriter must return immediately if w returns error.
//
// Since the written data is buffered, do not forget calling w.Flush
// when the data must be propagated to reader.
type StreamWriter func(w *bufio.Writer)

// NewStreamReader returns a reader, which replays all the data generated by sw.
//
// The returned reader may be passed to Response.SetBodyStream.
//
// See also Response.SetBodyStreamWriter.
func NewStreamReader(sw StreamWriter) io.Reader {
	pr, pw := io.Pipe()

	var bw *bufio.Writer
	bwv := streamWriterBufPool.Get()
	if bwv == nil {
		bw = bufio.NewWriter(pw)
		bwv = bw
	} else {
		bw = bwv.(*bufio.Writer)
		bw.Reset(pw)
	}

	go func() {
		defer func() {
			if r := recover(); r != nil {
				defaultLogger.Printf("panic in StreamWriter: %s\nStack trace:\n%s", r, debug.Stack())
			}
		}()

		sw(bw)
		bw.Flush()
		pw.Close()

		bw.Reset(nil)
		streamWriterBufPool.Put(bwv)
	}()

	return pr
}

var streamWriterBufPool sync.Pool
<|endoftext|>


<commit_before>package goboots

import (
	"bytes"
	"net/http"
	"reflect"
	"text/template"
	//"time"
	"encoding/binary"
)

type IController interface {
	//Setup(app *App)
	Init(app *App)
	Run(w http.ResponseWriter, r *http.Request, params []string) interface{}
	PreFilter(w http.ResponseWriter, r *http.Request, params []string) interface{}
	// rendering
	Render(w http.ResponseWriter, r *http.Request, content interface{})
	_registerMethod(name string, method reflect.Value)
	_getMethod(name string) (reflect.Value, bool)
}

type PageContent struct {
	Title       string
	Content     string
	UserContent string
	HeadInclude string
	FootInclude string
}

type RedirectPageContent struct {
	Title   string
	Message string
	Path    string
}

type ErrorPageContent struct {
	Title        string
	ErrorTitle   string
	ErrorMessage string
	Content      string
}

type Controller struct {
	App           *App
	Path          string
	Name          string
	LayoutName    string
	Action        string
	LayoutAction  string
	Params        []string
	PageTitle     string
	Layout        string
	ContentType   string
	customMethods map[string]reflect.Value
}

func (c *Controller) Init(app *App) {
	c.App = app
	c.PageTitle = ""
	c.Layout = "default"
	c.ContentType = "text/html; charset=utf-8"
}

func (c *Controller) Run(w http.ResponseWriter, r *http.Request, params []string) interface{} {
	// www.example.com/params[0]/params[1]/(...)params[n]
	content := &PageContent{
		Title:   c.App.Config.Name + " - " + c.PageTitle,
		Content: "content goes here",
	}
	return content
}

func (c *Controller) PreFilter(w http.ResponseWriter, r *http.Request, params []string) interface{} {
	return nil
}

func (c *Controller) Render(w http.ResponseWriter, r *http.Request, content interface{}) {
	c.render(w, r, content, nil)
}

func (c *Controller) RenderWithLayout(w http.ResponseWriter, r *http.Request, content interface{}, customLayout string) {
	c.render(w, r, content, customLayout)
}

func (c *Controller) render(w http.ResponseWriter, r *http.Request, content interface{}, customLayout string) {
	if len(c.Layout) && len(customLayout) == 0 {
		// no layout defined!
		var buff bytes.Buffer
		binary.Write(&buff, binary.LittleEndian, content)
		w.Write(buff.Bytes())
		return
	}
	layoutName := c.Layout
	if len(customLayout) > 0 {
		layoutName = customLayout
	}
	var layoutTpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		layoutTpl = c.App.GetLocalizedLayout(layoutName, w, r)
	} else {
		layoutTpl = c.App.GetLayout(layoutName)
	}
	layoutTpl.Execute(w, content)
}

// RenderFromCache renders an entire page to the app's bytecache
func (c *Controller) RenderToCache(w http.ResponseWriter, r *http.Request, name string, content interface{}) {
	if len(c.Layout) == 0 {
		// no layout defined!
		var buff bytes.Buffer
		binary.Write(&buff, binary.LittleEndian, content)
		c.App.ByteCaches.SetCache(name, buff.Bytes())
		return
	}
	var layoutTpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		layoutTpl = c.App.GetLocalizedLayout(c.Layout, w, r)
	} else {
		layoutTpl = c.App.GetLayout(c.Layout)
	}
	var buffer bytes.Buffer
	err := layoutTpl.Execute(&buffer, content)
	__panic(err)
	c.App.ByteCaches.SetCache(name, buffer.Bytes())
}

// RenderFromCache renders an entire page from the app's bytecache
func (c *Controller) RenderFromCache(w http.ResponseWriter, r *http.Request, name string) interface{} {
	w.Write(c.App.ByteCaches.GetCache(name).Content)
	return nil
}

func (c *Controller) ParseContent(w http.ResponseWriter, r *http.Request, locTemplatePath string, content interface{}) string {
	var tpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		tpl = c.App.GetLocalizedViewTemplate(locTemplatePath, w, r)
	} else {
		tpl = c.App.GetViewTemplate(locTemplatePath)
	}

	//TODO: handle error if template is nil
	var buffer bytes.Buffer
	err := tpl.Execute(&buffer, content)
	__panic(err)
	return buffer.String()
}

func (c *Controller) Redirect(w http.ResponseWriter, path string, title string, message string) interface{} {
	tpl := c.App.GetLayout("redirect")
	//TODO: handle error if template is nil
	content := &RedirectPageContent{
		Title:   title,
		Message: message,
		Path:    path,
	}
	tpl.Execute(w, content)
	return nil
}

func (c *Controller) PageError(w http.ResponseWriter, errorTitle string, errorMessage string, extraHTMLContent string) interface{} {
	tpl := c.App.GetLayout("error")
	//TODO: handle error if template is nil
	content := &ErrorPageContent{
		Title:        c.App.Config.Name + " - Error: " + errorTitle,
		ErrorTitle:   errorTitle,
		ErrorMessage: errorMessage,
		Content:      extraHTMLContent,
	}
	tpl.Execute(w, content)
	return nil
}

func (c *Controller) _registerMethod(name string, method reflect.Value) {
	if c.customMethods == nil {
		c.customMethods = make(map[string]reflect.Value, 0)
	}
	c.customMethods[name] = method
}
func (c *Controller) _getMethod(name string) (reflect.Value, bool) {
	if c.customMethods == nil {
		return reflect.Value{}, false
	}
	val, ok := c.customMethods[name]
	return val, ok
}
<commit_msg>Setup a renderWithLayout function<commit_after>package goboots

import (
	"bytes"
	"net/http"
	"reflect"
	"text/template"
	//"time"
	"encoding/binary"
)

type IController interface {
	//Setup(app *App)
	Init(app *App)
	Run(w http.ResponseWriter, r *http.Request, params []string) interface{}
	PreFilter(w http.ResponseWriter, r *http.Request, params []string) interface{}
	// rendering
	Render(w http.ResponseWriter, r *http.Request, content interface{})
	_registerMethod(name string, method reflect.Value)
	_getMethod(name string) (reflect.Value, bool)
}

type PageContent struct {
	Title       string
	Content     string
	UserContent string
	HeadInclude string
	FootInclude string
}

type RedirectPageContent struct {
	Title   string
	Message string
	Path    string
}

type ErrorPageContent struct {
	Title        string
	ErrorTitle   string
	ErrorMessage string
	Content      string
}

type Controller struct {
	App           *App
	Path          string
	Name          string
	LayoutName    string
	Action        string
	LayoutAction  string
	Params        []string
	PageTitle     string
	Layout        string
	ContentType   string
	customMethods map[string]reflect.Value
}

func (c *Controller) Init(app *App) {
	c.App = app
	c.PageTitle = ""
	c.Layout = "default"
	c.ContentType = "text/html; charset=utf-8"
}

func (c *Controller) Run(w http.ResponseWriter, r *http.Request, params []string) interface{} {
	// www.example.com/params[0]/params[1]/(...)params[n]
	content := &PageContent{
		Title:   c.App.Config.Name + " - " + c.PageTitle,
		Content: "content goes here",
	}
	return content
}

func (c *Controller) PreFilter(w http.ResponseWriter, r *http.Request, params []string) interface{} {
	return nil
}

func (c *Controller) Render(w http.ResponseWriter, r *http.Request, content interface{}) {
	c.render(w, r, content, "")
}

func (c *Controller) RenderWithLayout(w http.ResponseWriter, r *http.Request, content interface{}, customLayout string) {
	c.render(w, r, content, customLayout)
}

func (c *Controller) render(w http.ResponseWriter, r *http.Request, content interface{}, customLayout string) {
	if len(c.Layout) && len(customLayout) == 0 {
		// no layout defined!
		var buff bytes.Buffer
		binary.Write(&buff, binary.LittleEndian, content)
		w.Write(buff.Bytes())
		return
	}
	layoutName := c.Layout
	if len(customLayout) > 0 {
		layoutName = customLayout
	}
	var layoutTpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		layoutTpl = c.App.GetLocalizedLayout(layoutName, w, r)
	} else {
		layoutTpl = c.App.GetLayout(layoutName)
	}
	layoutTpl.Execute(w, content)
}

// RenderFromCache renders an entire page to the app's bytecache
func (c *Controller) RenderToCache(w http.ResponseWriter, r *http.Request, name string, content interface{}) {
	if len(c.Layout) == 0 {
		// no layout defined!
		var buff bytes.Buffer
		binary.Write(&buff, binary.LittleEndian, content)
		c.App.ByteCaches.SetCache(name, buff.Bytes())
		return
	}
	var layoutTpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		layoutTpl = c.App.GetLocalizedLayout(c.Layout, w, r)
	} else {
		layoutTpl = c.App.GetLayout(c.Layout)
	}
	var buffer bytes.Buffer
	err := layoutTpl.Execute(&buffer, content)
	__panic(err)
	c.App.ByteCaches.SetCache(name, buffer.Bytes())
}

// RenderFromCache renders an entire page from the app's bytecache
func (c *Controller) RenderFromCache(w http.ResponseWriter, r *http.Request, name string) interface{} {
	w.Write(c.App.ByteCaches.GetCache(name).Content)
	return nil
}

func (c *Controller) ParseContent(w http.ResponseWriter, r *http.Request, locTemplatePath string, content interface{}) string {
	var tpl *template.Template
	if len(c.App.Config.DefaultLanguage) > 0 {
		tpl = c.App.GetLocalizedViewTemplate(locTemplatePath, w, r)
	} else {
		tpl = c.App.GetViewTemplate(locTemplatePath)
	}

	//TODO: handle error if template is nil
	var buffer bytes.Buffer
	err := tpl.Execute(&buffer, content)
	__panic(err)
	return buffer.String()
}

func (c *Controller) Redirect(w http.ResponseWriter, path string, title string, message string) interface{} {
	tpl := c.App.GetLayout("redirect")
	//TODO: handle error if template is nil
	content := &RedirectPageContent{
		Title:   title,
		Message: message,
		Path:    path,
	}
	tpl.Execute(w, content)
	return nil
}

func (c *Controller) PageError(w http.ResponseWriter, errorTitle string, errorMessage string, extraHTMLContent string) interface{} {
	tpl := c.App.GetLayout("error")
	//TODO: handle error if template is nil
	content := &ErrorPageContent{
		Title:        c.App.Config.Name + " - Error: " + errorTitle,
		ErrorTitle:   errorTitle,
		ErrorMessage: errorMessage,
		Content:      extraHTMLContent,
	}
	tpl.Execute(w, content)
	return nil
}

func (c *Controller) _registerMethod(name string, method reflect.Value) {
	if c.customMethods == nil {
		c.customMethods = make(map[string]reflect.Value, 0)
	}
	c.customMethods[name] = method
}
func (c *Controller) _getMethod(name string) (reflect.Value, bool) {
	if c.customMethods == nil {
		return reflect.Value{}, false
	}
	val, ok := c.customMethods[name]
	return val, ok
}
<|endoftext|>


<commit_before>package views

const list = `<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{{.Title}}</title>
    <link rel="stylesheet" href="/assets/styles.css"></link>

{{.Title}}

        sign-in

        <input id="filter" type="search" placeholder="Filter..." tabindex="1" />

        {{range .Repos}}

{{.Name}}

{{.Description}}

        {{end}}

`
<commit_msg>Fix sign-in URL<commit_after>package views

const list = `<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{{.Title}}</title>
    <link rel="stylesheet" href="/assets/styles.css"></link>

{{.Title}}

        sign-in

        <input id="filter" type="search" placeholder="Filter..." tabindex="1" />

        {{range .Repos}}

{{.Name}}

{{.Description}}

        {{end}}

`
<|endoftext|>


<commit_before>package sshmgr

import (
	"net"
	"sync/atomic"

	"golang.org/x/crypto/ssh"
)

type sshClient struct {
	*ssh.Client
	config SSHConfig
	conn   net.Conn
	refs   int32
}

func (c *sshClient) incr() int32 {
	return atomic.AddInt32(&c.refs, 1)
}

func (c *sshClient) decr() int32 {
	return atomic.AddInt32(&c.refs, -1)
}

// newSSHClient creates a new ssh.Client from the given config
func newSSHClient(config SSHConfig) (*sshClient, error) {
	addr := config.NetAddr + ":" + config.Port
	sshConfig, err := newSSHClientConfig(config)
	if err != nil {
		return nil, err
	}

	conn, err := net.DialTimeout("tcp", addr, config.DialTimeout)
	if err != nil {
		return nil, err
	}
	c, chans, reqs, err := ssh.NewClientConn(conn, addr, sshConfig)
	if err != nil {
		return nil, err
	}

	sshClient := &sshClient{}
	sshClient.config = config
	sshClient.conn = conn
	sshClient.Client = ssh.NewClient(c, chans, reqs)
	return sshClient, nil
}
<commit_msg>Assume default port 22 when not specified in config<commit_after>package sshmgr

import (
	"net"
	"sync/atomic"

	"golang.org/x/crypto/ssh"
)

type sshClient struct {
	*ssh.Client
	config SSHConfig
	conn   net.Conn
	refs   int32
}

func (c *sshClient) incr() int32 {
	return atomic.AddInt32(&c.refs, 1)
}

func (c *sshClient) decr() int32 {
	return atomic.AddInt32(&c.refs, -1)
}

// newSSHClient creates a new ssh.Client from the given config
func newSSHClient(config SSHConfig) (*sshClient, error) {
	if config.Port == "" {
		config.Port = "22"
	}
	addr := config.NetAddr + ":" + config.Port
	sshConfig, err := newSSHClientConfig(config)
	if err != nil {
		return nil, err
	}

	conn, err := net.DialTimeout("tcp", addr, config.DialTimeout)
	if err != nil {
		return nil, err
	}
	c, chans, reqs, err := ssh.NewClientConn(conn, addr, sshConfig)
	if err != nil {
		return nil, err
	}

	sshClient := &sshClient{}
	sshClient.config = config
	sshClient.conn = conn
	sshClient.Client = ssh.NewClient(c, chans, reqs)
	return sshClient, nil
}
<|endoftext|>


<commit_before>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"time"

	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
)

var conn dbox.IConnection
var count int
var ratioTableName string

var (
	ratiototrf      = float64(0.392)
	sourcetablename = "salespls-summary"
	calctablename   = "salespls-summary"
	desttablename   = "salespls-summary"
	t0              time.Time
	masters         = toolkit.M{}
	sgaalloc        = map[string]float64{
		"EXP": 0.08,
		"I4":  0.08,
		"I6":  0.105,
	}
)

type plalloc struct {
	ID                     string `bson:"_id" json:"_id"`
	Key                    string
	Key1, Key2, Key3       string
	Ref1                   float64
	Current                float64
	Expect                 float64
	Absorbed               float64
	Ratio1, Ratio2, Ratio3 float64
}

type allocmap map[string]*plalloc

var (
	rdfiscals    = allocmap{}
	branchtotals = allocmap{}
	trxsrc       = "nakulrd"
)

func main() {
	setinitialconnection()
	conn.NewQuery().From(desttablename).
		Where(dbox.Eq("key.trxsrc", trxsrc)).
		Delete().
		Exec(nil)

	prepmastercalc()
	//buildratio()
	processTable()
}

func processTable() {
	connsave, _ := modules.GetDboxIConnection("db_godrej")
	defer connsave.Close()
	qsave := connsave.NewQuery().SetConfig("multiexec", true).From(desttablename).Save()

	connselect, _ := modules.GetDboxIConnection("db_godrej")
	defer connselect.Close()

	cursor, _ := connselect.NewQuery().
		From(calctablename).
		Where(dbox.Ne("key.trxsrc", trxsrc)).
		Select().Cursor(nil)
	defer cursor.Close()

	i := 0
	count := cursor.Count()
	mstone := 0
	t0 = time.Now()
	for {
		mr := toolkit.M{}
		e := cursor.Fetch(&mr, 1, false)
		if e != nil || i >= count {
			break
		}
		i++
		makeProgressLog("Processing", i, count, 5, &mstone, t0)

		mrid := mr.GetString("_id")
		key := mr.Get("key", toolkit.M{}).(toolkit.M)
		channelid := key.GetString("customer_channelid")
		branchid := key.GetString("customer_branchid")
		branchname := key.GetString("customer_branchname")

		if channelid != "I1" {
			discount := mr.GetFloat64("PL7A") * ratiototrf
			spg := mr.GetFloat64("PL31") * ratiototrf
			promo := mr.GetFloat64("Pl29A") * ratiototrf

			if discount != 0 || spg != 0 || promo != 0 {
				if branchid != "CD02" || branchid != "CD04" || branchid != "CD11" ||
					branchid != "CD09" {
					branchid = "CD02"
					branchname = "Jakarta"
				}

				mreverse := toolkit.M{}
				mreverse.Set("_id", mrid+"_rd_reverse")
				mreversekey := toolkit.M{}
				for k, v := range key {
					mreversekey.Set(k, v)
				}
				mreversekey.Set("customer_customergroup", "")
				mreversekey.Set("customer_customergroupname", "")
				mreversekey.Set("trxsrc", trxsrc)
				mreverse.Set("key", mreversekey)
				//mreverse.Set("PL7A", -discount)
				//mreverse.Set("PL29A32", -spg)
				//mreverse.Set("PL31C", -promo)
				gdrj.CalcSum(mreverse, masters)
				esave := qsave.Exec(toolkit.M{}.Set("data", mreverse))
				if esave != nil {
					toolkit.Printfn("Error: " + esave.Error())
					os.Exit(100)
				}

				/*
					                mrd := toolkit.M{}
									mrd.Set("_id", mrid+"_rd")
									mrdkey := toolkit.M{}
									for k, v := range key {
										mrdkey.Set(k, v)
									}
									mrdkey.Set("customer_channelid", "I1")
									mrdkey.Set("customer_reportchannel", "RD")
									mrdkey.Set("customer_customertype", "RD")
									mrdkey.Set("customer_channelname", "RD")
									mrdkey.Set("customer_branchid", branchid)
									mrdkey.Set("customer_branchname", branchname)
									mrdkey.Set("customer_branchgroup", branchname)
									mrdkey.Set("customer_reportsubchannel", "SPG & Promo Allocation")
									mrdkey.Set("customer_customergroup", "")
									mrdkey.Set("customer_customergroupname", "")
									mrdkey.Set("trxsrc", trxsrc)

									mrd.Set("key", mrdkey)
									//mrd.Set("PL7A", discount)
									//mrd.Set("PL29A32", spg)
									//mrd.Set("PL31C", promo)
									gdrj.CalcSum(mrd, masters)
									esave = qsave.Exec(toolkit.M{}.Set("data", mrd))
									if esave != nil {
										toolkit.Printfn("Error: " + esave.Error())
										os.Exit(100)
									}
				*/
			}
		}
	}
}

func adjustAllocs(allocsmap *allocmap, key string, current, expect, absorbed, ref1 float64) {
	allocs := *allocsmap
	alloc := allocs[key]
	if alloc == nil {
		alloc = new(plalloc)
		alloc.Key = key
		alloc.ID = key
	}
	alloc.Current += current
	alloc.Expect += expect
	alloc.Ref1 += ref1
	alloc.Absorbed += absorbed
	allocs[key] = alloc
	*allocsmap = allocs
}

func makeProgressLog(reference string, i, count, step int, current *int, tstart time.Time) int {
	perstep := count * step / 100
	icurrent := *current
	if icurrent == 0 {
		icurrent = perstep
	}
	pct := i * 100 / count
	if i >= icurrent {
		toolkit.Printfn("%s, %d of %d [%d pct] in %s",
			reference, i, count, pct, time.Since(tstart).String())
		icurrent += perstep
	}
	*current = icurrent
	return icurrent
}

func buildmap(holder interface{},
	fnModel func() orm.IModel,
	filter *dbox.Filter,
	fnIter func(holder interface{}, obj interface{})) interface{} {
	crx, ecrx := gdrj.Find(fnModel(), filter, nil)
	if ecrx != nil {
		toolkit.Printfn("Cursor Error: %s", ecrx.Error())
		os.Exit(100)
	}
	defer crx.Close()
	for {
		s := fnModel()
		e := crx.Fetch(s, 1, false)
		if e != nil {
			break
		}
		fnIter(holder, s)
	}
	return holder
}

func prepmastercalc() {
	toolkit.Println("--> PL MODEL")
	masters.Set("plmodel", buildmap(map[string]*gdrj.PLModel{},
		func() orm.IModel {
			return new(gdrj.PLModel)
		},
		nil,
		func(holder, obj interface{}) {
			h := holder.(map[string]*gdrj.PLModel)
			o := obj.(*gdrj.PLModel)
			h[o.ID] = o
		}).(map[string]*gdrj.PLModel))
}

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}
<commit_msg>asdsa<commit_after>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"time"

	"github.com/eaciit/dbox"
	"github.com/eaciit/orm/v1"
	"github.com/eaciit/toolkit"
)

var conn dbox.IConnection
var count int
var ratioTableName string

var (
	ratiototrf      = float64(0.392)
	sourcetablename = "salespls-summary"
	calctablename   = "salespls-summary"
	desttablename   = "salespls-summary"
	t0              time.Time
	masters         = toolkit.M{}
	sgaalloc        = map[string]float64{
		"EXP": 0.08,
		"I4":  0.08,
		"I6":  0.105,
	}
)

type plalloc struct {
	ID                     string `bson:"_id" json:"_id"`
	Key                    string
	Key1, Key2, Key3       string
	Ref1                   float64
	Current                float64
	Expect                 float64
	Absorbed               float64
	Ratio1, Ratio2, Ratio3 float64
}

type allocmap map[string]*plalloc

var (
	rdfiscals    = allocmap{}
	branchtotals = allocmap{}
	trxsrc       = "nakulrd"
)

func main() {
	setinitialconnection()
	conn.NewQuery().From(desttablename).
		Where(dbox.Eq("key.trxsrc", trxsrc)).
		Delete().
		Exec(nil)

	prepmastercalc()
	//buildratio()
	processTable()
}

func processTable() {
	connsave, _ := modules.GetDboxIConnection("db_godrej")
	defer connsave.Close()
	qsave := connsave.NewQuery().SetConfig("multiexec", true).From(desttablename).Save()

	connselect, _ := modules.GetDboxIConnection("db_godrej")
	defer connselect.Close()

	cursor, _ := connselect.NewQuery().
		From(calctablename).
		Where(dbox.Ne("key.trxsrc", trxsrc)).
		Select().Cursor(nil)
	defer cursor.Close()

	i := 0
	count := cursor.Count()
	mstone := 0
	t0 = time.Now()
	for {
		mr := toolkit.M{}
		e := cursor.Fetch(&mr, 1, false)
		if e != nil || i >= count {
			break
		}
		i++
		makeProgressLog("Processing", i, count, 5, &mstone, t0)

		mrid := mr.GetString("_id")
		key := mr.Get("key", toolkit.M{}).(toolkit.M)
		channelid := key.GetString("customer_channelid")
		branchid := key.GetString("customer_branchid")
		//branchname := key.GetString("customer_branchname")

		if channelid != "I1" {
			discount := mr.GetFloat64("PL7A") * ratiototrf
			spg := mr.GetFloat64("PL31") * ratiototrf
			promo := mr.GetFloat64("Pl29A") * ratiototrf

			if discount != 0 || spg != 0 || promo != 0 {
				if branchid != "CD02" || branchid != "CD04" || branchid != "CD11" ||
					branchid != "CD09" {
					branchid = "CD02"
					//branchname = "Jakarta"
				}

				mreverse := toolkit.M{}
				mreverse.Set("_id", mrid+"_rd_reverse")
				mreversekey := toolkit.M{}
				for k, v := range key {
					mreversekey.Set(k, v)
				}
				mreversekey.Set("customer_customergroup", "")
				mreversekey.Set("customer_customergroupname", "")
				mreversekey.Set("trxsrc", trxsrc)
				mreverse.Set("key", mreversekey)
				//mreverse.Set("PL7A", -discount)
				//mreverse.Set("PL29A32", -spg)
				//mreverse.Set("PL31C", -promo)
				gdrj.CalcSum(mreverse, masters)
				esave := qsave.Exec(toolkit.M{}.Set("data", mreverse))
				if esave != nil {
					toolkit.Printfn("Error: " + esave.Error())
					os.Exit(100)
				}

				/*
					                mrd := toolkit.M{}
									mrd.Set("_id", mrid+"_rd")
									mrdkey := toolkit.M{}
									for k, v := range key {
										mrdkey.Set(k, v)
									}
									mrdkey.Set("customer_channelid", "I1")
									mrdkey.Set("customer_reportchannel", "RD")
									mrdkey.Set("customer_customertype", "RD")
									mrdkey.Set("customer_channelname", "RD")
									mrdkey.Set("customer_branchid", branchid)
									mrdkey.Set("customer_branchname", branchname)
									mrdkey.Set("customer_branchgroup", branchname)
									mrdkey.Set("customer_reportsubchannel", "SPG & Promo Allocation")
									mrdkey.Set("customer_customergroup", "")
									mrdkey.Set("customer_customergroupname", "")
									mrdkey.Set("trxsrc", trxsrc)

									mrd.Set("key", mrdkey)
									//mrd.Set("PL7A", discount)
									//mrd.Set("PL29A32", spg)
									//mrd.Set("PL31C", promo)
									gdrj.CalcSum(mrd, masters)
									esave = qsave.Exec(toolkit.M{}.Set("data", mrd))
									if esave != nil {
										toolkit.Printfn("Error: " + esave.Error())
										os.Exit(100)
									}
				*/
			}
		}
	}
}

func adjustAllocs(allocsmap *allocmap, key string, current, expect, absorbed, ref1 float64) {
	allocs := *allocsmap
	alloc := allocs[key]
	if alloc == nil {
		alloc = new(plalloc)
		alloc.Key = key
		alloc.ID = key
	}
	alloc.Current += current
	alloc.Expect += expect
	alloc.Ref1 += ref1
	alloc.Absorbed += absorbed
	allocs[key] = alloc
	*allocsmap = allocs
}

func makeProgressLog(reference string, i, count, step int, current *int, tstart time.Time) int {
	perstep := count * step / 100
	icurrent := *current
	if icurrent == 0 {
		icurrent = perstep
	}
	pct := i * 100 / count
	if i >= icurrent {
		toolkit.Printfn("%s, %d of %d [%d pct] in %s",
			reference, i, count, pct, time.Since(tstart).String())
		icurrent += perstep
	}
	*current = icurrent
	return icurrent
}

func buildmap(holder interface{},
	fnModel func() orm.IModel,
	filter *dbox.Filter,
	fnIter func(holder interface{}, obj interface{})) interface{} {
	crx, ecrx := gdrj.Find(fnModel(), filter, nil)
	if ecrx != nil {
		toolkit.Printfn("Cursor Error: %s", ecrx.Error())
		os.Exit(100)
	}
	defer crx.Close()
	for {
		s := fnModel()
		e := crx.Fetch(s, 1, false)
		if e != nil {
			break
		}
		fnIter(holder, s)
	}
	return holder
}

func prepmastercalc() {
	toolkit.Println("--> PL MODEL")
	masters.Set("plmodel", buildmap(map[string]*gdrj.PLModel{},
		func() orm.IModel {
			return new(gdrj.PLModel)
		},
		nil,
		func(holder, obj interface{}) {
			h := holder.(map[string]*gdrj.PLModel)
			o := obj.(*gdrj.PLModel)
			h[o.ID] = o
		}).(map[string]*gdrj.PLModel))
}

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}
<|endoftext|>