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

package eng

import (
	"encoding/json"
	gl "github.com/chsc/gogl/gl33"
	"image"
	"image/draw"
	_ "image/png"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

// A Texture wraps an opengl texture and is mostly used for loading
// images and constructing Regions.
type Texture struct {
	id        gl.Uint
	width     int
	height    int
	minFilter gl.Int
	maxFilter gl.Int
	uWrap     gl.Int
	vWrap     gl.Int
}

// NewTexture takes either a string path to an image file, an
// io.Reader containing image date or an image.Image and returns a Texture.
func NewTexture(data interface{}) *Texture {
	var m image.Image

	switch data := data.(type) {
	default:
		log.Fatal("NewTexture needs a string or io.Reader")
	case string:
		file, err := os.Open(data)
		if err != nil {
			log.Fatal(err)
		}
		defer file.Close()
		img, _, err := image.Decode(file)
		if err != nil {
			panic(err)
		}
		m = img
	case io.Reader:
		img, _, err := image.Decode(data)
		if err != nil {
			panic(err)
		}
		m = img
	case image.Image:
		m = data
	}

	b := m.Bounds()
	newm := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(newm, newm.Bounds(), m, b.Min, draw.Src)

	width := m.Bounds().Max.X
	height := m.Bounds().Max.Y

	var id gl.Uint
	gl.GenTextures(1, &id)

	gl.Enable(gl.TEXTURE_2D)
	gl.BindTexture(gl.TEXTURE_2D, id)

	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)

	gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
	gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.Sizei(width), gl.Sizei(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Pointer(&newm.Pix[0]))

	gl.Disable(gl.TEXTURE_2D)

	return &Texture{id, width, height, gl.LINEAR, gl.LINEAR, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE}
}

// Split creates Regions from every width, height rect going from left
// to right, then down. This is useful for simple images with uniform cells.
func (t *Texture) Split(w, h int) []*Region {
	x := 0
	y := 0
	width := t.Width()
	height := t.Height()

	rows := height / h
	cols := width / w

	startX := x
	tiles := make([]*Region, 0)
	for row := 0; row < rows; row++ {
		x = startX
		for col := 0; col < cols; col++ {
			tiles = append(tiles, NewRegion(t, x, y, w, h))
			x += w
		}
		y += h
	}

	return tiles
}

func (t *Texture) Unpack(path string) map[string]*Region {
	regions := make(map[string]*Region)

	file, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatal(err)
	}

	var data interface{}
	err = json.Unmarshal(file, &data)
	if err != nil {
		log.Fatal(err)
	}

	root := data.(map[string]interface{})
	frames := root["frames"].([]interface{})
	for _, frameData := range frames {
		frame := frameData.(map[string]interface{})
		name := strings.Split(frame["filename"].(string), ".")[0]
		rect := frame["frame"].(map[string]interface{})
		x := int(rect["x"].(float64))
		y := int(rect["y"].(float64))
		w := int(rect["w"].(float64))
		h := int(rect["h"].(float64))
		regions[name] = NewRegion(t, x, y, w, h)
	}

	return regions
}

// Delete will dispose of the texture.
func (t *Texture) Delete() {
	gl.DeleteTextures(1, &t.id)
}

// Bind will bind the texture.
func (t *Texture) Bind() {
	gl.BindTexture(gl.TEXTURE_2D, t.id)
}

// Unbind will unbind all textures.
func (t *Texture) Unbind() {
	gl.BindTexture(gl.TEXTURE_2D, 0)
}

// Width returns the width of the texture.
func (t *Texture) Width() int {
	return t.width
}

// Height returns the height of the texture.
func (t *Texture) Height() int {
	return t.height
}

// SetFilter sets the filter type used when scaling a texture up or
// down. The default is nearest which will not doing any interpolation
// between pixels.
func (t *Texture) SetFilter(min, max gl.Int) {
	t.minFilter = min
	t.maxFilter = max
	t.Bind()
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, min)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, max)
}

// Returns the current min and max filters used.
func (t *Texture) Filter() (gl.Int, gl.Int) {
	return t.minFilter, t.maxFilter
}

func (t *Texture) SetWrap(u, v gl.Int) {
	t.uWrap = u
	t.vWrap = v
	t.Bind()
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, u)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, v)
}

func (t *Texture) Wrap() (gl.Int, gl.Int) {
	return t.uWrap, t.vWrap
}
<commit_msg>Texture defaults to linear filtering<commit_after>// Copyright 2013 Joseph Hager. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package eng

import (
	"encoding/json"
	gl "github.com/chsc/gogl/gl33"
	"image"
	"image/draw"
	_ "image/png"
	"io"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

// A Texture wraps an opengl texture and is mostly used for loading
// images and constructing Regions.
type Texture struct {
	id        gl.Uint
	width     int
	height    int
	minFilter gl.Int
	maxFilter gl.Int
	uWrap     gl.Int
	vWrap     gl.Int
}

// NewTexture takes either a string path to an image file, an
// io.Reader containing image date or an image.Image and returns a Texture.
func NewTexture(data interface{}) *Texture {
	var m image.Image

	switch data := data.(type) {
	default:
		log.Fatal("NewTexture needs a string or io.Reader")
	case string:
		file, err := os.Open(data)
		if err != nil {
			log.Fatal(err)
		}
		defer file.Close()
		img, _, err := image.Decode(file)
		if err != nil {
			panic(err)
		}
		m = img
	case io.Reader:
		img, _, err := image.Decode(data)
		if err != nil {
			panic(err)
		}
		m = img
	case image.Image:
		m = data
	}

	b := m.Bounds()
	newm := image.NewNRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
	draw.Draw(newm, newm.Bounds(), m, b.Min, draw.Src)

	width := m.Bounds().Max.X
	height := m.Bounds().Max.Y

	var id gl.Uint
	gl.GenTextures(1, &id)

	gl.Enable(gl.TEXTURE_2D)
	gl.BindTexture(gl.TEXTURE_2D, id)

	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)

	gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1)
	gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.Sizei(width), gl.Sizei(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Pointer(&newm.Pix[0]))

	gl.Disable(gl.TEXTURE_2D)

	return &Texture{id, width, height, gl.LINEAR, gl.LINEAR, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE}
}

// Split creates Regions from every width, height rect going from left
// to right, then down. This is useful for simple images with uniform cells.
func (t *Texture) Split(w, h int) []*Region {
	x := 0
	y := 0
	width := t.Width()
	height := t.Height()

	rows := height / h
	cols := width / w

	startX := x
	tiles := make([]*Region, 0)
	for row := 0; row < rows; row++ {
		x = startX
		for col := 0; col < cols; col++ {
			tiles = append(tiles, NewRegion(t, x, y, w, h))
			x += w
		}
		y += h
	}

	return tiles
}

func (t *Texture) Unpack(path string) map[string]*Region {
	regions := make(map[string]*Region)

	file, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatal(err)
	}

	var data interface{}
	err = json.Unmarshal(file, &data)
	if err != nil {
		log.Fatal(err)
	}

	root := data.(map[string]interface{})
	frames := root["frames"].([]interface{})
	for _, frameData := range frames {
		frame := frameData.(map[string]interface{})
		name := strings.Split(frame["filename"].(string), ".")[0]
		rect := frame["frame"].(map[string]interface{})
		x := int(rect["x"].(float64))
		y := int(rect["y"].(float64))
		w := int(rect["w"].(float64))
		h := int(rect["h"].(float64))
		regions[name] = NewRegion(t, x, y, w, h)
	}

	return regions
}

// Delete will dispose of the texture.
func (t *Texture) Delete() {
	gl.DeleteTextures(1, &t.id)
}

// Bind will bind the texture.
func (t *Texture) Bind() {
	gl.BindTexture(gl.TEXTURE_2D, t.id)
}

// Unbind will unbind all textures.
func (t *Texture) Unbind() {
	gl.BindTexture(gl.TEXTURE_2D, 0)
}

// Width returns the width of the texture.
func (t *Texture) Width() int {
	return t.width
}

// Height returns the height of the texture.
func (t *Texture) Height() int {
	return t.height
}

// SetFilter sets the filter type used when scaling a texture up or
// down. The default is nearest which will not doing any interpolation
// between pixels.
func (t *Texture) SetFilter(min, max gl.Int) {
	t.minFilter = min
	t.maxFilter = max
	t.Bind()
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, min)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, max)
}

// Returns the current min and max filters used.
func (t *Texture) Filter() (gl.Int, gl.Int) {
	return t.minFilter, t.maxFilter
}

func (t *Texture) SetWrap(u, v gl.Int) {
	t.uWrap = u
	t.vWrap = v
	t.Bind()
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, u)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, v)
}

func (t *Texture) Wrap() (gl.Int, gl.Int) {
	return t.uWrap, t.vWrap
}
<|endoftext|>


<commit_before>package syslogger

import (
	"log/syslog"
	"testing"

	"github.com/youtube/vitess/go/event"
)

type TestEvent struct {
	triggered bool
}

func (ev *TestEvent) Syslog(w *syslog.Writer) {
	ev.triggered = true
}

var _ Syslogger = (*TestEvent)(nil) // compile-time interface check

// TestSyslog checks that our callback works.
func TestSyslog(t *testing.T) {
	ev := new(TestEvent)
	event.Dispatch(ev)

	if !ev.triggered {
		t.Errorf("Syslog() was not called on event that implements Syslogger")
	}
}

// TestBadWriter checks that we don't panic or pass a nil Writer to the client
// when the connection fails.
func TestBadWriter(t *testing.T) {
	real_writer := writer
	writer = nil

	ev := new(TestEvent)
	event.Dispatch(ev)

	if ev.triggered {
		t.Errorf("passed nil writer to client")
	}

	writer = real_writer
}
<commit_msg>Use goStyleVariableName<commit_after>package syslogger

import (
	"log/syslog"
	"testing"

	"github.com/youtube/vitess/go/event"
)

type TestEvent struct {
	triggered bool
}

func (ev *TestEvent) Syslog(w *syslog.Writer) {
	ev.triggered = true
}

var _ Syslogger = (*TestEvent)(nil) // compile-time interface check

// TestSyslog checks that our callback works.
func TestSyslog(t *testing.T) {
	ev := new(TestEvent)
	event.Dispatch(ev)

	if !ev.triggered {
		t.Errorf("Syslog() was not called on event that implements Syslogger")
	}
}

// TestBadWriter checks that we don't panic or pass a nil Writer to the client
// when the connection fails.
func TestBadWriter(t *testing.T) {
	realWriter := writer
	writer = nil

	ev := new(TestEvent)
	event.Dispatch(ev)

	if ev.triggered {
		t.Errorf("passed nil writer to client")
	}

	writer = realWriter
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/streadway/amqp"
	"koding/tools/amqputil"
	"koding/migrators/mongo"
	"log"
)

var (
	EXCHANGE_NAME     = "a-relationshipExchange"
	WORKER_QUEUE_NAME = "relationshipEventWorker"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type Message struct {
	Event string `json:"event"`
	Data []EventData
}

type EventData struct {
	SourceName string
	SourceId   string
	TargetName string
	TargetId   string
	As         string
}

func main() {
	log.Println("Neo4J Feeder worker started")
	startConsuming()
	//looooop forever
	select {}
}

func startConsuming() {

	c := &Consumer{
		conn:    nil,
		channel: nil,
	}

	c.conn = amqputil.CreateConnection("neo4jFeeding")
	c.channel = amqputil.CreateChannel(c.conn)

	err := c.channel.ExchangeDeclare(EXCHANGE_NAME, "topic", true, false, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	//name, durable, autoDelete, exclusive, noWait, args Table
	if _, err := c.channel.QueueDeclare(
		WORKER_QUEUE_NAME, true, false, false, false, nil
	); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind(WORKER_QUEUE_NAME, "" /* binding key */, EXCHANGE_NAME, false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	//(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args Table) (<-chan Delivery, error) {
	relationshipEvent, err := c.channel.Consume("relationshipEventWorker", "neo4jFeeding", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	go func() {
		for msg := range relationshipEvent {
			body := fmt.Sprintf("%s", msg.Body)

			message, err := jsonDecode(body)
			if err != nil {
				log.Fatal(err)
			}
			//there will be only one array in data
			data := message.Data[0]
			fmt.Println(message.Event)
			if message.Event == "RelationshipSaved" {
				createNode(data)
			} else if message.Event == "RelationshipRemoved" {
				// deleteNode(data)
			}
		}
	}()
}

func createNode(data EventData) {

	sourceNode := neo4j.CreateUniqueNode(data.SourceId, data.SourceName)
	targetNode := neo4j.CreateUniqueNode(data.TargetId, data.TargetName)

	source := fmt.Sprintf("%s", sourceNode["create_relationship"])
	target := fmt.Sprintf("%s", targetNode["self"])
	neo4j.CreateRelationship(data.As, source, target)

}

func deleteNode(data EventData) {

	sourceNode := neo4j.DeleteNode(data.SourceId)
	fmt.Println(sourceNode)
	targetNode := neo4j.DeleteNode(data.TargetId)
	fmt.Println(targetNode)

}
<commit_msg>[go][koding][workers] changed exchange name<commit_after>package main

import (
	"fmt"
	"github.com/streadway/amqp"
	"koding/tools/amqputil"
	"koding/migrators/mongo"
	"log"
)

var (
	EXCHANGE_NAME     = "a-relationshipExchange"
	WORKER_QUEUE_NAME = "relationshipEventWorker"
)

type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
}

type Message struct {
	Event string `json:"event"`
	Data []EventData
}

type EventData struct {
	SourceName string
	SourceId   string
	TargetName string
	TargetId   string
	As         string
}

func main() {
	log.Println("Neo4J Feeder worker started")
	startConsuming()
	//looooop forever
	select {}
}

func startConsuming() {

	c := &Consumer{
		conn:    nil,
		channel: nil,
	}

	c.conn = amqputil.CreateConnection("neo4jFeeding")
	c.channel = amqputil.CreateChannel(c.conn)

	err := c.channel.ExchangeDeclare(EXCHANGE_NAME, "fanout", false, false, false, false, nil)
	if err != nil {
		log.Fatal("exchange.declare: %s", err)
	}

	//name, durable, autoDelete, exclusive, noWait, args Table
	if _, err := c.channel.QueueDeclare(
		WORKER_QUEUE_NAME, true, false, false, false, nil
	); err != nil {
		log.Fatal("queue.declare: %s", err)
	}

	if err := c.channel.QueueBind(WORKER_QUEUE_NAME, "" /* binding key */, EXCHANGE_NAME, false, nil); err != nil {
		log.Fatal("queue.bind: %s", err)
	}

	//(queue, consumer string, autoAck, exclusive, noLocal, noWait bool, args Table) (<-chan Delivery, error) {
	relationshipEvent, err := c.channel.Consume("relationshipEventWorker", "neo4jFeeding", true, false, false, false, nil)
	if err != nil {
		log.Fatal("basic.consume: %s", err)
	}

	go func() {
		for msg := range relationshipEvent {
			body := fmt.Sprintf("%s", msg.Body)

			message, err := jsonDecode(body)
			if err != nil {
				log.Fatal(err)
			}
			//there will be only one array in data
			data := message.Data[0]
			fmt.Println(message.Event)
			if message.Event == "RelationshipSaved" {
				createNode(data)
			} else if message.Event == "RelationshipRemoved" {
				// deleteNode(data)
			}
		}
	}()
}

func createNode(data EventData) {

	sourceNode := neo4j.CreateUniqueNode(data.SourceId, data.SourceName)
	targetNode := neo4j.CreateUniqueNode(data.TargetId, data.TargetName)

	source := fmt.Sprintf("%s", sourceNode["create_relationship"])
	target := fmt.Sprintf("%s", targetNode["self"])
	neo4j.CreateRelationship(data.As, source, target)

}

func deleteNode(data EventData) {

	sourceNode := neo4j.DeleteNode(data.SourceId)
	fmt.Println(sourceNode)
	targetNode := neo4j.DeleteNode(data.TargetId)
	fmt.Println(targetNode)

}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Vitess Authors.

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

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

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

package vtgate

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"

	"vitess.io/vitess/go/mysql"
	"vitess.io/vitess/go/test/endtoend/cluster"
)

func TestAggregateTypes(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(1,'a',1), (2,'A',1), (3,'b',1), (4,'c',3), (5,'c',4)")
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(6,'d',null), (7,'e',null), (8,'E',1)")
	assertMatches(t, conn, "select val1, count(distinct val2), count(*) from aggr_test group by val1", `[[VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("d") INT64(0) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)]]`)
	assertMatches(t, conn, "select val1, sum(distinct val2), sum(val2) from aggr_test group by val1", `[[VARCHAR("a") DECIMAL(1) DECIMAL(2)] [VARCHAR("b") DECIMAL(1) DECIMAL(1)] [VARCHAR("c") DECIMAL(7) DECIMAL(7)] [VARCHAR("d") NULL NULL] [VARCHAR("e") DECIMAL(1) DECIMAL(1)]]`)
	assertMatches(t, conn, "select val1, count(distinct val2) k, count(*) from aggr_test group by val1 order by k desc, val1", `[[VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)] [VARCHAR("d") INT64(0) INT64(1)]]`)
	assertMatches(t, conn, "select val1, count(distinct val2) k, count(*) from aggr_test group by val1 order by k desc, val1 limit 4", `[[VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)]]`)
	exec(t, conn, "delete from aggr_test")
}
<commit_msg>added an end to end test<commit_after>/*
Copyright 2019 The Vitess Authors.

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

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

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

package vtgate

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"

	"vitess.io/vitess/go/mysql"
	"vitess.io/vitess/go/test/endtoend/cluster"
)

func TestAggregateTypes(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(1,'a',1), (2,'A',1), (3,'b',1), (4,'c',3), (5,'c',4)")
	exec(t, conn, "insert into aggr_test(id, val1, val2) values(6,'d',null), (7,'e',null), (8,'E',1)")
	assertMatches(t, conn, "select val1, count(distinct val2), count(*) from aggr_test group by val1", `[[VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("d") INT64(0) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)]]`)
	assertMatches(t, conn, "select val1, sum(distinct val2), sum(val2) from aggr_test group by val1", `[[VARCHAR("a") DECIMAL(1) DECIMAL(2)] [VARCHAR("b") DECIMAL(1) DECIMAL(1)] [VARCHAR("c") DECIMAL(7) DECIMAL(7)] [VARCHAR("d") NULL NULL] [VARCHAR("e") DECIMAL(1) DECIMAL(1)]]`)
	assertMatches(t, conn, "select val1, count(distinct val2) k, count(*) from aggr_test group by val1 order by k desc, val1", `[[VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)] [VARCHAR("d") INT64(0) INT64(1)]]`)
	assertMatches(t, conn, "select val1, count(distinct val2) k, count(*) from aggr_test group by val1 order by k desc, val1 limit 4", `[[VARCHAR("c") INT64(2) INT64(2)] [VARCHAR("a") INT64(1) INT64(2)] [VARCHAR("b") INT64(1) INT64(1)] [VARCHAR("e") INT64(1) INT64(2)]]`)
	exec(t, conn, "delete from aggr_test")
}

func TestOrderByVarcharColumn(t *testing.T) {
	defer cluster.PanicHandler(t)
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &vtParams)
	require.Nil(t, err)
	defer conn.Close()
	exec(t, conn, "insert into t4(id1, id2) values(1,'a'), (2,'A'), (3,'b'), (4,'c'), (5,'test')")
	exec(t, conn, "insert into t4(id1, id2) values(6,'d'), (7,'e'), (8,'E')")
	assertMatches(t, conn, "select id1, id2 from t4 order by id2 desc", `[[INT64(5) VARCHAR("test")] [INT64(8) VARCHAR("E")] [INT64(7) VARCHAR("e")] [INT64(6) VARCHAR("d")] [INT64(4) VARCHAR("c")] [INT64(3) VARCHAR("b")] [INT64(2) VARCHAR("A")] [INT64(1) VARCHAR("a")]]`)
	exec(t, conn, "delete from t4")
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Google Inc.

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

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

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

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path"
	"strings"
	"testing"

	"github.com/youtube/vitess/go/mysql"
	"github.com/youtube/vitess/go/sqltypes"
	"github.com/youtube/vitess/go/vt/dbconfigs"
	"github.com/youtube/vitess/go/vt/vttablet/tabletserver"
	"github.com/youtube/vitess/go/vt/vttablet/tabletserver/tabletenv"
	"github.com/youtube/vitess/go/vt/vttest"

	vttestpb "github.com/youtube/vitess/go/vt/proto/vttest"
)

var (
	queryServer     *tabletserver.TabletServer
	mysqlConnParams mysql.ConnParams
	proxyConnParams mysql.ConnParams
)

func TestMain(m *testing.M) {
	flag.Parse() // Do not remove this comment, import into google3 depends on it
	tabletenv.Init()

	exitCode := func() int {
		// Launch MySQL.
		// We need a Keyspace in the topology, so the DbName is set.
		// We need a Shard too, so the database 'vttest' is created.
		cfg := vttest.Config{
			Topology: &vttestpb.VTTestTopology{
				Keyspaces: []*vttestpb.Keyspace{
					{
						Name: "vttest",
						Shards: []*vttestpb.Shard{
							{
								Name:           "0",
								DbNameOverride: "vttest",
							},
						},
					},
				},
			},
			OnlyMySQL: true,
		}
		if err := cfg.InitSchemas("vttest", testSchema, nil); err != nil {
			fmt.Fprintf(os.Stderr, "InitSchemas failed: %v\n", err)
			return 1
		}
		defer os.RemoveAll(cfg.SchemaDir)
		cluster := vttest.LocalCluster{
			Config: cfg,
		}
		if err := cluster.Setup(); err != nil {
			fmt.Fprintf(os.Stderr, "could not launch mysql: %v\n", err)
			return 1
		}
		defer cluster.TearDown()

		mysqlConnParams = cluster.MySQLConnParams()

		proxySock := path.Join(cluster.Env.Directory(), "mysqlproxy.sock")

		proxyConnParams.UnixSocket = proxySock
		proxyConnParams.Uname = "proxy"
		proxyConnParams.Pass = "letmein"

		*mysqlServerSocketPath = proxyConnParams.UnixSocket
		*mysqlAuthServerImpl = "none"

		dbcfgs := dbconfigs.DBConfigs{
			App: mysqlConnParams,
		}

		var err error
		queryServer, err = initProxy(&dbcfgs)
		if err != nil {
			fmt.Fprintf(os.Stderr, "could not start proxy: %v\n", err)
			return 1
		}
		defer queryServer.StopService()

		initMySQLProtocol()
		defer shutdownMySQLProtocol()

		return m.Run()
	}()
	os.Exit(exitCode)
}

var testSchema = `
create table test(id int, val varchar(256), primary key(id));
create table valtest(intval int default 0, floatval float default null, charval varchar(256) default null, binval varbinary(256) default null, primary key(intval));
`

func testFetch(t *testing.T, conn *mysql.Conn, sql string, expectedRows int) *sqltypes.Result {
	t.Helper()

	result, err := conn.ExecuteFetch(sql, 1000, false)
	if err != nil {
		t.Errorf("error: %v", err)
	}

	if len(result.Rows) != expectedRows {
		t.Errorf("expected %d rows but got %d", expectedRows, len(result.Rows))
	}

	return result
}

func testDML(t *testing.T, conn *mysql.Conn, sql string, expectedNumQueries int64, expectedRowsAffected uint64) {
	t.Helper()

	numQueries := tabletenv.MySQLStats.Count()
	result, err := conn.ExecuteFetch(sql, 1000, false)
	if err != nil {
		t.Errorf("error: %v", err)
	}
	numQueries = tabletenv.MySQLStats.Count() - numQueries

	if numQueries != expectedNumQueries {
		t.Errorf("expected %d mysql queries but got %d", expectedNumQueries, numQueries)
	}

	if result.RowsAffected != expectedRowsAffected {
		t.Errorf("expected %d rows affected but got %d", expectedRowsAffected, result.RowsAffected)
	}
}

func TestQueries(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	// Try a simple query case.
	testFetch(t, conn, "select * from test", 0)

	// Try a simple error case.
	_, err = conn.ExecuteFetch("select * from aa", 1000, true)
	if err == nil || !strings.Contains(err.Error(), "table aa not found in schema") {
		t.Fatalf("expected error but got: %v", err)
	}
}

func TestAutocommitDMLs(t *testing.T) {
	ctx := context.Background()

	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 3, 1)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "delete from test", 4, 1)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestPassthroughDMLs(t *testing.T) {
	ctx := context.Background()

	queryServer.SetPassthroughDMLs(true)
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 3, 1)
	testDML(t, conn, "insert into test (id, val) values(2, 'hello')", 3, 1)
	testDML(t, conn, "insert into test (id, val) values(3, 'hello')", 3, 1)

	// Subquery DMLs are errors in passthrough mode with SBR, unless
	// SetAllowUnsafeDMLs is set
	_, err = conn.ExecuteFetch("update test set val='goodbye'", 1000, true)
	if err == nil || !strings.Contains(err.Error(), "cannot identify primary key of statement") {
		t.Fatalf("expected error but got: %v", err)
	}

	queryServer.SetAllowUnsafeDMLs(true)

	// This is 3 queries in passthrough mode and not 4 queries as it would
	// be in non-passthrough mode
	testDML(t, conn, "update test set val='goodbye'", 3, 3)

	testFetch(t, conn, "select * from test where val='goodbye'", 3)
	testFetch(t, conn2, "select * from test where val='goodbye'", 3)

	testDML(t, conn, "delete from test", 4, 3)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestTransactions(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)
	testDML(t, conn, "commit", 1, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "delete from test", 2, 1)
	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn2, "begin", 1, 0)
	testDML(t, conn2, "delete from test", 2, 1)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestNoAutocommit(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testFetch(t, conn, "set autocommit=0", 0)

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 2, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)
	testDML(t, conn, "commit", 1, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "delete from test", 3, 1)
	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testFetch(t, conn2, "set autocommit=0", 0)
	testDML(t, conn2, "delete from test", 3, 1)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestTransactionsInProcess(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)

	// A second begin causes the first transaction to commit and then
	// runs the begin
	testDML(t, conn, "begin", 2, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "set autocommit=0", 0, 0)
	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(2, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 2)
	testFetch(t, conn2, "select * from test", 1)

	// Setting autocommit=1 causes the existing transaction to commit
	testDML(t, conn, "set autocommit=1", 1, 0)
	testFetch(t, conn, "select * from test", 2)
	testFetch(t, conn2, "select * from test", 2)

	testDML(t, conn, "insert into test (id, val) values(3, 'hello')", 3, 1)
	testFetch(t, conn, "select * from test", 3)
	testFetch(t, conn2, "select * from test", 3)

	testDML(t, conn2, "begin", 1, 0)
	testDML(t, conn2, "delete from test", 2, 3)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)

}

func TestOther(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testFetch(t, conn, "explain select * from test", 1)
	testFetch(t, conn, "select table_name, table_rows from information_schema.tables where table_name='test'", 1)

}
<commit_msg>Using temp dir for unix socket instead of vttest.<commit_after>/*
Copyright 2017 Google Inc.

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

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

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

import (
	"context"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"github.com/youtube/vitess/go/mysql"
	"github.com/youtube/vitess/go/sqltypes"
	"github.com/youtube/vitess/go/vt/dbconfigs"
	"github.com/youtube/vitess/go/vt/vttablet/tabletserver"
	"github.com/youtube/vitess/go/vt/vttablet/tabletserver/tabletenv"
	"github.com/youtube/vitess/go/vt/vttest"

	vttestpb "github.com/youtube/vitess/go/vt/proto/vttest"
)

var (
	queryServer     *tabletserver.TabletServer
	mysqlConnParams mysql.ConnParams
	proxyConnParams mysql.ConnParams
)

func TestMain(m *testing.M) {
	flag.Parse() // Do not remove this comment, import into google3 depends on it
	tabletenv.Init()

	exitCode := func() int {
		// Launch MySQL.
		// We need a Keyspace in the topology, so the DbName is set.
		// We need a Shard too, so the database 'vttest' is created.
		cfg := vttest.Config{
			Topology: &vttestpb.VTTestTopology{
				Keyspaces: []*vttestpb.Keyspace{
					{
						Name: "vttest",
						Shards: []*vttestpb.Shard{
							{
								Name:           "0",
								DbNameOverride: "vttest",
							},
						},
					},
				},
			},
			OnlyMySQL: true,
		}
		if err := cfg.InitSchemas("vttest", testSchema, nil); err != nil {
			fmt.Fprintf(os.Stderr, "InitSchemas failed: %v\n", err)
			return 1
		}
		defer os.RemoveAll(cfg.SchemaDir)
		cluster := vttest.LocalCluster{
			Config: cfg,
		}
		if err := cluster.Setup(); err != nil {
			fmt.Fprintf(os.Stderr, "could not launch mysql: %v\n", err)
			return 1
		}
		defer cluster.TearDown()
		mysqlConnParams = cluster.MySQLConnParams()

		// Setup a unix socket to connect to the proxy.
		// We use a temporary file.
		unixSocket, err := ioutil.TempFile("", "mysqlproxy.sock")
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create temp file: %v", err)
			return 1
		}
		proxySock := unixSocket.Name()
		os.Remove(proxySock)

		proxyConnParams.UnixSocket = proxySock
		proxyConnParams.Uname = "proxy"
		proxyConnParams.Pass = "letmein"

		*mysqlServerSocketPath = proxyConnParams.UnixSocket
		*mysqlAuthServerImpl = "none"

		// Initialize the query service on top of the vttest MySQL database.
		dbcfgs := dbconfigs.DBConfigs{
			App: mysqlConnParams,
		}
		queryServer, err = initProxy(&dbcfgs)
		if err != nil {
			fmt.Fprintf(os.Stderr, "could not start proxy: %v\n", err)
			return 1
		}
		defer queryServer.StopService()

		// Initialize the MySQL server protocol to talk to the query service.
		initMySQLProtocol()
		defer shutdownMySQLProtocol()

		return m.Run()
	}()
	os.Exit(exitCode)
}

var testSchema = `
create table test(id int, val varchar(256), primary key(id));
create table valtest(intval int default 0, floatval float default null, charval varchar(256) default null, binval varbinary(256) default null, primary key(intval));
`

func testFetch(t *testing.T, conn *mysql.Conn, sql string, expectedRows int) *sqltypes.Result {
	t.Helper()

	result, err := conn.ExecuteFetch(sql, 1000, false)
	if err != nil {
		t.Errorf("error: %v", err)
	}

	if len(result.Rows) != expectedRows {
		t.Errorf("expected %d rows but got %d", expectedRows, len(result.Rows))
	}

	return result
}

func testDML(t *testing.T, conn *mysql.Conn, sql string, expectedNumQueries int64, expectedRowsAffected uint64) {
	t.Helper()

	numQueries := tabletenv.MySQLStats.Count()
	result, err := conn.ExecuteFetch(sql, 1000, false)
	if err != nil {
		t.Errorf("error: %v", err)
	}
	numQueries = tabletenv.MySQLStats.Count() - numQueries

	if numQueries != expectedNumQueries {
		t.Errorf("expected %d mysql queries but got %d", expectedNumQueries, numQueries)
	}

	if result.RowsAffected != expectedRowsAffected {
		t.Errorf("expected %d rows affected but got %d", expectedRowsAffected, result.RowsAffected)
	}
}

func TestQueries(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	// Try a simple query case.
	testFetch(t, conn, "select * from test", 0)

	// Try a simple error case.
	_, err = conn.ExecuteFetch("select * from aa", 1000, true)
	if err == nil || !strings.Contains(err.Error(), "table aa not found in schema") {
		t.Fatalf("expected error but got: %v", err)
	}
}

func TestAutocommitDMLs(t *testing.T) {
	ctx := context.Background()

	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 3, 1)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "delete from test", 4, 1)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestPassthroughDMLs(t *testing.T) {
	ctx := context.Background()

	queryServer.SetPassthroughDMLs(true)
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 3, 1)
	testDML(t, conn, "insert into test (id, val) values(2, 'hello')", 3, 1)
	testDML(t, conn, "insert into test (id, val) values(3, 'hello')", 3, 1)

	// Subquery DMLs are errors in passthrough mode with SBR, unless
	// SetAllowUnsafeDMLs is set
	_, err = conn.ExecuteFetch("update test set val='goodbye'", 1000, true)
	if err == nil || !strings.Contains(err.Error(), "cannot identify primary key of statement") {
		t.Fatalf("expected error but got: %v", err)
	}

	queryServer.SetAllowUnsafeDMLs(true)

	// This is 3 queries in passthrough mode and not 4 queries as it would
	// be in non-passthrough mode
	testDML(t, conn, "update test set val='goodbye'", 3, 3)

	testFetch(t, conn, "select * from test where val='goodbye'", 3)
	testFetch(t, conn2, "select * from test where val='goodbye'", 3)

	testDML(t, conn, "delete from test", 4, 3)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestTransactions(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)
	testDML(t, conn, "commit", 1, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "delete from test", 2, 1)
	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn2, "begin", 1, 0)
	testDML(t, conn2, "delete from test", 2, 1)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestNoAutocommit(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testFetch(t, conn, "set autocommit=0", 0)

	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 2, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)
	testDML(t, conn, "commit", 1, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "delete from test", 3, 1)
	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testFetch(t, conn2, "set autocommit=0", 0)
	testDML(t, conn2, "delete from test", 3, 1)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)
}

func TestTransactionsInProcess(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}
	conn2, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(1, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 0)

	// A second begin causes the first transaction to commit and then
	// runs the begin
	testDML(t, conn, "begin", 2, 0)
	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)
	testDML(t, conn, "rollback", 1, 0)

	testFetch(t, conn, "select * from test", 1)
	testFetch(t, conn2, "select * from test", 1)

	testDML(t, conn, "set autocommit=0", 0, 0)
	testDML(t, conn, "begin", 1, 0)
	testDML(t, conn, "insert into test (id, val) values(2, 'hello')", 1, 1)
	testFetch(t, conn, "select * from test", 2)
	testFetch(t, conn2, "select * from test", 1)

	// Setting autocommit=1 causes the existing transaction to commit
	testDML(t, conn, "set autocommit=1", 1, 0)
	testFetch(t, conn, "select * from test", 2)
	testFetch(t, conn2, "select * from test", 2)

	testDML(t, conn, "insert into test (id, val) values(3, 'hello')", 3, 1)
	testFetch(t, conn, "select * from test", 3)
	testFetch(t, conn2, "select * from test", 3)

	testDML(t, conn2, "begin", 1, 0)
	testDML(t, conn2, "delete from test", 2, 3)
	testDML(t, conn2, "commit", 1, 0)

	testFetch(t, conn, "select * from test", 0)
	testFetch(t, conn2, "select * from test", 0)

}

func TestOther(t *testing.T) {
	ctx := context.Background()
	conn, err := mysql.Connect(ctx, &proxyConnParams)
	if err != nil {
		t.Fatal(err)
	}

	testFetch(t, conn, "explain select * from test", 1)
	testFetch(t, conn, "select table_name, table_rows from information_schema.tables where table_name='test'", 1)

}
<|endoftext|>


<commit_before>// Copyright © 2018 Mester
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package story

import (
	"fmt"
	"os"

	"github.com/cheggaaa/pb"
	"github.com/spf13/cobra"
	"gopkg.in/ahmdrz/goinsta.v2/utils"
)

var RootCmd = &cobra.Command{
	Use:   "stories",
	Short: "Get stories of a user",
	Run: func(cmd *cobra.Command, args []string) {
		output, err := cmd.Flags().GetString("output")
		if err != nil {
			output = "./files/"
		}

		target, err := cmd.Flags().GetString("target")
		if err != nil {
			fmt.Println(err)
			return
		}
		if target == "" {
			fmt.Println("required parameter `target`. See help")
			return
		}
		inst := utils.New()

		user, err := inst.Profiles.ByName(target)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		media := user.Stories()

		fmt.Println("Downloading...")
		for media.Next() {
			pgb := pb.StartNew(len(media.Items))
			for _, item := range media.Items {
				err := item.Download(output, "")
				if err != nil {
					fmt.Println(err)
				}
				pgb.Add(1)
			}
			pgb.Finish()
		}
	},
}

func init() {
	RootCmd.Flags().StringP("output", "o", "./files/", "Output directory")
	RootCmd.Flags().StringP("target", "t", "", "Target user")
}
<commit_msg>Add -i parameter to stories<commit_after>// Copyright © 2018 Mester
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package story

import (
	"fmt"
	"os"

	"github.com/cheggaaa/pb"
	"github.com/spf13/cobra"
	"gopkg.in/ahmdrz/goinsta.v2"
	"gopkg.in/ahmdrz/goinsta.v2/utils"
)

var RootCmd = &cobra.Command{
	Use:   "stories",
	Short: "Get stories of a user",
	Run: func(cmd *cobra.Command, args []string) {
		var id int64
		var target string
		cmd = cmd.Root()

		output, err := cmd.Flags().GetString("output")
		if err != nil {
			output = "./files/"
		}

		target, err = cmd.Flags().GetString("target")
		if err != nil {
			fmt.Println(err)
			return
		}
		if target == "" {
			id, err = cmd.Flags().GetInt64("id")
			if err != nil {
				fmt.Println(err)
				return
			}
			if id <= 0 {
				fmt.Println("-t or -i parameters are required")
				return
			}
		}
		inst := utils.New()

		var user *goinsta.User
		if target != "" {
			user, err = inst.Profiles.ByName(target)
		} else {
			user, err = inst.Profiles.ByID(id)
		}
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		media := user.Stories()

		fmt.Println("Downloading...")
		for media.Next() {
			pgb := pb.StartNew(len(media.Items))
			for _, item := range media.Items {
				err := item.Download(output, "")
				if err != nil {
					fmt.Println(err)
				}
				pgb.Add(1)
			}
			pgb.Finish()
		}
	},
}
<|endoftext|>


<commit_before>package sequential

import ()

// We need only one init function for both models
func (model *Model) InitBoardSignalNum() {
	// init on the metal
	model.BoardSignalNum = make([][][]int, 2)
	for strain_i := range model.BoardSignalNum {
		model.BoardSignalNum[strain_i] = make([][]int, model.Parameters.BoardSize)
		for row_i := range model.BoardSignalNum[strain_i] {
			model.BoardSignalNum[strain_i][row_i] = make([]int, model.Parameters.BoardSize)
		}
	}

	// init in the model
	center_coord := Coordinate{}
	for center_coord.r = 0; center_coord.r < model.Parameters.BoardSize; center_coord.r++ {
		for center_coord.c = 0; center_coord.c < model.Parameters.BoardSize; center_coord.c++ {
			rad_coord := Coordinate{}
			for rad_coord.r = center_coord.r - model.Parameters.SRadius; rad_coord.r <= center_coord.r+model.Parameters.SRadius; rad_coord.r++ {
				for rad_coord.c = center_coord.c - model.Parameters.SRadius; rad_coord.c <= center_coord.c+model.Parameters.SRadius; rad_coord.c++ {
					// here we count the number of signals for each cell

					// get strain at rad_coord
					strain_at_rad := model.CellStrain(rad_coord.ToroidCoordinates(model.Parameters.BoardSize))

					// the allele of signal of the strain at rad_coord
					signal_strain_at_rad := s4strain[strain_at_rad]

					// add one signal at center_coord of the signal allele from rad_coord
					model.AddToCellSignalNum(center_coord, signal_strain_at_rad, 1)
				}
			}
		}
	}
}

// TODO this comment sucks. initialize all the data samples
func (model *Model) initDataSamples() {
	model.initDataSamplesSnapshots()
	model.initDataSamplesFrequencies()
	model.initDataSamplesNeighborhoodFrequencies()
}

func (model *Model) SampleNum(freq int) (sampleNum int) {
	if model.Parameters.Generations%freq == 0 {
		// the case in which the last sample is the same as the last generation
		sampleNum = model.Parameters.Generations/freq + 1
	} else {
		// the case in which the last snapshot isn't the same as the last generation
		sampleNum = model.Parameters.Generations/freq + 2
	}
	return sampleNum
}

// Initialize the board snapshots samples
func (model *Model) initDataSamplesSnapshots() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerSnapshotSample)
	model.DataSamples.Snapshots = make([]Snapshot, sampleNum)

	for sample_i := range model.DataSamples.Snapshots {
		model.DataSamples.Snapshots[sample_i].Data = make([][]int, model.Parameters.BoardSize)
		for row := range model.DataSamples.Snapshots[sample_i].Data {
			model.DataSamples.Snapshots[sample_i].Data[row] = make([]int, model.Parameters.BoardSize)
		}
		//fmt.Println(sample_i, model.DataSamples.Snapshots[sample_i])
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.Snapshots = model.DataSamples.Snapshots[0:1]
}

// Initialize the strain frequencies samples
func (model *Model) initDataSamplesFrequencies() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerFrequencySample)

	model.DataSamples.Frequencies = make([]Frequency, sampleNum)

	for sample_i := range model.DataSamples.Frequencies {
		model.DataSamples.Frequencies[sample_i].Data = make([]int, 8)
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.Frequencies = model.DataSamples.Frequencies[0:1]
}

// Initialize the neighbors frequencies samples
func (model *Model) initDataSamplesNeighborhoodFrequencies() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerFrequencySample)

	model.DataSamples.NeighborsFrequencies = make([]NeighborsFrequency, sampleNum)
	for sample_i := range model.DataSamples.NeighborsFrequencies {
		data := make([][]int, 8)
		// for each strain we'll count how many strains are around it.
		for strain_i := range data {
			data[strain_i] = make([]int, 8)
		}
		model.DataSamples.NeighborsFrequencies[sample_i].Data = data
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.NeighborsFrequencies = model.DataSamples.NeighborsFrequencies[0:1]
}
<commit_msg>Fixing data samples slices initiation routines.<commit_after>package sequential

import ()

// We need only one init function for both models
func (model *Model) InitBoardSignalNum() {
	// init on the metal
	model.BoardSignalNum = make([][][]int, 2)
	for strain_i := range model.BoardSignalNum {
		model.BoardSignalNum[strain_i] = make([][]int, model.Parameters.BoardSize)
		for row_i := range model.BoardSignalNum[strain_i] {
			model.BoardSignalNum[strain_i][row_i] = make([]int, model.Parameters.BoardSize)
		}
	}

	// init in the model
	center_coord := Coordinate{}
	for center_coord.r = 0; center_coord.r < model.Parameters.BoardSize; center_coord.r++ {
		for center_coord.c = 0; center_coord.c < model.Parameters.BoardSize; center_coord.c++ {
			rad_coord := Coordinate{}
			for rad_coord.r = center_coord.r - model.Parameters.SRadius; rad_coord.r <= center_coord.r+model.Parameters.SRadius; rad_coord.r++ {
				for rad_coord.c = center_coord.c - model.Parameters.SRadius; rad_coord.c <= center_coord.c+model.Parameters.SRadius; rad_coord.c++ {
					// here we count the number of signals for each cell

					// get strain at rad_coord
					strain_at_rad := model.CellStrain(rad_coord.ToroidCoordinates(model.Parameters.BoardSize))

					// the allele of signal of the strain at rad_coord
					signal_strain_at_rad := s4strain[strain_at_rad]

					// add one signal at center_coord of the signal allele from rad_coord
					model.AddToCellSignalNum(center_coord, signal_strain_at_rad, 1)
				}
			}
		}
	}
}

// TODO this comment sucks. initialize all the data samples
func (model *Model) initDataSamples() {
	model.initDataSamplesSnapshots()
	model.initDataSamplesFrequencies()
	model.initDataSamplesNeighborhoodFrequencies()
}

func (model *Model) SampleNum(freq int) (sampleNum int) {
	if (model.Parameters.Generations-1)%freq == 0 {
		// the case in which the last sample is the same as the last generation
		sampleNum = (model.Parameters.Generations / freq) + 1
	} else {
		// the case in which the last snapshot isn't the same as the last generation
		sampleNum = (model.Parameters.Generations / freq) + 2
	}
	return sampleNum
}

// Initialize the board snapshots samples
func (model *Model) initDataSamplesSnapshots() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerSnapshotSample)
	model.DataSamples.Snapshots = make([]Snapshot, sampleNum)

	for sample_i := range model.DataSamples.Snapshots {
		model.DataSamples.Snapshots[sample_i].Data = make([][]int, model.Parameters.BoardSize)
		for row := range model.DataSamples.Snapshots[sample_i].Data {
			model.DataSamples.Snapshots[sample_i].Data[row] = make([]int, model.Parameters.BoardSize)
		}
		//fmt.Println(sample_i, model.DataSamples.Snapshots[sample_i])
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.Snapshots = model.DataSamples.Snapshots[0:1]
}

// Initialize the strain frequencies samples
func (model *Model) initDataSamplesFrequencies() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerFrequencySample)

	model.DataSamples.Frequencies = make([]Frequency, sampleNum)

	for sample_i := range model.DataSamples.Frequencies {
		model.DataSamples.Frequencies[sample_i].Data = make([]int, 8)
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.Frequencies = model.DataSamples.Frequencies[0:1]
}

// Initialize the neighbors frequencies samples
func (model *Model) initDataSamplesNeighborhoodFrequencies() {
	// This is the number of samples we'll take
	sampleNum := model.SampleNum(model.Settings.GenerationsPerFrequencySample)

	model.DataSamples.NeighborsFrequencies = make([]NeighborsFrequency, sampleNum)
	for sample_i := range model.DataSamples.NeighborsFrequencies {
		data := make([][]int, 8)
		// for each strain we'll count how many strains are around it.
		for strain_i := range data {
			data[strain_i] = make([]int, 8)
		}
		model.DataSamples.NeighborsFrequencies[sample_i].Data = data
	}

	// This trick makes it easy to take samples one after the next.
	// Every time you take a sample, you assign it to Slicename[len(Slicename)-1],
	// then you increase its len field by assigning Slicename = Slicename[0:len(Slicename)+1].
	model.DataSamples.NeighborsFrequencies = model.DataSamples.NeighborsFrequencies[0:1]
}
<|endoftext|>


<commit_before>package zbw

import "github.com/gonum/blas"

func Gemv(tA blas.Transpose, alpha complex128, A General, x Vector, beta complex128, y Vector) {
	if tA == blas.NoTrans {
		if x.N != A.Cols || y.N != A.Rows {
			panic("blas: dimension mismatch")
		}
	} else if tA == blas.Trans {
		if x.N != A.Rows || y.N != A.Cols {
			panic("blas: dimension mismatch")
		}
	} else {
		panic("blas: illegal value for tA")
	}

	impl.Zgemv(A.Order, tA, A.Rows, A.Cols, alpha, A.Data, A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Gbmv(tA blas.Transpose, alpha complex128, A GeneralBand, x Vector, beta complex128, y Vector) {
	if tA == blas.NoTrans {
		if x.N != A.Cols || y.N != A.Rows {
			panic("blas: dimension mismatch")
		}
	} else if tA == blas.Trans {
		if x.N != A.Rows || y.N != A.Cols {
			panic("blas: dimension mismatch")
		}
	} else {
		panic("blas: illegal value for tA")
	}
	impl.Zgbmv(A.Order, tA, A.Rows, A.Cols, A.KL, A.KU, alpha, A.Data,
		A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Trmv(tA blas.Transpose, A Triangular, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztrmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, A.Stride, x.Data, x.Inc)
}

func Tbmv(tA blas.Transpose, A TriangularBand, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztbmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.K, A.Data, A.Stride, x.Data, x.Inc)
}

func Tpmv(tA blas.Transpose, A TriangularPacked, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztpmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, x.Data, x.Inc)
}

func Trsv(tA blas.Transpose, A Triangular, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztrsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, A.Stride, x.Data, x.Inc)
}

func Tbsv(tA blas.Transpose, A TriangularBand, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztbsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.K, A.Data, A.Stride, x.Data, x.Inc)
}
func Tpsv(tA blas.Transpose, A TriangularPacked, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztpsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, x.Data, x.Inc)
}

func Hemv(alpha complex128, A Hermitian, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhemv(A.Order, A.Uplo, A.N, alpha, A.Data, A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Hbmv(alpha complex128, A HermitianBand, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhbmv(A.Order, A.Uplo, A.N, A.K, alpha, A.Data, A.Stride, x.Data,
		x.Inc, beta, y.Data, y.Inc)
}

func Hpmv(alpha complex128, A HermitianPacked, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpmv(A.Order, A.Uplo, A.N, alpha, A.Data, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Zgerc(alpha complex128, x Vector, y Vector, A General) {
	if x.N != A.Rows || y.N != A.Cols {
		panic("blas: dimension mismatch")
	}
	impl.Zgerc(A.Order, A.Rows, A.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zgeru(alpha complex128, x Vector, y Vector, A General) {
	if x.N != A.Rows || y.N != A.Cols {
		panic("blas: dimension mismatch")
	}
	impl.Zgeru(A.Order, A.Rows, A.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zher(alpha float64, x Vector, A Hermitian) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zher(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, A.Data, A.Stride)
}

func Zhpr(alpha float64, x Vector, A HermitianPacked) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpr(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, A.Data)
}

func Zher2(alpha complex128, x Vector, y Vector, A Hermitian) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zher2(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zhpr2(alpha complex128, x Vector, y Vector, A HermitianPacked) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpr2(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data)
}
<commit_msg>fixed bug with transpose argument<commit_after>package zbw

import "github.com/gonum/blas"

func Gemv(tA blas.Transpose, alpha complex128, A General, x Vector, beta complex128, y Vector) {
	if tA == blas.NoTrans {
		if x.N != A.Cols || y.N != A.Rows {
			panic("blas: dimension mismatch")
		}
	} else if tA == blas.ConjTrans {
		if x.N != A.Rows || y.N != A.Cols {
			panic("blas: dimension mismatch")
		}
	} else {
		panic("blas: illegal value for tA")
	}

	impl.Zgemv(A.Order, tA, A.Rows, A.Cols, alpha, A.Data, A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Gbmv(tA blas.Transpose, alpha complex128, A GeneralBand, x Vector, beta complex128, y Vector) {
	if tA == blas.NoTrans {
		if x.N != A.Cols || y.N != A.Rows {
			panic("blas: dimension mismatch")
		}
	} else if tA == blas.ConjTrans {
		if x.N != A.Rows || y.N != A.Cols {
			panic("blas: dimension mismatch")
		}
	} else {
		panic("blas: illegal value for tA")
	}
	impl.Zgbmv(A.Order, tA, A.Rows, A.Cols, A.KL, A.KU, alpha, A.Data,
		A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Trmv(tA blas.Transpose, A Triangular, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztrmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, A.Stride, x.Data, x.Inc)
}

func Tbmv(tA blas.Transpose, A TriangularBand, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztbmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.K, A.Data, A.Stride, x.Data, x.Inc)
}

func Tpmv(tA blas.Transpose, A TriangularPacked, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztpmv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, x.Data, x.Inc)
}

func Trsv(tA blas.Transpose, A Triangular, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztrsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, A.Stride, x.Data, x.Inc)
}

func Tbsv(tA blas.Transpose, A TriangularBand, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztbsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.K, A.Data, A.Stride, x.Data, x.Inc)
}
func Tpsv(tA blas.Transpose, A TriangularPacked, x Vector) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Ztpsv(A.Order, A.Uplo, tA, A.Diag, A.N, A.Data, x.Data, x.Inc)
}

func Hemv(alpha complex128, A Hermitian, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhemv(A.Order, A.Uplo, A.N, alpha, A.Data, A.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Hbmv(alpha complex128, A HermitianBand, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhbmv(A.Order, A.Uplo, A.N, A.K, alpha, A.Data, A.Stride, x.Data,
		x.Inc, beta, y.Data, y.Inc)
}

func Hpmv(alpha complex128, A HermitianPacked, x Vector, beta complex128, y Vector) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpmv(A.Order, A.Uplo, A.N, alpha, A.Data, x.Data, x.Inc, beta, y.Data, y.Inc)
}

func Zgerc(alpha complex128, x Vector, y Vector, A General) {
	if x.N != A.Rows || y.N != A.Cols {
		panic("blas: dimension mismatch")
	}
	impl.Zgerc(A.Order, A.Rows, A.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zgeru(alpha complex128, x Vector, y Vector, A General) {
	if x.N != A.Rows || y.N != A.Cols {
		panic("blas: dimension mismatch")
	}
	impl.Zgeru(A.Order, A.Rows, A.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zher(alpha float64, x Vector, A Hermitian) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zher(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, A.Data, A.Stride)
}

func Zhpr(alpha float64, x Vector, A HermitianPacked) {
	if x.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpr(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, A.Data)
}

func Zher2(alpha complex128, x Vector, y Vector, A Hermitian) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zher2(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data, A.Stride)
}

func Zhpr2(alpha complex128, x Vector, y Vector, A HermitianPacked) {
	if x.N != A.N || y.N != A.N {
		panic("blas: dimension mismatch")
	}
	impl.Zhpr2(A.Order, A.Uplo, A.N, alpha, x.Data, x.Inc, y.Data, y.Inc, A.Data)
}
<|endoftext|>


<commit_before>package commands

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/github/git-lfs/lfs"
	"github.com/spf13/cobra"
)

var (
	Debugging    = false
	ErrorBuffer  = &bytes.Buffer{}
	ErrorWriter  = io.MultiWriter(os.Stderr, ErrorBuffer)
	OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer)
	RootCmd      = &cobra.Command{
		Use:   "git-lfs",
		Short: "Git LFS provides large file storage to Git.",
		Run: func(cmd *cobra.Command, args []string) {
			versionCommand(cmd, args)
			cmd.Usage()
		},
	}
)

// Error prints a formatted message to Stderr.  It also gets printed to the
// panic log if one is created for this command.
func Error(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(ErrorWriter, line)
}

// Print prints a formatted message to Stdout.  It also gets printed to the
// panic log if one is created for this command.
func Print(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(OutputWriter, line)
}

// Exit prints a formatted message and exits.
func Exit(format string, args ...interface{}) {
	Error(format, args...)
	os.Exit(2)
}

// Debug prints a formatted message if debugging is enabled.  The formatted
// message also shows up in the panic log, if created.
func Debug(format string, args ...interface{}) {
	if !Debugging {
		return
	}
	log.Printf(format, args...)
}

// LoggedError prints a formatted message to Stderr and writes a stack trace for
// the error to a log file without exiting.
func LoggedError(err error, format string, args ...interface{}) {
	Error(format, args...)
	file := handlePanic(err)

	if len(file) > 0 {
		fmt.Fprintf(os.Stderr, "\nErrors logged to %s\nUse `git lfs logs last` to view the log.\n", file)
	}
}

// Panic prints a formatted message, and writes a stack trace for the error to
// a log file before exiting.
func Panic(err error, format string, args ...interface{}) {
	LoggedError(err, format, args...)
	os.Exit(2)
}

func Run() {
	RootCmd.Execute()
}

func PipeMediaCommand(name string, args ...string) error {
	return PipeCommand("bin/"+name, args...)
}

func PipeCommand(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func requireStdin(msg string) {
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) != 0 {
		Error("Cannot read from STDIN. %s", msg)
		os.Exit(1)
	}
}

func handlePanic(err error) string {
	if err == nil {
		return ""
	}

	return logPanic(err)
}

func logPanic(loggedError error) string {
	var fmtWriter io.Writer = os.Stderr

	if err := os.MkdirAll(lfs.LocalLogDir, 0755); err != nil {
		fmt.Fprintf(fmtWriter, "Unable to log panic to %s: %s\n\n", lfs.LocalLogDir, err.Error())
		return ""
	}

	now := time.Now()
	name := now.Format("20060102T150405.999999999")
	full := filepath.Join(lfs.LocalLogDir, name+".log")

	if file, err := os.Create(full); err != nil {
		filename := full
		full = ""
		defer func() {
			fmt.Fprintf(fmtWriter, "Unable to log panic to %s\n\n", filename)
			logPanicToWriter(fmtWriter, err)
		}()
	} else {
		fmtWriter = file
		defer file.Close()
	}

	logPanicToWriter(fmtWriter, loggedError)

	return full
}

func logPanicToWriter(w io.Writer, loggedError error) {
	fmt.Fprintf(w, "> %s", filepath.Base(os.Args[0]))
	if len(os.Args) > 0 {
		fmt.Fprintf(w, " %s", strings.Join(os.Args[1:], " "))
	}
	fmt.Fprintln(w)

	logEnv(w)
	fmt.Fprintln(w)

	w.Write(ErrorBuffer.Bytes())
	fmt.Fprintln(w)

	fmt.Fprintln(w, loggedError.Error())

	if wErr, ok := loggedError.(ErrorWithStack); ok {
		fmt.Fprintln(w, wErr.InnerError())
		for key, value := range wErr.Context() {
			fmt.Fprintf(w, "%s=%s\n", key, value)
		}
		w.Write(wErr.Stack())
	} else {
		w.Write(lfs.Stack())
	}
}

func logEnv(w io.Writer) {
	for _, env := range lfs.Environ() {
		fmt.Fprintln(w, env)
	}
}

type ErrorWithStack interface {
	Context() map[string]string
	InnerError() string
	Stack() []byte
}

func init() {
	log.SetOutput(ErrorWriter)
}
<commit_msg>ンンー ンンンン ンーンン<commit_after>package commands

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/github/git-lfs/lfs"
	"github.com/spf13/cobra"
)

var (
	Debugging    = false
	ErrorBuffer  = &bytes.Buffer{}
	ErrorWriter  = io.MultiWriter(os.Stderr, ErrorBuffer)
	OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer)
	RootCmd      = &cobra.Command{
		Use:   "git-lfs",
		Short: "Git LFS provides large file storage to Git.",
		Run: func(cmd *cobra.Command, args []string) {
			versionCommand(cmd, args)
			cmd.Usage()
		},
	}
)

// Error prints a formatted message to Stderr.  It also gets printed to the
// panic log if one is created for this command.
func Error(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(ErrorWriter, line)
}

// Print prints a formatted message to Stdout.  It also gets printed to the
// panic log if one is created for this command.
func Print(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(OutputWriter, line)
}

// Exit prints a formatted message and exits.
func Exit(format string, args ...interface{}) {
	Error(format, args...)
	os.Exit(2)
}

// Debug prints a formatted message if debugging is enabled.  The formatted
// message also shows up in the panic log, if created.
func Debug(format string, args ...interface{}) {
	if !Debugging {
		return
	}
	log.Printf(format, args...)
}

// LoggedError prints a formatted message to Stderr and writes a stack trace for
// the error to a log file without exiting.
func LoggedError(err error, format string, args ...interface{}) {
	Error(format, args...)
	file := handlePanic(err)

	if len(file) > 0 {
		fmt.Fprintf(os.Stderr, "\nErrors logged to %s\nUse `git lfs logs last` to view the log.\n", file)
	}
}

// Panic prints a formatted message, and writes a stack trace for the error to
// a log file before exiting.
func Panic(err error, format string, args ...interface{}) {
	LoggedError(err, format, args...)
	os.Exit(2)
}

func Run() {
	RootCmd.Execute()
}

func PipeMediaCommand(name string, args ...string) error {
	return PipeCommand("bin/"+name, args...)
}

func PipeCommand(name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func requireStdin(msg string) {
	stat, _ := os.Stdin.Stat()
	if (stat.Mode() & os.ModeCharDevice) != 0 {
		Error("Cannot read from STDIN. %s", msg)
		os.Exit(1)
	}
}

func handlePanic(err error) string {
	if err == nil {
		return ""
	}

	return logPanic(err)
}

func logPanic(loggedError error) string {
	var fmtWriter io.Writer = os.Stderr

	now := time.Now()
	name := now.Format("20060102T150405.999999999")
	full := filepath.Join(lfs.LocalLogDir, name+".log")

	if err := os.MkdirAll(lfs.LocalLogDir, 0755); err != nil {
		full = ""
		fmt.Fprintf(fmtWriter, "Unable to log panic to %s: %s\n\n", lfs.LocalLogDir, err.Error())
	} else if file, err := os.Create(full); err != nil {
		filename := full
		full = ""
		defer func() {
			fmt.Fprintf(fmtWriter, "Unable to log panic to %s\n\n", filename)
			logPanicToWriter(fmtWriter, err)
		}()
	} else {
		fmtWriter = file
		defer file.Close()
	}

	logPanicToWriter(fmtWriter, loggedError)

	return full
}

func logPanicToWriter(w io.Writer, loggedError error) {
	fmt.Fprintf(w, "> %s", filepath.Base(os.Args[0]))
	if len(os.Args) > 0 {
		fmt.Fprintf(w, " %s", strings.Join(os.Args[1:], " "))
	}
	fmt.Fprintln(w)

	logEnv(w)
	fmt.Fprintln(w)

	w.Write(ErrorBuffer.Bytes())
	fmt.Fprintln(w)

	fmt.Fprintln(w, loggedError.Error())

	if wErr, ok := loggedError.(ErrorWithStack); ok {
		fmt.Fprintln(w, wErr.InnerError())
		for key, value := range wErr.Context() {
			fmt.Fprintf(w, "%s=%s\n", key, value)
		}
		w.Write(wErr.Stack())
	} else {
		w.Write(lfs.Stack())
	}
}

func logEnv(w io.Writer) {
	for _, env := range lfs.Environ() {
		fmt.Fprintln(w, env)
	}
}

type ErrorWithStack interface {
	Context() map[string]string
	InnerError() string
	Stack() []byte
}

func init() {
	log.SetOutput(ErrorWriter)
}
<|endoftext|>


<commit_before>// This implements the Fs cache

package rc

import (
	"sync"
	"time"

	"github.com/ncw/rclone/fs"
)

var (
	fsCacheMu           sync.Mutex
	fsCache             = map[string]*cacheEntry{}
	fsNewFs             = fs.NewFs // for tests
	expireRunning       = false
	cacheExpireDuration = 300 * time.Second // expire the cache entry when it is older than this
	cacheExpireInterval = 60 * time.Second  // interval to run the cache expire
)

type cacheEntry struct {
	f        fs.Fs
	fsString string
	lastUsed time.Time
}

// GetCachedFs gets a fs.Fs named fsString either from the cache or creates it afresh
func GetCachedFs(fsString string) (f fs.Fs, err error) {
	fsCacheMu.Lock()
	defer fsCacheMu.Unlock()
	entry, ok := fsCache[fsString]
	if !ok {
		f, err = fsNewFs(fsString)
		if err != nil {
			return nil, err
		}
		entry = &cacheEntry{
			f:        f,
			fsString: fsString,
		}
		fsCache[fsString] = entry
	}
	entry.lastUsed = time.Now()
	if !expireRunning {
		time.AfterFunc(cacheExpireInterval, cacheExpire)
		expireRunning = true
	}
	return entry.f, err
}

// cacheExpire expires any entries that haven't been used recently
func cacheExpire() {
	fsCacheMu.Lock()
	defer fsCacheMu.Unlock()
	now := time.Now()
	for fsString, entry := range fsCache {
		if now.Sub(entry.lastUsed) > cacheExpireDuration {
			delete(fsCache, fsString)
		}
	}
	if len(fsCache) != 0 {
		time.AfterFunc(cacheExpireInterval, cacheExpire)
		expireRunning = true
	} else {
		expireRunning = false
	}
}

// GetFsNamed gets a fs.Fs named fsName either from the cache or creates it afresh
func GetFsNamed(in Params, fsName string) (f fs.Fs, err error) {
	fsString, err := in.GetString(fsName)
	if err != nil {
		return nil, err
	}

	return GetCachedFs(fsString)
}

// GetFs gets a fs.Fs named "fs" either from the cache or creates it afresh
func GetFs(in Params) (f fs.Fs, err error) {
	return GetFsNamed(in, "fs")
}

// GetFsAndRemoteNamed gets the fsName parameter from in, makes a
// remote or fetches it from the cache then gets the remoteName
// parameter from in too.
func GetFsAndRemoteNamed(in Params, fsName, remoteName string) (f fs.Fs, remote string, err error) {
	remote, err = in.GetString(remoteName)
	if err != nil {
		return
	}
	f, err = GetFsNamed(in, fsName)
	return

}

// GetFsAndRemote gets the `fs` parameter from in, makes a remote or
// fetches it from the cache then gets the `remote` parameter from in
// too.
func GetFsAndRemote(in Params) (f fs.Fs, remote string, err error) {
	return GetFsAndRemoteNamed(in, "fs", "remote")
}
<commit_msg>rc: implement rc.PutCachedFs for prefilling the remote cache<commit_after>// This implements the Fs cache

package rc

import (
	"sync"
	"time"

	"github.com/ncw/rclone/fs"
)

var (
	fsCacheMu           sync.Mutex
	fsCache             = map[string]*cacheEntry{}
	fsNewFs             = fs.NewFs // for tests
	expireRunning       = false
	cacheExpireDuration = 300 * time.Second // expire the cache entry when it is older than this
	cacheExpireInterval = 60 * time.Second  // interval to run the cache expire
)

type cacheEntry struct {
	f        fs.Fs
	fsString string
	lastUsed time.Time
}

// GetCachedFs gets a fs.Fs named fsString either from the cache or creates it afresh
func GetCachedFs(fsString string) (f fs.Fs, err error) {
	fsCacheMu.Lock()
	defer fsCacheMu.Unlock()
	entry, ok := fsCache[fsString]
	if !ok {
		f, err = fsNewFs(fsString)
		if err != nil {
			return nil, err
		}
		entry = &cacheEntry{
			f:        f,
			fsString: fsString,
		}
		fsCache[fsString] = entry
	}
	entry.lastUsed = time.Now()
	if !expireRunning {
		time.AfterFunc(cacheExpireInterval, cacheExpire)
		expireRunning = true
	}
	return entry.f, err
}

// PutCachedFs puts an fs.Fs named fsString into the cache
func PutCachedFs(fsString string, f fs.Fs) {
	fsCacheMu.Lock()
	defer fsCacheMu.Unlock()
	fsCache[fsString] = &cacheEntry{
		f:        f,
		fsString: fsString,
		lastUsed: time.Now(),
	}
	if !expireRunning {
		time.AfterFunc(cacheExpireInterval, cacheExpire)
		expireRunning = true
	}
}

// cacheExpire expires any entries that haven't been used recently
func cacheExpire() {
	fsCacheMu.Lock()
	defer fsCacheMu.Unlock()
	now := time.Now()
	for fsString, entry := range fsCache {
		if now.Sub(entry.lastUsed) > cacheExpireDuration {
			delete(fsCache, fsString)
		}
	}
	if len(fsCache) != 0 {
		time.AfterFunc(cacheExpireInterval, cacheExpire)
		expireRunning = true
	} else {
		expireRunning = false
	}
}

// GetFsNamed gets a fs.Fs named fsName either from the cache or creates it afresh
func GetFsNamed(in Params, fsName string) (f fs.Fs, err error) {
	fsString, err := in.GetString(fsName)
	if err != nil {
		return nil, err
	}

	return GetCachedFs(fsString)
}

// GetFs gets a fs.Fs named "fs" either from the cache or creates it afresh
func GetFs(in Params) (f fs.Fs, err error) {
	return GetFsNamed(in, "fs")
}

// GetFsAndRemoteNamed gets the fsName parameter from in, makes a
// remote or fetches it from the cache then gets the remoteName
// parameter from in too.
func GetFsAndRemoteNamed(in Params, fsName, remoteName string) (f fs.Fs, remote string, err error) {
	remote, err = in.GetString(remoteName)
	if err != nil {
		return
	}
	f, err = GetFsNamed(in, fsName)
	return

}

// GetFsAndRemote gets the `fs` parameter from in, makes a remote or
// fetches it from the cache then gets the `remote` parameter from in
// too.
func GetFsAndRemote(in Params) (f fs.Fs, remote string, err error) {
	return GetFsAndRemoteNamed(in, "fs", "remote")
}
<|endoftext|>


<commit_before>package game

import (
	"image/color"
	"time"

	"github.com/Bredgren/game1/game/camera"
	"github.com/Bredgren/geo"
	"github.com/hajimehoshi/ebiten"
)

const (
	playerMoveSpeed = 500
	playerGravity   = 50
	playerJumpSpeed = 700
	playerJumpTime  = 500 * time.Millisecond
)

type player struct {
	pos    geo.Vec
	vel    geo.Vec
	bounds geo.Rect
	img    *ebiten.Image

	Left  bool    // Move left button is down
	Right bool    // Move right button is down
	Move  float64 // Gampad axis for movement
	Jump  bool    // Jump button is down

	canJump   bool
	isJumping bool
	jumpTime  time.Duration
}

func newPlayer() *player {
	img, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest)
	img.Fill(color.Black)
	p := &player{
		bounds: geo.RectWH(16, 16),
		img:    img,

		canJump:   true,
		isJumping: false,
		jumpTime:  0,
	}
	return p
}

func (p *player) update(dt time.Duration) {
	if p.Move == 0 { // If gamepad axis isn't being used, check left/right buttons.
		if p.Left {
			p.Move = -1
		}
		if p.Right {
			p.Move = 1
		}
	}

	if p.isJumping {
		if p.jumpTime <= 0 || !p.Jump {
			p.isJumping = false
		} else {
			p.jumpTime -= dt
			p.vel.Y = geo.Lerp(0, -playerJumpSpeed, p.jumpTime.Seconds()/playerJumpTime.Seconds())
		}
	} else {
		p.vel.Y += playerGravity
		if p.Jump && p.canJump {
			p.isJumping = true
			p.jumpTime = playerJumpTime
		}
	}

	p.vel.X = p.Move * playerMoveSpeed

	p.pos.Add(p.vel.Times(dt.Seconds()))

	// Ground collision
	if p.pos.Y > 0 {
		p.pos.Y = 0
		p.canJump = true
	} else {
		p.canJump = false
	}

	p.bounds.SetBottomMid(p.pos.XY())

	// Reset Move for next frame, it will be set each frame by user input.
	p.Move = 0
}

func (p *player) draw(dst *ebiten.Image, cam *camera.Camera) {
	pos := cam.ScreenCoords(geo.VecXY(p.bounds.TopLeft()))
	opts := ebiten.DrawImageOptions{}
	opts.GeoM.Translate(pos.XY())
	dst.DrawImage(p.img, &opts)
}

func (p *player) Pos() geo.Vec {
	return p.pos
}

func (p *player) SetPos(pos geo.Vec) {
	p.pos = pos
	p.bounds.SetBottomMid(p.pos.XY())
}

func (p *player) handleLeft(down bool) bool {
	p.Left = down
	return false
}

func (p *player) handleRight(down bool) bool {
	p.Right = down
	return false
}

func (p *player) handleMove(val float64) bool {
	p.Move = val
	return false
}

func (p *player) handleJump(down bool) bool {
	p.Jump = down
	return false
}
<commit_msg>Tighten up player control and jump logic<commit_after>package game

import (
	"image/color"
	"time"

	"github.com/Bredgren/game1/game/camera"
	"github.com/Bredgren/geo"
	"github.com/hajimehoshi/ebiten"
)

const (
	playerMoveSpeed = 500
	playerGravity   = 50
	playerJumpSpeed = 700
	playerJumpTime  = 500 * time.Millisecond
)

type player struct {
	pos    geo.Vec
	vel    geo.Vec
	bounds geo.Rect
	img    *ebiten.Image

	Left  bool    // Move left button is down
	Right bool    // Move right button is down
	Move  float64 // Gampad axis for movement
	Jump  bool    // Jump button is down

	canJump   bool
	isJumping bool
	jumpTime  time.Duration
}

func newPlayer() *player {
	img, _ := ebiten.NewImage(16, 16, ebiten.FilterNearest)
	img.Fill(color.Black)
	p := &player{
		bounds: geo.RectWH(16, 16),
		img:    img,

		canJump:   true,
		isJumping: false,
		jumpTime:  0,
	}
	return p
}

func (p *player) update(dt time.Duration) {
	if p.Move == 0 { // If gamepad axis isn't being used, check left/right buttons.
		if p.Left {
			p.Move = -1
		}
		if p.Right {
			p.Move = 1
		}
	}

	p.vel.X = p.Move * playerMoveSpeed

	// Check if it's time to jump before handling jump the jump state so that we start
	// jumping as soon as possible
	if !p.isJumping && p.Jump && p.canJump {
		p.isJumping = true
		p.jumpTime = playerJumpTime
	}

	if p.isJumping {
		if p.jumpTime <= 0 || !p.Jump {
			p.isJumping = false
		} else {
			p.jumpTime -= dt
			p.vel.Y = geo.Lerp(0, -playerJumpSpeed, p.jumpTime.Seconds()/playerJumpTime.Seconds())
		}
	} else {
		p.vel.Y += playerGravity
	}

	p.pos.Add(p.vel.Times(dt.Seconds()))

	// Ground collision
	if p.pos.Y > 0 {
		p.pos.Y = 0
		p.canJump = true
	} else {
		p.canJump = false
	}

	p.bounds.SetBottomMid(p.pos.XY())

	// Reset Move for next frame, it will be set each frame by user input.
	p.Move = 0
}

func (p *player) draw(dst *ebiten.Image, cam *camera.Camera) {
	pos := cam.ScreenCoords(geo.VecXY(p.bounds.TopLeft()))
	opts := ebiten.DrawImageOptions{}
	opts.GeoM.Translate(pos.XY())
	dst.DrawImage(p.img, &opts)
}

func (p *player) Pos() geo.Vec {
	return p.pos
}

func (p *player) SetPos(pos geo.Vec) {
	p.pos = pos
	p.bounds.SetBottomMid(p.pos.XY())
}

func (p *player) handleLeft(down bool) bool {
	p.Left = down
	return false
}

func (p *player) handleRight(down bool) bool {
	p.Right = down
	return false
}

func (p *player) handleMove(val float64) bool {
	p.Move = val
	return false
}

func (p *player) handleJump(down bool) bool {
	p.Jump = down
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"go/parser"
	"go/token"
	"os"
	"strings"
)

func init() {
	// declare sub-command "gourd gen service"
	appendCmds("gen", cli.Command{
		Name:    "service",
		Aliases: []string{"s"},
		Usage:   "generate service from a type",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "type, t",
				Value: "",
				Usage: "comma-separated list of type names; must be set",
			},
			cli.StringFlag{
				Name:  "storage, s",
				Value: "upperio",
				Usage: "the storage type behind the service",
			},
			cli.StringFlag{
				Name:  "output, o",
				Value: "",
				Usage: "output file name; default srcdir/<type>_service.go",
			},
		},
		Action: genService,
	})

	tpls.Append("gen:general",
		`// Note: This file is generated by gourd.
// If you want to re-generate this in the future, do not change it.

{{ template "package" . }}

import (
{{ template "imports" . }}
)
{{ template "code" . }}
	`)
}

// generate the service go file
func genService(c *cli.Context) {

	// files to parse
	var fns []string
	if len(c.Args()) == 0 {
		// TODO: find all .go in the current folder
		fmt.Println("Please provide files to parse")
		os.Exit(1)
	} else {
		fns = c.Args()
	}

	// target type
	if c.String("type") == "" {
		fmt.Println("Please provide the target type(s)")
		os.Exit(1)
	}
	tn := c.String("type")

	// separated the type names with comma
	tns := strings.Split(tn, ",")

	// storage
	var s string
	s = c.String("storage")

	// read type of type name from given file(s)
	pkg, ts, ok := readTypeFile(fns[0], tns)
	if !ok {
		fmt.Printf("Type \"%s\" not found in the provided file(s). Exit.\n", tn)
		os.Exit(1)
	}

	// loop through each type found
	for _, t := range ts {

		// output file
		var o string
		if c.String("output") == "" {
			o = strings.ToLower(t.Name) + "_service.go"
		} else {
			o = c.String("output")
		}

		// create output file (if not exists)
		f, err := os.Create(o)
		defer FormatFile(o)
		defer f.Close()
		if err != nil {
			fmt.Printf("Failed to create output file \"%s\".\n", o)
			fmt.Printf("Error: \"%s\"\nExit.\n", err.Error())
			os.Exit(1)
		}

		// write the generated output to file
		err = tpls.New("gen service:"+s).Execute(f, map[string]interface{}{
			"Pkg":  pkg,
			"Type": t,
		})
		if err != nil {
			fmt.Printf("Failed to write to file \"%s\".\n", o)
			fmt.Printf("Error: \"%s\"\nExit.\n", err.Error())
			os.Exit(1)
		}
	}

}

// test if a string exists in a string slice
func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// read typeSpec from files
func readTypeFile(inputPath string, tns []string) (pkg string, specs []genTypeSpec, ok bool) {
	fset := token.NewFileSet()

	// TODO: get to know what inputPath can be (e.g. dir?)
	f, err := parser.ParseFile(fset, inputPath, nil, parser.ParseComments)
	if err != nil {
		panic(err)
	}

	// read package name
	if f.Name == nil {
		fmt.Println("Error. Unknown package name. Exit.")
		os.Exit(1)
	} else {
		pkg = f.Name.Name
	}

	// read types name and details
	for ts := range filterTypeSpec(filterGenDecl(chanDecls(f.Decls))) {
		pts := parseTypeSpec(ts)
		if stringInSlice(pts.Name, tns) {
			specs = append(specs, pts)
			ok = true
		}
	}
	return
}
<commit_msg>Improve readTypeFile error reporting<commit_after>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"go/parser"
	"go/token"
	"os"
	"strings"
)

func init() {
	// declare sub-command "gourd gen service"
	appendCmds("gen", cli.Command{
		Name:    "service",
		Aliases: []string{"s"},
		Usage:   "generate service from a type",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "type, t",
				Value: "",
				Usage: "comma-separated list of type names; must be set",
			},
			cli.StringFlag{
				Name:  "storage, s",
				Value: "upperio",
				Usage: "the storage type behind the service",
			},
			cli.StringFlag{
				Name:  "output, o",
				Value: "",
				Usage: "output file name; default srcdir/<type>_service.go",
			},
		},
		Action: genService,
	})

	tpls.Append("gen:general",
		`// Note: This file is generated by gourd.
// If you want to re-generate this in the future, do not change it.

{{ template "package" . }}

import (
{{ template "imports" . }}
)
{{ template "code" . }}
	`)
}

// generate the service go file
func genService(c *cli.Context) {

	// files to parse
	var fns []string
	if len(c.Args()) == 0 {
		// TODO: find all .go in the current folder
		fmt.Println("Please provide files to parse")
		os.Exit(1)
	} else {
		fns = c.Args()
	}

	// target type
	if c.String("type") == "" {
		fmt.Println("Please provide the target type(s)")
		os.Exit(1)
	}
	tn := c.String("type")

	// separated the type names with comma
	tns := strings.Split(tn, ",")

	// storage
	var s string
	s = c.String("storage")

	// read type of type name from given file(s)
	pkg, ts, err := readTypeFile(fns[0], tns)
	if err != nil {
		fmt.Printf("Error parsing \"%s\". Error: %s. Exit.", fns[0], err.Error())
		os.Exit(1)
	}

	// loop through each type found
	for _, t := range ts {

		// output file
		var o string
		if c.String("output") == "" {
			o = strings.ToLower(t.Name) + "_service.go"
		} else {
			o = c.String("output")
		}

		// create output file (if not exists)
		f, err := os.Create(o)
		defer FormatFile(o)
		defer f.Close()
		if err != nil {
			fmt.Printf("Failed to create output file \"%s\".\n", o)
			fmt.Printf("Error: \"%s\"\nExit.\n", err.Error())
			os.Exit(1)
		}

		// write the generated output to file
		err = tpls.New("gen service:"+s).Execute(f, map[string]interface{}{
			"Pkg":  pkg,
			"Type": t,
		})
		if err != nil {
			fmt.Printf("Failed to write to file \"%s\".\n", o)
			fmt.Printf("Error: \"%s\"\nExit.\n", err.Error())
			os.Exit(1)
		}
	}

}

// test if a string exists in a string slice
func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

// read typeSpec from files
func readTypeFile(inputPath string, tns []string) (pkg string, specs []genTypeSpec, err error) {
	fset := token.NewFileSet()

	// inputPath can only be filename
	f, err := parser.ParseFile(fset, inputPath, nil, parser.ParseComments)
	if err != nil {
		return
	}

	// read package name
	if f.Name == nil {
		err = fmt.Errorf("Unknown package name")
	} else {
		pkg = f.Name.Name
	}

	// read types name and details
	for ts := range filterTypeSpec(filterGenDecl(chanDecls(f.Decls))) {
		pts := parseTypeSpec(ts)
		if stringInSlice(pts.Name, tns) {
			specs = append(specs, pts)
		}
	}

	// see if all types needed are found
	if len(tns) != len(specs) {
		// TODO: improve this error message. Be specific on missing type.
		err = fmt.Errorf("Not all types can be found.")
	}

	return
}
<|endoftext|>


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

import (
	"github.com/gin-gonic/gin"
	"github.com/mkevac/debugcharts/bindata"
	"log"
)

// add by mint.zhao.chiu@gmail.com
// add supported for gin web framework
func GinDebugRouter(router gin.IRouter) {
	charts := router.Group("/debug/charts")
	{
		charts.GET("/data-feed", ginDataFeedHandler)
		charts.GET("/data", ginDataHandler)
		charts.GET("", ginHandleAsset("static/index.html"))
		charts.GET("/main.js", ginHandleAsset("static/main.js"))
	}
}

func ginDataFeedHandler(ctx *gin.Context) {
	s.dataFeedHandler(ctx.Writer, ctx.Request)
}

func ginDataHandler(ctx *gin.Context) {
	dataHandler(ctx.Writer, ctx.Request)
}

func ginHandleAsset(path string) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		data, err := bindata.Asset(path)
		if err != nil {
			log.Fatal(err)
		}

		n, err := ctx.Writer.Write(data)
		if err != nil {
			log.Fatal(err)
		}

		if n != len(data) {
			log.Fatal("wrote less than supposed to")
		}
	}
}
<commit_msg>bug fix<commit_after>// Copyright 2015 mint.zhao.chiu@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package debugcharts

import (
	"github.com/gin-gonic/gin"
	"github.com/mkevac/debugcharts/bindata"
	"log"
)

// add by mint.zhao.chiu@gmail.com
// add supported for gin web framework
func GinDebugRouter(router gin.IRouter) {
	charts := router.Group("/debug/charts")
	{
		charts.GET("/data-feed", ginDataFeedHandler)
		charts.GET("/data", ginDataHandler)
		charts.GET("/", ginHandleAsset("static/index.html"))
		charts.GET("/main.js", ginHandleAsset("static/main.js"))
	}
}

func ginDataFeedHandler(ctx *gin.Context) {
	s.dataFeedHandler(ctx.Writer, ctx.Request)
}

func ginDataHandler(ctx *gin.Context) {
	dataHandler(ctx.Writer, ctx.Request)
}

func ginHandleAsset(path string) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		data, err := bindata.Asset(path)
		if err != nil {
			log.Fatal(err)
		}

		n, err := ctx.Writer.Write(data)
		if err != nil {
			log.Fatal(err)
		}

		if n != len(data) {
			log.Fatal("wrote less than supposed to")
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Timo Savola. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package compile

import (
	"github.com/tsavola/wag/internal/obj"
)

type ObjectMapper = obj.ObjectMapper

type dummyMap struct{}

func (dummyMap) InitObjectMap(int, int)   {}
func (dummyMap) PutImportFuncAddr(int32)  {}
func (dummyMap) PutFuncAddr(int32)        {}
func (dummyMap) PutCallSite(int32, int32) {}
func (dummyMap) PutInsnAddr(int32)        {}
func (dummyMap) PutDataBlock(int32, int)  {}

// FuncMap implements ObjectMapper.  It stores addresses of the non-import
// functions which were specified by the creator.
type FuncMap struct {
	FuncAddrs map[uint32]int32

	funcIndex uint32
}

func NewFuncMap(funcIndexes ...uint32) (m *FuncMap) {
	m = &FuncMap{
		FuncAddrs: make(map[uint32]int32),
	}
	for _, index := range funcIndexes {
		m.FuncAddrs[index] = 0
	}
	return
}

func (*FuncMap) InitObjectMap(int, int) {}

func (m *FuncMap) PutImportFuncAddr(int32) {
	m.funcIndex++
}

func (m *FuncMap) PutFuncAddr(addr int32) {
	if _, specified := m.FuncAddrs[m.funcIndex]; specified {
		m.FuncAddrs[m.funcIndex] = addr
	}
	m.funcIndex++
}

func (*FuncMap) PutCallSite(int32, int32) {}
func (*FuncMap) PutInsnAddr(int32)        {}
func (*FuncMap) PutDataBlock(int32, int)  {}
<commit_msg>compile: remove secondary FuncMap implementation<commit_after>// Copyright (c) 2018 Timo Savola. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package compile

import (
	"github.com/tsavola/wag/internal/obj"
)

type ObjectMapper = obj.ObjectMapper

type dummyMap struct{}

func (dummyMap) InitObjectMap(int, int)   {}
func (dummyMap) PutImportFuncAddr(int32)  {}
func (dummyMap) PutFuncAddr(int32)        {}
func (dummyMap) PutCallSite(int32, int32) {}
func (dummyMap) PutInsnAddr(int32)        {}
func (dummyMap) PutDataBlock(int32, int)  {}
<|endoftext|>


<commit_before>package gh

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func Test_PerformMerge(t *testing.T) {
	assert := assert.New(t)
	_ = assert
}
<commit_msg>Add client tests in github_test.go<commit_after>package gh

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func Test_Client(t *testing.T) {
	assert := assert.New(t)

	c1 := NewClient("token1", "owner1", "repo1")
	c2 := NewClient("token2", "owner2", "repo2")
	c3 := NewClient("token1", "owner3", "repo3")

	assert.NotEqual(c1.client, c2.client)
	assert.Equal(c1.client, c3.client)
	assert.NotEqual(c2.client, c3.client)
	assert.Equal([]string{"owner1", "repo1"}, []string{c1.owner, c1.repo})
	assert.Equal([]string{"owner2", "repo2"}, []string{c2.owner, c2.repo})
	assert.Equal([]string{"owner3", "repo3"}, []string{c3.owner, c3.repo})
}
<|endoftext|>


<commit_before>package complete

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

func File(buf []rune, pos int) ([]string, error) {
	i := strings.LastIndexAny(string(buf[:pos]), " '") + 1
	prefix := string(buf[i:pos])
	p, pend := filepath.Split(prefix)
	if p == "" {
		p = "."
	}
	if strings.HasPrefix(p, "~") {
		p = os.Getenv("HOME") + p[1:]
	}
	dir, err := os.Open(p)
	if err != nil {
		return nil, err
	}
	defer dir.Close()
	names := make([]string, 0, len(pend))
	dirnames, err := dir.Readdirnames(0)
	if err != nil {
		return nil, err
	}
	for _, name := range dirnames {
		if !strings.HasPrefix(name, pend) {
			continue
		}
		n := name[len(pend):]
		stat, err := os.Stat(filepath.Join(p, name))
		if err != nil {
			return nil, err
		}
		if stat.IsDir() {
			n += "/"
		}
		names = append(names, n)
	}
	return names, nil
}

func FromPath(buf []rune, pos int) ([]string, error) {
	i := strings.LastIndexAny(string(buf[:pos]), " '") + 1
	prefix := string(buf[i:pos])
	path := os.Getenv("PATH")
	names := make([]string, 0, 1)
	for _, dir := range filepath.SplitList(path) {
		if dir == "" {
			dir = "."
		}
		files, err := ioutil.ReadDir(dir)
		if err != nil {
			return nil, err
		}
		for _, file := range files {
			if !strings.HasPrefix(file.Name(), prefix) {
				continue
			}
			names = append(names, file.Name()[len(prefix):])
		}
	}
	return names, nil
}
<commit_msg>Sort files which is the entries of file completion<commit_after>package complete

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

func File(buf []rune, pos int) ([]string, error) {
	i := strings.LastIndexAny(string(buf[:pos]), " '") + 1
	prefix := string(buf[i:pos])
	p, pend := filepath.Split(prefix)
	if p == "" {
		p = "."
	}
	if strings.HasPrefix(p, "~") {
		p = os.Getenv("HOME") + p[1:]
	}
	dir, err := os.Open(p)
	if err != nil {
		return nil, err
	}
	defer dir.Close()
	names := make([]string, 0, len(pend))
	dirnames, err := dir.Readdirnames(0)
	if err != nil {
		return nil, err
	}
	sort.Strings(dirnames)
	for _, name := range dirnames {
		if !strings.HasPrefix(name, pend) {
			continue
		}
		n := name[len(pend):]
		stat, err := os.Stat(filepath.Join(p, name))
		if err != nil {
			return nil, err
		}
		if stat.IsDir() {
			n += "/"
		}
		names = append(names, n)
	}
	return names, nil
}

func FromPath(buf []rune, pos int) ([]string, error) {
	i := strings.LastIndexAny(string(buf[:pos]), " '") + 1
	prefix := string(buf[i:pos])
	path := os.Getenv("PATH")
	names := make([]string, 0, 1)
	for _, dir := range filepath.SplitList(path) {
		if dir == "" {
			dir = "."
		}
		files, err := ioutil.ReadDir(dir)
		if err != nil {
			return nil, err
		}
		for _, file := range files {
			if !strings.HasPrefix(file.Name(), prefix) {
				continue
			}
			names = append(names, file.Name()[len(prefix):])
		}
	}
	return names, nil
}
<|endoftext|>