<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package models

import (
	"encoding/json"
	"errors"
	"log"
	"os"
	"strings"

	h "github.com/ernestio/api-gateway/helpers"
	aes "github.com/ernestio/crypto/aes"
	"github.com/sirupsen/logrus"
)

// Project holds the project response from datacenter-store
type Project struct {
	ID           int                    `json:"id"`
	Name         string                 `json:"name"`
	Type         string                 `json:"type"`
	Credentials  map[string]interface{} `json:"credentials,omitempty"`
	Environments []string               `json:"environments,omitempty"`
	Roles        []string               `json:"roles,omitempty"`
}

// Validate the project
func (d *Project) Validate() error {
	if d.Name == "" {
		return errors.New("Project name is empty")
	}

	if strings.Contains(d.Name, EnvNameSeparator) {
		return errors.New("Project name does not support char '" + EnvNameSeparator + "' as part of its name")
	}

	if d.Type == "" {
		return errors.New("Project type is empty")
	}

	return nil
}

// Map : maps a project from a request's body and validates the input
func (d *Project) Map(data []byte) error {
	if err := json.Unmarshal(data, &d); err != nil {
		h.L.WithFields(logrus.Fields{
			"input": string(data),
		}).Error("Couldn't unmarshal given input")
		return NewError(InvalidInputCode, "Invalid input")
	}

	return nil
}

// FindByName : Searches for all projects with a name equal to the specified
func (d *Project) FindByName(name string, project *Project) (err error) {
	query := make(map[string]interface{})
	query["name"] = name
	if err := NewBaseModel(d.getStore()).GetBy(query, project); err != nil {
		return err
	}
	return nil
}

// FindByID : Gets a model by its id
func (d *Project) FindByID(id int) (err error) {
	query := make(map[string]interface{})
	query["id"] = id
	if err := NewBaseModel(d.getStore()).GetBy(query, d); err != nil {
		return err
	}
	return nil
}

// FindByIDs : Gets a model by its id
func (d *Project) FindByIDs(ids []string, ds *[]Project) (err error) {
	query := make(map[string]interface{})
	query["names"] = ids
	if err := NewBaseModel(d.getStore()).FindBy(query, ds); err != nil {
		return err
	}
	return nil
}

// FindAll : Searches for all entities on the store current user
// has access to
func (d *Project) FindAll(au User, projects *[]Project) (err error) {
	query := make(map[string]interface{})
	if err := NewBaseModel(d.getStore()).FindBy(query, projects); err != nil {
		return err
	}
	return nil
}

// Save : calls datacenter.set with the marshalled current entity
func (d *Project) Save() (err error) {
	if err := NewBaseModel(d.getStore()).Save(d); err != nil {
		return err
	}

	return nil
}

// Delete : will delete a project by its id
func (d *Project) Delete() (err error) {
	query := make(map[string]interface{})
	query["id"] = d.ID
	if err := NewBaseModel(d.getStore()).Delete(query); err != nil {
		return err
	}
	return nil
}

// Redact : removes all sensitive fields from the return
// data before outputting to the user
func (d *Project) Redact() {
	for k, v := range d.Credentials {
		if k == "region" || k == "external_network" || k == "username" {
			sv, ok := v.(string)
			if !ok {
				log.Println("could not assert credential value")
				delete(d.Credentials, k)
				continue
			}

			dv, err := decrypt(sv)
			if err != nil {
				log.Println("could not decrypt credentials value")
				delete(d.Credentials, k)
				continue
			}

			d.Credentials[k] = dv
		} else {
			delete(d.Credentials, k)
		}
	}
}

// Improve : adds extra data to this entity
func (d *Project) Improve() {
}

// Envs : Get the envs related with current project
func (d *Project) Envs() (envs []Env, err error) {
	var s Env
	err = s.FindByProjectID(d.ID, &envs)
	return
}

// GetID : ID getter
func (d *Project) GetID() string {
	return d.Name
}

// GetType : Gets the resource type
func (d *Project) GetType() string {
	return "project"
}

// Override : override not empty parameters with the given project ones
func (d *Project) Override(dt Project) {
	for k, v := range dt.Credentials {
		d.Credentials[k] = v
	}
}

// Encrypt : encrypts sensible data
func (d *Project) Encrypt() {
	for k, v := range d.Credentials {
		xc, ok := v.(string)
		if !ok {
			continue
		}

		d.Credentials[k], _ = crypt(xc)
	}
}

func decrypt(s string) (string, error) {
	crypto := aes.New()
	key := os.Getenv("ERNEST_CRYPTO_KEY")
	if s != "" {
		encrypted, err := crypto.Decrypt(s, key)
		if err != nil {
			return "", err
		}
		s = encrypted
	}

	return s, nil
}

func crypt(s string) (string, error) {
	crypto := aes.New()
	key := os.Getenv("ERNEST_CRYPTO_KEY")
	if s != "" {
		encrypted, err := crypto.Encrypt(s, key)
		if err != nil {
			return "", err
		}
		s = encrypted
	}

	return s, nil
}

func (d *Project) getStore() string {
	return "datacenter"
}
<commit_msg>not redacting vcloud url<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package models

import (
	"encoding/json"
	"errors"
	"log"
	"os"
	"strings"

	h "github.com/ernestio/api-gateway/helpers"
	aes "github.com/ernestio/crypto/aes"
	"github.com/sirupsen/logrus"
)

// Project holds the project response from datacenter-store
type Project struct {
	ID           int                    `json:"id"`
	Name         string                 `json:"name"`
	Type         string                 `json:"type"`
	Credentials  map[string]interface{} `json:"credentials,omitempty"`
	Environments []string               `json:"environments,omitempty"`
	Roles        []string               `json:"roles,omitempty"`
}

// Validate the project
func (d *Project) Validate() error {
	if d.Name == "" {
		return errors.New("Project name is empty")
	}

	if strings.Contains(d.Name, EnvNameSeparator) {
		return errors.New("Project name does not support char '" + EnvNameSeparator + "' as part of its name")
	}

	if d.Type == "" {
		return errors.New("Project type is empty")
	}

	return nil
}

// Map : maps a project from a request's body and validates the input
func (d *Project) Map(data []byte) error {
	if err := json.Unmarshal(data, &d); err != nil {
		h.L.WithFields(logrus.Fields{
			"input": string(data),
		}).Error("Couldn't unmarshal given input")
		return NewError(InvalidInputCode, "Invalid input")
	}

	return nil
}

// FindByName : Searches for all projects with a name equal to the specified
func (d *Project) FindByName(name string, project *Project) (err error) {
	query := make(map[string]interface{})
	query["name"] = name
	if err := NewBaseModel(d.getStore()).GetBy(query, project); err != nil {
		return err
	}
	return nil
}

// FindByID : Gets a model by its id
func (d *Project) FindByID(id int) (err error) {
	query := make(map[string]interface{})
	query["id"] = id
	if err := NewBaseModel(d.getStore()).GetBy(query, d); err != nil {
		return err
	}
	return nil
}

// FindByIDs : Gets a model by its id
func (d *Project) FindByIDs(ids []string, ds *[]Project) (err error) {
	query := make(map[string]interface{})
	query["names"] = ids
	if err := NewBaseModel(d.getStore()).FindBy(query, ds); err != nil {
		return err
	}
	return nil
}

// FindAll : Searches for all entities on the store current user
// has access to
func (d *Project) FindAll(au User, projects *[]Project) (err error) {
	query := make(map[string]interface{})
	if err := NewBaseModel(d.getStore()).FindBy(query, projects); err != nil {
		return err
	}
	return nil
}

// Save : calls datacenter.set with the marshalled current entity
func (d *Project) Save() (err error) {
	if err := NewBaseModel(d.getStore()).Save(d); err != nil {
		return err
	}

	return nil
}

// Delete : will delete a project by its id
func (d *Project) Delete() (err error) {
	query := make(map[string]interface{})
	query["id"] = d.ID
	if err := NewBaseModel(d.getStore()).Delete(query); err != nil {
		return err
	}
	return nil
}

// Redact : removes all sensitive fields from the return
// data before outputting to the user
func (d *Project) Redact() {
	for k, v := range d.Credentials {
		if k == "region" || k == "external_network" || k == "username" || k == "vcloud_url" {
			sv, ok := v.(string)
			if !ok {
				log.Println("could not assert credential value")
				delete(d.Credentials, k)
				continue
			}

			dv, err := decrypt(sv)
			if err != nil {
				log.Println("could not decrypt credentials value")
				delete(d.Credentials, k)
				continue
			}

			d.Credentials[k] = dv
		} else {
			delete(d.Credentials, k)
		}
	}
}

// Improve : adds extra data to this entity
func (d *Project) Improve() {
}

// Envs : Get the envs related with current project
func (d *Project) Envs() (envs []Env, err error) {
	var s Env
	err = s.FindByProjectID(d.ID, &envs)
	return
}

// GetID : ID getter
func (d *Project) GetID() string {
	return d.Name
}

// GetType : Gets the resource type
func (d *Project) GetType() string {
	return "project"
}

// Override : override not empty parameters with the given project ones
func (d *Project) Override(dt Project) {
	for k, v := range dt.Credentials {
		d.Credentials[k] = v
	}
}

// Encrypt : encrypts sensible data
func (d *Project) Encrypt() {
	for k, v := range d.Credentials {
		xc, ok := v.(string)
		if !ok {
			continue
		}

		d.Credentials[k], _ = crypt(xc)
	}
}

func decrypt(s string) (string, error) {
	crypto := aes.New()
	key := os.Getenv("ERNEST_CRYPTO_KEY")
	if s != "" {
		encrypted, err := crypto.Decrypt(s, key)
		if err != nil {
			return "", err
		}
		s = encrypted
	}

	return s, nil
}

func crypt(s string) (string, error) {
	crypto := aes.New()
	key := os.Getenv("ERNEST_CRYPTO_KEY")
	if s != "" {
		encrypted, err := crypto.Encrypt(s, key)
		if err != nil {
			return "", err
		}
		s = encrypted
	}

	return s, nil
}

func (d *Project) getStore() string {
	return "datacenter"
}
<|endoftext|>


<commit_before>// Copyright ©2012 Dan Kortschak <dan.kortschak@adelaide.edu.au>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package kdtree

import (
	"flag"
	"fmt"
	check "launchpad.net/gocheck"
	"math/rand"
	"os"
	"strings"
	"testing"
	"unsafe"
)

var (
	genDot   = flag.Bool("dot", false, "Generate dot code for failing trees.")
	dotLimit = flag.Int("dotmax", 100, "Maximum size for tree output for dot format.")
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct{}

var _ = check.Suite(&S{})

var (
	// Using example from WP article.
	wpData  = Points{{2, 3}, {5, 4}, {9, 6}, {4, 7}, {8, 1}, {7, 2}}
	wpBound = &Bounding{Point{2, 1}, Point{9, 7}}
	bData   = func(i int) Points {
		p := make(Points, i)
		for i := range p {
			p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
		}
		return p
	}(1e2)
	bTree = New(bData, true)
)

func (s *S) TestNew(c *check.C) {
	var t *Tree
	NewTreePanics := func() (panicked bool) {
		defer func() {
			if r := recover(); r != nil {
				panicked = true
			}
		}()
		t = New(wpData, true)
		return
	}
	c.Check(NewTreePanics(), check.Equals, false)
	c.Check(t.Root.isKDTree(), check.Equals, true)
	for _, p := range wpData {
		c.Check(t.Contains(p), check.Equals, true)
	}
	c.Check(t.Root.Bounding, check.DeepEquals, wpBound)
	if c.Failed() && *genDot && t.Len() <= *dotLimit {
		err := dotFile(t, "TestNew", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

func (s *S) TestInsert(c *check.C) {
	t := New(wpData, true)
	t.Insert(Point{0, 0}, true)
	t.Insert(Point{10, 10}, true)
	c.Check(t.Root.isKDTree(), check.Equals, true)
	c.Check(t.Root.Bounding, check.DeepEquals, &Bounding{Point{0, 0}, Point{10, 10}})
	if c.Failed() && *genDot && t.Len() <= *dotLimit {
		err := dotFile(t, "TestInsert", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

type compFn func(float64) bool

func left(v float64) bool  { return v <= 0 }
func right(v float64) bool { return !left(v) }

func (n *Node) isKDTree() bool {
	if n == nil {
		return true
	}
	if !n.Left.isPartitioned(n.Point, left, n.Plane) {
		return false
	}
	if !n.Right.isPartitioned(n.Point, right, n.Plane) {
		return false
	}
	return n.Left.isKDTree() && n.Right.isKDTree()
}

func (n *Node) isPartitioned(pivot Comparable, fn compFn, plane Dim) bool {
	if n == nil {
		return true
	}
	if n.Left != nil && fn(pivot.Compare(n.Left.Point, plane)) {
		return false
	}
	if n.Right != nil && fn(pivot.Compare(n.Right.Point, plane)) {
		return false
	}
	return n.Left.isPartitioned(pivot, fn, plane) && n.Right.isPartitioned(pivot, fn, plane)
}

func nearest(q Point, p Points) (Point, float64) {
	min := q.Distance(p[0])
	var r int
	for i := 1; i < p.Len(); i++ {
		d := q.Distance(p[i])
		if d < min {
			min = d
			r = i
		}
	}
	return p[r], min
}

func (s *S) TestNearest(c *check.C) {
	t := New(wpData, false)
	for i, q := range append([]Point{
		{4, 6},
		{7, 5},
		{8, 7},
		{6, -5},
		{1e5, 1e5},
		{1e5, -1e5},
		{-1e5, 1e5},
		{-1e5, -1e5},
		{1e5, 0},
		{0, -1e5},
		{0, 1e5},
		{-1e5, 0},
	}, wpData...) {
		p, d := t.Nearest(q)
		ep, ed := nearest(q, wpData)
		c.Check(p, check.DeepEquals, ep, check.Commentf("Test %d: query %.3f expects %.3f", i, q, ep))
		c.Check(d, check.Equals, ed)
	}
}

func BenchmarkNew(b *testing.B) {
	b.StopTimer()
	p := make(Points, 1e5)
	for i := range p {
		p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		_ = New(p, false)
	}
}

func BenchmarkNewBounds(b *testing.B) {
	b.StopTimer()
	p := make(Points, 1e5)
	for i := range p {
		p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		_ = New(p, true)
	}
}

func BenchmarkInsert(b *testing.B) {
	t := &Tree{}
	for i := 0; i < b.N; i++ {
		t.Insert(Point{rand.Float64(), rand.Float64(), rand.Float64()}, false)
	}
}

func BenchmarkInsertBounds(b *testing.B) {
	t := &Tree{}
	for i := 0; i < b.N; i++ {
		t.Insert(Point{rand.Float64(), rand.Float64(), rand.Float64()}, true)
	}
}

func (s *S) TestBenches(c *check.C) {
	c.Check(bTree.Root.isKDTree(), check.Equals, true)
	for i := 0; i < 1e3; i++ {
		q := Point{rand.Float64(), rand.Float64(), rand.Float64()}
		p, d := bTree.Nearest(q)
		ep, ed := nearest(q, bData)
		c.Check(p, check.DeepEquals, ep, check.Commentf("Test %d: query %.3f expects %.3f", i, q, ep))
		c.Check(d, check.Equals, ed)
	}
	if c.Failed() && *genDot && bTree.Len() <= *dotLimit {
		err := dotFile(bTree, "TestBenches", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

func BenchmarkNearest(b *testing.B) {
	var (
		r Comparable
		d float64
	)
	for i := 0; i < b.N; i++ {
		r, d = bTree.Nearest(Point{rand.Float64(), rand.Float64(), rand.Float64()})
	}
	_, _ = r, d
}

func BenchmarkNearBrute(b *testing.B) {
	var (
		r Comparable
		d float64
	)
	for i := 0; i < b.N; i++ {
		r, d = nearest(Point{rand.Float64(), rand.Float64(), rand.Float64()}, bData)
	}
	_, _ = r, d
}

func dot(t *Tree, label string) string {
	if t == nil {
		return ""
	}
	var (
		s      []string
		follow func(*Node)
	)
	follow = func(n *Node) {
		id := uintptr(unsafe.Pointer(n))
		c := fmt.Sprintf("%d[label = \"<Left> |<Elem> %s/%.3f\\n%.3f|<Right>\"];",
			id, n, n.Point.(Point)[n.Plane], *n.Bounding)
		if n.Left != nil {
			c += fmt.Sprintf("\n\t\tedge [arrowhead=normal]; \"%d\":Left -> \"%d\":Elem;",
				id, uintptr(unsafe.Pointer(n.Left)))
			follow(n.Left)
		}
		if n.Right != nil {
			c += fmt.Sprintf("\n\t\tedge [arrowhead=normal]; \"%d\":Right -> \"%d\":Elem;",
				id, uintptr(unsafe.Pointer(n.Right)))
			follow(n.Right)
		}
		s = append(s, c)
	}
	if t.Root != nil {
		follow(t.Root)
	}
	return fmt.Sprintf("digraph %s {\n\tnode [shape=record,height=0.1];\n\t%s\n}\n",
		label,
		strings.Join(s, "\n\t"),
	)
}

func dotFile(t *Tree, label, dotString string) (err error) {
	if t == nil && dotString == "" {
		return
	}
	f, err := os.Create(label + ".dot")
	if err != nil {
		return
	}
	defer f.Close()
	if dotString == "" {
		fmt.Fprintf(f, dot(t, label))
	} else {
		fmt.Fprintf(f, dotString)
	}
	return
}
<commit_msg>Ensure that Insert* benchmarks are comparable<commit_after>// Copyright ©2012 Dan Kortschak <dan.kortschak@adelaide.edu.au>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package kdtree

import (
	"flag"
	"fmt"
	check "launchpad.net/gocheck"
	"math/rand"
	"os"
	"strings"
	"testing"
	"unsafe"
)

var (
	genDot   = flag.Bool("dot", false, "Generate dot code for failing trees.")
	dotLimit = flag.Int("dotmax", 100, "Maximum size for tree output for dot format.")
)

func Test(t *testing.T) { check.TestingT(t) }

type S struct{}

var _ = check.Suite(&S{})

var (
	// Using example from WP article.
	wpData  = Points{{2, 3}, {5, 4}, {9, 6}, {4, 7}, {8, 1}, {7, 2}}
	wpBound = &Bounding{Point{2, 1}, Point{9, 7}}
	bData   = func(i int) Points {
		p := make(Points, i)
		for i := range p {
			p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
		}
		return p
	}(1e2)
	bTree = New(bData, true)
)

func (s *S) TestNew(c *check.C) {
	var t *Tree
	NewTreePanics := func() (panicked bool) {
		defer func() {
			if r := recover(); r != nil {
				panicked = true
			}
		}()
		t = New(wpData, true)
		return
	}
	c.Check(NewTreePanics(), check.Equals, false)
	c.Check(t.Root.isKDTree(), check.Equals, true)
	for _, p := range wpData {
		c.Check(t.Contains(p), check.Equals, true)
	}
	c.Check(t.Root.Bounding, check.DeepEquals, wpBound)
	if c.Failed() && *genDot && t.Len() <= *dotLimit {
		err := dotFile(t, "TestNew", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

func (s *S) TestInsert(c *check.C) {
	t := New(wpData, true)
	t.Insert(Point{0, 0}, true)
	t.Insert(Point{10, 10}, true)
	c.Check(t.Root.isKDTree(), check.Equals, true)
	c.Check(t.Root.Bounding, check.DeepEquals, &Bounding{Point{0, 0}, Point{10, 10}})
	if c.Failed() && *genDot && t.Len() <= *dotLimit {
		err := dotFile(t, "TestInsert", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

type compFn func(float64) bool

func left(v float64) bool  { return v <= 0 }
func right(v float64) bool { return !left(v) }

func (n *Node) isKDTree() bool {
	if n == nil {
		return true
	}
	if !n.Left.isPartitioned(n.Point, left, n.Plane) {
		return false
	}
	if !n.Right.isPartitioned(n.Point, right, n.Plane) {
		return false
	}
	return n.Left.isKDTree() && n.Right.isKDTree()
}

func (n *Node) isPartitioned(pivot Comparable, fn compFn, plane Dim) bool {
	if n == nil {
		return true
	}
	if n.Left != nil && fn(pivot.Compare(n.Left.Point, plane)) {
		return false
	}
	if n.Right != nil && fn(pivot.Compare(n.Right.Point, plane)) {
		return false
	}
	return n.Left.isPartitioned(pivot, fn, plane) && n.Right.isPartitioned(pivot, fn, plane)
}

func nearest(q Point, p Points) (Point, float64) {
	min := q.Distance(p[0])
	var r int
	for i := 1; i < p.Len(); i++ {
		d := q.Distance(p[i])
		if d < min {
			min = d
			r = i
		}
	}
	return p[r], min
}

func (s *S) TestNearest(c *check.C) {
	t := New(wpData, false)
	for i, q := range append([]Point{
		{4, 6},
		{7, 5},
		{8, 7},
		{6, -5},
		{1e5, 1e5},
		{1e5, -1e5},
		{-1e5, 1e5},
		{-1e5, -1e5},
		{1e5, 0},
		{0, -1e5},
		{0, 1e5},
		{-1e5, 0},
	}, wpData...) {
		p, d := t.Nearest(q)
		ep, ed := nearest(q, wpData)
		c.Check(p, check.DeepEquals, ep, check.Commentf("Test %d: query %.3f expects %.3f", i, q, ep))
		c.Check(d, check.Equals, ed)
	}
}

func BenchmarkNew(b *testing.B) {
	b.StopTimer()
	p := make(Points, 1e5)
	for i := range p {
		p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		_ = New(p, false)
	}
}

func BenchmarkNewBounds(b *testing.B) {
	b.StopTimer()
	p := make(Points, 1e5)
	for i := range p {
		p[i] = Point{rand.Float64(), rand.Float64(), rand.Float64()}
	}
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		_ = New(p, true)
	}
}

func BenchmarkInsert(b *testing.B) {
	rand.Seed(1)
	t := &Tree{}
	for i := 0; i < b.N; i++ {
		t.Insert(Point{rand.Float64(), rand.Float64(), rand.Float64()}, false)
	}
}

func BenchmarkInsertBounds(b *testing.B) {
	rand.Seed(1)
	t := &Tree{}
	for i := 0; i < b.N; i++ {
		t.Insert(Point{rand.Float64(), rand.Float64(), rand.Float64()}, true)
	}
}

func (s *S) TestBenches(c *check.C) {
	c.Check(bTree.Root.isKDTree(), check.Equals, true)
	for i := 0; i < 1e3; i++ {
		q := Point{rand.Float64(), rand.Float64(), rand.Float64()}
		p, d := bTree.Nearest(q)
		ep, ed := nearest(q, bData)
		c.Check(p, check.DeepEquals, ep, check.Commentf("Test %d: query %.3f expects %.3f", i, q, ep))
		c.Check(d, check.Equals, ed)
	}
	if c.Failed() && *genDot && bTree.Len() <= *dotLimit {
		err := dotFile(bTree, "TestBenches", "")
		if err != nil {
			c.Errorf("Dot file write failed: %v", err)
		}
	}
}

func BenchmarkNearest(b *testing.B) {
	var (
		r Comparable
		d float64
	)
	for i := 0; i < b.N; i++ {
		r, d = bTree.Nearest(Point{rand.Float64(), rand.Float64(), rand.Float64()})
	}
	_, _ = r, d
}

func BenchmarkNearBrute(b *testing.B) {
	var (
		r Comparable
		d float64
	)
	for i := 0; i < b.N; i++ {
		r, d = nearest(Point{rand.Float64(), rand.Float64(), rand.Float64()}, bData)
	}
	_, _ = r, d
}

func dot(t *Tree, label string) string {
	if t == nil {
		return ""
	}
	var (
		s      []string
		follow func(*Node)
	)
	follow = func(n *Node) {
		id := uintptr(unsafe.Pointer(n))
		c := fmt.Sprintf("%d[label = \"<Left> |<Elem> %s/%.3f\\n%.3f|<Right>\"];",
			id, n, n.Point.(Point)[n.Plane], *n.Bounding)
		if n.Left != nil {
			c += fmt.Sprintf("\n\t\tedge [arrowhead=normal]; \"%d\":Left -> \"%d\":Elem;",
				id, uintptr(unsafe.Pointer(n.Left)))
			follow(n.Left)
		}
		if n.Right != nil {
			c += fmt.Sprintf("\n\t\tedge [arrowhead=normal]; \"%d\":Right -> \"%d\":Elem;",
				id, uintptr(unsafe.Pointer(n.Right)))
			follow(n.Right)
		}
		s = append(s, c)
	}
	if t.Root != nil {
		follow(t.Root)
	}
	return fmt.Sprintf("digraph %s {\n\tnode [shape=record,height=0.1];\n\t%s\n}\n",
		label,
		strings.Join(s, "\n\t"),
	)
}

func dotFile(t *Tree, label, dotString string) (err error) {
	if t == nil && dotString == "" {
		return
	}
	f, err := os.Create(label + ".dot")
	if err != nil {
		return
	}
	defer f.Close()
	if dotString == "" {
		fmt.Fprintf(f, dot(t, label))
	} else {
		fmt.Fprintf(f, dotString)
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// Package weapp 小程序的相关操作
package weapp

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/issue9/wechat/mp/common/result"
)

const (
	grantType = "authorization_code"

	loginURL = "https://api.weixin.qq.com/sns/jscode2session"
)

// Response 返回的数据
type Response struct {
	Openid     string `json:"openid"`
	SessionKey string `json:"session_key"`
	ExpiresIn  int    `json:"expires_in"`
}

// Authorization 执行登录验证，并获取相应的数据
func Authorization(appid, secret, jscode string) (*Response, error) {
	vals := url.Values{}
	vals.Set("grant_type", grantType)
	vals.Set("appid", appid)
	vals.Set("secret", secret)
	vals.Set("js_code", jscode)

	url := loginURL + "?" + vals.Encode()

	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	bs, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	data := &Response{}
	if err := json.Unmarshal(bs, data); err != nil {
		return nil, err
	}

	if data.Openid != "" { // 正常数据，肯定有 openid
		return data, nil
	}

	rslt := &result.Result{}
	if err := json.Unmarshal(bs, rslt); err != nil {
		return nil, err
	}
	return nil, rslt
}
<commit_msg>修正字段错误<commit_after>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

// Package weapp 小程序的相关操作
package weapp

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/issue9/wechat/mp/common/result"
)

const (
	grantType = "authorization_code"

	loginURL = "https://api.weixin.qq.com/sns/jscode2session"
)

// Response 返回的数据
type Response struct {
	Openid     string `json:"openid"`
	SessionKey string `json:"session_key"`
	UnionID    string `json:"unionid,omitempty"` // 某些情况下存在
}

// Authorization 执行登录验证，并获取相应的数据
func Authorization(appid, secret, jscode string) (*Response, error) {
	vals := url.Values{}
	vals.Set("grant_type", grantType)
	vals.Set("appid", appid)
	vals.Set("secret", secret)
	vals.Set("js_code", jscode)

	url := loginURL + "?" + vals.Encode()

	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	bs, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()

	data := &Response{}
	if err := json.Unmarshal(bs, data); err != nil {
		return nil, err
	}

	if data.Openid != "" { // 正常数据，肯定有 openid
		return data, nil
	}

	rslt := &result.Result{}
	if err := json.Unmarshal(bs, rslt); err != nil {
		return nil, err
	}
	return nil, rslt
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/julienschmidt/httprouter"

	"io/ioutil"
)

type NoteController struct {
	dbConnection *DBConnection
	config       *Config
}

func (nController *NoteController) index(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	index, err := ioutil.ReadFile("./web/index.html")

	panic(err)

	if err != nil {
		panic(err)
		return
	}

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	fmt.Fprintf(w, string(index))
}

func (nController *NoteController) ShowFavIcon(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	http.ServeFile(w, r, "./web/favicon.png")
}

func (nController *NoteController) saveUserNote(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userID := r.FormValue("user_id")
	noteID := r.FormValue("note_id")
	title := r.FormValue("title")
	body := r.FormValue("body")

	config := nController.config

	userEmail := ""
	userQuery := "SELECT email FROM users WHERE id=$1"
	e := nController.dbConnection.db.QueryRow(userQuery, userID).Scan(&userEmail)

	if e != nil {
	}

	query := ""

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if noteID == "" {
		sha1Hash := sha1.New()
		sha1Hash.Write([]byte(time.Now().String() + title + body + userID))
		sha1HashString := sha1Hash.Sum(nil)

		noteID = fmt.Sprintf("%x", sha1HashString)

		query = "INSERT INTO notes(id, user_id, title, body, date_created) VALUES($1, $2, $3, $4, datetime('now'))"
		_, err := nController.dbConnection.db.Exec(query, noteID, userID, title, body)

		if err == nil {
			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
			w.WriteHeader(http.StatusOK)

			if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0", "note_id": noteID}); err != nil {
				panic(err)
			}

			if userEmail != "" {
				notifier := &Notifier{
					config:    config,
					userMail:  userEmail,
					noteTitle: title,
					noteBody:  body,
				}
				notifier.sendNotification("create")
			}

			return
		}

		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusNotFound)
		if err := json.NewEncoder(w).Encode(err); err != nil {
			panic(err)
		}
	} else {
		query = "UPDATE notes SET title=$1, body=$2 WHERE id=$3"
		_, err := nController.dbConnection.db.Exec(query, title, body, noteID)

		if err == nil {
			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
			w.WriteHeader(http.StatusOK)

			if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0", "note_id": noteID}); err != nil {
				panic(err)
			}

			if userEmail != "" {
				notifier := &Notifier{
					config:    config,
					userMail:  userEmail,
					noteTitle: title,
				}
				notifier.sendNotification("edit")
			}

			return
		}

		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusNotFound)
		if err := json.NewEncoder(w).Encode(err); err != nil {
			panic(err)
		}
	}

}

func (nController *NoteController) deleteUserNote(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	noteID := r.FormValue("note_id")

	noteTitle := ""
	noteBody := ""
	dateCreated := ""

	userEmail := ""

	noteQuery := "SELECT n.title, n.body, n.date_created, u.email FROM notes n INNER JOIN users u ON n.id=$1 AND n.user_id=u.id"
	_ = nController.dbConnection.db.QueryRow(noteQuery, noteID).Scan(&noteTitle, &noteBody, &dateCreated, &userEmail)

	config := nController.config

	query := "DELETE FROM notes WHERE id=$1"

	_, err := nController.dbConnection.db.Exec(query, noteID)

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusOK)

		if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0"}); err != nil {
			panic(err)
		}

		if userEmail != "" {
			notifier := &Notifier{
				config:      config,
				userMail:    userEmail,
				noteTitle:   noteTitle,
				noteBody:    noteBody,
				dateCreated: dateCreated,
			}
			notifier.sendNotification("delete")
		}

		return
	}

	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	if err := json.NewEncoder(w).Encode(err); err != nil {
		panic(err)
	}
}

func (nController *NoteController) listAllUserNotes(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userID := r.FormValue("user_id")

	query := "SELECT id, title, body, date_created FROM notes WHERE user_id=$1 ORDER BY date_created DESC"

	rows, err := nController.dbConnection.db.Query(query, userID)

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusOK)

		notes := make([]*NoteModel, 0)

		for rows.Next() {

			newNote := new(NoteModel)

			_ = rows.Scan(
				&newNote.Id,
				&newNote.Title,
				&newNote.Body,
				&newNote.Date)

			notes = append(notes, newNote)

		}

		if err := json.NewEncoder(w).Encode(notes); err != nil {
			panic(err)
		}
		return
	}

	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	if err := json.NewEncoder(w).Encode(err); err != nil {
		panic(err)
	}

}
<commit_msg>Update<commit_after>package main

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/julienschmidt/httprouter"

	"io/ioutil"
)

type NoteController struct {
	dbConnection *DBConnection
	config       *Config
}

func (nController *NoteController) index(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	index, err := ioutil.ReadFile("./web/index.html")

	//panic(err)

	if err != nil {
		panic(err)
		return
	}

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	fmt.Fprintf(w, string(index))
}

func (nController *NoteController) ShowFavIcon(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
	w.Header().Set("Content-Type", "image/png")

	http.ServeFile(w, r, "./web/favicon.png")
}

func (nController *NoteController) saveUserNote(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userID := r.FormValue("user_id")
	noteID := r.FormValue("note_id")
	title := r.FormValue("title")
	body := r.FormValue("body")

	config := nController.config

	userEmail := ""
	userQuery := "SELECT email FROM users WHERE id=$1"
	e := nController.dbConnection.db.QueryRow(userQuery, userID).Scan(&userEmail)

	if e != nil {
	}

	query := ""

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if noteID == "" {
		sha1Hash := sha1.New()
		sha1Hash.Write([]byte(time.Now().String() + title + body + userID))
		sha1HashString := sha1Hash.Sum(nil)

		noteID = fmt.Sprintf("%x", sha1HashString)

		query = "INSERT INTO notes(id, user_id, title, body, date_created) VALUES($1, $2, $3, $4, datetime('now'))"
		_, err := nController.dbConnection.db.Exec(query, noteID, userID, title, body)

		if err == nil {
			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
			w.WriteHeader(http.StatusOK)

			if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0", "note_id": noteID}); err != nil {
				panic(err)
			}

			if userEmail != "" {
				notifier := &Notifier{
					config:    config,
					userMail:  userEmail,
					noteTitle: title,
					noteBody:  body,
				}
				notifier.sendNotification("create")
			}

			return
		}

		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusNotFound)
		if err := json.NewEncoder(w).Encode(err); err != nil {
			panic(err)
		}
	} else {
		query = "UPDATE notes SET title=$1, body=$2 WHERE id=$3"
		_, err := nController.dbConnection.db.Exec(query, title, body, noteID)

		if err == nil {
			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
			w.WriteHeader(http.StatusOK)

			if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0", "note_id": noteID}); err != nil {
				panic(err)
			}

			if userEmail != "" {
				notifier := &Notifier{
					config:    config,
					userMail:  userEmail,
					noteTitle: title,
				}
				notifier.sendNotification("edit")
			}

			return
		}

		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusNotFound)
		if err := json.NewEncoder(w).Encode(err); err != nil {
			panic(err)
		}
	}

}

func (nController *NoteController) deleteUserNote(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	noteID := r.FormValue("note_id")

	noteTitle := ""
	noteBody := ""
	dateCreated := ""

	userEmail := ""

	noteQuery := "SELECT n.title, n.body, n.date_created, u.email FROM notes n INNER JOIN users u ON n.id=$1 AND n.user_id=u.id"
	_ = nController.dbConnection.db.QueryRow(noteQuery, noteID).Scan(&noteTitle, &noteBody, &dateCreated, &userEmail)

	config := nController.config

	query := "DELETE FROM notes WHERE id=$1"

	_, err := nController.dbConnection.db.Exec(query, noteID)

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusOK)

		if err := json.NewEncoder(w).Encode(map[string]string{"status": "success", "error_code": "0"}); err != nil {
			panic(err)
		}

		if userEmail != "" {
			notifier := &Notifier{
				config:      config,
				userMail:    userEmail,
				noteTitle:   noteTitle,
				noteBody:    noteBody,
				dateCreated: dateCreated,
			}
			notifier.sendNotification("delete")
		}

		return
	}

	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	if err := json.NewEncoder(w).Encode(err); err != nil {
		panic(err)
	}
}

func (nController *NoteController) listAllUserNotes(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
	userID := r.FormValue("user_id")

	query := "SELECT id, title, body, date_created FROM notes WHERE user_id=$1 ORDER BY date_created DESC"

	rows, err := nController.dbConnection.db.Query(query, userID)

	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	if err == nil {
		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusOK)

		notes := make([]*NoteModel, 0)

		for rows.Next() {

			newNote := new(NoteModel)

			_ = rows.Scan(
				&newNote.Id,
				&newNote.Title,
				&newNote.Body,
				&newNote.Date)

			notes = append(notes, newNote)

		}

		if err := json.NewEncoder(w).Encode(notes); err != nil {
			panic(err)
		}
		return
	}

	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(http.StatusNotFound)
	if err := json.NewEncoder(w).Encode(err); err != nil {
		panic(err)
	}

}
<|endoftext|>


<commit_before>package g

import (
	"strings"

	. "github.com/alecthomas/chroma" // nolint
	"github.com/alecthomas/chroma/lexers/h"
	"github.com/alecthomas/chroma/lexers/internal"
)

// Go lexer.
var Go = internal.Register(MustNewLexer(
	&Config{
		Name:      "Go",
		Aliases:   []string{"go", "golang"},
		Filenames: []string{"*.go"},
		MimeTypes: []string{"text/x-gosrc"},
	},
	Rules{
		"root": {
			{`\n`, Text, nil},
			{`\s+`, Text, nil},
			{`\\\n`, Text, nil},
			{`//(.*?)\n`, CommentSingle, nil},
			{`/(\\\n)?[*](.|\n)*?[*](\\\n)?/`, CommentMultiline, nil},
			{`(import|package)\b`, KeywordNamespace, nil},
			{`(var|func|struct|map|chan|type|interface|const)\b`, KeywordDeclaration, nil},
			{Words(``, `\b`, `break`, `default`, `select`, `case`, `defer`, `go`, `else`, `goto`, `switch`, `fallthrough`, `if`, `range`, `continue`, `for`, `return`), Keyword, nil},
			{`(true|false|iota|nil)\b`, KeywordConstant, nil},
			{Words(``, `\b(\()`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `int`, `int8`, `int16`, `int32`, `int64`, `float`, `float32`, `float64`, `complex64`, `complex128`, `byte`, `rune`, `string`, `bool`, `error`, `uintptr`, `print`, `println`, `panic`, `recover`, `close`, `complex`, `real`, `imag`, `len`, `cap`, `append`, `copy`, `delete`, `new`, `make`), ByGroups(NameBuiltin, Punctuation), nil},
			{Words(``, `\b`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `int`, `int8`, `int16`, `int32`, `int64`, `float`, `float32`, `float64`, `complex64`, `complex128`, `byte`, `rune`, `string`, `bool`, `error`, `uintptr`), KeywordType, nil},
			{`\d+i`, LiteralNumber, nil},
			{`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil},
			{`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil},
			{`\d+[Ee][-+]\d+i`, LiteralNumber, nil},
			{`\d+(\.\d+[eE][+\-]?\d+|\.\d*|[eE][+\-]?\d+)`, LiteralNumberFloat, nil},
			{`\.\d+([eE][+\-]?\d+)?`, LiteralNumberFloat, nil},
			{`0[0-7]+`, LiteralNumberOct, nil},
			{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
			{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
			{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
			{"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil},
			{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
			{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
			{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
			{`[^\W\d]\w*`, NameOther, nil},
		},
	},
).SetAnalyser(func(text string) float32 {
	if strings.Contains(text, "fmt.") && strings.Contains(text, "package ") {
		return 0.5
	}
	if strings.Contains(text, "package ") {
		return 0.1
	}
	return 0.0
}))

var goTemplateRules = Rules{
	"root": {
		{`{{[-]?`, CommentPreproc, Push("template")},
		{`[^{]+`, Other, nil},
		{`{`, Other, nil},
	},
	"template": {
		{`[-]?}}`, CommentPreproc, Pop(1)},
		{`\s+`, Whitespace, nil},
		{`/\*.*?\*/`, Comment, nil},
		{`(?=}})`, CommentPreproc, Pop(1)}, // Terminate the pipeline
		{`\(`, Operator, Push("subexpression")},
		{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
		Include("expression"),
	},
	"subexpression": {
		{`\)`, Operator, Pop(1)},
		Include("expression"),
	},
	"expression": {
		{`\(`, Operator, Push("subexpression")},
		{`(range|if|else|while|with|template|end|true|false|nil|and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b`, Keyword, nil},
		{`\||:=`, Operator, nil},
		{`[$]?[^\W\d]\w*`, NameOther, nil},
		{`[$]?\.(?:[^\W\d]\w*)?`, NameAttribute, nil},
		{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
		{`\d+i`, LiteralNumber, nil},
		{`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil},
		{`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil},
		{`\d+[Ee][-+]\d+i`, LiteralNumber, nil},
		{`\d+(\.\d+[eE][+\-]?\d+|\.\d*|[eE][+\-]?\d+)`, LiteralNumberFloat, nil},
		{`\.\d+([eE][+\-]?\d+)?`, LiteralNumberFloat, nil},
		{`0[0-7]+`, LiteralNumberOct, nil},
		{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
		{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
		{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
		{"`[^`]*`", LiteralString, nil},
	},
}

var GoHTMLTemplate = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
	&Config{
		Name:    "Go HTML Template",
		Aliases: []string{"go-html-template"},
	},
	goTemplateRules,
)))

var GoTextTemplate = internal.Register(MustNewLexer(
	&Config{
		Name:    "Go Text Template",
		Aliases: []string{"go-text-template"},
	},
	goTemplateRules,
))
<commit_msg>Correct handling of whitespace in Go templates.<commit_after>package g

import (
	"strings"

	. "github.com/alecthomas/chroma" // nolint
	"github.com/alecthomas/chroma/lexers/h"
	"github.com/alecthomas/chroma/lexers/internal"
)

// Go lexer.
var Go = internal.Register(MustNewLexer(
	&Config{
		Name:      "Go",
		Aliases:   []string{"go", "golang"},
		Filenames: []string{"*.go"},
		MimeTypes: []string{"text/x-gosrc"},
	},
	Rules{
		"root": {
			{`\n`, Text, nil},
			{`\s+`, Text, nil},
			{`\\\n`, Text, nil},
			{`//(.*?)\n`, CommentSingle, nil},
			{`/(\\\n)?[*](.|\n)*?[*](\\\n)?/`, CommentMultiline, nil},
			{`(import|package)\b`, KeywordNamespace, nil},
			{`(var|func|struct|map|chan|type|interface|const)\b`, KeywordDeclaration, nil},
			{Words(``, `\b`, `break`, `default`, `select`, `case`, `defer`, `go`, `else`, `goto`, `switch`, `fallthrough`, `if`, `range`, `continue`, `for`, `return`), Keyword, nil},
			{`(true|false|iota|nil)\b`, KeywordConstant, nil},
			{Words(``, `\b(\()`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `int`, `int8`, `int16`, `int32`, `int64`, `float`, `float32`, `float64`, `complex64`, `complex128`, `byte`, `rune`, `string`, `bool`, `error`, `uintptr`, `print`, `println`, `panic`, `recover`, `close`, `complex`, `real`, `imag`, `len`, `cap`, `append`, `copy`, `delete`, `new`, `make`), ByGroups(NameBuiltin, Punctuation), nil},
			{Words(``, `\b`, `uint`, `uint8`, `uint16`, `uint32`, `uint64`, `int`, `int8`, `int16`, `int32`, `int64`, `float`, `float32`, `float64`, `complex64`, `complex128`, `byte`, `rune`, `string`, `bool`, `error`, `uintptr`), KeywordType, nil},
			{`\d+i`, LiteralNumber, nil},
			{`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil},
			{`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil},
			{`\d+[Ee][-+]\d+i`, LiteralNumber, nil},
			{`\d+(\.\d+[eE][+\-]?\d+|\.\d*|[eE][+\-]?\d+)`, LiteralNumberFloat, nil},
			{`\.\d+([eE][+\-]?\d+)?`, LiteralNumberFloat, nil},
			{`0[0-7]+`, LiteralNumberOct, nil},
			{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
			{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
			{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
			{"(`)([^`]*)(`)", ByGroups(LiteralString, Using(TypeRemappingLexer(GoTextTemplate, TypeMapping{{Other, LiteralString, nil}})), LiteralString), nil},
			{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
			{`(<<=|>>=|<<|>>|<=|>=|&\^=|&\^|\+=|-=|\*=|/=|%=|&=|\|=|&&|\|\||<-|\+\+|--|==|!=|:=|\.\.\.|[+\-*/%&])`, Operator, nil},
			{`[|^<>=!()\[\]{}.,;:]`, Punctuation, nil},
			{`[^\W\d]\w*`, NameOther, nil},
		},
	},
).SetAnalyser(func(text string) float32 {
	if strings.Contains(text, "fmt.") && strings.Contains(text, "package ") {
		return 0.5
	}
	if strings.Contains(text, "package ") {
		return 0.1
	}
	return 0.0
}))

var goTemplateRules = Rules{
	"root": {
		{`{{[-]?`, CommentPreproc, Push("template")},
		{`[^{]+`, Other, nil},
		{`{`, Other, nil},
	},
	"template": {
		{`[-]?}}`, CommentPreproc, Pop(1)},
		{`/\*.*?\*/`, Comment, nil},
		{`(?=}})`, CommentPreproc, Pop(1)}, // Terminate the pipeline
		{`\(`, Operator, Push("subexpression")},
		{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
		Include("expression"),
	},
	"subexpression": {
		{`\)`, Operator, Pop(1)},
		Include("expression"),
	},
	"expression": {
		{`\s+`, Whitespace, nil},
		{`\(`, Operator, Push("subexpression")},
		{`(range|if|else|while|with|template|end|true|false|nil|and|call|html|index|js|len|not|or|print|printf|println|urlquery|eq|ne|lt|le|gt|ge)\b`, Keyword, nil},
		{`\||:=`, Operator, nil},
		{`[$]?[^\W\d]\w*`, NameOther, nil},
		{`[$]?\.(?:[^\W\d]\w*)?`, NameAttribute, nil},
		{`"(\\\\|\\"|[^"])*"`, LiteralString, nil},
		{`\d+i`, LiteralNumber, nil},
		{`\d+\.\d*([Ee][-+]\d+)?i`, LiteralNumber, nil},
		{`\.\d+([Ee][-+]\d+)?i`, LiteralNumber, nil},
		{`\d+[Ee][-+]\d+i`, LiteralNumber, nil},
		{`\d+(\.\d+[eE][+\-]?\d+|\.\d*|[eE][+\-]?\d+)`, LiteralNumberFloat, nil},
		{`\.\d+([eE][+\-]?\d+)?`, LiteralNumberFloat, nil},
		{`0[0-7]+`, LiteralNumberOct, nil},
		{`0[xX][0-9a-fA-F]+`, LiteralNumberHex, nil},
		{`(0|[1-9][0-9]*)`, LiteralNumberInteger, nil},
		{`'(\\['"\\abfnrtv]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|[^\\])'`, LiteralStringChar, nil},
		{"`[^`]*`", LiteralString, nil},
	},
}

var GoHTMLTemplate = internal.Register(DelegatingLexer(h.HTML, MustNewLexer(
	&Config{
		Name:    "Go HTML Template",
		Aliases: []string{"go-html-template"},
	},
	goTemplateRules,
)))

var GoTextTemplate = internal.Register(MustNewLexer(
	&Config{
		Name:    "Go Text Template",
		Aliases: []string{"go-text-template"},
	},
	goTemplateRules,
))
<|endoftext|>


<commit_before>package lfs

import "sync/atomic"

// Batcher provides a way to process a set of items in groups of n. Items can
// be added to the batcher from multiple goroutines and pulled off in groups
// when one of the following conditions occurs:
//   * The batch size is reached
//   * Exit() is called
// When an Exit() occurs, the group may be smaller than the batch size.
type Batcher struct {
	exited     uint32
	batchSize  int
	input      chan Transferable
	batchReady chan []Transferable
}

// NewBatcher creates a Batcher with the batchSize.
func NewBatcher(batchSize int) *Batcher {
	b := &Batcher{
		batchSize:  batchSize,
		input:      make(chan Transferable, batchSize),
		batchReady: make(chan []Transferable),
	}

	go b.acceptInput()
	return b
}

// Add adds an item to the batcher. Add is safe to call from multiple
// goroutines.
func (b *Batcher) Add(t Transferable) {
	if atomic.CompareAndSwapUint32(&b.exited, 1, 0) {
		b.input = make(chan Transferable, b.batchSize)
		go b.acceptInput()
	}

	b.input <- t
}

// Next will wait for the one of the above batch triggers to occur and return
// the accumulated batch.
func (b *Batcher) Next() []Transferable {
	return <-b.batchReady
}

// Exit stops all batching and allows Next() to return. Calling Add() after
// calling Exit() will result in a panic, unless Reset() is called first.
func (b *Batcher) Exit() {
	atomic.StoreUint32(&b.exited, 1)
	close(b.input)
}

// acceptInput runs in its own goroutine and accepts input from external
// clients. It fills and dispenses batches in a sequential order: for a batch
// size N, N items will be processed before a new batch is ready.
func (b *Batcher) acceptInput() {
	exit := false

	for {
		batch := make([]Transferable, 0, b.batchSize)
	Loop:
		for len(batch) < b.batchSize {
			t, ok := <-b.input
			if !ok {
				exit = true // input channel was closed by Exit()
				break Loop
			}
			batch = append(batch, t)
		}

		b.batchReady <- batch

		if exit {
			return
		}
	}
}
<commit_msg>ラララララ ラー ララララー<commit_after>package lfs

import "sync/atomic"

// Batcher provides a way to process a set of items in groups of n. Items can
// be added to the batcher from multiple goroutines and pulled off in groups
// when one of the following conditions occurs:
//   * The batch size is reached
//   * Exit() is called
// When an Exit() occurs, the group may be smaller than the batch size.
type Batcher struct {
	exited     uint32
	batchSize  int
	input      chan Transferable
	batchReady chan []Transferable
}

// NewBatcher creates a Batcher with the batchSize.
func NewBatcher(batchSize int) *Batcher {
	b := &Batcher{
		batchSize:  batchSize,
		input:      make(chan Transferable, batchSize),
		batchReady: make(chan []Transferable),
	}

	go b.acceptInput()
	return b
}

// Add adds an item to the batcher. Add is safe to call from multiple
// goroutines.
func (b *Batcher) Add(t Transferable) {
	if atomic.CompareAndSwapUint32(&b.exited, 1, 0) {
		b.input = make(chan Transferable, b.batchSize)
		go b.acceptInput()
	}

	b.input <- t
}

// Next will wait for the one of the above batch triggers to occur and return
// the accumulated batch.
func (b *Batcher) Next() []Transferable {
	return <-b.batchReady
}

// Exit stops all batching and allows Next() to return. Calling Add() will
// reset the batcher.
func (b *Batcher) Exit() {
	atomic.StoreUint32(&b.exited, 1)
	close(b.input)
}

// acceptInput runs in its own goroutine and accepts input from external
// clients. It fills and dispenses batches in a sequential order: for a batch
// size N, N items will be processed before a new batch is ready.
func (b *Batcher) acceptInput() {
	exit := false

	for {
		batch := make([]Transferable, 0, b.batchSize)
	Loop:
		for len(batch) < b.batchSize {
			t, ok := <-b.input
			if !ok {
				exit = true // input channel was closed by Exit()
				break Loop
			}
			batch = append(batch, t)
		}

		b.batchReady <- batch

		if exit {
			return
		}
	}
}
<|endoftext|>


<commit_before>package gorm

import (
	"bytes"
	"strings"
)

// Copied from golint
var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
var commonInitialismsReplacer *strings.Replacer

func init() {
	var commonInitialismsForReplacer []string
	for _, initialism := range commonInitialisms {
		commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
	}
	commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
}

var smap = map[string]string{}
var mutex = &sync.Mutex{}

func ToDBName(name string) string {
	if v, ok := smap[name]; ok {
		return v
	}

	value := commonInitialismsReplacer.Replace(name)
	buf := bytes.NewBufferString("")
	for i, v := range value {
		if i > 0 && v >= 'A' && v <= 'Z' {
			buf.WriteRune('_')
		}
		buf.WriteRune(v)
	}

	s := strings.ToLower(buf.String())
	mutex.Lock()
	smap[name] = s
	mutex.Unlock()
	return s
}

type expr struct {
	expr string
	args []interface{}
}

func Expr(expression string, args ...interface{}) *expr {
	return &expr{expr: expression, args: args}
}
<commit_msg>import sync<commit_after>package gorm

import (
	"bytes"
	"strings"
	"sync"
)

// Copied from golint
var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
var commonInitialismsReplacer *strings.Replacer

func init() {
	var commonInitialismsForReplacer []string
	for _, initialism := range commonInitialisms {
		commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
	}
	commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
}

var smap = map[string]string{}
var mutex = &sync.Mutex{}

func ToDBName(name string) string {
	if v, ok := smap[name]; ok {
		return v
	}

	value := commonInitialismsReplacer.Replace(name)
	buf := bytes.NewBufferString("")
	for i, v := range value {
		if i > 0 && v >= 'A' && v <= 'Z' {
			buf.WriteRune('_')
		}
		buf.WriteRune(v)
	}

	s := strings.ToLower(buf.String())
	mutex.Lock()
	smap[name] = s
	mutex.Unlock()
	return s
}

type expr struct {
	expr string
	args []interface{}
}

func Expr(expression string, args ...interface{}) *expr {
	return &expr{expr: expression, args: args}
}
<|endoftext|>


<commit_before>package kolpa

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// Parses and replaces tags in a text with provided values in the map m.
func (g *Generator) parser(text string, m map[string]string) string {
	src := []byte(text)
	search := regexp.MustCompile(`{{(.*?)}}`)

	src = search.ReplaceAllFunc(src, func(s []byte) []byte {
		return []byte(m[string(s)[2:len(s)-2]])
	})

	return string(src)
}

// Parses and replaces tags in a text with provided values in the map m.
func (g *Generator) nparser(text string, m map[int]string) string {
	src := []byte(text)
	search := regexp.MustCompile(`{{(.*?)}}`)

	c := 0
	src = search.ReplaceAllFunc(src, func(s []byte) []byte {
		res := []byte(m[c])
		c++
		return res
	})

	return string(src)
}

// Concatenates multiple string slices by using append function and returns new slice.
func appendMultiple(slices ...[]string) []string {
	base := slices[0]
	rest := slices[1:]

	for _, slice := range rest {
		base = append(base, slice...)
	}

	return base
}

// Concatenates a slice of string slices into a string slice
func (g *Generator) appendMultipleWithSlice(slices []string) ([]string, error) {
	var result [][]string
	var slice []string
	var err error

	for _, v := range slices {
		slice, err = g.fileToSlice(v)
		if err != nil {
			return nil, err
		}
		result = append(result, slice)
	}

	base := result[0]
	rest := result[1:]

	for _, slice := range rest {
		base = append(base, slice...)
	}

	return base, nil
}

// Takes format and outputs the needed variables for the format
// Sample input: `{{prefix_female}} {{female_first_name}}`
// Sample output: [ prefix_female female_first_name ]
func (g *Generator) formatToSlice(format string) []string {
	re := regexp.MustCompile(`{{(.*?)}}`)

	find := re.FindAllStringSubmatch(format, -1)

	res := []string{}

	for _, v := range find {
		res = append(res, v[1])
	}
	return res
}

// Reads the file "fName" and returns its content as a slice of strings.
func (g *Generator) fileToSlice(fName string) ([]string, error) {
	var res []string
	path := "data/" + g.Locale_ + "/" + fName
	file, err := os.Open(path)

	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		res = append(res, scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		//log.Println("Inteded generation is not valid for selected language. Switching to en_US.")
		g.Locale_ = "en_US"
		return g.fileToSlice(fName)
	}

	return res, nil
}

// Reads the all files starting with "fName" and returns their content as a slice of strings.
func (g *Generator) fileToSliceAll(fName string) ([]string, error) {
	var res []string
	var err error
	var file *os.File

	path := "data/" + g.Locale_ + "/"

	f, err := os.Open(path)

	if err != nil {
		return nil, err
	}

	l, err := f.Readdirnames(-1)

	if err != nil {
		return nil, err
	}

	fNames := l[:0]
	for _, x := range l {
		if strings.HasPrefix(x, fName) {
			fNames = append(fNames, x)
		}
	}

	for _, name := range fNames {
		file, err = os.Open(path + name)

		if err != nil {
			return nil, err
		}
		defer file.Close()

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			res = append(res, scanner.Text())
		}

		if err := scanner.Err(); err != nil {
			return nil, err
		}
	}

	if len(res) == 0 {
		return nil, fmt.Errorf("Length is zero.")
	}

	return res, nil
}

// Reads the tab separated file 'fName' and returns its content as a map of strings to strings.
func (g *Generator) fileToMap(fName string) map[string]string {
	m := make(map[string]string)
	path := "data/" + g.Locale_ + "/" + fName
	file, err := os.Open(path)

	if err != nil {
		return m
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "\t")

		mapLine(line, m)
	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	return m
}

// Returns random item from the given string slice.
func getRandom(options []string) string {
	rand.Seed(time.Now().UTC().UnixNano())
	return options[rand.Intn(len(options))]
}

// Returns random boolean variable.
func randBool() bool {
	rand.Seed(time.Now().UTC().UnixNano())
	val := rand.Float64()

	return parseRandomToBoolean(val)
}

// Returns all possible data for languages.
func getLanguages() []string {
	path := "data/"
	files, _ := ioutil.ReadDir(path)
	var n string
	var res []string

	for _, f := range files {
		n = string(f.Name())
		if string(n[0]) != "." {
			res = append(res, f.Name())
		}
	}

	return res
}

// Returns if given file is contains parseable content or not.
func (g *Generator) isParseable(sl string) bool {
	if len(sl) == 0 {
		return false
	}

	re := regexp.MustCompile(`{{(.*?)}}`)

	if match := re.FindString(sl); len(match) > 0 {
		return true
	}

	return false
}

// Returns if given file contains content that needs to be replaced with numeric values.
func (g *Generator) isNumeric(sl []string) bool {
	if len(sl) == 0 {
		return false
	}

	re := regexp.MustCompile(`##(.*?)##`)

	if match := re.FindString(sl[0]); len(match) > 0 {
		return true
	}

	return false
}

// Generates an integer with given digit length and greater than or equal and less than parameters
func (g *Generator) numericRandomizer(args []string) string {
	length, err := strconv.Atoi(args[0])
	gte, err2 := strconv.Atoi(args[1])
	lt, err3 := strconv.Atoi(args[2])

	if err != nil && err2 != nil && err3 != nil {
		return "something is wrong with arguments of numeric randomizer function"
	}

	var buffer bytes.Buffer

	for i := 0; i < length; i++ {
		buffer.WriteString(strconv.Itoa(int(g.numBetween(gte, lt))))
	}

	return buffer.String()
}

// Generates a random integer between given greater than or equal and less than parameters
func (g *Generator) numBetween(gte int, lt int) int32 {
	return rand.Int31n(int32(lt)-int32(gte)) + int32(gte)
}

// Determines the type of given token. It should be whether func or default.
func (g *Generator) typeOfToken(token string) string {
	if token[0] == '%' && token[len(token)-1] == '%' {
		return "func"
	} else if token[0:4] == "same" {
		return "same"
	}

	return "default"
}

// Calls DateTimeAfterWithString function and returns its Stringer method.
// This function is specifically written for in format function calls.
func (g *Generator) userAgentDateAfter(args []string) string {
	return g.DateFormatter("2006-01-02 15:04:05", g.DateTimeAfterWithString(args[0]).UTC().String())
}

func mapLine(line []string, data map[string]string) {
	if len(line) > 1 {
		data[line[0]] = line[1]
	}
}

func parseRandomToBoolean(val float64) bool {
	if val <= 0.5 {
		return true
	}

	return false
}
<commit_msg>reversed gopath PR<commit_after>package kolpa

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// Parses and replaces tags in a text with provided values in the map m.
func (g *Generator) parser(text string, m map[string]string) string {
	src := []byte(text)
	search := regexp.MustCompile(`{{(.*?)}}`)

	src = search.ReplaceAllFunc(src, func(s []byte) []byte {
		return []byte(m[string(s)[2:len(s)-2]])
	})

	return string(src)
}

// Parses and replaces tags in a text with provided values in the map m.
func (g *Generator) nparser(text string, m map[int]string) string {
	src := []byte(text)
	search := regexp.MustCompile(`{{(.*?)}}`)

	c := 0
	src = search.ReplaceAllFunc(src, func(s []byte) []byte {
		res := []byte(m[c])
		c++
		return res
	})

	return string(src)
}

// Concatenates multiple string slices by using append function and returns new slice.
func appendMultiple(slices ...[]string) []string {
	base := slices[0]
	rest := slices[1:]

	for _, slice := range rest {
		base = append(base, slice...)
	}

	return base
}

// Concatenates a slice of string slices into a string slice
func (g *Generator) appendMultipleWithSlice(slices []string) ([]string, error) {
	var result [][]string
	var slice []string
	var err error

	for _, v := range slices {
		slice, err = g.fileToSlice(v)
		if err != nil {
			return nil, err
		}
		result = append(result, slice)
	}

	base := result[0]
	rest := result[1:]

	for _, slice := range rest {
		base = append(base, slice...)
	}

	return base, nil
}

// Takes format and outputs the needed variables for the format
// Sample input: `{{prefix_female}} {{female_first_name}}`
// Sample output: [ prefix_female female_first_name ]
func (g *Generator) formatToSlice(format string) []string {
	re := regexp.MustCompile(`{{(.*?)}}`)

	find := re.FindAllStringSubmatch(format, -1)

	res := []string{}

	for _, v := range find {
		res = append(res, v[1])
	}
	return res
}

// Reads the file "fName" and returns its content as a slice of strings.
func (g *Generator) fileToSlice(fName string) ([]string, error) {
	var res []string
	path := os.Getenv("GOPATH") + "/src/" + g.Pkg + "/data/" + g.Locale_ + "/" + fName
	file, err := os.Open(path)

	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		res = append(res, scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		//log.Println("Inteded generation is not valid for selected language. Switching to en_US.")
		g.Locale_ = "en_US"
		return g.fileToSlice(fName)
	}

	return res, nil
}

// Reads the all files starting with "fName" and returns their content as a slice of strings.
func (g *Generator) fileToSliceAll(fName string) ([]string, error) {
	var res []string
	var err error
	var file *os.File

	path := os.Getenv("GOPATH") + "/src/" + g.Pkg + "/data/" + g.Locale_ + "/"

	f, err := os.Open(path)

	if err != nil {
		return nil, err
	}

	l, err := f.Readdirnames(-1)

	if err != nil {
		return nil, err
	}

	fNames := l[:0]
	for _, x := range l {
		if strings.HasPrefix(x, fName) {
			fNames = append(fNames, x)
		}
	}

	for _, name := range fNames {
		file, err = os.Open(path + name)

		if err != nil {
			return nil, err
		}
		defer file.Close()

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			res = append(res, scanner.Text())
		}

		if err := scanner.Err(); err != nil {
			return nil, err
		}
	}

	if len(res) == 0 {
		return nil, fmt.Errorf("Length is zero.")
	}

	return res, nil
}

// Reads the tab separated file 'fName' and returns its content as a map of strings to strings.
func (g *Generator) fileToMap(fName string) map[string]string {
	m := make(map[string]string)
	path := os.Getenv("GOPATH") + "/src/" + g.Pkg + "/data/" + g.Locale_ + "/" + fName
	file, err := os.Open(path)

	if err != nil {
		return m
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "\t")

		mapLine(line, m)
	}

	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}

	return m
}

// Returns random item from the given string slice.
func getRandom(options []string) string {
	rand.Seed(time.Now().UTC().UnixNano())
	return options[rand.Intn(len(options))]
}

// Returns random boolean variable.
func randBool() bool {
	rand.Seed(time.Now().UTC().UnixNano())
	val := rand.Float64()

	return parseRandomToBoolean(val)
}

// Returns all possible data for languages.
func getLanguages() []string {
	path := os.Getenv("GOPATH") + "/src/" + reflect.TypeOf(Generator{}).PkgPath() + "/data/"
	files, _ := ioutil.ReadDir(path)
	var n string
	var res []string

	for _, f := range files {
		n = string(f.Name())
		if string(n[0]) != "." {
			res = append(res, f.Name())
		}
	}

	return res
}

// Returns if given file is contains parseable content or not.
func (g *Generator) isParseable(sl string) bool {
	if len(sl) == 0 {
		return false
	}

	re := regexp.MustCompile(`{{(.*?)}}`)

	if match := re.FindString(sl); len(match) > 0 {
		return true
	}

	return false
}

// Returns if given file contains content that needs to be replaced with numeric values.
func (g *Generator) isNumeric(sl []string) bool {
	if len(sl) == 0 {
		return false
	}

	re := regexp.MustCompile(`##(.*?)##`)

	if match := re.FindString(sl[0]); len(match) > 0 {
		return true
	}

	return false
}

// Generates an integer with given digit length and greater than or equal and less than parameters
func (g *Generator) numericRandomizer(args []string) string {
	length, err := strconv.Atoi(args[0])
	gte, err2 := strconv.Atoi(args[1])
	lt, err3 := strconv.Atoi(args[2])

	if err != nil && err2 != nil && err3 != nil {
		return "something is wrong with arguments of numeric randomizer function"
	}

	var buffer bytes.Buffer

	for i := 0; i < length; i++ {
		buffer.WriteString(strconv.Itoa(int(g.numBetween(gte, lt))))
	}

	return buffer.String()
}

// Generates a random integer between given greater than or equal and less than parameters
func (g *Generator) numBetween(gte int, lt int) int32 {
	return rand.Int31n(int32(lt)-int32(gte)) + int32(gte)
}

// Determines the type of given token. It should be whether func or default.
func (g *Generator) typeOfToken(token string) string {
	if token[0] == '%' && token[len(token)-1] == '%' {
		return "func"
	} else if token[0:4] == "same" {
		return "same"
	}

	return "default"
}

// Calls DateTimeAfterWithString function and returns its Stringer method.
// This function is specifically written for in format function calls.
func (g *Generator) userAgentDateAfter(args []string) string {
	return g.DateFormatter("2006-01-02 15:04:05", g.DateTimeAfterWithString(args[0]).UTC().String())
}

func mapLine(line []string, data map[string]string) {
	if len(line) > 1 {
		data[line[0]] = line[1]
	}
}

func parseRandomToBoolean(val float64) bool {
	if val <= 0.5 {
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package godns

import (
	"bytes"
	"errors"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"golang.org/x/net/proxy"
	"gopkg.in/gomail.v2"
)

var (
	// Logo for GoDNS
	Logo = `

 ██████╗  ██████╗ ██████╗ ███╗   ██╗███████╗
██╔════╝ ██╔═══██╗██╔══██╗████╗  ██║██╔════╝
██║  ███╗██║   ██║██║  ██║██╔██╗ ██║███████╗
██║   ██║██║   ██║██║  ██║██║╚██╗██║╚════██║
╚██████╔╝╚██████╔╝██████╔╝██║ ╚████║███████║
 ╚═════╝  ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝

GoDNS V%s
https://github.com/TimothyYe/godns

`
)

const (
	// PanicMax is the max allowed panic times
	PanicMax = 5
	// INTERVAL is minute
	INTERVAL = 5
	// DNSPOD for dnspod.cn
	DNSPOD = "DNSPod"
	// HE for he.net
	HE = "HE"
)

// GetCurrentIP gets public IP from internet
func GetCurrentIP(configuration *Settings) (string, error) {
	client := &http.Client{}

	if configuration.Socks5Proxy != "" {

		log.Println("use socks5 proxy:" + configuration.Socks5Proxy)
		dialer, err := proxy.SOCKS5("tcp", configuration.Socks5Proxy, nil, proxy.Direct)
		if err != nil {
			log.Println("can't connect to the proxy:", err)
			return "", err
		}

		httpTransport := &http.Transport{}
		client.Transport = httpTransport
		httpTransport.Dial = dialer.Dial
	}

	response, err := client.Get(configuration.IPUrl)

	if err != nil {
		log.Println("Cannot get IP...")
		return "", err
	}

	defer response.Body.Close()

	body, _ := ioutil.ReadAll(response.Body)
	return string(body), nil
}

// CheckSettings check the format of settings
func CheckSettings(config *Settings) error {
	if config.Provider == DNSPOD {
		if (config.Email == "" || config.Password == "") && config.LoginToken == "" {
			return errors.New("email/password or login token cannot be empty")
		}
	} else if config.Provider == HE {
		if config.Password == "" {
			return errors.New("password cannot be empty")
		}
	} else {
		return errors.New("please provide supported DNS provider: DNSPod/HE")
	}

	return nil
}

// SaveCurrentIP saves current IP into a template file
func SaveCurrentIP(currentIP string) {
	ioutil.WriteFile("./.current_ip", []byte(currentIP), os.FileMode(0644))
}

// LoadCurrentIP loads saved IP from template file
func LoadCurrentIP() string {
	content, err := ioutil.ReadFile("./.current_ip")

	if err != nil {
		return ""
	}

	return strings.Replace(string(content), "\n", "", -1)
}

// SendNotify sends mail notify if IP is changed
func SendNotify(configuration *Settings, domain, currentIP string) error {
	m := gomail.NewMessage()

	m.SetHeader("From", configuration.Notify.SMTPUsername)
	m.SetHeader("To", configuration.Notify.SendTo)
	m.SetHeader("Subject", "GoDNS Notification")
	log.Println("currentIP:", currentIP)
	log.Println("domain:", domain)
	m.SetBody("text/html", buildTemplate(currentIP, domain))

	d := gomail.NewPlainDialer(configuration.Notify.SMTPServer, configuration.Notify.SMTPPort, configuration.Notify.SMTPUsername, configuration.Notify.SMTPPassword)

	// Send the email config by sendlist	.
	if err := d.DialAndSend(m); err != nil {
		log.Println("Send email notification with error:", err.Error())
		return err
	}
	return nil
}

func buildTemplate(currentIP, domain string) string {
	t := template.New("notification template")
	t.Parse(MailTemplate)

	data := struct {
		CurrentIP string
		Domain    string
	}{
		currentIP,
		domain,
	}

	var tpl bytes.Buffer
	if err := t.Execute(&tpl, data); err != nil {
		log.Println(err.Error())
		return ""
	}

	log.Println("result:", tpl.String())
	return tpl.String()
}
<commit_msg>remove debug info<commit_after>package godns

import (
	"bytes"
	"errors"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"golang.org/x/net/proxy"
	"gopkg.in/gomail.v2"
)

var (
	// Logo for GoDNS
	Logo = `

 ██████╗  ██████╗ ██████╗ ███╗   ██╗███████╗
██╔════╝ ██╔═══██╗██╔══██╗████╗  ██║██╔════╝
██║  ███╗██║   ██║██║  ██║██╔██╗ ██║███████╗
██║   ██║██║   ██║██║  ██║██║╚██╗██║╚════██║
╚██████╔╝╚██████╔╝██████╔╝██║ ╚████║███████║
 ╚═════╝  ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝╚══════╝

GoDNS V%s
https://github.com/TimothyYe/godns

`
)

const (
	// PanicMax is the max allowed panic times
	PanicMax = 5
	// INTERVAL is minute
	INTERVAL = 5
	// DNSPOD for dnspod.cn
	DNSPOD = "DNSPod"
	// HE for he.net
	HE = "HE"
)

// GetCurrentIP gets public IP from internet
func GetCurrentIP(configuration *Settings) (string, error) {
	client := &http.Client{}

	if configuration.Socks5Proxy != "" {

		log.Println("use socks5 proxy:" + configuration.Socks5Proxy)
		dialer, err := proxy.SOCKS5("tcp", configuration.Socks5Proxy, nil, proxy.Direct)
		if err != nil {
			log.Println("can't connect to the proxy:", err)
			return "", err
		}

		httpTransport := &http.Transport{}
		client.Transport = httpTransport
		httpTransport.Dial = dialer.Dial
	}

	response, err := client.Get(configuration.IPUrl)

	if err != nil {
		log.Println("Cannot get IP...")
		return "", err
	}

	defer response.Body.Close()

	body, _ := ioutil.ReadAll(response.Body)
	return string(body), nil
}

// CheckSettings check the format of settings
func CheckSettings(config *Settings) error {
	if config.Provider == DNSPOD {
		if (config.Email == "" || config.Password == "") && config.LoginToken == "" {
			return errors.New("email/password or login token cannot be empty")
		}
	} else if config.Provider == HE {
		if config.Password == "" {
			return errors.New("password cannot be empty")
		}
	} else {
		return errors.New("please provide supported DNS provider: DNSPod/HE")
	}

	return nil
}

// SaveCurrentIP saves current IP into a template file
func SaveCurrentIP(currentIP string) {
	ioutil.WriteFile("./.current_ip", []byte(currentIP), os.FileMode(0644))
}

// LoadCurrentIP loads saved IP from template file
func LoadCurrentIP() string {
	content, err := ioutil.ReadFile("./.current_ip")

	if err != nil {
		return ""
	}

	return strings.Replace(string(content), "\n", "", -1)
}

// SendNotify sends mail notify if IP is changed
func SendNotify(configuration *Settings, domain, currentIP string) error {
	m := gomail.NewMessage()

	m.SetHeader("From", configuration.Notify.SMTPUsername)
	m.SetHeader("To", configuration.Notify.SendTo)
	m.SetHeader("Subject", "GoDNS Notification")
	log.Println("currentIP:", currentIP)
	log.Println("domain:", domain)
	m.SetBody("text/html", buildTemplate(currentIP, domain))

	d := gomail.NewPlainDialer(configuration.Notify.SMTPServer, configuration.Notify.SMTPPort, configuration.Notify.SMTPUsername, configuration.Notify.SMTPPassword)

	// Send the email config by sendlist	.
	if err := d.DialAndSend(m); err != nil {
		log.Println("Send email notification with error:", err.Error())
		return err
	}
	return nil
}

func buildTemplate(currentIP, domain string) string {
	t := template.New("notification template")
	t.Parse(MailTemplate)

	data := struct {
		CurrentIP string
		Domain    string
	}{
		currentIP,
		domain,
	}

	var tpl bytes.Buffer
	if err := t.Execute(&tpl, data); err != nil {
		log.Println(err.Error())
		return ""
	}

	return tpl.String()
}
<|endoftext|>


<commit_before>// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// author           sigu-399
// author-github    https://github.com/sigu-399
// author-mail      sigu.399@gmail.com
//
// repository-name  gojsonschema
// repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language.
//
// description      Various utility functions.
//
// created          26-02-2013

package gojsonschema

import (
	"encoding/json"
	"fmt"
	"log"
	"math"
	"reflect"
)

func isKind(what interface{}, kind reflect.Kind) bool {
	return reflect.ValueOf(what).Kind() == kind
}

func existsMapKey(m map[string]interface{}, k string) bool {
	_, ok := m[k]
	return ok
}

func isStringInSlice(s []string, what string) bool {
	for i := range s {
		if s[i] == what {
			return true
		}
	}
	return false
}

// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
const (
	max_json_float = float64(1<<53 - 1) // 9007199254740991.0 	 	 2^53 - 1
	min_json_float = -float64(1 << 53 - 1)  //-9007199254740991.0	-2^53 - 1
)

// allow for integers [-2^53, 2^53-1] inclusive
func isFloat64AnInteger(f float64) bool {

	if math.IsNaN(f) || math.IsInf(f, 0) || f < min_json_float || f > max_json_float {
		return false
	}

	return f == float64(int64(f)) || f == float64(uint64(f))
}

// formats a number so that it is displayed as the smallest string possible
func validationErrorFormatNumber(n float64) string {

	if isFloat64AnInteger(n) {
		return fmt.Sprintf("%d", int64(n))
	}

	return fmt.Sprintf("%g", n)
}

func marshalToJsonString(value interface{}) (*string, error) {

	mBytes, err := json.Marshal(value)
	if err != nil {
		return nil, err
	}

	sBytes := string(mBytes)
	return &sBytes, nil
}

const internalLogEnabled = false

func internalLog(message string) {
	if internalLogEnabled {
		log.Print(message)
	}
}
<commit_msg>Added utility routines for common patterns<commit_after>// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// author           sigu-399
// author-github    https://github.com/sigu-399
// author-mail      sigu.399@gmail.com
//
// repository-name  gojsonschema
// repository-desc  An implementation of JSON Schema, based on IETF's draft v4 - Go language.
//
// description      Various utility functions.
//
// created          26-02-2013

package gojsonschema

import (
	"encoding/json"
	"fmt"
	"log"
	"math"
	"reflect"
)

func mustBeInteger(what interface{}) *float64 {
	var number float64
	if isKind(what, reflect.Float64) {
		number = what.(float64)
		if isFloat64AnInteger(number) {
			return &number
		} else {
			return nil
		}
	} else if isKind(what, reflect.Int) {
		number = float64(what.(int))
		return &number
	}
	return nil
}

func mustBeNumber(what interface{}) *float64 {
	var number float64

	if isKind(what, reflect.Float64) {
		number = what.(float64)
		return &number
	} else if isKind(what, reflect.Int) {
		number = float64(what.(int))
		return &number
	}
	return nil
}

func isKind(what interface{}, kind reflect.Kind) bool {
	return reflect.ValueOf(what).Kind() == kind
}

func existsMapKey(m map[string]interface{}, k string) bool {
	_, ok := m[k]
	return ok
}

func isStringInSlice(s []string, what string) bool {
	for i := range s {
		if s[i] == what {
			return true
		}
	}
	return false
}

// same as ECMA Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
const (
	max_json_float = float64(1<<53 - 1)  // 9007199254740991.0 	 	 2^53 - 1
	min_json_float = -float64(1<<53 - 1) //-9007199254740991.0	-2^53 - 1
)

// allow for integers [-2^53, 2^53-1] inclusive
func isFloat64AnInteger(f float64) bool {

	if math.IsNaN(f) || math.IsInf(f, 0) || f < min_json_float || f > max_json_float {
		return false
	}

	return f == float64(int64(f)) || f == float64(uint64(f))
}

// formats a number so that it is displayed as the smallest string possible
func validationErrorFormatNumber(n float64) string {

	if isFloat64AnInteger(n) {
		return fmt.Sprintf("%d", int64(n))
	}

	return fmt.Sprintf("%g", n)
}

func marshalToJsonString(value interface{}) (*string, error) {

	mBytes, err := json.Marshal(value)
	if err != nil {
		return nil, err
	}

	sBytes := string(mBytes)
	return &sBytes, nil
}

const internalLogEnabled = false

func internalLog(message string) {
	if internalLogEnabled {
		log.Print(message)
	}
}
<|endoftext|>


<commit_before>package gorm

import (
	"bytes"
	"database/sql/driver"
	"fmt"
	"reflect"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"time"
)

// NowFunc returns current time, this function is exported in order to be able
// to give the flexibility to the developer to customize it according to their
// needs, e.g:
//    gorm.NowFunc = func() time.Time {
//      return time.Now().UTC()
//    }
var NowFunc = func() time.Time {
	return time.Now()
}

// Copied from golint
var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
var commonInitialismsReplacer *strings.Replacer

func init() {
	var commonInitialismsForReplacer []string
	for _, initialism := range commonInitialisms {
		commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
	}
	commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
}

type safeMap struct {
	m map[string]string
	l *sync.RWMutex
}

func (s *safeMap) Set(key string, value string) {
	s.l.Lock()
	defer s.l.Unlock()
	s.m[key] = value
}

func (s *safeMap) Get(key string) string {
	s.l.RLock()
	defer s.l.RUnlock()
	return s.m[key]
}

func newSafeMap() *safeMap {
	return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
}

var smap = newSafeMap()

type strCase bool

const (
	lower strCase = false
	upper strCase = true
)

// ToDBName convert string to db name
func ToDBName(name string) string {
	if v := smap.Get(name); v != "" {
		return v
	}

	if name == "" {
		return ""
	}

	var (
		value                        = commonInitialismsReplacer.Replace(name)
		buf                          = bytes.NewBufferString("")
		lastCase, currCase, nextCase strCase
	)

	for i, v := range value[:len(value)-1] {
		nextCase = strCase(value[i+1] >= 'A' && value[i+1] <= 'Z')
		if i > 0 {
			if currCase == upper {
				if lastCase == upper && nextCase == upper {
					buf.WriteRune(v)
				} else {
					if value[i-1] != '_' && value[i+1] != '_' {
						buf.WriteRune('_')
					}
					buf.WriteRune(v)
				}
			} else {
				buf.WriteRune(v)
			}
		} else {
			currCase = upper
			buf.WriteRune(v)
		}
		lastCase = currCase
		currCase = nextCase
	}

	buf.WriteByte(value[len(value)-1])

	s := strings.ToLower(buf.String())
	smap.Set(name, s)
	return s
}

// SQL expression
type expr struct {
	expr string
	args []interface{}
}

// Expr generate raw SQL expression, for example:
//     DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
func Expr(expression string, args ...interface{}) *expr {
	return &expr{expr: expression, args: args}
}

func indirect(reflectValue reflect.Value) reflect.Value {
	for reflectValue.Kind() == reflect.Ptr {
		reflectValue = reflectValue.Elem()
	}
	return reflectValue
}

func toQueryMarks(primaryValues [][]interface{}) string {
	var results []string

	for _, primaryValue := range primaryValues {
		var marks []string
		for range primaryValue {
			marks = append(marks, "?")
		}

		if len(marks) > 1 {
			results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
		} else {
			results = append(results, strings.Join(marks, ""))
		}
	}
	return strings.Join(results, ",")
}

func toQueryCondition(scope *Scope, columns []string) string {
	var newColumns []string
	for _, column := range columns {
		newColumns = append(newColumns, scope.Quote(column))
	}

	if len(columns) > 1 {
		return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
	}
	return strings.Join(newColumns, ",")
}

func toQueryValues(values [][]interface{}) (results []interface{}) {
	for _, value := range values {
		for _, v := range value {
			results = append(results, v)
		}
	}
	return
}

func fileWithLineNum() string {
	for i := 2; i < 15; i++ {
		_, file, line, ok := runtime.Caller(i)
		if ok && (!regexp.MustCompile(`jinzhu/gorm/.*.go`).MatchString(file) || regexp.MustCompile(`jinzhu/gorm/.*test.go`).MatchString(file)) {
			return fmt.Sprintf("%v:%v", file, line)
		}
	}
	return ""
}

func isBlank(value reflect.Value) bool {
	return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
}

func toSearchableMap(attrs ...interface{}) (result interface{}) {
	if len(attrs) > 1 {
		if str, ok := attrs[0].(string); ok {
			result = map[string]interface{}{str: attrs[1]}
		}
	} else if len(attrs) == 1 {
		if attr, ok := attrs[0].(map[string]interface{}); ok {
			result = attr
		}

		if attr, ok := attrs[0].(interface{}); ok {
			result = attr
		}
	}
	return
}

func equalAsString(a interface{}, b interface{}) bool {
	return toString(a) == toString(b)
}

func toString(str interface{}) string {
	if values, ok := str.([]interface{}); ok {
		var results []string
		for _, value := range values {
			results = append(results, toString(value))
		}
		return strings.Join(results, "_")
	} else if bytes, ok := str.([]byte); ok {
		return string(bytes)
	} else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
		return fmt.Sprintf("%v", reflectValue.Interface())
	}
	return ""
}

func makeSlice(elemType reflect.Type) interface{} {
	if elemType.Kind() == reflect.Slice {
		elemType = elemType.Elem()
	}
	sliceType := reflect.SliceOf(elemType)
	slice := reflect.New(sliceType)
	slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
	return slice.Interface()
}

func strInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// getValueFromFields return given fields's value
func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
	// If value is a nil pointer, Indirect returns a zero Value!
	// Therefor we need to check for a zero value,
	// as FieldByName could panic
	if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
		for _, fieldName := range fieldNames {
			if fieldValue := indirectValue.FieldByName(fieldName); fieldValue.IsValid() {
				result := fieldValue.Interface()
				if r, ok := result.(driver.Valuer); ok {
					result, _ = r.Value()
				}
				results = append(results, result)
			}
		}
	}
	return
}

func addExtraSpaceIfExist(str string) string {
	if str != "" {
		return " " + str
	}
	return ""
}
<commit_msg>Fixing go get error<commit_after>package gorm

import (
	"bytes"
	"database/sql/driver"
	"fmt"
	"reflect"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"time"
)

// NowFunc returns current time, this function is exported in order to be able
// to give the flexibility to the developer to customize it according to their
// needs, e.g:
//    gorm.NowFunc = func() time.Time {
//      return time.Now().UTC()
//    }
var NowFunc = func() time.Time {
	return time.Now()
}

// Copied from golint
var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
var commonInitialismsReplacer *strings.Replacer

func init() {
	var commonInitialismsForReplacer []string
	for _, initialism := range commonInitialisms {
		commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
	}
	commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
}

type safeMap struct {
	m map[string]string
	l *sync.RWMutex
}

func (s *safeMap) Set(key string, value string) {
	s.l.Lock()
	defer s.l.Unlock()
	s.m[key] = value
}

func (s *safeMap) Get(key string) string {
	s.l.RLock()
	defer s.l.RUnlock()
	return s.m[key]
}

func newSafeMap() *safeMap {
	return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
}

var smap = newSafeMap()

type strCase bool

const (
	lower strCase = false
	upper strCase = true
)

// ToDBName convert string to db name
func ToDBName(name string) string {
	if v := smap.Get(name); v != "" {
		return v
	}

	if name == "" {
		return ""
	}

	var (
		value                        = commonInitialismsReplacer.Replace(name)
		buf                          = bytes.NewBufferString("")
		lastCase, currCase, nextCase strCase
	)

	for i, v := range value[:len(value)-1] {
		nextCase = strCase(value[i+1] >= 'A' && value[i+1] <= 'Z')
		if i > 0 {
			if currCase == upper {
				if lastCase == upper && nextCase == upper {
					buf.WriteRune(v)
				} else {
					if value[i-1] != '_' && value[i+1] != '_' {
						buf.WriteRune('_')
					}
					buf.WriteRune(v)
				}
			} else {
				buf.WriteRune(v)
			}
		} else {
			currCase = upper
			buf.WriteRune(v)
		}
		lastCase = currCase
		currCase = nextCase
	}

	buf.WriteByte(value[len(value)-1])

	s := strings.ToLower(buf.String())
	smap.Set(name, s)
	return s
}

// SQL expression
type expr struct {
	expr string
	args []interface{}
}

// Expr generate raw SQL expression, for example:
//     DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
func Expr(expression string, args ...interface{}) *expr {
	return &expr{expr: expression, args: args}
}

func indirect(reflectValue reflect.Value) reflect.Value {
	for reflectValue.Kind() == reflect.Ptr {
		reflectValue = reflectValue.Elem()
	}
	return reflectValue
}

func toQueryMarks(primaryValues [][]interface{}) string {
	var results []string

	for _, primaryValue := range primaryValues {
		var marks []string
		for _,_ = range primaryValue {
			marks = append(marks, "?")
		}

		if len(marks) > 1 {
			results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
		} else {
			results = append(results, strings.Join(marks, ""))
		}
	}
	return strings.Join(results, ",")
}

func toQueryCondition(scope *Scope, columns []string) string {
	var newColumns []string
	for _, column := range columns {
		newColumns = append(newColumns, scope.Quote(column))
	}

	if len(columns) > 1 {
		return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
	}
	return strings.Join(newColumns, ",")
}

func toQueryValues(values [][]interface{}) (results []interface{}) {
	for _, value := range values {
		for _, v := range value {
			results = append(results, v)
		}
	}
	return
}

func fileWithLineNum() string {
	for i := 2; i < 15; i++ {
		_, file, line, ok := runtime.Caller(i)
		if ok && (!regexp.MustCompile(`jinzhu/gorm/.*.go`).MatchString(file) || regexp.MustCompile(`jinzhu/gorm/.*test.go`).MatchString(file)) {
			return fmt.Sprintf("%v:%v", file, line)
		}
	}
	return ""
}

func isBlank(value reflect.Value) bool {
	return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
}

func toSearchableMap(attrs ...interface{}) (result interface{}) {
	if len(attrs) > 1 {
		if str, ok := attrs[0].(string); ok {
			result = map[string]interface{}{str: attrs[1]}
		}
	} else if len(attrs) == 1 {
		if attr, ok := attrs[0].(map[string]interface{}); ok {
			result = attr
		}

		if attr, ok := attrs[0].(interface{}); ok {
			result = attr
		}
	}
	return
}

func equalAsString(a interface{}, b interface{}) bool {
	return toString(a) == toString(b)
}

func toString(str interface{}) string {
	if values, ok := str.([]interface{}); ok {
		var results []string
		for _, value := range values {
			results = append(results, toString(value))
		}
		return strings.Join(results, "_")
	} else if bytes, ok := str.([]byte); ok {
		return string(bytes)
	} else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
		return fmt.Sprintf("%v", reflectValue.Interface())
	}
	return ""
}

func makeSlice(elemType reflect.Type) interface{} {
	if elemType.Kind() == reflect.Slice {
		elemType = elemType.Elem()
	}
	sliceType := reflect.SliceOf(elemType)
	slice := reflect.New(sliceType)
	slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
	return slice.Interface()
}

func strInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// getValueFromFields return given fields's value
func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
	// If value is a nil pointer, Indirect returns a zero Value!
	// Therefor we need to check for a zero value,
	// as FieldByName could panic
	if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
		for _, fieldName := range fieldNames {
			if fieldValue := indirectValue.FieldByName(fieldName); fieldValue.IsValid() {
				result := fieldValue.Interface()
				if r, ok := result.(driver.Valuer); ok {
					result, _ = r.Value()
				}
				results = append(results, result)
			}
		}
	}
	return
}

func addExtraSpaceIfExist(str string) string {
	if str != "" {
		return " " + str
	}
	return ""
}
<|endoftext|>