<commit_before>package export

import (
	"bytes"
	"os"
	"reflect"
	"runtime"
	"runtime/debug"
	"runtime/pprof"
	"runtime/trace"
	"strconv"
	"time"
)

func readOSArgs() []byte {
	var reply []byte
	for _, arg := range os.Args {
		if reply != nil {
			reply = append(reply, ' ')
		}
		hasspace := false
		for i := 0; i < len(arg); i++ {
			if arg[i] == ' ' {
				hasspace = true
				break
			}
		}
		if hasspace {
			reply = append(reply, '"')
			reply = append(reply, arg...)
			reply = append(reply, '"')
		} else {
			reply = append(reply, arg...)
		}
	}
	return reply
}

func readNumGoroutine() []byte {
	return strconv.AppendInt(nil, int64(runtime.NumGoroutine()), 10)
}

func readRuntimeStack() []byte {
	n := 1 << 14
	var buf []byte
	for n <= 64<<20 {
		buf = make([]byte, n)
		n = runtime.Stack(buf, true)
		if n < len(buf) {
			break
		}
		n += n
	}
	return buf
}

func readMemStats() []byte {
	var mem runtime.MemStats
	runtime.ReadMemStats(&mem)
	return structToJSON(make([]byte, 0, 128), nil, reflect.ValueOf(&mem).Elem())
}

func handleGCStats(v string) []byte {
	if v == "gc" {
		runtime.GC()
	}
	var st debug.GCStats
	debug.ReadGCStats(&st)
	return structToJSON(make([]byte, 0, 64), nil, reflect.ValueOf(&st).Elem())
}

func handleGOMAXPROCS(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(runtime.GOMAXPROCS(n)), 10)
}

func handleSetMaxThreads(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(debug.SetMaxThreads(n)), 10)
}

func handleSetGCPercent(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(debug.SetGCPercent(n)), 10)
}

func listProfiles() []byte {
	var reply []byte
	for _, p := range pprof.Profiles() {
		reply = append(reply, p.Name()...)
		reply = append(reply, ' ')
		reply = strconv.AppendInt(reply, int64(p.Count()), 10)
		reply = append(reply, '\n')
	}
	return reply
}

func fetchProfile(args []string) []byte {
	if len(args) == 0 {
		return nil
	}
	debug := 1
	if len(args) >= 2 {
		debug, _ = strconv.Atoi(args[1])
	}
	p := pprof.Lookup(args[0])
	var buf bytes.Buffer
	p.WriteTo(&buf, debug)
	return buf.Bytes()
}

func onCmdPprof(args []string) []byte {
	if len(args) == 0 {
		return listProfiles()
	}
	return fetchProfile(args)
}

func onCmdTrace(args []string) []byte {
	if len(args) == 0 || args[0] != "start" {
		return []byte("start [seconds:1]\n")
	}
	var sec int64
	if len(args) == 2 {
		sec, _ = strconv.ParseInt(args[1], 10, 64)
	}
	if sec <= 0 {
		sec = 1
	}

	var buf bytes.Buffer
	err := trace.Start(&buf)
	if err != nil {
		return append([]byte(err.Error()), '\n')
	}
	time.Sleep(time.Duration(sec) * time.Second)
	trace.Stop()
	return buf.Bytes()
}

func onCmdProfile(args []string) []byte {
	if len(args) == 0 || args[0] != "start" {
		return []byte("start [seconds:30]\n")
	}
	var sec int64
	if len(args) == 2 {
		sec, _ = strconv.ParseInt(args[1], 10, 64)
	}
	if sec <= 0 {
		sec = 30
	}
	var buf bytes.Buffer
	err := pprof.StartCPUProfile(&buf)
	if err != nil {
		return append([]byte(err.Error()), '\n')
	}
	time.Sleep(time.Duration(sec) * time.Second)
	pprof.StopCPUProfile()
	return buf.Bytes()
}

func init() {
	vars["os.Args"] = GetOnlyFunc(readOSArgs)
	vars["runtime.GOOS"] = runtime.GOOS
	vars["runtime.GOARCH"] = runtime.GOARCH
	vars["runtime.Version"] = runtime.Version()
	vars["runtime.NumGoroutine"] = GetOnlyFunc(readNumGoroutine)
	vars["runtime.Stack"] = GetOnlyFunc(readRuntimeStack)
	vars["runtime.MemStats"] = GetOnlyFunc(readMemStats)
	vars["runtime.GOMAXPROCS"] = VarFunc(handleGOMAXPROCS)
	vars["debug.GCStats"] = VarFunc(handleGCStats)
	vars["debug.SetMaxThreads"] = VarFunc(handleSetMaxThreads)
	vars["debug.SetGCPercent"] = VarFunc(handleSetGCPercent)

	cmds["PPROF"] = onCmdPprof
	cmds["TRACE"] = onCmdTrace
	cmds["PROFILE"] = onCmdProfile
}
<commit_msg>fix nil profile<commit_after>package export

import (
	"bytes"
	"os"
	"reflect"
	"runtime"
	"runtime/debug"
	"runtime/pprof"
	"runtime/trace"
	"strconv"
	"time"
)

func readOSArgs() []byte {
	var reply []byte
	for _, arg := range os.Args {
		if reply != nil {
			reply = append(reply, ' ')
		}
		hasspace := false
		for i := 0; i < len(arg); i++ {
			if arg[i] == ' ' {
				hasspace = true
				break
			}
		}
		if hasspace {
			reply = append(reply, '"')
			reply = append(reply, arg...)
			reply = append(reply, '"')
		} else {
			reply = append(reply, arg...)
		}
	}
	return reply
}

func readNumGoroutine() []byte {
	return strconv.AppendInt(nil, int64(runtime.NumGoroutine()), 10)
}

func readRuntimeStack() []byte {
	n := 1 << 14
	var buf []byte
	for n <= 64<<20 {
		buf = make([]byte, n)
		n = runtime.Stack(buf, true)
		if n < len(buf) {
			break
		}
		n += n
	}
	return buf
}

func readMemStats() []byte {
	var mem runtime.MemStats
	runtime.ReadMemStats(&mem)
	return structToJSON(make([]byte, 0, 128), nil, reflect.ValueOf(&mem).Elem())
}

func handleGCStats(v string) []byte {
	if v == "gc" {
		runtime.GC()
	}
	var st debug.GCStats
	debug.ReadGCStats(&st)
	return structToJSON(make([]byte, 0, 64), nil, reflect.ValueOf(&st).Elem())
}

func handleGOMAXPROCS(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(runtime.GOMAXPROCS(n)), 10)
}

func handleSetMaxThreads(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(debug.SetMaxThreads(n)), 10)
}

func handleSetGCPercent(v string) []byte {
	n := 0
	if v != "" {
		n, _ = strconv.Atoi(v)
	}
	return strconv.AppendInt(nil, int64(debug.SetGCPercent(n)), 10)
}

func listProfiles() []byte {
	var reply []byte
	for _, p := range pprof.Profiles() {
		reply = append(reply, p.Name()...)
		reply = append(reply, ' ')
		reply = strconv.AppendInt(reply, int64(p.Count()), 10)
		reply = append(reply, '\n')
	}
	return reply
}

func fetchProfile(args []string) []byte {
	if len(args) == 0 {
		return nil
	}
	debug := 1
	if len(args) >= 2 {
		debug, _ = strconv.Atoi(args[1])
	}
	p := pprof.Lookup(args[0])
	if p == nil {
		return nil
	}
	var buf bytes.Buffer
	p.WriteTo(&buf, debug)
	return buf.Bytes()
}

func onCmdPprof(args []string) []byte {
	if len(args) == 0 {
		return listProfiles()
	}
	return fetchProfile(args)
}

func onCmdTrace(args []string) []byte {
	if len(args) == 0 || args[0] != "start" {
		return []byte("start [seconds:1]\n")
	}
	var sec int64
	if len(args) == 2 {
		sec, _ = strconv.ParseInt(args[1], 10, 64)
	}
	if sec <= 0 {
		sec = 1
	}

	var buf bytes.Buffer
	err := trace.Start(&buf)
	if err != nil {
		return append([]byte(err.Error()), '\n')
	}
	time.Sleep(time.Duration(sec) * time.Second)
	trace.Stop()
	return buf.Bytes()
}

func onCmdProfile(args []string) []byte {
	if len(args) == 0 || args[0] != "start" {
		return []byte("start [seconds:30]\n")
	}
	var sec int64
	if len(args) == 2 {
		sec, _ = strconv.ParseInt(args[1], 10, 64)
	}
	if sec <= 0 {
		sec = 30
	}
	var buf bytes.Buffer
	err := pprof.StartCPUProfile(&buf)
	if err != nil {
		return append([]byte(err.Error()), '\n')
	}
	time.Sleep(time.Duration(sec) * time.Second)
	pprof.StopCPUProfile()
	return buf.Bytes()
}

func init() {
	vars["os.Args"] = GetOnlyFunc(readOSArgs)
	vars["runtime.GOOS"] = runtime.GOOS
	vars["runtime.GOARCH"] = runtime.GOARCH
	vars["runtime.Version"] = runtime.Version()
	vars["runtime.NumGoroutine"] = GetOnlyFunc(readNumGoroutine)
	vars["runtime.Stack"] = GetOnlyFunc(readRuntimeStack)
	vars["runtime.MemStats"] = GetOnlyFunc(readMemStats)
	vars["runtime.GOMAXPROCS"] = VarFunc(handleGOMAXPROCS)
	vars["debug.GCStats"] = VarFunc(handleGCStats)
	vars["debug.SetMaxThreads"] = VarFunc(handleSetMaxThreads)
	vars["debug.SetGCPercent"] = VarFunc(handleSetGCPercent)

	cmds["PPROF"] = onCmdPprof
	cmds["TRACE"] = onCmdTrace
	cmds["PROFILE"] = onCmdProfile
}
<|endoftext|>


<commit_before>package gscplib

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"

	"code.google.com/p/goauth2/oauth"
	"code.google.com/p/google-api-go-client/storage/v1"
)

const (
	scope       = storage.DevstorageFull_controlScope
	authURL     = "https://accounts.google.com/o/oauth2/auth"
	tokenURL    = "https://accounts.google.com/o/oauth2/token"
	entityName  = "allUsers"
	redirectURL = "urn:ietf:wg:oauth:2.0:oob"
)

func SplitRemote(remote string) []string {
	fields := strings.FieldsFunc(
		remote, func(r rune) bool {
			return r == '@' || r == ':'
		})
	return fields
}

func GetRemoteObjectName(remote []string) (string, string, string) {
	if len(remote) < 3 {
		log.Fatalf("Remote path [%v] not fully specified (project@bucket:object)", remote)
	}
	return remote[0], remote[1], remote[2]
}

func GetRemoteBucketName(remote []string) (string, string) {
	if len(remote) < 2 {
		log.Fatalf("Remote bucket [%v] not fully specified (project@bucket)", remote)
	}
	return remote[0], remote[1]
}

type store struct {
	auth    *oauth.Config
	code    string
	service *storage.Service
}

func NewStore(clientId, clientSecret, cache, code string) *store {
	this := new(store)
	this.code = code
	this.auth = &oauth.Config{
		ClientId:     clientId,
		ClientSecret: clientSecret,
		Scope:        scope,
		AuthURL:      authURL,
		TokenURL:     tokenURL,
		TokenCache:   oauth.CacheFile(cache),
		RedirectURL:  redirectURL,
	}
	return this
}

func (this *store) getService() *storage.Service {
	if this.service == nil {
		// Set up a transport using the config
		transport := &oauth.Transport{
			Config:    this.auth,
			Transport: http.DefaultTransport,
		}

		token, err := this.auth.TokenCache.Token()
		if err != nil {
			if this.code == "" {
				url := this.auth.AuthCodeURL("")
				fmt.Println("Visit URL to get a code then run again with GSCP_CODE=YOUR_CODE")
				fmt.Println(url)
				os.Exit(1)
			}
			// Exchange auth code for access token
			token, err = transport.Exchange(this.code)
			if err != nil {
				log.Fatal("Exchange: ", err)
			}
			fmt.Printf("Token is cached in %v\n", this.auth.TokenCache)
		}
		transport.Token = token

		httpClient := transport.Client()
		this.service, err = storage.New(httpClient)
	}
	return this.service
}

func (this *store) Put(local, remote string) error {
	project, bucket, objectName := GetRemoteObjectName(SplitRemote(remote))
	if _, err := this.getService().Buckets.Get(bucket).Do(); err != nil {
		if _, err := this.getService().Buckets.Insert(project, &storage.Bucket{Name: bucket}).Do(); err != nil {
			return err
		}
	}
	object := &storage.Object{Name: objectName}
	file, err := os.Open(local)
	if err != nil {
		return err
	}
	_, err = this.getService().Objects.Insert(bucket, object).Media(file).Do()
	return err
}

func (this *store) Get(remote, local string) error {
	// Get an object from a bucket.
	_, bucket, object := GetRemoteObjectName(SplitRemote(remote))
	if res, err := this.getService().Objects.Get(bucket, object).Do(); err == nil {
		fmt.Printf("The media download link for %v/%v is %v.\n\n", bucket, res.Name, res.MediaLink)
		return nil
	} else {
		return err
	}
}

func (this *store) Buckets(project string) ([]string, error) {
	this.getService().Buckets.List(project).Do()
	if res, err := this.getService().Buckets.List(project).Do(); err == nil {
		buckets := make([]string, 0)
		for _, item := range res.Items {
			buckets = append(buckets, item.Id)
		}
		return buckets, nil
	} else {
		return []string{}, err
	}
}

func (this *store) Ls(remote string) ([]string, error) {
	_, bucket := GetRemoteBucketName(SplitRemote(remote))
	if res, err := this.getService().Objects.List(bucket).Do(); err == nil {
		objects := make([]string, 0)
		for _, object := range res.Items {
			objects = append(objects, object.Name)
		}
		return objects, nil
	} else {
		return []string{}, err
	}
}

func (this *store) Chmod(remote, entity, role string) error {
	_, bucket, object := GetRemoteObjectName(SplitRemote(remote))
	acl := &storage.ObjectAccessControl{
		Bucket: bucket, Entity: entity, Object: object, Role: role,
	}
	_, err := this.getService().ObjectAccessControls.Insert(bucket, object, acl).Do()
	return err
}
<commit_msg>[ag] get working<commit_after>package gscplib

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"strings"

	"code.google.com/p/goauth2/oauth"
	"code.google.com/p/google-api-go-client/storage/v1"
)

const (
	scope       = storage.DevstorageFull_controlScope
	authURL     = "https://accounts.google.com/o/oauth2/auth"
	tokenURL    = "https://accounts.google.com/o/oauth2/token"
	entityName  = "allUsers"
	redirectURL = "urn:ietf:wg:oauth:2.0:oob"
)

func SplitRemote(remote string) []string {
	fields := strings.FieldsFunc(
		remote, func(r rune) bool {
			return r == '@' || r == ':'
		})
	return fields
}

func GetRemoteObjectName(remote []string) (string, string, string) {
	if len(remote) < 3 {
		log.Fatalf("Remote path [%v] not fully specified (project@bucket:object)", remote)
	}
	return remote[0], remote[1], remote[2]
}

func GetRemoteBucketName(remote []string) (string, string) {
	if len(remote) < 2 {
		log.Fatalf("Remote bucket [%v] not fully specified (project@bucket)", remote)
	}
	return remote[0], remote[1]
}

type store struct {
	auth    *oauth.Config
	code    string
	service *storage.Service
	client  *http.Client
}

func NewStore(clientId, clientSecret, cache, code string) *store {
	this := new(store)
	this.code = code
	this.auth = &oauth.Config{
		ClientId:     clientId,
		ClientSecret: clientSecret,
		Scope:        scope,
		AuthURL:      authURL,
		TokenURL:     tokenURL,
		TokenCache:   oauth.CacheFile(cache),
		RedirectURL:  redirectURL,
	}

	return this
}

func (this *store) getService() *storage.Service {
	this.init()
	return this.service
}

func (this *store) getClient() *http.Client {
	this.init()
	return this.client
}

func (this *store) init() {
	if this.service == nil || this.client == nil {
		// Set up a transport using the config
		transport := &oauth.Transport{
			Config:    this.auth,
			Transport: http.DefaultTransport,
		}

		token, err := this.auth.TokenCache.Token()
		if err != nil {
			if this.code == "" {
				url := this.auth.AuthCodeURL("")
				fmt.Println("Visit URL to get a code then run again with GSCP_CODE=YOUR_CODE")
				fmt.Println(url)
				os.Exit(1)
			}
			// Exchange auth code for access token
			token, err = transport.Exchange(this.code)
			if err != nil {
				log.Fatal("Exchange: ", err)
			}
			fmt.Printf("Token is cached in %v\n", this.auth.TokenCache)
		}
		transport.Token = token

		httpClient := transport.Client()
		this.client = httpClient
		this.service, err = storage.New(httpClient)
	}
}

func (this *store) Put(local, remote string) error {
	project, bucket, objectName := GetRemoteObjectName(SplitRemote(remote))
	if _, err := this.getService().Buckets.Get(bucket).Do(); err != nil {
		if _, err := this.getService().Buckets.Insert(project, &storage.Bucket{Name: bucket}).Do(); err != nil {
			return err
		}
	}
	object := &storage.Object{Name: objectName}
	file, err := os.Open(local)
	if err != nil {
		return err
	}
	_, err = this.getService().Objects.Insert(bucket, object).Media(file).Do()
	return err
}

func (this *store) download(remote, local string) error {

	err := os.MkdirAll(path.Dir(local), 0755)

	if !os.IsExist(err) && err != nil {
		log.Fatal(err)
	}
	out, err := os.Create(local)
	defer out.Close()

	resp, err := this.client.Get(remote)
	defer resp.Body.Close()

	n := int64(0)
	for n < resp.ContentLength {
		r, err := io.Copy(out, resp.Body)
		if err != nil {
			return err
		}
		n += r
	}
	return nil
}

func (this *store) Get(remote, local string) error {
	_, bucket, object := GetRemoteObjectName(SplitRemote(remote))
	if local == "." {
		local = object
	}
	if res, err := this.getService().Objects.Get(bucket, object).Do(); err == nil {
		return this.download(res.MediaLink, local)
	} else {
		return err
	}
}

func (this *store) Buckets(project string) ([]string, error) {
	this.getService().Buckets.List(project).Do()
	if res, err := this.getService().Buckets.List(project).Do(); err == nil {
		buckets := make([]string, 0)
		for _, item := range res.Items {
			buckets = append(buckets, item.Id)
		}
		return buckets, nil
	} else {
		return []string{}, err
	}
}

func (this *store) Ls(remote string) ([]string, error) {
	_, bucket := GetRemoteBucketName(SplitRemote(remote))
	if res, err := this.getService().Objects.List(bucket).Do(); err == nil {
		objects := make([]string, 0)
		for _, object := range res.Items {
			objects = append(objects, object.Name)
		}
		return objects, nil
	} else {
		return []string{}, err
	}
}

func (this *store) Chmod(remote, entity, role string) error {
	_, bucket, object := GetRemoteObjectName(SplitRemote(remote))
	acl := &storage.ObjectAccessControl{
		Bucket: bucket, Entity: entity, Object: object, Role: role,
	}
	_, err := this.getService().ObjectAccessControls.Insert(bucket, object, acl).Do()
	return err
}
<|endoftext|>


<commit_before>package hamt32

import "strings"

type tableStack interface {
	peek() tableI
	pop() tableI
	push(tableI) tableStack
	//shift() tableI
	//unshift(tableI) tableStack
	isEmpty() bool
	len() int
}

//
// []tableI implementation of "tableStack interface".
//

type tableSlice []tableI

// Constructs an tableSlice impl of the tableStack interface.
//func newTableStack() tableSlice {
//	return make(tableSlice, 0, MaxDepth)
//}

// Constructs an tableSlice impl of the tableStack interface.
func newTableStack() tableStack {
	var ts = make(tableSlice, 0, MaxDepth)
	return &ts
}

// path.peek() returns the last entry without inserted with path.push(...)
func (path *tableSlice) peek() tableI {
	if len(*path) == 0 {
		return nil
	}
	return (*path)[len(*path)-1]
}

// Put a new tableI in the path object.
// You should never push nil, but we are not checking to prevent this.
func (path *tableSlice) push(tab tableI) tableStack {
	//_ = ASSERT && Assert(tab != nil, "tableSlice.push(nil) not allowed")
	*path = append(*path, tab)
	return path
}

// path.pop() returns & remmoves the last entry inserted with path.push(...).
func (path *tableSlice) pop() tableI {
	if len(*path) == 0 {
		//FIXME: should I do this or let the runtime panic on index out of range
		return nil
	}

	var parent = (*path)[len(*path)-1]
	*path = (*path)[:len(*path)-1]
	return parent
}

//func (path *tableSlice) shift() tableI {
//	var t tableI
//	t, *path = (*path)[0], (*path)[1:]
//	return t
//}
//
//func (path *tableSlice) unshift(t tableI) tableStack {
//	*path = append([]tableI{t}, (*path)...)
//	return path
//}

// path.isEmpty() returns true if there are no entries in the path object,
// otherwise it returns false.
func (path *tableSlice) isEmpty() bool {
	return len(*path) == 0
}

func (path *tableSlice) len() int {
	return len(*path)
}

// Convert path to a string representation. This is only good for debug messages.
// It is not a string format to convert back from.
func (path tableSlice) String() string {
	var paths = make([]string, len(path))

	for i, pv := range path {
		paths[i] = pv.String()
	}

	var vals = strings.Join(paths, ", ")

	return "[ " + vals + " ]"
}
<commit_msg>moved stack.go to table_stack.go<commit_after><|endoftext|>


<commit_before>package main

import (
	"github.com/gopherjs/gopherjs/js"
	"github.com/hashicorp/hcl"
	"github.com/hashicorp/hil"
	"github.com/hashicorp/hil/ast"
)

func parseHcl(v string) (interface{}, error) {
	return hcl.ParseString(v)
}

func parseHilWithPosition(v string, column, line int, filename string) (interface{}, error) {
	return hil.ParseWithPosition(v, ast.Pos{
		Column:   column,
		Line:     line,
		Filename: filename,
	})
}

func main() {
	exports := js.Module.Get("exports")
	exports.Set("parseHcl", parseHcl)
	exports.Set("parseHil", parseHilWithPosition)
}
<commit_msg>Properly emit the error message<commit_after>package main

import (
	"github.com/gopherjs/gopherjs/js"
	"github.com/hashicorp/hcl"
	hclParser "github.com/hashicorp/hcl/hcl/parser"
	hclToken "github.com/hashicorp/hcl/hcl/token"
	"github.com/hashicorp/hil"
	"github.com/hashicorp/hil/ast"
	"github.com/hashicorp/hil/parser"
)

type hclError struct {
	Pos *hclToken.Pos
	Err string
}

func parseHcl(v string) (interface{}, *hclError) {
	result, err := hcl.ParseString(v)

	if err != nil {
		if pErr, ok := err.(*hclParser.PosError); ok {
			return nil, &hclError{
				Pos: &pErr.Pos,
				Err: pErr.Err.Error(),
			}
		}

		return result, &hclError{
			Pos: nil,
			Err: err.Error(),
		}
	}

	return result, nil
}

type hilError struct {
	Pos *ast.Pos
	Err string
}

func parseHilWithPosition(v string, column, line int, filename string) (interface{}, *hilError) {
	result, err := hil.ParseWithPosition(v, ast.Pos{
		Column:   column,
		Line:     line,
		Filename: filename,
	})

	if err != nil {
		if pErr, ok := err.(*parser.ParseError); ok {
			return nil, &hilError{
				Pos: &pErr.Pos,
				Err: pErr.String(),
			}
		}

		return nil, &hilError{
			Pos: nil,
			Err: err.Error(),
		}
	}

	return result, nil
}

func main() {
	exports := js.Module.Get("exports")
	exports.Set("parseHcl", parseHcl)
	exports.Set("parseHil", parseHilWithPosition)
}
<|endoftext|>


<commit_before>package consensus

import (
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/types"
)

type (
	// blockMarshaller encodes a Block for storage.
	blockMarshaller interface {
		Marshal(types.Block) []byte
	}

	// processedBlockUnmarshaller decodes a processedBlock from a byte slice.
	processedBlockUnmarshaller interface {
		Unmarshal([]byte, *processedBlock) error
	}

	// stdBlockMarshaller is an implementation of blockMarshaller that uses the
	// Sia/encoding package to encode a Block.
	stdBlockMarshaller struct{}

	// stdProcessedBlockUnmarshaller is an implementation of
	// processedBlockUnmarshaller that uses the Sia/encoding package to decode
	// a processedBlock from a byte slice.
	stdProcessedBlockUnmarshaller struct{}
)

func (m stdBlockMarshaller) Marshal(block types.Block) []byte {
	return encoding.Marshal(block)
}

func (um stdProcessedBlockUnmarshaller) Unmarshal(blockBytes []byte, block *processedBlock) error {
	return encoding.Unmarshal(blockBytes, block)
}
<commit_msg>Removing unused block_marshal.go file<commit_after><|endoftext|>


<commit_before>package vizzini_test

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/onsi/say"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager/lagertest"

	"github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
	"time"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/consuladapter"
	"github.com/cloudfoundry-incubator/locket"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

var bbsClient bbs.Client
var locketClient locket.Client
var domain string
var otherDomain string
var defaultRootFS string
var guid string
var startTime time.Time

var bbsAddress string
var consulAddress string
var routableDomainSuffix string
var hostAddress string

func init() {
	flag.StringVar(&bbsAddress, "bbs-address", "http://10.244.16.130:8889", "http address for the bbs (required)")
	flag.StringVar(&consulAddress, "consul-address", "http://127.0.0.1:8500", "http address for the consul agent (required)")
	flag.StringVar(&routableDomainSuffix, "routable-domain-suffix", "bosh-lite.com", "suffix to use when constructing FQDN")
	flag.StringVar(&hostAddress, "host-address", "10.0.2.2", "address that a process running in a container on Diego can use to reach the machine running this test.  Typically the gateway on the vagrant VM.")
	flag.Parse()

	if bbsAddress == "" {
		log.Fatal("i need a bbs address to talk to Diego...")
	}

	if consulAddress == "" {
		log.Fatal("i need a consul address to talk to Diego...")
	}
}

func TestVizziniSuite(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "ReceptorSuite Suite")
}

func NewGuid() string {
	u, err := uuid.NewV4()
	Ω(err).ShouldNot(HaveOccurred())
	return domain + "-" + u.String()[:8]
}

var _ = BeforeSuite(func() {
	timeout := os.Getenv("DEFAULT_EVENTUALLY_TIMEOUT")
	if timeout == "" {
		SetDefaultEventuallyTimeout(10 * time.Second)
	} else {
		duration, err := time.ParseDuration(timeout)
		Ω(err).ShouldNot(HaveOccurred(), "invalid timeout")
		fmt.Printf("Setting Default Eventually Timeout to %s\n", duration)
		SetDefaultEventuallyTimeout(duration)
	}
	SetDefaultEventuallyPollingInterval(500 * time.Millisecond)
	SetDefaultConsistentlyPollingInterval(200 * time.Millisecond)
	domain = fmt.Sprintf("vizzini-%d", GinkgoParallelNode())
	otherDomain = fmt.Sprintf("vizzini-other-%d", GinkgoParallelNode())
	defaultRootFS = models.PreloadedRootFS("cflinuxfs2")

	bbsClient = bbs.NewClient(bbsAddress)
	consulClient, err := consuladapter.NewClient(consulAddress)
	Ω(err).ShouldNot(HaveOccurred())

	sessionMgr := consuladapter.NewSessionManager(consulClient)
	consulSession, err := consuladapter.NewSession("vizzini", 10*time.Second, consulClient, sessionMgr)
	Ω(err).ShouldNot(HaveOccurred())

	logger := lagertest.NewTestLogger("vizzini")

	locketClient = locket.NewClient(consulSession, clock.NewClock(), logger)
})

var _ = BeforeEach(func() {
	startTime = time.Now()
	guid = NewGuid()
})

var _ = AfterEach(func() {
	defer func() {
		endTime := time.Now()
		fmt.Fprint(GinkgoWriter, say.Cyan("\n%s\nThis test referenced GUID %s\nStart time: %s (%d)\nEnd time: %s (%d)\n", CurrentGinkgoTestDescription().FullTestText, guid, startTime, startTime.Unix(), endTime, endTime.Unix()))
	}()

	for _, domain := range []string{domain, otherDomain} {
		ClearOutTasksInDomain(domain)
		ClearOutDesiredLRPsInDomain(domain)
	}
})

var _ = AfterSuite(func() {
	for _, domain := range []string{domain, otherDomain} {
		bbsClient.UpsertDomain(domain, 5*time.Minute) //leave the domain around forever so that Diego cleans up if need be
	}

	for _, domain := range []string{domain, otherDomain} {
		ClearOutDesiredLRPsInDomain(domain)
		ClearOutTasksInDomain(domain)
	}
})
<commit_msg>Add ssl configuration for bbs<commit_after>package vizzini_test

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"

	"github.com/onsi/say"
	"github.com/pivotal-golang/clock"
	"github.com/pivotal-golang/lager/lagertest"

	"github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
	"time"

	"github.com/cloudfoundry-incubator/bbs"
	"github.com/cloudfoundry-incubator/consuladapter"
	"github.com/cloudfoundry-incubator/locket"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

var bbsClient bbs.Client
var locketClient locket.Client
var domain string
var otherDomain string
var defaultRootFS string
var guid string
var startTime time.Time

var bbsAddress string
var bbsCA string
var bbsClientCert string
var bbsClientKey string
var consulAddress string
var routableDomainSuffix string
var hostAddress string

func init() {
	flag.StringVar(&bbsAddress, "bbs-address", "http://10.244.16.130:8889", "http address for the bbs (required)")
	flag.StringVar(&bbsCA, "bbs-ca", "", "bbs ca cert")
	flag.StringVar(&bbsClientCert, "bbs-client-cert", "", "bbs client ssl certificate")
	flag.StringVar(&bbsClientKey, "bbs-client-key", "", "bbs client ssl key")
	flag.StringVar(&consulAddress, "consul-address", "http://127.0.0.1:8500", "http address for the consul agent (required)")
	flag.StringVar(&routableDomainSuffix, "routable-domain-suffix", "bosh-lite.com", "suffix to use when constructing FQDN")
	flag.StringVar(&hostAddress, "host-address", "10.0.2.2", "address that a process running in a container on Diego can use to reach the machine running this test.  Typically the gateway on the vagrant VM.")
	flag.Parse()

	if bbsAddress == "" {
		log.Fatal("i need a bbs address to talk to Diego...")
	}

	if consulAddress == "" {
		log.Fatal("i need a consul address to talk to Diego...")
	}
}

func TestVizziniSuite(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "ReceptorSuite Suite")
}

func NewGuid() string {
	u, err := uuid.NewV4()
	Ω(err).ShouldNot(HaveOccurred())
	return domain + "-" + u.String()[:8]
}

var _ = BeforeSuite(func() {
	timeout := os.Getenv("DEFAULT_EVENTUALLY_TIMEOUT")
	if timeout == "" {
		SetDefaultEventuallyTimeout(10 * time.Second)
	} else {
		duration, err := time.ParseDuration(timeout)
		Ω(err).ShouldNot(HaveOccurred(), "invalid timeout")
		fmt.Printf("Setting Default Eventually Timeout to %s\n", duration)
		SetDefaultEventuallyTimeout(duration)
	}
	SetDefaultEventuallyPollingInterval(500 * time.Millisecond)
	SetDefaultConsistentlyPollingInterval(200 * time.Millisecond)
	domain = fmt.Sprintf("vizzini-%d", GinkgoParallelNode())
	otherDomain = fmt.Sprintf("vizzini-other-%d", GinkgoParallelNode())
	defaultRootFS = models.PreloadedRootFS("cflinuxfs2")

	var err error
	bbsClient = initializeBBSClient()

	consulClient, err := consuladapter.NewClient(consulAddress)
	Ω(err).ShouldNot(HaveOccurred())

	sessionMgr := consuladapter.NewSessionManager(consulClient)
	consulSession, err := consuladapter.NewSession("vizzini", 10*time.Second, consulClient, sessionMgr)
	Ω(err).ShouldNot(HaveOccurred())

	logger := lagertest.NewTestLogger("vizzini")

	locketClient = locket.NewClient(consulSession, clock.NewClock(), logger)
})

var _ = BeforeEach(func() {
	startTime = time.Now()
	guid = NewGuid()
})

var _ = AfterEach(func() {
	defer func() {
		endTime := time.Now()
		fmt.Fprint(GinkgoWriter, say.Cyan("\n%s\nThis test referenced GUID %s\nStart time: %s (%d)\nEnd time: %s (%d)\n", CurrentGinkgoTestDescription().FullTestText, guid, startTime, startTime.Unix(), endTime, endTime.Unix()))
	}()

	for _, domain := range []string{domain, otherDomain} {
		ClearOutTasksInDomain(domain)
		ClearOutDesiredLRPsInDomain(domain)
	}
})

var _ = AfterSuite(func() {
	for _, domain := range []string{domain, otherDomain} {
		bbsClient.UpsertDomain(domain, 5*time.Minute) //leave the domain around forever so that Diego cleans up if need be
	}

	for _, domain := range []string{domain, otherDomain} {
		ClearOutDesiredLRPsInDomain(domain)
		ClearOutTasksInDomain(domain)
	}
})

func initializeBBSClient() bbs.Client {
	bbsURL, err := url.Parse(bbsAddress)
	Ω(err).ShouldNot(HaveOccurred())

	if bbsURL.Scheme != "https" {
		return bbs.NewClient(bbsAddress)
	}

	bbsClient, err := bbs.NewSecureClient(bbsAddress, bbsCA, bbsClientCert, bbsClientKey)
	Ω(err).ShouldNot(HaveOccurred())
	return bbsClient
}
<|endoftext|>


<commit_before>// Package local provides the default implementation for volumes. It
// is used to mount data volume containers and directories local to
// the host server.
package local // import "github.com/docker/docker/volume/local"

import (
	"encoding/json"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"sync"

	"github.com/docker/docker/daemon/names"
	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/quota"
	"github.com/docker/docker/volume"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

const (
	// volumeDataPathName is the name of the directory where the volume data is stored.
	// It uses a very distinctive name to avoid collisions migrating data between
	// Docker versions.
	volumeDataPathName = "_data"
	volumesPathName    = "volumes"
)

var (
	// ErrNotFound is the typed error returned when the requested volume name can't be found
	ErrNotFound = errors.New("volume not found")
	// volumeNameRegex ensures the name assigned for the volume is valid.
	// This name is used to create the bind directory, so we need to avoid characters that
	// would make the path to escape the root directory.
	volumeNameRegex = names.RestrictedNamePattern
)

type activeMount struct {
	count   uint64
	mounted bool
}

// New instantiates a new Root instance with the provided scope. Scope
// is the base path that the Root instance uses to store its
// volumes. The base path is created here if it does not exist.
func New(scope string, rootIdentity idtools.Identity) (*Root, error) {
	r := &Root{
		path:         filepath.Join(scope, volumesPathName),
		volumes:      make(map[string]*localVolume),
		rootIdentity: rootIdentity,
	}

	if err := idtools.MkdirAllAndChown(r.path, 0701, idtools.CurrentIdentity()); err != nil {
		return nil, err
	}

	dirs, err := os.ReadDir(r.path)
	if err != nil {
		return nil, err
	}

	if r.quotaCtl, err = quota.NewControl(r.path); err != nil {
		logrus.Debugf("No quota support for local volumes in %s: %v", r.path, err)
	}

	for _, d := range dirs {
		if !d.IsDir() {
			continue
		}

		name := d.Name()
		v := &localVolume{
			driverName: r.Name(),
			name:       name,
			path:       r.DataPath(name),
			quotaCtl:   r.quotaCtl,
		}
		if b, err := os.ReadFile(filepath.Join(r.path, name, "opts.json")); err == nil {
			opts := optsConfig{}
			if err := json.Unmarshal(b, &opts); err != nil {
				return nil, errors.Wrapf(err, "error while unmarshaling volume options for volume: %s", name)
			}
			// Make sure this isn't an empty optsConfig.
			// This could be empty due to buggy behavior in older versions of Docker.
			if !reflect.DeepEqual(opts, optsConfig{}) {
				v.opts = &opts
			}
			// unmount anything that may still be mounted (for example, from an
			// unclean shutdown). This is a no-op on windows
			unmount(v.path)
		}
		r.volumes[name] = v
	}

	return r, nil
}

// Root implements the Driver interface for the volume package and
// manages the creation/removal of volumes. It uses only standard vfs
// commands to create/remove dirs within its provided scope.
type Root struct {
	m            sync.Mutex
	path         string
	quotaCtl     *quota.Control
	volumes      map[string]*localVolume
	rootIdentity idtools.Identity
}

// List lists all the volumes
func (r *Root) List() ([]volume.Volume, error) {
	var ls []volume.Volume
	r.m.Lock()
	for _, v := range r.volumes {
		ls = append(ls, v)
	}
	r.m.Unlock()
	return ls, nil
}

// DataPath returns the constructed path of this volume.
func (r *Root) DataPath(volumeName string) string {
	return filepath.Join(r.path, volumeName, volumeDataPathName)
}

// Name returns the name of Root, defined in the volume package in the DefaultDriverName constant.
func (r *Root) Name() string {
	return volume.DefaultDriverName
}

// Create creates a new volume.Volume with the provided name, creating
// the underlying directory tree required for this volume in the
// process.
func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error) {
	if err := r.validateName(name); err != nil {
		return nil, err
	}
	if err := r.validateOpts(opts); err != nil {
		return nil, err
	}

	r.m.Lock()
	defer r.m.Unlock()

	v, exists := r.volumes[name]
	if exists {
		return v, nil
	}

	path := r.DataPath(name)
	volRoot := filepath.Dir(path)
	// Root dir does not need to be accessed by the remapped root
	if err := idtools.MkdirAllAndChown(volRoot, 0701, idtools.CurrentIdentity()); err != nil {
		return nil, errors.Wrapf(errdefs.System(err), "error while creating volume root path '%s'", volRoot)
	}

	// Remapped root does need access to the data path
	if err := idtools.MkdirAllAndChown(path, 0755, r.rootIdentity); err != nil {
		return nil, errors.Wrapf(errdefs.System(err), "error while creating volume data path '%s'", path)
	}

	var err error
	defer func() {
		if err != nil {
			os.RemoveAll(filepath.Dir(path))
		}
	}()

	v = &localVolume{
		driverName: r.Name(),
		name:       name,
		path:       path,
		quotaCtl:   r.quotaCtl,
	}

	if len(opts) != 0 {
		if err = v.setOpts(opts); err != nil {
			return nil, err
		}
		var b []byte
		b, err = json.Marshal(v.opts)
		if err != nil {
			return nil, err
		}
		if err = os.WriteFile(filepath.Join(filepath.Dir(path), "opts.json"), b, 0600); err != nil {
			return nil, errdefs.System(errors.Wrap(err, "error while persisting volume options"))
		}
	}

	r.volumes[name] = v
	return v, nil
}

// Remove removes the specified volume and all underlying data. If the
// given volume does not belong to this driver and an error is
// returned. The volume is reference counted, if all references are
// not released then the volume is not removed.
func (r *Root) Remove(v volume.Volume) error {
	r.m.Lock()
	defer r.m.Unlock()

	lv, ok := v.(*localVolume)
	if !ok {
		return errdefs.System(errors.Errorf("unknown volume type %T", v))
	}

	if lv.active.count > 0 {
		return errdefs.System(errors.New("volume has active mounts"))
	}

	if err := lv.unmount(); err != nil {
		return err
	}

	realPath, err := filepath.EvalSymlinks(lv.path)
	if err != nil {
		if !os.IsNotExist(err) {
			return err
		}
		realPath = filepath.Dir(lv.path)
	}

	if realPath == r.path || !strings.HasPrefix(realPath, r.path) {
		return errdefs.System(errors.Errorf("unable to remove a directory outside of the local volume root %s: %s", r.path, realPath))
	}

	if err := removePath(realPath); err != nil {
		return err
	}

	delete(r.volumes, lv.name)
	return removePath(filepath.Dir(lv.path))
}

func removePath(path string) error {
	if err := os.RemoveAll(path); err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return errdefs.System(errors.Wrapf(err, "error removing volume path '%s'", path))
	}
	return nil
}

// Get looks up the volume for the given name and returns it if found
func (r *Root) Get(name string) (volume.Volume, error) {
	r.m.Lock()
	v, exists := r.volumes[name]
	r.m.Unlock()
	if !exists {
		return nil, ErrNotFound
	}
	return v, nil
}

// Scope returns the local volume scope
func (r *Root) Scope() string {
	return volume.LocalScope
}

func (r *Root) validateName(name string) error {
	if len(name) == 1 {
		return errdefs.InvalidParameter(errors.New("volume name is too short, names should be at least two alphanumeric characters"))
	}
	if !volumeNameRegex.MatchString(name) {
		return errdefs.InvalidParameter(errors.Errorf("%q includes invalid characters for a local volume name, only %q are allowed. If you intended to pass a host directory, use absolute path", name, names.RestrictedNameChars))
	}
	return nil
}

// localVolume implements the Volume interface from the volume package and
// represents the volumes created by Root.
type localVolume struct {
	m sync.Mutex
	// unique name of the volume
	name string
	// path is the path on the host where the data lives
	path string
	// driverName is the name of the driver that created the volume.
	driverName string
	// opts is the parsed list of options used to create the volume
	opts *optsConfig
	// active refcounts the active mounts
	active activeMount
	// reference to Root instances quotaCtl
	quotaCtl *quota.Control
}

// Name returns the name of the given Volume.
func (v *localVolume) Name() string {
	return v.name
}

// DriverName returns the driver that created the given Volume.
func (v *localVolume) DriverName() string {
	return v.driverName
}

// Path returns the data location.
func (v *localVolume) Path() string {
	return v.path
}

// CachedPath returns the data location
func (v *localVolume) CachedPath() string {
	return v.path
}

// Mount implements the localVolume interface, returning the data location.
// If there are any provided mount options, the resources will be mounted at this point
func (v *localVolume) Mount(id string) (string, error) {
	v.m.Lock()
	defer v.m.Unlock()
	if v.needsMount() {
		if !v.active.mounted {
			if err := v.mount(); err != nil {
				return "", errdefs.System(err)
			}
			v.active.mounted = true
		}
		v.active.count++
	}
	if err := v.postMount(); err != nil {
		return "", err
	}
	return v.path, nil
}

// Unmount dereferences the id, and if it is the last reference will unmount any resources
// that were previously mounted.
func (v *localVolume) Unmount(id string) error {
	v.m.Lock()
	defer v.m.Unlock()

	// Always decrement the count, even if the unmount fails
	// Essentially docker doesn't care if this fails, it will send an error, but
	// ultimately there's nothing that can be done. If we don't decrement the count
	// this volume can never be removed until a daemon restart occurs.
	if v.needsMount() {
		v.active.count--
	}

	if v.active.count > 0 {
		return nil
	}

	return v.unmount()
}

func (v *localVolume) Status() map[string]interface{} {
	return nil
}

// getAddress finds out address/hostname from options
func getAddress(opts string) string {
	optsList := strings.Split(opts, ",")
	for i := 0; i < len(optsList); i++ {
		if strings.HasPrefix(optsList[i], "addr=") {
			addr := strings.SplitN(optsList[i], "=", 2)[1]
			return addr
		}
	}
	return ""
}

// getPassword finds out a password from options
func getPassword(opts string) string {
	optsList := strings.Split(opts, ",")
	for i := 0; i < len(optsList); i++ {
		if strings.HasPrefix(optsList[i], "password=") {
			passwd := strings.SplitN(optsList[i], "=", 2)[1]
			return passwd
		}
	}
	return ""
}
<commit_msg>volume/local: store both volume's "data" and "root" path<commit_after>// Package local provides the default implementation for volumes. It
// is used to mount data volume containers and directories local to
// the host server.
package local // import "github.com/docker/docker/volume/local"

import (
	"encoding/json"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"sync"

	"github.com/docker/docker/daemon/names"
	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/idtools"
	"github.com/docker/docker/quota"
	"github.com/docker/docker/volume"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

const (
	// volumeDataPathName is the name of the directory where the volume data is stored.
	// It uses a very distinctive name to avoid collisions migrating data between
	// Docker versions.
	volumeDataPathName = "_data"
	volumesPathName    = "volumes"
)

var (
	// ErrNotFound is the typed error returned when the requested volume name can't be found
	ErrNotFound = errors.New("volume not found")
	// volumeNameRegex ensures the name assigned for the volume is valid.
	// This name is used to create the bind directory, so we need to avoid characters that
	// would make the path to escape the root directory.
	volumeNameRegex = names.RestrictedNamePattern
)

type activeMount struct {
	count   uint64
	mounted bool
}

// New instantiates a new Root instance with the provided scope. Scope
// is the base path that the Root instance uses to store its
// volumes. The base path is created here if it does not exist.
func New(scope string, rootIdentity idtools.Identity) (*Root, error) {
	r := &Root{
		path:         filepath.Join(scope, volumesPathName),
		volumes:      make(map[string]*localVolume),
		rootIdentity: rootIdentity,
	}

	if err := idtools.MkdirAllAndChown(r.path, 0701, idtools.CurrentIdentity()); err != nil {
		return nil, err
	}

	dirs, err := os.ReadDir(r.path)
	if err != nil {
		return nil, err
	}

	if r.quotaCtl, err = quota.NewControl(r.path); err != nil {
		logrus.Debugf("No quota support for local volumes in %s: %v", r.path, err)
	}

	for _, d := range dirs {
		if !d.IsDir() {
			continue
		}

		name := d.Name()
		v := &localVolume{
			driverName: r.Name(),
			name:       name,
			rootPath:   filepath.Join(r.path, name),
			path:       filepath.Join(r.path, name, volumeDataPathName),
			quotaCtl:   r.quotaCtl,
		}
		if b, err := os.ReadFile(filepath.Join(v.rootPath, "opts.json")); err == nil {
			opts := optsConfig{}
			if err := json.Unmarshal(b, &opts); err != nil {
				return nil, errors.Wrapf(err, "error while unmarshaling volume options for volume: %s", name)
			}
			// Make sure this isn't an empty optsConfig.
			// This could be empty due to buggy behavior in older versions of Docker.
			if !reflect.DeepEqual(opts, optsConfig{}) {
				v.opts = &opts
			}
			// unmount anything that may still be mounted (for example, from an
			// unclean shutdown). This is a no-op on windows
			unmount(v.path)
		}
		r.volumes[name] = v
	}

	return r, nil
}

// Root implements the Driver interface for the volume package and
// manages the creation/removal of volumes. It uses only standard vfs
// commands to create/remove dirs within its provided scope.
type Root struct {
	m            sync.Mutex
	path         string
	quotaCtl     *quota.Control
	volumes      map[string]*localVolume
	rootIdentity idtools.Identity
}

// List lists all the volumes
func (r *Root) List() ([]volume.Volume, error) {
	var ls []volume.Volume
	r.m.Lock()
	for _, v := range r.volumes {
		ls = append(ls, v)
	}
	r.m.Unlock()
	return ls, nil
}

// Name returns the name of Root, defined in the volume package in the DefaultDriverName constant.
func (r *Root) Name() string {
	return volume.DefaultDriverName
}

// Create creates a new volume.Volume with the provided name, creating
// the underlying directory tree required for this volume in the
// process.
func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error) {
	if err := r.validateName(name); err != nil {
		return nil, err
	}
	if err := r.validateOpts(opts); err != nil {
		return nil, err
	}

	r.m.Lock()
	defer r.m.Unlock()

	v, exists := r.volumes[name]
	if exists {
		return v, nil
	}

	v = &localVolume{
		driverName: r.Name(),
		name:       name,
		rootPath:   filepath.Join(r.path, name),
		path:       filepath.Join(r.path, name, volumeDataPathName),
		quotaCtl:   r.quotaCtl,
	}

	// Root dir does not need to be accessed by the remapped root
	if err := idtools.MkdirAllAndChown(v.rootPath, 0701, idtools.CurrentIdentity()); err != nil {
		return nil, errors.Wrapf(errdefs.System(err), "error while creating volume root path '%s'", v.rootPath)
	}

	// Remapped root does need access to the data path
	if err := idtools.MkdirAllAndChown(v.path, 0755, r.rootIdentity); err != nil {
		return nil, errors.Wrapf(errdefs.System(err), "error while creating volume data path '%s'", v.path)
	}

	var err error
	defer func() {
		if err != nil {
			os.RemoveAll(v.rootPath)
		}
	}()

	if len(opts) != 0 {
		if err = v.setOpts(opts); err != nil {
			return nil, err
		}
		var b []byte
		b, err = json.Marshal(v.opts)
		if err != nil {
			return nil, err
		}
		if err = os.WriteFile(filepath.Join(v.rootPath, "opts.json"), b, 0600); err != nil {
			return nil, errdefs.System(errors.Wrap(err, "error while persisting volume options"))
		}
	}

	r.volumes[name] = v
	return v, nil
}

// Remove removes the specified volume and all underlying data. If the
// given volume does not belong to this driver and an error is
// returned. The volume is reference counted, if all references are
// not released then the volume is not removed.
func (r *Root) Remove(v volume.Volume) error {
	r.m.Lock()
	defer r.m.Unlock()

	lv, ok := v.(*localVolume)
	if !ok {
		return errdefs.System(errors.Errorf("unknown volume type %T", v))
	}

	if lv.active.count > 0 {
		return errdefs.System(errors.New("volume has active mounts"))
	}

	if err := lv.unmount(); err != nil {
		return err
	}

	// TODO(thaJeztah) is there a reason we're evaluating the data-path here, and not the volume's rootPath?
	realPath, err := filepath.EvalSymlinks(lv.path)
	if err != nil {
		if !os.IsNotExist(err) {
			return err
		}
		// if the volume's data-directory wasn't found, fall back to using the
		// volume's root path (see 8d27417bfeff316346d00c07a456b0e1b056e788)
		realPath = lv.rootPath
	}

	if realPath == r.path || !strings.HasPrefix(realPath, r.path) {
		return errdefs.System(errors.Errorf("unable to remove a directory outside of the local volume root %s: %s", r.path, realPath))
	}

	if err := removePath(realPath); err != nil {
		return err
	}

	delete(r.volumes, lv.name)
	return removePath(lv.rootPath)
}

func removePath(path string) error {
	if err := os.RemoveAll(path); err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return errdefs.System(errors.Wrapf(err, "error removing volume path '%s'", path))
	}
	return nil
}

// Get looks up the volume for the given name and returns it if found
func (r *Root) Get(name string) (volume.Volume, error) {
	r.m.Lock()
	v, exists := r.volumes[name]
	r.m.Unlock()
	if !exists {
		return nil, ErrNotFound
	}
	return v, nil
}

// Scope returns the local volume scope
func (r *Root) Scope() string {
	return volume.LocalScope
}

func (r *Root) validateName(name string) error {
	if len(name) == 1 {
		return errdefs.InvalidParameter(errors.New("volume name is too short, names should be at least two alphanumeric characters"))
	}
	if !volumeNameRegex.MatchString(name) {
		return errdefs.InvalidParameter(errors.Errorf("%q includes invalid characters for a local volume name, only %q are allowed. If you intended to pass a host directory, use absolute path", name, names.RestrictedNameChars))
	}
	return nil
}

// localVolume implements the Volume interface from the volume package and
// represents the volumes created by Root.
type localVolume struct {
	m sync.Mutex
	// unique name of the volume
	name string
	// rootPath is the volume's root path, where the volume's metadata is stored.
	rootPath string
	// path is the path on the host where the data lives
	path string
	// driverName is the name of the driver that created the volume.
	driverName string
	// opts is the parsed list of options used to create the volume
	opts *optsConfig
	// active refcounts the active mounts
	active activeMount
	// reference to Root instances quotaCtl
	quotaCtl *quota.Control
}

// Name returns the name of the given Volume.
func (v *localVolume) Name() string {
	return v.name
}

// DriverName returns the driver that created the given Volume.
func (v *localVolume) DriverName() string {
	return v.driverName
}

// Path returns the data location.
func (v *localVolume) Path() string {
	return v.path
}

// CachedPath returns the data location
func (v *localVolume) CachedPath() string {
	return v.path
}

// Mount implements the localVolume interface, returning the data location.
// If there are any provided mount options, the resources will be mounted at this point
func (v *localVolume) Mount(id string) (string, error) {
	v.m.Lock()
	defer v.m.Unlock()
	if v.needsMount() {
		if !v.active.mounted {
			if err := v.mount(); err != nil {
				return "", errdefs.System(err)
			}
			v.active.mounted = true
		}
		v.active.count++
	}
	if err := v.postMount(); err != nil {
		return "", err
	}
	return v.path, nil
}

// Unmount dereferences the id, and if it is the last reference will unmount any resources
// that were previously mounted.
func (v *localVolume) Unmount(id string) error {
	v.m.Lock()
	defer v.m.Unlock()

	// Always decrement the count, even if the unmount fails
	// Essentially docker doesn't care if this fails, it will send an error, but
	// ultimately there's nothing that can be done. If we don't decrement the count
	// this volume can never be removed until a daemon restart occurs.
	if v.needsMount() {
		v.active.count--
	}

	if v.active.count > 0 {
		return nil
	}

	return v.unmount()
}

func (v *localVolume) Status() map[string]interface{} {
	return nil
}

// getAddress finds out address/hostname from options
func getAddress(opts string) string {
	optsList := strings.Split(opts, ",")
	for i := 0; i < len(optsList); i++ {
		if strings.HasPrefix(optsList[i], "addr=") {
			addr := strings.SplitN(optsList[i], "=", 2)[1]
			return addr
		}
	}
	return ""
}

// getPassword finds out a password from options
func getPassword(opts string) string {
	optsList := strings.Split(opts, ",")
	for i := 0; i < len(optsList); i++ {
		if strings.HasPrefix(optsList[i], "password=") {
			passwd := strings.SplitN(optsList[i], "=", 2)[1]
			return passwd
		}
	}
	return ""
}
<|endoftext|>


<commit_before>package main

// whitelist is a list of phone numbers allowed to be reached in development environments
var whitelist = []string{
	"+12098677445", // philip
	"+16268231898", // tommy
	"+15107178357", // angelica
}
<commit_msg>remove phone numbers .  .<commit_after>package main

// whitelist is a list of phone numbers allowed to be reached in development environments
var whitelist = []string{}
<|endoftext|>


<commit_before>package snapshot

import (
	"context"
	"sync"

	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/snapshots"
	digest "github.com/opencontainers/go-digest"
)

type Mountable interface {
	// ID() string
	Mount() ([]mount.Mount, error)
	Release() error
}

type SnapshotterBase interface {
	Mounts(ctx context.Context, key string) (Mountable, error)
	Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error
	View(ctx context.Context, key, parent string, opts ...snapshots.Opt) (Mountable, error)

	Stat(ctx context.Context, key string) (snapshots.Info, error)
	Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error)
	Usage(ctx context.Context, key string) (snapshots.Usage, error)
	Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error
	Remove(ctx context.Context, key string) error
	Walk(ctx context.Context, fn func(context.Context, snapshots.Info) error) error
	Close() error
}

// Snapshotter defines interface that any snapshot implementation should satisfy
type Snapshotter interface {
	Blobmapper
	SnapshotterBase
}

type Blobmapper interface {
	GetBlob(ctx context.Context, key string) (digest.Digest, digest.Digest, error)
	SetBlob(ctx context.Context, key string, diffID, blob digest.Digest) error
}

func FromContainerdSnapshotter(s snapshots.Snapshotter) SnapshotterBase {
	return &fromContainerd{Snapshotter: s}
}

type fromContainerd struct {
	snapshots.Snapshotter
}

func (s *fromContainerd) Mounts(ctx context.Context, key string) (Mountable, error) {
	mounts, err := s.Snapshotter.Mounts(ctx, key)
	if err != nil {
		return nil, err
	}
	return &staticMountable{mounts}, nil
}
func (s *fromContainerd) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error {
	_, err := s.Snapshotter.Prepare(ctx, key, parent, opts...)
	return err
}
func (s *fromContainerd) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) (Mountable, error) {
	mounts, err := s.Snapshotter.View(ctx, key, parent, opts...)
	if err != nil {
		return nil, err
	}
	return &staticMountable{mounts}, nil
}

type staticMountable struct {
	mounts []mount.Mount
}

func (m *staticMountable) Mount() ([]mount.Mount, error) {
	return m.mounts, nil
}

func (cm *staticMountable) Release() error {
	return nil
}

// NewContainerdSnapshotter converts snapshotter to containerd snapshotter
func NewContainerdSnapshotter(s Snapshotter) (snapshots.Snapshotter, func() error) {
	cs := &containerdSnapshotter{Snapshotter: s}
	return cs, cs.release
}

type containerdSnapshotter struct {
	mu        sync.Mutex
	releasers []func() error
	Snapshotter
}

func (cs *containerdSnapshotter) release() error {
	cs.mu.Lock()
	defer cs.mu.Unlock()
	var err error
	for _, f := range cs.releasers {
		if err1 := f(); err != nil && err == nil {
			err = err1
		}
	}
	return err
}

func (cs *containerdSnapshotter) returnMounts(mf Mountable) ([]mount.Mount, error) {
	mounts, err := mf.Mount()
	if err != nil {
		return nil, err
	}
	cs.mu.Lock()
	cs.releasers = append(cs.releasers, mf.Release)
	cs.mu.Unlock()
	return mounts, nil
}

func (cs *containerdSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
	mf, err := cs.Snapshotter.Mounts(ctx, key)
	if err != nil {
		return nil, err
	}
	return cs.returnMounts(mf)
}

func (cs *containerdSnapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
	if err := cs.Snapshotter.Prepare(ctx, key, parent, opts...); err != nil {
		return nil, err
	}
	return cs.Mounts(ctx, key)
}
func (cs *containerdSnapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
	mf, err := cs.Snapshotter.View(ctx, key, parent, opts...)
	if err != nil {
		return nil, err
	}
	return cs.returnMounts(mf)
}
<commit_msg>snapshot: fix impossible condition<commit_after>package snapshot

import (
	"context"
	"sync"

	"github.com/containerd/containerd/mount"
	"github.com/containerd/containerd/snapshots"
	digest "github.com/opencontainers/go-digest"
)

type Mountable interface {
	// ID() string
	Mount() ([]mount.Mount, error)
	Release() error
}

type SnapshotterBase interface {
	Mounts(ctx context.Context, key string) (Mountable, error)
	Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error
	View(ctx context.Context, key, parent string, opts ...snapshots.Opt) (Mountable, error)

	Stat(ctx context.Context, key string) (snapshots.Info, error)
	Update(ctx context.Context, info snapshots.Info, fieldpaths ...string) (snapshots.Info, error)
	Usage(ctx context.Context, key string) (snapshots.Usage, error)
	Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error
	Remove(ctx context.Context, key string) error
	Walk(ctx context.Context, fn func(context.Context, snapshots.Info) error) error
	Close() error
}

// Snapshotter defines interface that any snapshot implementation should satisfy
type Snapshotter interface {
	Blobmapper
	SnapshotterBase
}

type Blobmapper interface {
	GetBlob(ctx context.Context, key string) (digest.Digest, digest.Digest, error)
	SetBlob(ctx context.Context, key string, diffID, blob digest.Digest) error
}

func FromContainerdSnapshotter(s snapshots.Snapshotter) SnapshotterBase {
	return &fromContainerd{Snapshotter: s}
}

type fromContainerd struct {
	snapshots.Snapshotter
}

func (s *fromContainerd) Mounts(ctx context.Context, key string) (Mountable, error) {
	mounts, err := s.Snapshotter.Mounts(ctx, key)
	if err != nil {
		return nil, err
	}
	return &staticMountable{mounts}, nil
}
func (s *fromContainerd) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) error {
	_, err := s.Snapshotter.Prepare(ctx, key, parent, opts...)
	return err
}
func (s *fromContainerd) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) (Mountable, error) {
	mounts, err := s.Snapshotter.View(ctx, key, parent, opts...)
	if err != nil {
		return nil, err
	}
	return &staticMountable{mounts}, nil
}

type staticMountable struct {
	mounts []mount.Mount
}

func (m *staticMountable) Mount() ([]mount.Mount, error) {
	return m.mounts, nil
}

func (cm *staticMountable) Release() error {
	return nil
}

// NewContainerdSnapshotter converts snapshotter to containerd snapshotter
func NewContainerdSnapshotter(s Snapshotter) (snapshots.Snapshotter, func() error) {
	cs := &containerdSnapshotter{Snapshotter: s}
	return cs, cs.release
}

type containerdSnapshotter struct {
	mu        sync.Mutex
	releasers []func() error
	Snapshotter
}

func (cs *containerdSnapshotter) release() error {
	cs.mu.Lock()
	defer cs.mu.Unlock()
	var err error
	for _, f := range cs.releasers {
		if err1 := f(); err1 != nil && err == nil {
			err = err1
		}
	}
	return err
}

func (cs *containerdSnapshotter) returnMounts(mf Mountable) ([]mount.Mount, error) {
	mounts, err := mf.Mount()
	if err != nil {
		return nil, err
	}
	cs.mu.Lock()
	cs.releasers = append(cs.releasers, mf.Release)
	cs.mu.Unlock()
	return mounts, nil
}

func (cs *containerdSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
	mf, err := cs.Snapshotter.Mounts(ctx, key)
	if err != nil {
		return nil, err
	}
	return cs.returnMounts(mf)
}

func (cs *containerdSnapshotter) Prepare(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
	if err := cs.Snapshotter.Prepare(ctx, key, parent, opts...); err != nil {
		return nil, err
	}
	return cs.Mounts(ctx, key)
}
func (cs *containerdSnapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) ([]mount.Mount, error) {
	mf, err := cs.Snapshotter.View(ctx, key, parent, opts...)
	if err != nil {
		return nil, err
	}
	return cs.returnMounts(mf)
}
<|endoftext|>


<commit_before>/*
github.com/dokipen/debug is a port of visionmedia/debug nodejs lib. It is meant to be extremely quick to get going with. All configuration is done on the commandline with the DEBUG environmental variable.

The current differences with nodejs's debug are that timing is not supported and we include the debug callers file and line number in the output.
*/
package debug

import (
	"crypto/md5"
	"fmt"
	colorfmt "github.com/wsxiaoys/terminal/color"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

// Possible color values.
const COLORS = "rgbcmykw"

// Formatted in two stages. First (color, namespace, color) which is cached,
// then (file, linenum, message, elapsetime) for the actual message.
const FMT = "  @%s%s@| @!%%s:%%d@| @w%%s@| @%s+%%s@|\n"

type message struct {
	from_file string
	from_line int
	namespace string
	message   string
	args      []interface{}
}

type messageChan chan *message

var (
	fmtCache = map[string]string{}
	globs    []string
	msgCh    = make(messageChan)
)

func (msg *message) log(elapsed time.Duration) {
	if fmtstr := formatFor(msg.namespace); fmtstr != "" {
		payload := fmt.Sprintf(msg.message, msg.args...)
		content := fmt.Sprintf(fmtstr, msg.from_file, msg.from_line, payload, elapsed)
		colorfmt.Print(content)
	}
}

func worker(ch messageChan) {
	last := time.Now()
	for {
		msg := <-ch
		elapsed := time.Since(last)
		last = time.Now()
		msg.log(elapsed)
	}
}

/*
init prepares the environmental DEBUG variable.
*/
func init() {
	debug := os.Getenv("DEBUG")
	if debug == "" {
		globs = []string{}
	} else {
		globs = strings.Split(debug, " ")
	}
	go worker(msgCh)
}

/*
match checks if the namespace is enabled for debug logging. It also seeds the
cache for the namespace to speed things up.
*/
func formatFor(namespace string) string {
	var ok bool

	if match, ok := fmtCache[namespace]; ok {
		return match
	}

	for _, glob := range globs {
		if ok, _ = filepath.Match(glob, namespace); ok {
			color := colorFor(namespace)
			fmtCache[namespace] = fmt.Sprintf(FMT, color, namespace, color)
			return fmtCache[namespace]
		}
	}
	fmtCache[namespace] = ""
	return fmtCache[namespace]
}

/*
getcolor returns the color of the namespace.
*/
func colorFor(namespace string) string {
	h := md5.New()
	io.WriteString(h, namespace)
	var sum int
	sumbytes := h.Sum(nil)
	for _, i := range sumbytes {
		sum += int(i)
	}
	return string(COLORS[sum%len(COLORS)])

}

// Public API
/*
Log sends the log message to the log worker to be written to stdout.
*/
func Log(namespace, msg string, args ...interface{}) {
	_, path, line, _ := runtime.Caller(2)
	message := &message{
		from_file: filepath.Base(path),
		from_line: line,
		namespace: namespace,
		message:   msg,
		args:      args,
	}
	msgCh <- message
}

/*
Logger returns a closure for namespacing Log.
*/
func Logger(namespace string) func(string, ...interface{}) {
	return func(msg string, args ...interface{}) {
		Log(namespace, msg, args...)
	}
}
<commit_msg>Enhance format<commit_after>/*
github.com/dokipen/debug is a port of visionmedia/debug nodejs lib. It is meant to be extremely quick to get going with. All configuration is done on the commandline with the DEBUG environmental variable.

The current differences with nodejs's debug are that timing is not supported and we include the debug callers file and line number in the output.
*/
package debug

import (
	"crypto/md5"
	"fmt"
	colorfmt "github.com/wsxiaoys/terminal/color"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

// Possible color values.
const COLORS = "rgbcmy"

// Formatted in two stages. First (color, namespace, color) which is cached,
// then (file, linenum, message, elapsetime) for the actual message.
const FMT = "  @%s%s@| @!%%s:%%d@| @{.w}%%s@| @{/%s}+%%s@|\n"

type message struct {
	from_file string
	from_line int
	namespace string
	message   string
	args      []interface{}
}

type messageChan chan *message

var (
	fmtCache = map[string]string{}
	globs    []string
	msgCh    = make(messageChan)
)

func (msg *message) log(elapsed time.Duration) {
	if fmtstr := formatFor(msg.namespace); fmtstr != "" {
		payload := fmt.Sprintf(msg.message, msg.args...)
		content := fmt.Sprintf(fmtstr, msg.from_file, msg.from_line, payload, elapsed)
		colorfmt.Print(content)
	}
}

func worker(ch messageChan) {
	last := time.Now()
	for {
		msg := <-ch
		elapsed := time.Since(last)
		last = time.Now()
		msg.log(elapsed)
	}
}

/*
init prepares the environmental DEBUG variable.
*/
func init() {
	debug := os.Getenv("DEBUG")
	if debug == "" {
		globs = []string{}
	} else {
		globs = strings.Split(debug, " ")
	}
	go worker(msgCh)
}

/*
match checks if the namespace is enabled for debug logging. It also seeds the
cache for the namespace to speed things up.
*/
func formatFor(namespace string) string {
	var ok bool

	if match, ok := fmtCache[namespace]; ok {
		return match
	}

	for _, glob := range globs {
		if ok, _ = filepath.Match(glob, namespace); ok {
			color := colorFor(namespace)
			fmtCache[namespace] = fmt.Sprintf(FMT, color, namespace, color)
			return fmtCache[namespace]
		}
	}
	fmtCache[namespace] = ""
	return fmtCache[namespace]
}

/*
getcolor returns the color of the namespace.
*/
func colorFor(namespace string) string {
	h := md5.New()
	io.WriteString(h, namespace)
	var sum int
	sumbytes := h.Sum(nil)
	for _, i := range sumbytes {
		sum += int(i)
	}
	return string(COLORS[sum%len(COLORS)])

}

// Public API
/*
Log sends the log message to the log worker to be written to stdout.
*/
func Log(namespace, msg string, args ...interface{}) {
	_, path, line, _ := runtime.Caller(2)
	message := &message{
		from_file: filepath.Base(path),
		from_line: line,
		namespace: namespace,
		message:   msg,
		args:      args,
	}
	msgCh <- message
}

/*
Logger returns a closure for namespacing Log.
*/
func Logger(namespace string) func(string, ...interface{}) {
	return func(msg string, args ...interface{}) {
		Log(namespace, msg, args...)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.

package gin

import (
	"bytes"
	"fmt"
	"html/template"
	"runtime"
	"strconv"
	"strings"
)

const ginSupportMinGoVer = 6

// IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode.
func IsDebugging() bool {
	return ginMode == debugCode
}

// DebugPrintRouteFunc indicates debug log output format.
var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int)

func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
	if IsDebugging() {
		nuHandlers := len(handlers)
		handlerName := nameOfFunction(handlers.Last())
		if DebugPrintRouteFunc == nil {
			debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
		} else {
			DebugPrintRouteFunc(httpMethod, absolutePath, handlerName, nuHandlers)
		}
	}
}

func debugPrintLoadTemplate(tmpl *template.Template) {
	if IsDebugging() {
		var buf bytes.Buffer
		for _, tmpl := range tmpl.Templates() {
			buf.WriteString("\t- ")
			buf.WriteString(tmpl.Name())
			buf.WriteString("\n")
		}
		debugPrint("Loaded HTML Templates (%d): \n%s\n", len(tmpl.Templates()), buf.String())
	}
}

func debugPrint(format string, values ...interface{}) {
	if IsDebugging() {
		fmt.Printf("[GIN-debug] "+format, values...)
	}
}

func getMinVer(v string) (uint64, error) {
	first := strings.IndexByte(v, '.')
	last := strings.LastIndexByte(v, '.')
	if first == last {
		return strconv.ParseUint(v[first+1:], 10, 64)
	}
	return strconv.ParseUint(v[first+1:last], 10, 64)
}

func debugPrintWARNINGDefault() {
	if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
		debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.

`)
	}
	debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

`)
}

func debugPrintWARNINGNew() {
	debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

`)
}

func debugPrintWARNINGSetHTMLTemplate() {
	debugPrint(`[WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called
at initialization. ie. before any route is registered or the router is listening in a socket:

	router := gin.Default()
	router.SetHTMLTemplate(template) // << good place

`)
}

func debugPrintError(err error) {
	if err != nil {
		debugPrint("[ERROR] %v\n", err)
	}
}
<commit_msg>fix: fmt output log to os.Stderr (#1571)<commit_after>// Copyright 2014 Manu Martinez-Almeida.  All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.

package gin

import (
	"bytes"
	"fmt"
	"html/template"
	"os"
	"runtime"
	"strconv"
	"strings"
)

const ginSupportMinGoVer = 6

// IsDebugging returns true if the framework is running in debug mode.
// Use SetMode(gin.ReleaseMode) to disable debug mode.
func IsDebugging() bool {
	return ginMode == debugCode
}

// DebugPrintRouteFunc indicates debug log output format.
var DebugPrintRouteFunc func(httpMethod, absolutePath, handlerName string, nuHandlers int)

func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
	if IsDebugging() {
		nuHandlers := len(handlers)
		handlerName := nameOfFunction(handlers.Last())
		if DebugPrintRouteFunc == nil {
			debugPrint("%-6s %-25s --> %s (%d handlers)\n", httpMethod, absolutePath, handlerName, nuHandlers)
		} else {
			DebugPrintRouteFunc(httpMethod, absolutePath, handlerName, nuHandlers)
		}
	}
}

func debugPrintLoadTemplate(tmpl *template.Template) {
	if IsDebugging() {
		var buf bytes.Buffer
		for _, tmpl := range tmpl.Templates() {
			buf.WriteString("\t- ")
			buf.WriteString(tmpl.Name())
			buf.WriteString("\n")
		}
		debugPrint("Loaded HTML Templates (%d): \n%s\n", len(tmpl.Templates()), buf.String())
	}
}

func debugPrint(format string, values ...interface{}) {
	if IsDebugging() {
		fmt.Fprintf(os.Stderr, "[GIN-debug] "+format, values...)
	}
}

func getMinVer(v string) (uint64, error) {
	first := strings.IndexByte(v, '.')
	last := strings.LastIndexByte(v, '.')
	if first == last {
		return strconv.ParseUint(v[first+1:], 10, 64)
	}
	return strconv.ParseUint(v[first+1:last], 10, 64)
}

func debugPrintWARNINGDefault() {
	if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
		debugPrint(`[WARNING] Now Gin requires Go 1.6 or later and Go 1.7 will be required soon.

`)
	}
	debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

`)
}

func debugPrintWARNINGNew() {
	debugPrint(`[WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

`)
}

func debugPrintWARNINGSetHTMLTemplate() {
	debugPrint(`[WARNING] Since SetHTMLTemplate() is NOT thread-safe. It should only be called
at initialization. ie. before any route is registered or the router is listening in a socket:

	router := gin.Default()
	router.SetHTMLTemplate(template) // << good place

`)
}

func debugPrintError(err error) {
	if err != nil {
		debugPrint("[ERROR] %v\n", err)
	}
}
<|endoftext|>


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

// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package stmts

import (
	"github.com/juju/errors"
	"github.com/pingcap/tidb/column"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/expression"
	"github.com/pingcap/tidb/field"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/plan"
	"github.com/pingcap/tidb/rset"
	"github.com/pingcap/tidb/sessionctx/variable"
	"github.com/pingcap/tidb/stmt"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/util/errors2"
	"github.com/pingcap/tidb/util/format"
	"github.com/pingcap/tidb/util/types"
)

var _ stmt.Statement = (*InsertIntoStmt)(nil)

// Priority const values.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
const (
	NoPriority = iota
	LowPriority
	HighPriority
	DelayedPriority
)

// InsertIntoStmt is a statement to insert new rows into an existing table.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
type InsertIntoStmt struct {
	ColNames    []string
	Lists       [][]expression.Expression
	Sel         plan.Planner
	TableIdent  table.Ident
	Setlist     []*expression.Assignment
	Priority    int
	OnDuplicate []expression.Assignment

	Text string
}

// Explain implements the stmt.Statement Explain interface.
func (s *InsertIntoStmt) Explain(ctx context.Context, w format.Formatter) {
	w.Format("%s\n", s.Text)
}

// IsDDL implements the stmt.Statement IsDDL interface.
func (s *InsertIntoStmt) IsDDL() bool {
	return false
}

// OriginText implements the stmt.Statement OriginText interface.
func (s *InsertIntoStmt) OriginText() string {
	return s.Text
}

// SetText implements the stmt.Statement SetText interface.
func (s *InsertIntoStmt) SetText(text string) {
	s.Text = text
}

// execExecSelect implements `insert table select ... from ...`.
func (s *InsertIntoStmt) execSelect(t table.Table, cols []*column.Col, ctx context.Context) (_ rset.Recordset, err error) {
	r, err := s.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer r.Close()
	if len(r.GetFields()) != len(cols) {
		return nil, errors.Errorf("Column count %d doesn't match value count %d", len(cols), len(r.GetFields()))
	}

	var bufRecords [][]interface{}
	var lastInsertIds []uint64
	for {
		var row *plan.Row
		row, err = r.Next(ctx)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if row == nil {
			break
		}
		data0 := make([]interface{}, len(t.Cols()))
		marked := make(map[int]struct{}, len(cols))
		for i, d := range row.Data {
			data0[cols[i].Offset] = d
			marked[cols[i].Offset] = struct{}{}
		}

		if err = s.initDefaultValues(ctx, t, data0, marked); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CastValues(ctx, data0, cols); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CheckNotNull(t.Cols(), data0); err != nil {
			return nil, errors.Trace(err)
		}
		var v interface{}
		v, err = types.Clone(data0)
		if err != nil {
			return nil, errors.Trace(err)
		}

		bufRecords = append(bufRecords, v.([]interface{}))
		lastInsertIds = append(lastInsertIds, variable.GetSessionVars(ctx).LastInsertID)
	}

	for i, r := range bufRecords {
		variable.GetSessionVars(ctx).SetLastInsertID(lastInsertIds[i])
		if _, err = t.AddRecord(ctx, r); err != nil {
			return nil, errors.Trace(err)
		}
	}
	return nil, nil
}

// There are three types of insert statements:
// 1 insert ... values(...)  --> name type column
// 2 insert ... set x=y...   --> set type column
// 3 insert ... (select ..)  --> name type column
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
func (s *InsertIntoStmt) getColumns(tableCols []*column.Col) ([]*column.Col, error) {
	var cols []*column.Col
	var err error

	if len(s.Setlist) > 0 {
		// Process `set` type column.
		columns := make([]string, 0, len(s.Setlist))
		for _, v := range s.Setlist {
			columns = append(columns, v.ColName)
		}

		cols, err = column.FindCols(tableCols, columns)
		if err != nil {
			return nil, errors.Errorf("INSERT INTO %s: %s", s.TableIdent, err)
		}

		if len(cols) == 0 {
			return nil, errors.Errorf("INSERT INTO %s: empty column", s.TableIdent)
		}
	} else {
		// Process `name` type column.
		cols, err = column.FindCols(tableCols, s.ColNames)
		if err != nil {
			return nil, errors.Errorf("INSERT INTO %s: %s", s.TableIdent, err)
		}

		// If cols are empty, use all columns instead.
		if len(cols) == 0 {
			cols = tableCols
		}
	}

	// Check column whether is specified only once.
	err = column.CheckOnce(cols)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return cols, nil
}

func (s *InsertIntoStmt) getDefaultValues(ctx context.Context, cols []*column.Col) (map[interface{}]interface{}, error) {
	m := map[interface{}]interface{}{}
	for _, v := range cols {
		if value, ok, err := getDefaultValue(ctx, v); ok {
			if err != nil {
				return nil, errors.Trace(err)
			}

			m[v.Name.L] = value
		}
	}

	return m, nil
}

func (s *InsertIntoStmt) getSetList() error {
	if len(s.Setlist) > 0 {
		if len(s.Lists) > 0 {
			return errors.Errorf("INSERT INTO %s: set type should not use values", s.TableIdent)
		}

		var l []expression.Expression
		for _, v := range s.Setlist {
			l = append(l, v.Expr)
		}
		s.Lists = append(s.Lists, l)
	}

	return nil
}

// Exec implements the stmt.Statement Exec interface.
func (s *InsertIntoStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
	t, err := getTable(ctx, s.TableIdent)
	if err != nil {
		return nil, errors.Trace(err)
	}
	cols, err := s.getColumns(t.Cols())
	if err != nil {
		return nil, errors.Trace(err)
	}

	// Process `insert ... (select ..) `
	if s.Sel != nil {
		return s.execSelect(t, cols, ctx)
	}

	// Process `insert ... set x=y...`
	if err = s.getSetList(); err != nil {
		return nil, errors.Trace(err)
	}

	m, err := s.getDefaultValues(ctx, t.Cols())
	if err != nil {
		return nil, errors.Trace(err)
	}
	insertValueCount := len(s.Lists[0])
	toUpdateColumns, err := getOnDuplicateUpdateColumns(s.OnDuplicate, t)
	if err != nil {
		return nil, errors.Trace(err)
	}

	for i, list := range s.Lists {
		if err = s.checkValueCount(insertValueCount, len(list), i, cols); err != nil {
			return nil, errors.Trace(err)
		}
		row, h, err := s.addRecord(ctx, t, cols, list, m)
		if err == nil {
			continue
		}

		if h == -1 || len(s.OnDuplicate) == 0 || !errors2.ErrorEqual(err, kv.ErrKeyExists) {
			return nil, errors.Trace(err)
		}
		if err = execOnDuplicateUpdate(ctx, t, row, h, toUpdateColumns); err != nil {
			return nil, errors.Trace(err)
		}
	}

	return nil, nil
}

func (s *InsertIntoStmt) checkValueCount(insertValueCount, valueCount, num int, cols []*column.Col) error {
	if insertValueCount != valueCount {
		// "insert into t values (), ()" is valid.
		// "insert into t values (), (1)" is not valid.
		// "insert into t values (1), ()" is not valid.
		// "insert into t values (1,2), (1)" is not valid.
		// So the value count must be same for all insert list.
		return errors.Errorf("Column count doesn't match value count at row %d", num+1)
	}
	if valueCount == 0 && len(s.ColNames) > 0 {
		// "insert into t (c1) values ()" is not valid.
		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", s.TableIdent, len(s.ColNames), 0)
	} else if valueCount > 0 && valueCount != len(cols) {
		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", s.TableIdent, len(cols), valueCount)
	}

	return nil
}

func (s *InsertIntoStmt) addRecord(ctx context.Context, t table.Table, cols []*column.Col, list []expression.Expression, m map[interface{}]interface{}) ([]interface{}, int64, error) {
	r := make([]interface{}, len(t.Cols()))
	marked := make(map[int]struct{}, len(list))
	for i, expr := range list {
		// For "insert into t values (default)" Default Eval.
		m[expression.ExprEvalDefaultName] = cols[i].Name.O

		val, evalErr := expr.Eval(ctx, m)
		if evalErr != nil {
			return nil, -1, errors.Trace(evalErr)
		}
		r[cols[i].Offset] = val
		marked[cols[i].Offset] = struct{}{}
	}

	// Clear last insert id.
	variable.GetSessionVars(ctx).SetLastInsertID(0)

	err := s.initDefaultValues(ctx, t, r, marked)
	if err != nil {
		return nil, -1, errors.Trace(err)
	}
	if err = column.CastValues(ctx, r, cols); err != nil {
		return nil, -1, errors.Trace(err)
	}
	if err = column.CheckNotNull(t.Cols(), r); err != nil {
		return nil, -1, errors.Trace(err)
	}

	// Notes: incompatible with mysql
	// MySQL will set last insert id to the first row, as follows:
	// `t(id int AUTO_INCREMENT, c1 int, PRIMARY KEY (id))`
	// `insert t (c1) values(1),(2),(3);`
	// Last insert id will be 1, not 3.
	h, err := t.AddRecord(ctx, r)

	return r, h, err
}

func execOnDuplicateUpdate(ctx context.Context, t table.Table, row []interface{}, h int64, cols map[int]expression.Assignment) error {
	// On duplicate key update the duplicate row.
	// Evaluate the updated value.
	// TODO: report rows affected and last insert id.
	data, err := t.Row(ctx, h)
	if err != nil {
		return errors.Trace(err)
	}

	toUpdateArgs := map[interface{}]interface{}{}
	toUpdateArgs[expression.ExprEvalValuesFunc] = func(name string) (interface{}, error) {
		c, err1 := findColumnByName(t, name)
		if err1 != nil {
			return nil, errors.Trace(err1)
		}
		return row[c.Offset], nil
	}

	if err = updateRecord(ctx, h, data, t, cols, toUpdateArgs, 0, true); err != nil {
		return errors.Trace(err)
	}

	return nil
}

func getOnDuplicateUpdateColumns(assignList []expression.Assignment, t table.Table) (map[int]expression.Assignment, error) {
	m := make(map[int]expression.Assignment, len(assignList))

	for _, v := range assignList {
		c, err := findColumnByName(t, field.JoinQualifiedName("", v.TableName, v.ColName))
		if err != nil {
			return nil, errors.Trace(err)
		}
		m[c.Offset] = v
	}
	return m, nil
}

func (s *InsertIntoStmt) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error {
	var err error
	var defaultValueCols []*column.Col
	for i, c := range t.Cols() {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}

		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
			continue
		}

		if mysql.HasAutoIncrementFlag(c.Flag) {
			var id int64
			if id, err = t.AllocAutoID(); err != nil {
				return errors.Trace(err)
			}
			row[i] = id
			variable.GetSessionVars(ctx).SetLastInsertID(uint64(id))
		} else {
			var value interface{}
			value, _, err = getDefaultValue(ctx, c)
			if err != nil {
				return errors.Trace(err)
			}

			row[i] = value
		}

		defaultValueCols = append(defaultValueCols, c)
	}

	if err = column.CastValues(ctx, row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}

	return nil
}
<commit_msg>stmt: rename addRecord to getRow<commit_after>// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.

// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package stmts

import (
	"github.com/juju/errors"
	"github.com/pingcap/tidb/column"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/expression"
	"github.com/pingcap/tidb/field"
	"github.com/pingcap/tidb/kv"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/plan"
	"github.com/pingcap/tidb/rset"
	"github.com/pingcap/tidb/sessionctx/variable"
	"github.com/pingcap/tidb/stmt"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/util/errors2"
	"github.com/pingcap/tidb/util/format"
	"github.com/pingcap/tidb/util/types"
)

var _ stmt.Statement = (*InsertIntoStmt)(nil)

// Priority const values.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
const (
	NoPriority = iota
	LowPriority
	HighPriority
	DelayedPriority
)

// InsertIntoStmt is a statement to insert new rows into an existing table.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
type InsertIntoStmt struct {
	ColNames    []string
	Lists       [][]expression.Expression
	Sel         plan.Planner
	TableIdent  table.Ident
	Setlist     []*expression.Assignment
	Priority    int
	OnDuplicate []expression.Assignment

	Text string
}

// Explain implements the stmt.Statement Explain interface.
func (s *InsertIntoStmt) Explain(ctx context.Context, w format.Formatter) {
	w.Format("%s\n", s.Text)
}

// IsDDL implements the stmt.Statement IsDDL interface.
func (s *InsertIntoStmt) IsDDL() bool {
	return false
}

// OriginText implements the stmt.Statement OriginText interface.
func (s *InsertIntoStmt) OriginText() string {
	return s.Text
}

// SetText implements the stmt.Statement SetText interface.
func (s *InsertIntoStmt) SetText(text string) {
	s.Text = text
}

// execExecSelect implements `insert table select ... from ...`.
func (s *InsertIntoStmt) execSelect(t table.Table, cols []*column.Col, ctx context.Context) (_ rset.Recordset, err error) {
	r, err := s.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}
	defer r.Close()
	if len(r.GetFields()) != len(cols) {
		return nil, errors.Errorf("Column count %d doesn't match value count %d", len(cols), len(r.GetFields()))
	}

	var bufRecords [][]interface{}
	var lastInsertIds []uint64
	for {
		var row *plan.Row
		row, err = r.Next(ctx)
		if err != nil {
			return nil, errors.Trace(err)
		}
		if row == nil {
			break
		}
		data0 := make([]interface{}, len(t.Cols()))
		marked := make(map[int]struct{}, len(cols))
		for i, d := range row.Data {
			data0[cols[i].Offset] = d
			marked[cols[i].Offset] = struct{}{}
		}

		if err = s.initDefaultValues(ctx, t, data0, marked); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CastValues(ctx, data0, cols); err != nil {
			return nil, errors.Trace(err)
		}

		if err = column.CheckNotNull(t.Cols(), data0); err != nil {
			return nil, errors.Trace(err)
		}
		var v interface{}
		v, err = types.Clone(data0)
		if err != nil {
			return nil, errors.Trace(err)
		}

		bufRecords = append(bufRecords, v.([]interface{}))
		lastInsertIds = append(lastInsertIds, variable.GetSessionVars(ctx).LastInsertID)
	}

	for i, r := range bufRecords {
		variable.GetSessionVars(ctx).SetLastInsertID(lastInsertIds[i])
		if _, err = t.AddRecord(ctx, r); err != nil {
			return nil, errors.Trace(err)
		}
	}
	return nil, nil
}

// There are three types of insert statements:
// 1 insert ... values(...)  --> name type column
// 2 insert ... set x=y...   --> set type column
// 3 insert ... (select ..)  --> name type column
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
func (s *InsertIntoStmt) getColumns(tableCols []*column.Col) ([]*column.Col, error) {
	var cols []*column.Col
	var err error

	if len(s.Setlist) > 0 {
		// Process `set` type column.
		columns := make([]string, 0, len(s.Setlist))
		for _, v := range s.Setlist {
			columns = append(columns, v.ColName)
		}

		cols, err = column.FindCols(tableCols, columns)
		if err != nil {
			return nil, errors.Errorf("INSERT INTO %s: %s", s.TableIdent, err)
		}

		if len(cols) == 0 {
			return nil, errors.Errorf("INSERT INTO %s: empty column", s.TableIdent)
		}
	} else {
		// Process `name` type column.
		cols, err = column.FindCols(tableCols, s.ColNames)
		if err != nil {
			return nil, errors.Errorf("INSERT INTO %s: %s", s.TableIdent, err)
		}

		// If cols are empty, use all columns instead.
		if len(cols) == 0 {
			cols = tableCols
		}
	}

	// Check column whether is specified only once.
	err = column.CheckOnce(cols)
	if err != nil {
		return nil, errors.Trace(err)
	}

	return cols, nil
}

func (s *InsertIntoStmt) getDefaultValues(ctx context.Context, cols []*column.Col) (map[interface{}]interface{}, error) {
	m := map[interface{}]interface{}{}
	for _, v := range cols {
		if value, ok, err := getDefaultValue(ctx, v); ok {
			if err != nil {
				return nil, errors.Trace(err)
			}

			m[v.Name.L] = value
		}
	}

	return m, nil
}

func (s *InsertIntoStmt) getSetList() error {
	if len(s.Setlist) > 0 {
		if len(s.Lists) > 0 {
			return errors.Errorf("INSERT INTO %s: set type should not use values", s.TableIdent)
		}

		var l []expression.Expression
		for _, v := range s.Setlist {
			l = append(l, v.Expr)
		}
		s.Lists = append(s.Lists, l)
	}

	return nil
}

// Exec implements the stmt.Statement Exec interface.
func (s *InsertIntoStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
	t, err := getTable(ctx, s.TableIdent)
	if err != nil {
		return nil, errors.Trace(err)
	}
	cols, err := s.getColumns(t.Cols())
	if err != nil {
		return nil, errors.Trace(err)
	}

	// Process `insert ... (select ..) `
	if s.Sel != nil {
		return s.execSelect(t, cols, ctx)
	}

	// Process `insert ... set x=y...`
	if err = s.getSetList(); err != nil {
		return nil, errors.Trace(err)
	}

	m, err := s.getDefaultValues(ctx, t.Cols())
	if err != nil {
		return nil, errors.Trace(err)
	}
	insertValueCount := len(s.Lists[0])
	toUpdateColumns, err := getOnDuplicateUpdateColumns(s.OnDuplicate, t)
	if err != nil {
		return nil, errors.Trace(err)
	}

	for i, list := range s.Lists {
		if err = s.checkValueCount(insertValueCount, len(list), i, cols); err != nil {
			return nil, errors.Trace(err)
		}

		row, err := s.getRow(ctx, t, cols, list, m)
		if err != nil {
			return nil, errors.Trace(err)
		}

		// Notes: incompatible with mysql
		// MySQL will set last insert id to the first row, as follows:
		// `t(id int AUTO_INCREMENT, c1 int, PRIMARY KEY (id))`
		// `insert t (c1) values(1),(2),(3);`
		// Last insert id will be 1, not 3.
		h, err := t.AddRecord(ctx, row)
		if err == nil {
			continue
		}

		if len(s.OnDuplicate) == 0 || !errors2.ErrorEqual(err, kv.ErrKeyExists) {
			return nil, errors.Trace(err)
		}
		if err = execOnDuplicateUpdate(ctx, t, row, h, toUpdateColumns); err != nil {
			return nil, errors.Trace(err)
		}
	}

	return nil, nil
}

func (s *InsertIntoStmt) checkValueCount(insertValueCount, valueCount, num int, cols []*column.Col) error {
	if insertValueCount != valueCount {
		// "insert into t values (), ()" is valid.
		// "insert into t values (), (1)" is not valid.
		// "insert into t values (1), ()" is not valid.
		// "insert into t values (1,2), (1)" is not valid.
		// So the value count must be same for all insert list.
		return errors.Errorf("Column count doesn't match value count at row %d", num+1)
	}
	if valueCount == 0 && len(s.ColNames) > 0 {
		// "insert into t (c1) values ()" is not valid.
		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", s.TableIdent, len(s.ColNames), 0)
	} else if valueCount > 0 && valueCount != len(cols) {
		return errors.Errorf("INSERT INTO %s: expected %d value(s), have %d", s.TableIdent, len(cols), valueCount)
	}

	return nil
}

func (s *InsertIntoStmt) getRow(ctx context.Context, t table.Table, cols []*column.Col, list []expression.Expression, m map[interface{}]interface{}) ([]interface{}, error) {
	r := make([]interface{}, len(t.Cols()))
	marked := make(map[int]struct{}, len(list))
	for i, expr := range list {
		// For "insert into t values (default)" Default Eval.
		m[expression.ExprEvalDefaultName] = cols[i].Name.O

		val, evalErr := expr.Eval(ctx, m)
		if evalErr != nil {
			return nil, errors.Trace(evalErr)
		}
		r[cols[i].Offset] = val
		marked[cols[i].Offset] = struct{}{}
	}

	// Clear last insert id.
	variable.GetSessionVars(ctx).SetLastInsertID(0)

	err := s.initDefaultValues(ctx, t, r, marked)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CastValues(ctx, r, cols); err != nil {
		return nil, errors.Trace(err)
	}
	if err = column.CheckNotNull(t.Cols(), r); err != nil {
		return nil, errors.Trace(err)
	}

	return r, err
}

func execOnDuplicateUpdate(ctx context.Context, t table.Table, row []interface{}, h int64, cols map[int]expression.Assignment) error {
	// On duplicate key update the duplicate row.
	// Evaluate the updated value.
	// TODO: report rows affected and last insert id.
	data, err := t.Row(ctx, h)
	if err != nil {
		return errors.Trace(err)
	}

	toUpdateArgs := map[interface{}]interface{}{}
	toUpdateArgs[expression.ExprEvalValuesFunc] = func(name string) (interface{}, error) {
		c, err1 := findColumnByName(t, name)
		if err1 != nil {
			return nil, errors.Trace(err1)
		}
		return row[c.Offset], nil
	}

	if err = updateRecord(ctx, h, data, t, cols, toUpdateArgs, 0, true); err != nil {
		return errors.Trace(err)
	}

	return nil
}

func getOnDuplicateUpdateColumns(assignList []expression.Assignment, t table.Table) (map[int]expression.Assignment, error) {
	m := make(map[int]expression.Assignment, len(assignList))

	for _, v := range assignList {
		c, err := findColumnByName(t, field.JoinQualifiedName("", v.TableName, v.ColName))
		if err != nil {
			return nil, errors.Trace(err)
		}
		m[c.Offset] = v
	}
	return m, nil
}

func (s *InsertIntoStmt) initDefaultValues(ctx context.Context, t table.Table, row []interface{}, marked map[int]struct{}) error {
	var err error
	var defaultValueCols []*column.Col
	for i, c := range t.Cols() {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}

		// If the nil value is evaluated in insert list, we will use nil except auto increment column.
		if _, ok := marked[i]; ok && !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
			continue
		}

		if mysql.HasAutoIncrementFlag(c.Flag) {
			var id int64
			if id, err = t.AllocAutoID(); err != nil {
				return errors.Trace(err)
			}
			row[i] = id
			variable.GetSessionVars(ctx).SetLastInsertID(uint64(id))
		} else {
			var value interface{}
			value, _, err = getDefaultValue(ctx, c)
			if err != nil {
				return errors.Trace(err)
			}

			row[i] = value
		}

		defaultValueCols = append(defaultValueCols, c)
	}

	if err = column.CastValues(ctx, row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}

	return nil
}
<|endoftext|>


<commit_before>package registration

import (
	"github.com/PaluMacil/dwn/database/store"
	"github.com/PaluMacil/dwn/module/core"
	"time"
)

type UserCreationRequest struct {
	Email                      string `json:"email"`
	Password                   string `json:"password"`
	WithVerifiedEmail          bool   `json:"withVerifiedEmail"`
	IgnorePasswordRequirements bool   `json:"ignorePasswordRequirements"`
	MustChangePWNextLogin      bool   `json:"mustChangePWNextLogin"`
	GivenName                  string `json:"givenName"`
	FamilyName                 string `json:"familyName"`
}

// Validate examines a request object for creation of a new user and returns a slice
// of validation errors or an empty slice if the request is valid
func (req UserCreationRequest) Validate() []string {
	validationErrors := make([]string, 0)
	//TODO: check for restricted fields, bad pw choice, cetc
	return validationErrors
}

func (req UserCreationRequest) User(id store.Identity) (core.User, error) {
	passwordHash, err := core.CreateHash(req.Password)
	if err != nil {
		return core.User{}, err
	}
	// TODO: send verification email
	user := core.User{
		ID:           id,
		PrimaryEmail: req.Email,
		Emails: []core.Email{
			{
				Email:    req.Email,
				Verified: false,
				// TODO: verified code and date
				// VerificationCode: uuid.Must(uuid.NewV4()).String(),
			},
		},
		//TODO: tag, displayName
		PasswordHash: passwordHash,
		GivenName:    req.GivenName,
		FamilyName:   req.FamilyName,
		ModifiedDate: time.Now(),
		CreatedDate:  time.Now(),
	}

	return user, nil
}
<commit_msg>for now, set displayname to actual name<commit_after>package registration

import (
	"fmt"
	"github.com/PaluMacil/dwn/database/store"
	"github.com/PaluMacil/dwn/module/core"
	"time"
)

type UserCreationRequest struct {
	Email                      string `json:"email"`
	Password                   string `json:"password"`
	WithVerifiedEmail          bool   `json:"withVerifiedEmail"`
	IgnorePasswordRequirements bool   `json:"ignorePasswordRequirements"`
	MustChangePWNextLogin      bool   `json:"mustChangePWNextLogin"`
	GivenName                  string `json:"givenName"`
	FamilyName                 string `json:"familyName"`
}

// Validate examines a request object for creation of a new user and returns a slice
// of validation errors or an empty slice if the request is valid
func (req UserCreationRequest) Validate() []string {
	validationErrors := make([]string, 0)
	//TODO: check for restricted fields, bad pw choice, cetc
	return validationErrors
}

func (req UserCreationRequest) User(id store.Identity) (core.User, error) {
	displayName := core.DisplayName(fmt.Sprintf("%s %s", req.GivenName, req.FamilyName))
	passwordHash, err := core.CreateHash(req.Password)
	if err != nil {
		return core.User{}, err
	}
	// TODO: send verification email
	user := core.User{
		ID:           id,
		PrimaryEmail: req.Email,
		Emails: []core.Email{
			{
				Email:    req.Email,
				Verified: false,
				// TODO: verified code and date
				// VerificationCode: uuid.Must(uuid.NewV4()).String(),
			},
		},
		//TODO: tag
		DisplayName:  displayName,
		PasswordHash: passwordHash,
		GivenName:    req.GivenName,
		FamilyName:   req.FamilyName,
		ModifiedDate: time.Now(),
		CreatedDate:  time.Now(),
	}

	return user, nil
}
<|endoftext|>