<commit_before>package main

import (
	"crypto/sha1"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/dickeyxxx/golock"
	"github.com/franela/goreq"
	"github.com/heroku/heroku-cli/gode"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Hidden:      true,
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Flags:       []Flag{{Name: "background", Hidden: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = Channel
		}
		t := "foreground"
		if ctx.Flags["background"] == true {
			t = "background"
		}
		Update(channel, t)
	},
}

var binPath string
var updateLockPath = filepath.Join(AppDir(), "updating.lock")
var autoupdateFile = filepath.Join(AppDir(), "autoupdate")

func init() {
	binPath = os.Args[0]
}

// Update updates the CLI and plugins
func Update(channel string, t string) {
	if !IsUpdateNeeded(t) {
		return
	}
	done := make(chan bool)
	go func() {
		touchAutoupdateFile()
		updateCLI(channel)
		updateNode()
		updatePlugins(t)
		done <- true
	}()
	select {
	case <-time.After(time.Second * 300):
		Errln("Timed out while updating")
	case <-done:
	}
}

func updatePlugins(t string) {
	updated := false
	plugins := PluginNamesNotSymlinked()
	if len(plugins) == 0 {
		return
	}
	Err("Updating plugins... ")
	if t == "foreground" || t == "block" {
		b, _ := gode.UpdatePackages()
		if len(b) > 0 {
			updated = true
		}
	} else {
		for _, name := range plugins {
			lockfile := updateLockPath + "." + name
			LogIfError(golock.Lock(lockfile))
			b, _ := gode.UpdatePackage(name)
			LogIfError(golock.Unlock(lockfile))
			if len(b) > 0 {
				updated = true
			}
		}
	}
	Errln("done")
	if updated {
		Err("rebuilding plugins cache... ")
		ClearPluginCache()
		WritePluginCache(GetPlugins())
		Errln("done")
	}
}

func updateCLI(channel string) {
	manifest, err := getUpdateManifest(channel)
	if err != nil {
		Warn("Error updating CLI")
		PrintError(err)
		return
	}
	if manifest.Version == Version && manifest.Channel == Channel {
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out\n", Version, manifest.Version)
		return
	}
	LogIfError(golock.Lock(updateLockPath))
	defer golock.Unlock(updateLockPath)
	Errf("Updating v4 CLI to %s (%s)... ", manifest.Version, manifest.Channel)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", build.URL); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != build.Sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	os.Rename(binPath, binPath+".old")
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
	os.Remove(binPath + ".old")
	Errln("done")
}

// IsUpdateNeeded checks if an update is available
func IsUpdateNeeded(t string) bool {
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	if t == "background" {
		return time.Since(f.ModTime()) > 4*time.Hour
	} else if t == "block" {
		return time.Since(f.ModTime()) > 336*time.Hour
	}
	return true
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) (*manifest, error) {
	res, err := goreq.Request{
		Uri:       "https://cli-assets.heroku.com/" + channel + "/manifest.json",
		ShowDebug: debugging,
	}.Do()
	if err != nil {
		return nil, err
	}
	var m manifest
	res.Body.FromJsonTo(&m)
	return &m, nil
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	res, err := goreq.Request{
		Uri:       url + ".gz",
		ShowDebug: debugging,
	}.Do()
	if err != nil {
		return err
	}
	if res.StatusCode != 200 {
		b, _ := res.Body.ToString()
		return errors.New(b)
	}
	defer res.Body.Close()
	_, err = io.Copy(out, res.Body)
	if err != nil {
		return err
	}
	return out.Close()
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

// TriggerBackgroundUpdate will trigger an update to the client in the background
func TriggerBackgroundUpdate() {
	if IsUpdateNeeded("background") {
		exec.Command(binPath, "update", "--background").Start()
	}
}
<commit_msg>added logging message<commit_after>package main

import (
	"crypto/sha1"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/dickeyxxx/golock"
	"github.com/franela/goreq"
	"github.com/heroku/heroku-cli/gode"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Hidden:      true,
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Flags:       []Flag{{Name: "background", Hidden: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = Channel
		}
		t := "foreground"
		if ctx.Flags["background"] == true {
			t = "background"
		}
		Update(channel, t)
	},
}

var binPath string
var updateLockPath = filepath.Join(AppDir(), "updating.lock")
var autoupdateFile = filepath.Join(AppDir(), "autoupdate")

func init() {
	binPath = os.Args[0]
}

// Update updates the CLI and plugins
func Update(channel string, t string) {
	Debugln("running from " + binPath)
	if !IsUpdateNeeded(t) {
		return
	}
	done := make(chan bool)
	go func() {
		touchAutoupdateFile()
		updateCLI(channel)
		updateNode()
		updatePlugins(t)
		done <- true
	}()
	select {
	case <-time.After(time.Second * 300):
		Errln("Timed out while updating")
	case <-done:
	}
}

func updatePlugins(t string) {
	updated := false
	plugins := PluginNamesNotSymlinked()
	if len(plugins) == 0 {
		return
	}
	Err("Updating plugins... ")
	if t == "foreground" || t == "block" {
		b, _ := gode.UpdatePackages()
		if len(b) > 0 {
			updated = true
		}
	} else {
		for _, name := range plugins {
			lockfile := updateLockPath + "." + name
			LogIfError(golock.Lock(lockfile))
			b, _ := gode.UpdatePackage(name)
			LogIfError(golock.Unlock(lockfile))
			if len(b) > 0 {
				updated = true
			}
		}
	}
	Errln("done")
	if updated {
		Err("rebuilding plugins cache... ")
		ClearPluginCache()
		WritePluginCache(GetPlugins())
		Errln("done")
	}
}

func updateCLI(channel string) {
	manifest, err := getUpdateManifest(channel)
	if err != nil {
		Warn("Error updating CLI")
		PrintError(err)
		return
	}
	if manifest.Version == Version && manifest.Channel == Channel {
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out\n", Version, manifest.Version)
		return
	}
	LogIfError(golock.Lock(updateLockPath))
	defer golock.Unlock(updateLockPath)
	Errf("Updating v4 CLI to %s (%s)... ", manifest.Version, manifest.Channel)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", build.URL); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != build.Sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	os.Rename(binPath, binPath+".old")
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
	os.Remove(binPath + ".old")
	Errln("done")
}

// IsUpdateNeeded checks if an update is available
func IsUpdateNeeded(t string) bool {
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	if t == "background" {
		return time.Since(f.ModTime()) > 4*time.Hour
	} else if t == "block" {
		return time.Since(f.ModTime()) > 336*time.Hour
	}
	return true
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) (*manifest, error) {
	res, err := goreq.Request{
		Uri:       "https://cli-assets.heroku.com/" + channel + "/manifest.json",
		ShowDebug: debugging,
	}.Do()
	if err != nil {
		return nil, err
	}
	var m manifest
	res.Body.FromJsonTo(&m)
	return &m, nil
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	res, err := goreq.Request{
		Uri:       url + ".gz",
		ShowDebug: debugging,
	}.Do()
	if err != nil {
		return err
	}
	if res.StatusCode != 200 {
		b, _ := res.Body.ToString()
		return errors.New(b)
	}
	defer res.Body.Close()
	_, err = io.Copy(out, res.Body)
	if err != nil {
		return err
	}
	return out.Close()
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

// TriggerBackgroundUpdate will trigger an update to the client in the background
func TriggerBackgroundUpdate() {
	if IsUpdateNeeded("background") {
		exec.Command(binPath, "update", "--background").Start()
	}
}
<|endoftext|>


<commit_before>// Packge cpu contains functions for obtaining information about the cetral
// processing unit.
package cpu

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
)

var sprintf = fmt.Sprintf

// parseCPUInfo returns a newline-delimited string slice of '/proc/cpuinfo'.
func parseCPUInfo() []string {
	cached, _ := ioutil.ReadFile("/proc/cpuinfo")
	return strings.Split(string(cached), "\n")
}

// parseCPUCount returns the number of CPU cores in the system.
func parseCPUCount(cpuinfo []string) int {
	cores, _ := strconv.Atoi(strings.Fields(cpuinfo[len(cpuinfo) - 18])[3])
	return cores + 1
}

/* parseFrequency obtains the CPU frequency. It first uses Fields to return only
 * the field on that line that contains the CPU frequency. Then, it uses Replace
 * to replace the periods (for three digit frequencies) with a space. Finally,
 * it returns the frequency and adds 'MHz' at the end. */
func parseFrequency(frequency string) string {
	frequency = strings.Fields(frequency)[3][:4]
	frequency = strings.Replace(frequency, ".", " ", -1)
	return frequency + " MHz"
}

// getFrequencyFormat returns the printf format for the current core frequency.
func getFrequencyFormat(index *int, lastCore int) string {
	if *index == lastCore {
		return "%s"
	} else {
		return "%s "
	}
}

// getCoreFrequency returns the frequency of the current core.
func getCoreFrequency(cpuInfo []string, index *int, format *string) string {
	return sprintf(*format, parseFrequency(cpuInfo[*index*28+7]))
}

// Frequencies returns a string containing the frequencies of each CPU core.
func Frequencies(cpufreqs *string, done chan bool) {
	cpuInfo := parseCPUInfo()
	numCPUs := parseCPUCount(cpuInfo)
	var cpuFrequencies string
	for index := 0; index < numCPUs; index++ {
		format := getFrequencyFormat(&index, numCPUs-1)
		cpuFrequencies += getCoreFrequency(cpuInfo, &index, &format)
	}
	*cpufreqs = "Cores:" + cpuFrequencies
	done <- true
}

// getTemperature returns the CPU temperature as indicated by 'hwmon'.
func getTemperature() int {
	input, _ := ioutil.ReadFile("/sys/class/hwmon/hwmon0/temp1_input")
	temp, _ := strconv.Atoi(string(input)[:2])
	return temp
}

// CPUTemp sets the temperature of the CPU.
func CPUTemp(cputemp *int, done chan bool) {
	*cputemp = getTemperature()
	done <- true
}

// Model returns the CPU Model
func Model() string {
	modelinfo := strings.Fields(parseCPUInfo()[4])[3:]
	vendor := modelinfo[0]
	model := modelinfo[1]
	return vendor + " " + model
}
<commit_msg>Fallback in case CPU temp can't be read<commit_after>// Packge cpu contains functions for obtaining information about the cetral
// processing unit.
package cpu

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
)

var sprintf = fmt.Sprintf

// parseCPUInfo returns a newline-delimited string slice of '/proc/cpuinfo'.
func parseCPUInfo() []string {
	cached, _ := ioutil.ReadFile("/proc/cpuinfo")
	return strings.Split(string(cached), "\n")
}

// parseCPUCount returns the number of CPU cores in the system.
func parseCPUCount(cpuinfo []string) int {
	cores, _ := strconv.Atoi(strings.Fields(cpuinfo[len(cpuinfo) - 18])[3])
	return cores + 1
}

/* parseFrequency obtains the CPU frequency. It first uses Fields to return only
 * the field on that line that contains the CPU frequency. Then, it uses Replace
 * to replace the periods (for three digit frequencies) with a space. Finally,
 * it returns the frequency and adds 'MHz' at the end. */
func parseFrequency(frequency string) string {
	frequency = strings.Fields(frequency)[3][:4]
	frequency = strings.Replace(frequency, ".", " ", -1)
	return frequency + " MHz"
}

// getFrequencyFormat returns the printf format for the current core frequency.
func getFrequencyFormat(index *int, lastCore int) string {
	if *index == lastCore {
		return "%s"
	} else {
		return "%s "
	}
}

// getCoreFrequency returns the frequency of the current core.
func getCoreFrequency(cpuInfo []string, index *int, format *string) string {
	return sprintf(*format, parseFrequency(cpuInfo[*index*28+7]))
}

// Frequencies returns a string containing the frequencies of each CPU core.
func Frequencies(cpufreqs *string, done chan bool) {
	cpuInfo := parseCPUInfo()
	numCPUs := parseCPUCount(cpuInfo)
	var cpuFrequencies string
	for index := 0; index < numCPUs; index++ {
		format := getFrequencyFormat(&index, numCPUs-1)
		cpuFrequencies += getCoreFrequency(cpuInfo, &index, &format)
	}
	*cpufreqs = "Cores:" + cpuFrequencies
	done <- true
}

// getTemperature returns the CPU temperature as indicated by 'hwmon'.
func getTemperature() int {
	input, err := ioutil.ReadFile("/sys/class/hwmon/hwmon0/temp1_input")
	var temp string
	if err == nil {
		temp, _ = strconv.Atoi(string(input)[:2])
	} else {
		temp = "N/A"
	}
	return temp
}

// CPUTemp sets the temperature of the CPU.
func CPUTemp(cputemp *int, done chan bool) {
	*cputemp = getTemperature()
	done <- true
}

// Model returns the CPU Model
func Model() string {
	modelinfo := strings.Fields(parseCPUInfo()[4])[3:]
	vendor := modelinfo[0]
	model := modelinfo[1]
	return vendor + " " + model
}
<|endoftext|>


<commit_before>package upkeep

import (
	docker "github.com/fsouza/go-dockerclient"
	dri "github.com/jeffjen/docker-monitor/driver"
	disc "github.com/jeffjen/go-discovery"
	"github.com/jeffjen/go-libkv/libkv"
	timer "github.com/jeffjen/go-libkv/timer"

	log "github.com/Sirupsen/logrus"

	"encoding/gob"
	"net"
	"time"
)

const (
	DEFAULT_SYNC_PATH  = "/tmp"
	DEFAULT_SYNC_CYCLE = 2 * time.Minute
)

var (
	Sched *timer.Timer

	rec *libkv.Store

	AllocDriver func(string) (dri.Driver, error) = nil

	Advertise string
)

func noop(string) (dri.Driver, error) {
	return &dri.Noop{}, nil
}

func sync(jobId int64) {
	if err := rec.Save(DEFAULT_SYNC_PATH); err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("persist failed")
	} else {
		log.Infof("persist: %v", DEFAULT_SYNC_PATH)
	}
}

func Init(persist bool) {
	var err error

	Advertise, _, _ = net.SplitHostPort(disc.Advertise)

	if AllocDriver == nil {
		AllocDriver = noop // default safety net for driver maker
	}

	Sched = timer.NewTimer()

	Sched.Tic() // start the scheduler, don't ever stop

	if persist {
		if rec, err = libkv.Load(DEFAULT_SYNC_PATH); err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("load failed")
		}
		for _, k := range rec.Key() {
			MakeService(rec.Get(k).(*Service))
		}
		Sched.RepeatFunc(DEFAULT_SYNC_CYCLE, 1, sync)
	} else {
		rec = libkv.NewStore()
	}
}

func init() {
	gob.Register(&Service{})
	gob.Register([]docker.APIPort{})
}
<commit_msg>NIT: arrange 3rd party import order<commit_after>package upkeep

import (
	dri "github.com/jeffjen/docker-monitor/driver"
	disc "github.com/jeffjen/go-discovery"
	"github.com/jeffjen/go-libkv/libkv"
	timer "github.com/jeffjen/go-libkv/timer"

	log "github.com/Sirupsen/logrus"
	docker "github.com/fsouza/go-dockerclient"

	"encoding/gob"
	"net"
	"time"
)

const (
	DEFAULT_SYNC_PATH  = "/tmp"
	DEFAULT_SYNC_CYCLE = 2 * time.Minute
)

var (
	Sched *timer.Timer

	rec *libkv.Store

	AllocDriver func(string) (dri.Driver, error) = nil

	Advertise string
)

func noop(string) (dri.Driver, error) {
	return &dri.Noop{}, nil
}

func sync(jobId int64) {
	if err := rec.Save(DEFAULT_SYNC_PATH); err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("persist failed")
	} else {
		log.Infof("persist: %v", DEFAULT_SYNC_PATH)
	}
}

func Init(persist bool) {
	var err error

	Advertise, _, _ = net.SplitHostPort(disc.Advertise)

	if AllocDriver == nil {
		AllocDriver = noop // default safety net for driver maker
	}

	Sched = timer.NewTimer()

	Sched.Tic() // start the scheduler, don't ever stop

	if persist {
		if rec, err = libkv.Load(DEFAULT_SYNC_PATH); err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("load failed")
		}
		for _, k := range rec.Key() {
			MakeService(rec.Get(k).(*Service))
		}
		Sched.RepeatFunc(DEFAULT_SYNC_CYCLE, 1, sync)
	} else {
		rec = libkv.NewStore()
	}
}

func init() {
	gob.Register(&Service{})
	gob.Register([]docker.APIPort{})
}
<|endoftext|>


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

package cachingfs_test

import (
	"io/ioutil"
	"log"
	"strings"
	"testing"
	"time"

	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/samples/cachingfs"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
)

func TestHelloFS(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type CachingFSTest struct {
	mfs *fuse.MountedFileSystem
}

var _ TearDownInterface = &CachingFSTest{}

func init() { RegisterTestSuite(&CachingFSTest{}) }

func (t *CachingFSTest) setUp(
	lookupEntryTimeout time.Duration,
	getattrTimeout time.Duration) {
	var err error

	// Set up a temporary directory for mounting.
	mountPoint, err := ioutil.TempDir("", "caching_fs_test")
	AssertEq(nil, err)

	// Create a file system.
	fs, err := cachingfs.NewCachingFS(lookupEntryTimeout, getattrTimeout)
	AssertEq(nil, err)

	// Mount it.
	t.mfs, err = fuse.Mount(mountPoint, fs)
	AssertEq(nil, err)

	err = t.mfs.WaitForReady(context.Background())
	AssertEq(nil, err)
}

func (t *CachingFSTest) TearDown() {
	// Was the file system mounted?
	if t.mfs == nil {
		return
	}

	// Unmount the file system. Try again on "resource busy" errors.
	delay := 10 * time.Millisecond
	for {
		err := t.mfs.Unmount()
		if err == nil {
			break
		}

		if strings.Contains(err.Error(), "resource busy") {
			log.Println("Resource busy error while unmounting; trying again")
			time.Sleep(delay)
			delay = time.Duration(1.3 * float64(delay))
			continue
		}

		panic("MountedFileSystem.Unmount: " + err.Error())
	}

	if err := t.mfs.Join(context.Background()); err != nil {
		panic("MountedFileSystem.Join: " + err.Error())
	}
}

////////////////////////////////////////////////////////////////////////
// Test functions
////////////////////////////////////////////////////////////////////////

func (t *CachingFSTest) DoesFoo() {
	AssertTrue(false, "TODO")
}
<commit_msg>Added several test names.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cachingfs_test

import (
	"io/ioutil"
	"log"
	"strings"
	"testing"
	"time"

	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/samples/cachingfs"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
)

func TestHelloFS(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type CachingFSTest struct {
	mfs *fuse.MountedFileSystem
}

var _ TearDownInterface = &CachingFSTest{}

func (t *CachingFSTest) setUp(
	lookupEntryTimeout time.Duration,
	getattrTimeout time.Duration) {
	var err error

	// Set up a temporary directory for mounting.
	mountPoint, err := ioutil.TempDir("", "caching_fs_test")
	AssertEq(nil, err)

	// Create a file system.
	fs, err := cachingfs.NewCachingFS(lookupEntryTimeout, getattrTimeout)
	AssertEq(nil, err)

	// Mount it.
	t.mfs, err = fuse.Mount(mountPoint, fs)
	AssertEq(nil, err)

	err = t.mfs.WaitForReady(context.Background())
	AssertEq(nil, err)
}

func (t *CachingFSTest) TearDown() {
	// Was the file system mounted?
	if t.mfs == nil {
		return
	}

	// Unmount the file system. Try again on "resource busy" errors.
	delay := 10 * time.Millisecond
	for {
		err := t.mfs.Unmount()
		if err == nil {
			break
		}

		if strings.Contains(err.Error(), "resource busy") {
			log.Println("Resource busy error while unmounting; trying again")
			time.Sleep(delay)
			delay = time.Duration(1.3 * float64(delay))
			continue
		}

		panic("MountedFileSystem.Unmount: " + err.Error())
	}

	if err := t.mfs.Join(context.Background()); err != nil {
		panic("MountedFileSystem.Join: " + err.Error())
	}
}

////////////////////////////////////////////////////////////////////////
// Basics
////////////////////////////////////////////////////////////////////////

type BasicsTest struct {
	NoCachingTest
}

func init() { RegisterTestSuite(&BasicsTest{}) }

func (t *BasicsTest) StatNonexistent_Root() {
	AssertTrue(false, "TODO")
}

func (t *BasicsTest) StatNonexistent_Dir() {
	AssertTrue(false, "TODO")
}

func (t *BasicsTest) StatFoo() {
	AssertTrue(false, "TODO")
}

func (t *BasicsTest) StatDir() {
	AssertTrue(false, "TODO")
}

func (t *BasicsTest) StatBar() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// No caching
////////////////////////////////////////////////////////////////////////

type NoCachingTest struct {
	CachingFSTest
}

var _ SetUpInterface = &NoCachingTest{}

func init() { RegisterTestSuite(&NoCachingTest{}) }

func (t *NoCachingTest) SetUp(ti *TestInfo) {
	const (
		lookupEntryTimeout = 0
		getattrTimeout     = 0
	)

	t.CachingFSTest.setUp(lookupEntryTimeout, getattrTimeout)
}

func (t *NoCachingTest) StatStat() {
	AssertTrue(false, "TODO")
}

func (t *NoCachingTest) StatRenumberStat() {
	AssertTrue(false, "TODO")
}

func (t *NoCachingTest) StatMtimeStat() {
	AssertTrue(false, "TODO")
}

func (t *NoCachingTest) StatRenumberMtimeStat() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>/*
   Package edgeworth is a second generation iris core.

   It provides instruction decoding, execution, unparsing, and mnemonic
   generation.

   Edgeworth extends the iris architecture to 24-bits and is a modified harvard
   architecture where data and code can be used somewhat interchangeably
*/
package edgeworth

import "fmt"
type Instruction uint64
type ControlBits uint16
type RegisterIndex byte
type Datum uint32
type GetRegisterIndexError struct {
      IndexProvided int
}

func (e *GetRegisterIndexError) Error() string {
   return fmt.Sprintf("Register index %d is out of range!", e.IndexProvided)
}

func (inst Instruction) GetControlBits() ControlBits {
   return ControlBits(inst & 0x000000000000FFFF)
}

func (inst Instruction) GetRegisterIndex(index int) (RegisterIndex, error) {
   var a Instruction
   a = (inst &^ 0x000000000000FFFF) >> 16
   if index >= 0 && index < 6  {
      return RegisterIndex(a>>(8*Instruction(index))), nil
   } else {
      return 0, &GetRegisterIndexError {
         index,
      }
   }
}

<commit_msg>Fixed up the binary operations<commit_after>/*
   Package edgeworth is a second generation iris core.

   It provides instruction decoding, execution, unparsing, and mnemonic
   generation.

   Edgeworth extends the iris architecture to 24-bits and is a modified harvard
   architecture where data and code can be used somewhat interchangeably
*/
package edgeworth

import "fmt"
type Instruction uint64
type ControlBits uint16
type RegisterIndex byte
type Datum uint32
type GetRegisterIndexError struct {
      IndexProvided int
}

func (e *GetRegisterIndexError) Error() string {
   return fmt.Sprintf("Register index %d is out of range!", e.IndexProvided)
}

func (inst Instruction) GetControlBits() ControlBits {
   return ControlBits(inst & 0x000000000000FFFF)
}

func (inst Instruction) GetRegisterIndex(index int) (RegisterIndex, error) {
   var a Instruction
   a = (inst & 0xFFFFFFFFFFFF0000) >> 16
   if index >= 0 && index < 6  {
      return RegisterIndex(a>>(8*Instruction(index))), nil
   } else {
      return 0, &GetRegisterIndexError {
         index,
      }
   }
}

func (d Datum) GetTagBits() byte {
   return byte((d & 0xFF000000) >> 24)
}

func (d Datum) GetValue() Datum {
   return Datum(d & 0x00FFFFFF)
}

<|endoftext|>


<commit_before>package adodb

import (
	"errors"
	"database/sql"
	"database/sql/driver"
	"github.com/mattn/go-ole"
	"github.com/mattn/go-ole/oleutil"
	"io"
	"math/big"
	"time"
	"unsafe"
)

func init() {
	ole.CoInitialize(0)
	sql.Register("adodb", &AdodbDriver{})
}

type AdodbDriver struct {

}

type AdodbConn struct {
	db *ole.IDispatch
}

type AdodbTx struct {
	c *AdodbConn
}

func (tx *AdodbTx) Commit() error {
	_, err := oleutil.CallMethod(tx.c.db, "CommitTrans")
	if err != nil {
		return err
	}
	return nil
}

func (tx *AdodbTx) Rollback() error {
	_, err := oleutil.CallMethod(tx.c.db, "Rollback")
	if err != nil {
		return err
	}
	return nil
}

func (c *AdodbConn) exec(cmd string) error {
	_, err := oleutil.CallMethod(c.db, "Execute", cmd)
	return err
}

func (c *AdodbConn) Begin() (driver.Tx, error) {
	_, err := oleutil.CallMethod(c.db, "BeginTrans")
	if err != nil {
		return nil, err
	}
	return &AdodbTx{c}, nil
}

func (d *AdodbDriver) Open(dsn string) (driver.Conn, error) {
	unknown, err := oleutil.CreateObject("ADODB.Connection")
	if err != nil {
		return nil, err
	}
	db, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.CallMethod(db, "Open", dsn)
	if err != nil {
		return nil, err
	}
	return &AdodbConn{db}, nil
}

func (c *AdodbConn) Close() error {
	_, err := oleutil.CallMethod(c.db, "Close")
	if err != nil {
		return err
	}
	c.db = nil
	return nil
}

type AdodbStmt struct {
	c  *AdodbConn
	s  *ole.IDispatch
	ps *ole.IDispatch
	b  []string
}

func (c *AdodbConn) Prepare(query string) (driver.Stmt, error) {
	unknown, err := oleutil.CreateObject("ADODB.Command")
	if err != nil {
		return nil, err
	}
	s, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "ActiveConnection", c.db)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "CommandText", query)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "CommandType", 1)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "Prepared", true)
	if err != nil {
		return nil, err
	}
	val, err := oleutil.GetProperty(s, "Parameters")
	if err != nil {
		return nil, err
	}
	return &AdodbStmt{c, s, val.ToIDispatch(), nil}, nil
}

func (s *AdodbStmt) Bind(bind []string) error {
	s.b = bind
	return nil
}

func (s *AdodbStmt) Close() error {
	s.s.Release()
	return nil
}

func (s *AdodbStmt) NumInput() int {
	if s.b != nil {
		return len(s.b)
	}
	_, err := oleutil.CallMethod(s.ps, "Refresh")
	if err != nil {
		return -1
	}
	val, err := oleutil.GetProperty(s.ps, "Count")
	if err != nil {
		return -1
	}
	c := int(val.Val)
	return c
}

func (s *AdodbStmt) bind(args []driver.Value) error {
	if s.b != nil {
		for i, v := range args {
			var b string = "?"
			if len(s.b) < i {
				b = s.b[i]
			}
			unknown, err := oleutil.CallMethod(s.s, "CreateParameter", b, 12, 1)
			if err != nil {
				return err
			}
			param := unknown.ToIDispatch()
			defer param.Release()
			_, err = oleutil.PutProperty(param, "Value", v)
			if err != nil {
				return err
			}
			_, err = oleutil.CallMethod(s.ps, "Append", param)
			if err != nil {
				return err
			}
		}
	} else {
		for i, v := range args {
			var varval ole.VARIANT
			varval.VT = ole.VT_I4
			varval.Val = int64(i)
			val, err := oleutil.CallMethod(s.ps, "Item", &varval)
			if err != nil {
				return err
			}
			item := val.ToIDispatch()
			defer item.Release()
			_, err = oleutil.PutProperty(item, "Value", v)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (s *AdodbStmt) Query(args []driver.Value) (driver.Rows, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	rc, err := oleutil.CallMethod(s.s, "Execute")
	if err != nil {
		return nil, err
	}
	return &AdodbRows{s, rc.ToIDispatch(), -1, nil}, nil
}

func (s *AdodbStmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	_, err := oleutil.CallMethod(s.s, "Execute")
	if err != nil {
		return nil, err
	}
	return driver.ResultNoRows, nil
}

type AdodbRows struct {
	s    *AdodbStmt
	rc   *ole.IDispatch
	nc   int
	cols []string
}

func (rc *AdodbRows) Close() error {
	_, err := oleutil.CallMethod(rc.rc, "Close")
	if err != nil {
		return err
	}
	return nil
}

func (rc *AdodbRows) Columns() []string {
	if rc.nc != len(rc.cols) {
		unknown, err := oleutil.GetProperty(rc.rc, "Fields")
		if err != nil {
			return []string{}
		}
		fields := unknown.ToIDispatch()
		defer fields.Release()
		val, err := oleutil.GetProperty(fields, "Count")
		if err != nil {
			return []string{}
		}
		rc.nc = int(val.Val)
		rc.cols = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			var varval ole.VARIANT
			varval.VT = ole.VT_I4
			varval.Val = int64(i)
			val, err := oleutil.CallMethod(fields, "Item", &varval)
			if err != nil {
				return []string{}
			}
			item := val.ToIDispatch()
			if err != nil {
				return []string{}
			}
			name, err := oleutil.GetProperty(item, "Name")
			if err != nil {
				return []string{}
			}
			rc.cols[i] = name.ToString()
			item.Release()
		}
	}
	return rc.cols
}

func (rc *AdodbRows) Next(dest []driver.Value) error {
	unknown, err := oleutil.GetProperty(rc.rc, "EOF")
	if err != nil {
		return io.EOF
	}
	if unknown.Val != 0 {
		return errors.New("EOF")
	}
	unknown, err = oleutil.GetProperty(rc.rc, "Fields")
	if err != nil {
		return err
	}
	fields := unknown.ToIDispatch()
	defer fields.Release()
	for i := range dest {
		var varval ole.VARIANT
		varval.VT = ole.VT_I4
		varval.Val = int64(i)
		val, err := oleutil.CallMethod(fields, "Item", &varval)
		if err != nil {
			return err
		}
		field := val.ToIDispatch()
		defer field.Release()
		typ, err := oleutil.GetProperty(field, "Type")
		if err != nil {
			return err
		}
		val, err = oleutil.GetProperty(field, "Value")
		if err != nil {
			return err
		}
		field.Release()
		switch typ.Val {
		case 0: // ADEMPTY
			// TODO
		case 2: // ADSMALLINT
			dest[i] = int16(val.Val)
		case 3: // ADINTEGER
			dest[i] = int32(val.Val)
		case 4: // ADSINGLE
			dest[i] = float32(val.Val)
		case 5: // ADDOUBLE
			dest[i] = val.Val
		case 6: // ADCURRENCY
			dest[i] = float64(val.Val)
		case 7: // ADDATE
			// TODO
		case 8: // ADBSTR
			dest[i] = val.ToString()
		case 9: // ADIDISPATCH
			dest[i] = val.ToIDispatch()
		case 10: // ADERROR
			// TODO
		case 11: // ADBOOLEAN
			if val.Val != 0 {
				dest[i] = true
			} else {
				dest[i] = false
			}
		case 12: // ADVARIANT
			dest[i] = val
		case 13: // ADIUNKNOWN
			dest[i] = val.ToIUnknown()
		case 14: // ADDECIMAL
			// TODO
		case 16: // ADTINYINT
			dest[i] = int8(val.Val)
		case 17: // ADUNSIGNEDTINYINT
			dest[i] = uint8(val.Val)
		case 18: // ADUNSIGNEDSMALLINT
			dest[i] = uint16(val.Val)
		case 19: // ADUNSIGNEDINT
			dest[i] = uint32(val.Val)
		case 20: // ADBIGINT
			dest[i] = big.NewInt(val.Val)
		case 21: // ADUNSIGNEDBIGINT
			// TODO
		case 72: // ADGUID
			// TODO
		case 128: // ADBINARY
			sa := *(**ole.SAFEARRAY)(unsafe.Pointer(&val.Val))
			dest[i] = (*[1 << 30]byte)(unsafe.Pointer(uintptr(sa.PvData)))[0:sa.CbElements]
		case 129: // ADCHAR
			dest[i] = uint8(val.Val)
		case 130: // ADWCHAR
			dest[i] = uint16(val.Val)
		case 131: // ADNUMERIC
			dest[i] = val.Val
		case 132: // ADUSERDEFINED
			dest[i] = uintptr(val.Val)
		case 133: // ADDBDATE
			dest[i] = time.Unix(0, val.Val).UTC()
		case 134: // ADDBTIME
			dest[i] = time.Unix(0, val.Val).UTC()
		case 135: // ADDBTIMESTAMP
			dest[i] = time.Unix(0, val.Val).UTC()
		case 136: // ADCHAPTER
			dest[i] = val.ToString()
		case 200: // ADVARCHAR
			dest[i] = val.ToString()
		case 201: // ADLONGVARCHAR
			dest[i] = val.ToString()
		case 202: // ADVARWCHAR
			dest[i] = val.ToString()
		case 203: // ADLONGVARWCHAR
			dest[i] = val.ToString()
		case 204: // ADVARBINARY
			// TODO
		case 205: // ADLONGVARBINARY
			// TODO
		}
	}
	_, err = oleutil.CallMethod(rc.rc, "MoveNext")
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>also decimal. related issue #3<commit_after>package adodb

import (
	"errors"
	"database/sql"
	"database/sql/driver"
	"github.com/mattn/go-ole"
	"github.com/mattn/go-ole/oleutil"
	"io"
	"math/big"
	"time"
	"unsafe"
)

func init() {
	ole.CoInitialize(0)
	sql.Register("adodb", &AdodbDriver{})
}

type AdodbDriver struct {

}

type AdodbConn struct {
	db *ole.IDispatch
}

type AdodbTx struct {
	c *AdodbConn
}

func (tx *AdodbTx) Commit() error {
	_, err := oleutil.CallMethod(tx.c.db, "CommitTrans")
	if err != nil {
		return err
	}
	return nil
}

func (tx *AdodbTx) Rollback() error {
	_, err := oleutil.CallMethod(tx.c.db, "Rollback")
	if err != nil {
		return err
	}
	return nil
}

func (c *AdodbConn) exec(cmd string) error {
	_, err := oleutil.CallMethod(c.db, "Execute", cmd)
	return err
}

func (c *AdodbConn) Begin() (driver.Tx, error) {
	_, err := oleutil.CallMethod(c.db, "BeginTrans")
	if err != nil {
		return nil, err
	}
	return &AdodbTx{c}, nil
}

func (d *AdodbDriver) Open(dsn string) (driver.Conn, error) {
	unknown, err := oleutil.CreateObject("ADODB.Connection")
	if err != nil {
		return nil, err
	}
	db, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.CallMethod(db, "Open", dsn)
	if err != nil {
		return nil, err
	}
	return &AdodbConn{db}, nil
}

func (c *AdodbConn) Close() error {
	_, err := oleutil.CallMethod(c.db, "Close")
	if err != nil {
		return err
	}
	c.db = nil
	return nil
}

type AdodbStmt struct {
	c  *AdodbConn
	s  *ole.IDispatch
	ps *ole.IDispatch
	b  []string
}

func (c *AdodbConn) Prepare(query string) (driver.Stmt, error) {
	unknown, err := oleutil.CreateObject("ADODB.Command")
	if err != nil {
		return nil, err
	}
	s, err := unknown.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "ActiveConnection", c.db)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "CommandText", query)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "CommandType", 1)
	if err != nil {
		return nil, err
	}
	_, err = oleutil.PutProperty(s, "Prepared", true)
	if err != nil {
		return nil, err
	}
	val, err := oleutil.GetProperty(s, "Parameters")
	if err != nil {
		return nil, err
	}
	return &AdodbStmt{c, s, val.ToIDispatch(), nil}, nil
}

func (s *AdodbStmt) Bind(bind []string) error {
	s.b = bind
	return nil
}

func (s *AdodbStmt) Close() error {
	s.s.Release()
	return nil
}

func (s *AdodbStmt) NumInput() int {
	if s.b != nil {
		return len(s.b)
	}
	_, err := oleutil.CallMethod(s.ps, "Refresh")
	if err != nil {
		return -1
	}
	val, err := oleutil.GetProperty(s.ps, "Count")
	if err != nil {
		return -1
	}
	c := int(val.Val)
	return c
}

func (s *AdodbStmt) bind(args []driver.Value) error {
	if s.b != nil {
		for i, v := range args {
			var b string = "?"
			if len(s.b) < i {
				b = s.b[i]
			}
			unknown, err := oleutil.CallMethod(s.s, "CreateParameter", b, 12, 1)
			if err != nil {
				return err
			}
			param := unknown.ToIDispatch()
			defer param.Release()
			_, err = oleutil.PutProperty(param, "Value", v)
			if err != nil {
				return err
			}
			_, err = oleutil.CallMethod(s.ps, "Append", param)
			if err != nil {
				return err
			}
		}
	} else {
		for i, v := range args {
			var varval ole.VARIANT
			varval.VT = ole.VT_I4
			varval.Val = int64(i)
			val, err := oleutil.CallMethod(s.ps, "Item", &varval)
			if err != nil {
				return err
			}
			item := val.ToIDispatch()
			defer item.Release()
			_, err = oleutil.PutProperty(item, "Value", v)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func (s *AdodbStmt) Query(args []driver.Value) (driver.Rows, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	rc, err := oleutil.CallMethod(s.s, "Execute")
	if err != nil {
		return nil, err
	}
	return &AdodbRows{s, rc.ToIDispatch(), -1, nil}, nil
}

func (s *AdodbStmt) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	_, err := oleutil.CallMethod(s.s, "Execute")
	if err != nil {
		return nil, err
	}
	return driver.ResultNoRows, nil
}

type AdodbRows struct {
	s    *AdodbStmt
	rc   *ole.IDispatch
	nc   int
	cols []string
}

func (rc *AdodbRows) Close() error {
	_, err := oleutil.CallMethod(rc.rc, "Close")
	if err != nil {
		return err
	}
	return nil
}

func (rc *AdodbRows) Columns() []string {
	if rc.nc != len(rc.cols) {
		unknown, err := oleutil.GetProperty(rc.rc, "Fields")
		if err != nil {
			return []string{}
		}
		fields := unknown.ToIDispatch()
		defer fields.Release()
		val, err := oleutil.GetProperty(fields, "Count")
		if err != nil {
			return []string{}
		}
		rc.nc = int(val.Val)
		rc.cols = make([]string, rc.nc)
		for i := 0; i < rc.nc; i++ {
			var varval ole.VARIANT
			varval.VT = ole.VT_I4
			varval.Val = int64(i)
			val, err := oleutil.CallMethod(fields, "Item", &varval)
			if err != nil {
				return []string{}
			}
			item := val.ToIDispatch()
			if err != nil {
				return []string{}
			}
			name, err := oleutil.GetProperty(item, "Name")
			if err != nil {
				return []string{}
			}
			rc.cols[i] = name.ToString()
			item.Release()
		}
	}
	return rc.cols
}

func (rc *AdodbRows) Next(dest []driver.Value) error {
	unknown, err := oleutil.GetProperty(rc.rc, "EOF")
	if err != nil {
		return io.EOF
	}
	if unknown.Val != 0 {
		return errors.New("EOF")
	}
	unknown, err = oleutil.GetProperty(rc.rc, "Fields")
	if err != nil {
		return err
	}
	fields := unknown.ToIDispatch()
	defer fields.Release()
	for i := range dest {
		var varval ole.VARIANT
		varval.VT = ole.VT_I4
		varval.Val = int64(i)
		val, err := oleutil.CallMethod(fields, "Item", &varval)
		if err != nil {
			return err
		}
		field := val.ToIDispatch()
		defer field.Release()
		typ, err := oleutil.GetProperty(field, "Type")
		if err != nil {
			return err
		}
		val, err = oleutil.GetProperty(field, "Value")
		if err != nil {
			return err
		}
		field.Release()
		switch typ.Val {
		case 0: // ADEMPTY
			// TODO
		case 2: // ADSMALLINT
			dest[i] = int16(val.Val)
		case 3: // ADINTEGER
			dest[i] = int32(val.Val)
		case 4: // ADSINGLE
			dest[i] = float32(val.Val)
		case 5: // ADDOUBLE
			dest[i] = val.Val
		case 6: // ADCURRENCY
			dest[i] = float64(val.Val)
		case 7: // ADDATE
			// TODO
		case 8: // ADBSTR
			dest[i] = val.ToString()
		case 9: // ADIDISPATCH
			dest[i] = val.ToIDispatch()
		case 10: // ADERROR
			// TODO
		case 11: // ADBOOLEAN
			if val.Val != 0 {
				dest[i] = true
			} else {
				dest[i] = false
			}
		case 12: // ADVARIANT
			dest[i] = val
		case 13: // ADIUNKNOWN
			dest[i] = val.ToIUnknown()
		case 14: // ADDECIMAL
			dest[i] = float64(val.Val)
		case 16: // ADTINYINT
			dest[i] = int8(val.Val)
		case 17: // ADUNSIGNEDTINYINT
			dest[i] = uint8(val.Val)
		case 18: // ADUNSIGNEDSMALLINT
			dest[i] = uint16(val.Val)
		case 19: // ADUNSIGNEDINT
			dest[i] = uint32(val.Val)
		case 20: // ADBIGINT
			dest[i] = big.NewInt(val.Val)
		case 21: // ADUNSIGNEDBIGINT
			// TODO
		case 72: // ADGUID
			// TODO
		case 128: // ADBINARY
			sa := *(**ole.SAFEARRAY)(unsafe.Pointer(&val.Val))
			dest[i] = (*[1 << 30]byte)(unsafe.Pointer(uintptr(sa.PvData)))[0:sa.CbElements]
		case 129: // ADCHAR
			dest[i] = uint8(val.Val)
		case 130: // ADWCHAR
			dest[i] = uint16(val.Val)
		case 131: // ADNUMERIC
			dest[i] = val.Val
		case 132: // ADUSERDEFINED
			dest[i] = uintptr(val.Val)
		case 133: // ADDBDATE
			dest[i] = time.Unix(0, val.Val).UTC()
		case 134: // ADDBTIME
			dest[i] = time.Unix(0, val.Val).UTC()
		case 135: // ADDBTIMESTAMP
			dest[i] = time.Unix(0, val.Val).UTC()
		case 136: // ADCHAPTER
			dest[i] = val.ToString()
		case 200: // ADVARCHAR
			dest[i] = val.ToString()
		case 201: // ADLONGVARCHAR
			dest[i] = val.ToString()
		case 202: // ADVARWCHAR
			dest[i] = val.ToString()
		case 203: // ADLONGVARWCHAR
			dest[i] = val.ToString()
		case 204: // ADVARBINARY
			// TODO
		case 205: // ADLONGVARBINARY
			// TODO
		}
	}
	_, err = oleutil.CallMethod(rc.rc, "MoveNext")
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package fastjet

import (
	"math"

	"github.com/go-hep/fmom"
)

// // Used to protect against parton-level events where pt can be zero
// // for some partons, giving rapidity=infinity. KtJet fails in those cases.
// const (
// 	MaxRap = 1e5
// )

// UserInfo holds extra user information in a Jet
type UserInfo interface{}

// Jet holds minimal information of use for jet-clustering routines
type Jet struct {
	fmom.PxPyPzE

	UserInfo  UserInfo // holds extra user information for this Jet
	hidx      int      // cluster sequence history index
	structure JetStructure
}

func NewJet(px, py, pz, e float64) Jet {
	return Jet{
		PxPyPzE: fmom.NewPxPyPzE(px, py, pz, e),
		hidx:    -1,
	}
}

func (jet *Jet) Pt2() float64 {
	pt := jet.Pt()
	return pt * pt
}

func (jet *Jet) Rapidity() float64 {
	return 0.5 * math.Log((jet.E()+jet.Pz())/(jet.E()-jet.Pz()))
	/*
		var rap float64
		if jet.E() == math.Abs(jet.Pz()) && jet.Pt2() == 0 {
			rap = MaxRap + math.Abs(jet.Pz())
		} else {
			m := jet.M()
			m2 := math.Max(0, m*m) // effective mass - force non-tachyonic mass
			e := jet.E() + math.Abs(jet.Pz())
			rap = 0.5 * math.Log((jet.Pt2()+m2)/(e*e))
		}

		if jet.Pz() > 0 {
			rap = -rap
		}
		return rap
	*/
}

// Constituents returns the list of constituents for this jet.
func (jet *Jet) Constituents() []Jet {
	subjets, err := jet.structure.Constituents(jet)
	if err != nil {
		panic(err)
	}
	return subjets
}

// Distance returns the squared cylinder (rapidity-phi) distance between 2 jets
func Distance(j1, j2 *Jet) float64 {
	dphi := deltaPhi(j1, j2)
	drap := deltaRap(j1, j2)
	return dphi*dphi + drap*drap
}

func deltaPhi(j1, j2 *Jet) float64 {
	dphi := math.Abs(j1.Phi() - j2.Phi())
	if dphi > math.Pi {
		dphi = 2*math.Pi - dphi
	}
	return dphi
}

func deltaRap(j1, j2 *Jet) float64 {
	return j1.Rapidity() - j2.Rapidity()
}
<commit_msg>jet: add a cache for rapidity, pt2 and phi (optimization)<commit_after>package fastjet

import (
	"math"

	"github.com/go-hep/fmom"
)

// // Used to protect against parton-level events where pt can be zero
// // for some partons, giving rapidity=infinity. KtJet fails in those cases.
// const (
// 	MaxRap = 1e5
// )

// UserInfo holds extra user information in a Jet
type UserInfo interface{}

// Jet holds minimal information of use for jet-clustering routines
type Jet struct {
	fmom.PxPyPzE

	UserInfo  UserInfo // holds extra user information for this Jet
	hidx      int      // cluster sequence history index
	structure JetStructure

	// -- cache

	rap float64
	pt2 float64
	phi float64
}

func NewJet(px, py, pz, e float64) Jet {
	jet := Jet{
		PxPyPzE: fmom.NewPxPyPzE(px, py, pz, e),
		hidx:    -1,
	}
	jet.setupCache()
	return jet
}

func (jet *Jet) setupCache() {
	pt := jet.Pt()
	jet.pt2 = pt * pt

	jet.rap = 0.5 * math.Log((jet.E()+jet.Pz())/(jet.E()-jet.Pz()))
	jet.phi = jet.PxPyPzE.Phi()
}

func (jet *Jet) Pt2() float64 {
	return jet.pt2
}

func (jet *Jet) Phi() float64 {
	return jet.phi
}

func (jet *Jet) Rapidity() float64 {
	return jet.rap
	/*
		var rap float64
		if jet.E() == math.Abs(jet.Pz()) && jet.Pt2() == 0 {
			rap = MaxRap + math.Abs(jet.Pz())
		} else {
			m := jet.M()
			m2 := math.Max(0, m*m) // effective mass - force non-tachyonic mass
			e := jet.E() + math.Abs(jet.Pz())
			rap = 0.5 * math.Log((jet.Pt2()+m2)/(e*e))
		}

		if jet.Pz() > 0 {
			rap = -rap
		}
		return rap
	*/
}

// Constituents returns the list of constituents for this jet.
func (jet *Jet) Constituents() []Jet {
	subjets, err := jet.structure.Constituents(jet)
	if err != nil {
		panic(err)
	}
	return subjets
}

// Distance returns the squared cylinder (rapidity-phi) distance between 2 jets
func Distance(j1, j2 *Jet) float64 {
	//dphi := deltaPhi(j1, j2)
	dphi := math.Abs(j1.Phi() - j2.Phi())
	if dphi > math.Pi {
		dphi = 2*math.Pi - dphi
	}
	drap := j1.Rapidity() - j2.Rapidity()
	return dphi*dphi + drap*drap
}

func deltaPhi(j1, j2 *Jet) float64 {
	dphi := math.Abs(j1.Phi() - j2.Phi())
	if dphi > math.Pi {
		dphi = 2*math.Pi - dphi
	}
	return dphi
}

func deltaRap(j1, j2 *Jet) float64 {
	return j1.Rapidity() - j2.Rapidity()
}
<|endoftext|>


<commit_before>// Copyright 2014 Matthew Endsley
// All rights reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted providing that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package gojwe

import (
	"bytes"
	"compress/flate"
	"crypto"
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/json"
	"errors"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"strings"
)

// Verify and decrypt a draft-7 JWE object
func VerifyAndDecryptDraft7(jwe string, key crypto.PrivateKey) ([]byte, error) {
	parts := strings.Split(jwe, ".")
	if len(parts) != 5 {
		return nil, errors.New("Wrong number of parts")
	}

	// decode the JWE header
	var header struct {
		Alg string `json:"alg"`
		Enc string `json:"enc"`
		Zip string `json:"zip"`
	}
	data, err := safeDecode(parts[0])
	if err != nil {
		return nil, fmt.Errorf("Malformed header: %v", err)
	}
	err = json.Unmarshal(data, &header)
	if err != nil {
		return nil, fmt.Errorf("Failed to decode header: %v", err)
	}

	var encryptionKey []byte
	encryptionKeyData, err := safeDecode(parts[1])
	if err != nil {
		return nil, fmt.Errorf("Malformed encryption key: %v", err)
	}

	// decode the encryption key
	switch header.Alg {
	case "RSA-OAEP", "RSA-OAEP-256":
		rsaKey, ok := key.(*rsa.PrivateKey)
		if !ok {
			return nil, fmt.Errorf("Expected an RSA private key. Got %T", key)
		}

		var h hash.Hash
		if header.Alg == "RSA-OAEP" {
			h = sha1.New()
		} else if header.Alg == "RSA-OAEP-256" {
			h = sha256.New()
		} else {
			panic("Logic error with algorithm " + header.Alg)
		}

		encryptionKey, err = rsa.DecryptOAEP(h, rand.Reader, rsaKey, encryptionKeyData, nil)
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt encryption key: %v", err)
		}

	case "RSA1_5":
		rsaKey, ok := key.(*rsa.PrivateKey)
		if !ok {
			return nil, fmt.Errorf("Expected RSA private key. Got %T", key)
		}

		encryptionKey, err = rsa.DecryptPKCS1v15(rand.Reader, rsaKey, encryptionKeyData)
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt encryption key: %v", err)
		}

	case "A128KW", "A256KW":
		aesKey, ok := key.([]byte)
		if !ok {
			return nil, fmt.Errorf("Expected shared symmetric key ([]byte). Got %T", key)
		}

		encryptionKey, err = AesKeyUnwrap(aesKey, encryptionKeyData)
		if err != nil {
			return nil, fmt.Errorf("Failed to unwrap key: %v", err)
		}

	default:
		return nil, fmt.Errorf("Unsupported ALG keytype %s", header.Alg)
	}

	// decode IV
	iv, err := safeDecode(parts[2])
	if err != nil {
		return nil, fmt.Errorf("Malformed IV: %v", err)
	}

	// decode cipher text
	cipherText, err := safeDecode(parts[3])
	if err != nil {
		return nil, fmt.Errorf("Malformed cipher text: %v", err)
	}

	// decode authtag
	authTag, err := safeDecode(parts[4])
	if err != nil {
		return nil, fmt.Errorf("Malformed authtag: %v", err)
	}

	// decrypt and verify cipher text
	var plainText []byte

	switch header.Enc {
	case "A128CBC+HS256", "A256CBC+HS512":
		// derive keys
		var encKey, macKey []byte
		var hfunc func() hash.Hash
		if header.Enc == "A128CBC+HS256" {
			encKey, macKey = concatKDF(encryptionKey, header.Enc, 128, 256)
			hfunc = sha256.New
		} else if header.Enc == "A256CBC+HS512" {
			encKey, macKey = concatKDF(encryptionKey, header.Enc, 256, 512)
			hfunc = sha512.New
		} else {
			panic("Bad ENC logic for type: " + header.Enc)
		}

		// verify authtag
		hm := hmac.New(hfunc, macKey)
		io.WriteString(hm, parts[0])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[1])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[2])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[3])
		if !hmac.Equal(authTag, hm.Sum(nil)) {
			return nil, errors.New("Integrity check failed")
		}

		// decrpyt ciphertext (in-place)
		block, err := aes.NewCipher(encKey)
		if err != nil {
			return nil, fmt.Errorf("Failed to create an AES block cipher: %v", err)
		}

		c := cipher.NewCBCDecrypter(block, iv)
		c.CryptBlocks(cipherText, cipherText)
		plainText = cipherText

		// remove PCKS#7 padding
		padding := int(plainText[len(plainText)-1])
		plainText = plainText[:len(plainText)-padding]

	case "A128GCM", "A256GCM":
		// create the "additional data" for the GCM cipher
		additionalData := new(bytes.Buffer)
		additionalData.WriteString(parts[0])
		additionalData.WriteRune('.')
		additionalData.WriteString(parts[1])
		additionalData.WriteRune('.')
		additionalData.WriteString(parts[2])

		// create the authenticating cipher
		block, err := aes.NewCipher(encryptionKey)
		if err != nil {
			return nil, fmt.Errorf("Failed to create an AES block cipher: %v", err)
		}
		c, err := cipher.NewGCM(block)
		if err != nil {
			return nil, fmt.Errorf("Failed to create GCM cipher: %v", err)
		}

		// decrypt the cipher text (in-place)
		_, err = c.Open(cipherText[:0], iv, append(cipherText, authTag...), additionalData.Bytes())
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt: %v", err)
		}
		plainText = cipherText

	default:
		return nil, fmt.Errorf("Unsupported ENC keytype %s", header.Enc)
	}

	// need to deflate plain text?
	if header.Zip == "DEF" {
		plainText, err = ioutil.ReadAll(flate.NewReader(bytes.NewReader(plainText)))
		if err != nil {
			return nil, fmt.Errorf("Failed to inflate plain text: %v", err)
		}
	}

	return plainText, nil
}
<commit_msg>Factor out common concatKDF logic<commit_after>// Copyright 2014 Matthew Endsley
// All rights reserved
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted providing that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package gojwe

import (
	"bytes"
	"compress/flate"
	"crypto"
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/json"
	"errors"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"strings"
)

// Verify and decrypt a draft-7 JWE object
func VerifyAndDecryptDraft7(jwe string, key crypto.PrivateKey) ([]byte, error) {
	parts := strings.Split(jwe, ".")
	if len(parts) != 5 {
		return nil, errors.New("Wrong number of parts")
	}

	// decode the JWE header
	var header struct {
		Alg string `json:"alg"`
		Enc string `json:"enc"`
		Zip string `json:"zip"`
	}
	data, err := safeDecode(parts[0])
	if err != nil {
		return nil, fmt.Errorf("Malformed header: %v", err)
	}
	err = json.Unmarshal(data, &header)
	if err != nil {
		return nil, fmt.Errorf("Failed to decode header: %v", err)
	}

	var encryptionKey []byte
	encryptionKeyData, err := safeDecode(parts[1])
	if err != nil {
		return nil, fmt.Errorf("Malformed encryption key: %v", err)
	}

	// decode the encryption key
	switch header.Alg {
	case "RSA-OAEP", "RSA-OAEP-256":
		rsaKey, ok := key.(*rsa.PrivateKey)
		if !ok {
			return nil, fmt.Errorf("Expected an RSA private key. Got %T", key)
		}

		var h hash.Hash
		if header.Alg == "RSA-OAEP" {
			h = sha1.New()
		} else if header.Alg == "RSA-OAEP-256" {
			h = sha256.New()
		} else {
			panic("Logic error with algorithm " + header.Alg)
		}

		encryptionKey, err = rsa.DecryptOAEP(h, rand.Reader, rsaKey, encryptionKeyData, nil)
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt encryption key: %v", err)
		}

	case "RSA1_5":
		rsaKey, ok := key.(*rsa.PrivateKey)
		if !ok {
			return nil, fmt.Errorf("Expected RSA private key. Got %T", key)
		}

		encryptionKey, err = rsa.DecryptPKCS1v15(rand.Reader, rsaKey, encryptionKeyData)
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt encryption key: %v", err)
		}

	case "A128KW", "A256KW":
		aesKey, ok := key.([]byte)
		if !ok {
			return nil, fmt.Errorf("Expected shared symmetric key ([]byte). Got %T", key)
		}

		encryptionKey, err = AesKeyUnwrap(aesKey, encryptionKeyData)
		if err != nil {
			return nil, fmt.Errorf("Failed to unwrap key: %v", err)
		}

	default:
		return nil, fmt.Errorf("Unsupported ALG keytype %s", header.Alg)
	}

	// decode IV
	iv, err := safeDecode(parts[2])
	if err != nil {
		return nil, fmt.Errorf("Malformed IV: %v", err)
	}

	// decode cipher text
	cipherText, err := safeDecode(parts[3])
	if err != nil {
		return nil, fmt.Errorf("Malformed cipher text: %v", err)
	}

	// decode authtag
	authTag, err := safeDecode(parts[4])
	if err != nil {
		return nil, fmt.Errorf("Malformed authtag: %v", err)
	}

	// decrypt and verify cipher text
	var plainText []byte

	switch header.Enc {
	case "A128CBC+HS256", "A256CBC+HS512":
		// derive keys
		var encSize, macSize int
		var hfunc func() hash.Hash
		if header.Enc == "A128CBC+HS256" {
			encSize, macSize = 128, 256
			hfunc = sha256.New
		} else if header.Enc == "A256CBC+HS512" {
			encSize, macSize = 256, 512
			hfunc = sha512.New
		} else {
			panic("Bad ENC logic for type: " + header.Enc)
		}

		encKey, macKey := concatKDF(encryptionKey, header.Enc, encSize, macSize)

		// verify authtag
		hm := hmac.New(hfunc, macKey)
		io.WriteString(hm, parts[0])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[1])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[2])
		io.WriteString(hm, ".")
		io.WriteString(hm, parts[3])
		if !hmac.Equal(authTag, hm.Sum(nil)) {
			return nil, errors.New("Integrity check failed")
		}

		// decrpyt ciphertext (in-place)
		block, err := aes.NewCipher(encKey)
		if err != nil {
			return nil, fmt.Errorf("Failed to create an AES block cipher: %v", err)
		}

		c := cipher.NewCBCDecrypter(block, iv)
		c.CryptBlocks(cipherText, cipherText)
		plainText = cipherText

		// remove PCKS#7 padding
		padding := int(plainText[len(plainText)-1])
		plainText = plainText[:len(plainText)-padding]

	case "A128GCM", "A256GCM":
		// create the "additional data" for the GCM cipher
		additionalData := new(bytes.Buffer)
		additionalData.WriteString(parts[0])
		additionalData.WriteRune('.')
		additionalData.WriteString(parts[1])
		additionalData.WriteRune('.')
		additionalData.WriteString(parts[2])

		// create the authenticating cipher
		block, err := aes.NewCipher(encryptionKey)
		if err != nil {
			return nil, fmt.Errorf("Failed to create an AES block cipher: %v", err)
		}
		c, err := cipher.NewGCM(block)
		if err != nil {
			return nil, fmt.Errorf("Failed to create GCM cipher: %v", err)
		}

		// decrypt the cipher text (in-place)
		_, err = c.Open(cipherText[:0], iv, append(cipherText, authTag...), additionalData.Bytes())
		if err != nil {
			return nil, fmt.Errorf("Failed to decrypt: %v", err)
		}
		plainText = cipherText

	default:
		return nil, fmt.Errorf("Unsupported ENC keytype %s", header.Enc)
	}

	// need to deflate plain text?
	if header.Zip == "DEF" {
		plainText, err = ioutil.ReadAll(flate.NewReader(bytes.NewReader(plainText)))
		if err != nil {
			return nil, fmt.Errorf("Failed to inflate plain text: %v", err)
		}
	}

	return plainText, nil
}
<|endoftext|>


<commit_before>package pgtype_test

import (
	"math"
	"reflect"
	"testing"

	"github.com/jackc/pgx/pgtype"
	"github.com/jackc/pgx/pgtype/testutil"
)

func TestQCharTranscode(t *testing.T) {
	testutil.TestPgxSuccessfulTranscodeEqFunc(t, `"char"`, []interface{}{
		pgtype.QChar{Int: math.MinInt8, Status: pgtype.Present},
		pgtype.QChar{Int: -1, Status: pgtype.Present},
		pgtype.QChar{Int: 0, Status: pgtype.Present},
		pgtype.QChar{Int: 1, Status: pgtype.Present},
		pgtype.QChar{Int: math.MaxInt8, Status: pgtype.Present},
		pgtype.QChar{Int: 0, Status: pgtype.Null},
	}, func(a, b interface{}) bool {
		return reflect.DeepEqual(a, b)
	})
}

func TestQCharSet(t *testing.T) {
	successfulTests := []struct {
		source interface{}
		result pgtype.QChar
	}{
		{source: int8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int16(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int32(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int64(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int8(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int16(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int32(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int64(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: uint8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint16(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint32(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint64(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: "1", result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: _int8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
	}

	for i, tt := range successfulTests {
		var r pgtype.QChar
		err := r.Set(tt.source)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if r != tt.result {
			t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
		}
	}
}

func TestQCharAssignTo(t *testing.T) {
	var i8 int8
	var i16 int16
	var i32 int32
	var i64 int64
	var i int
	var ui8 uint8
	var ui16 uint16
	var ui32 uint32
	var ui64 uint64
	var ui uint
	var pi8 *int8
	var _i8 _int8
	var _pi8 *_int8

	simpleTests := []struct {
		src      pgtype.QChar
		dst      interface{}
		expected interface{}
	}{
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i8, expected: int8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i16, expected: int16(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i32, expected: int32(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i64, expected: int64(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i, expected: int(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui8, expected: uint8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui16, expected: uint16(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui32, expected: uint32(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui64, expected: uint64(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui, expected: uint(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &_i8, expected: _int8(42)},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &pi8, expected: ((*int8)(nil))},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &_pi8, expected: ((*_int8)(nil))},
	}

	for i, tt := range simpleTests {
		err := tt.src.AssignTo(tt.dst)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if dst := reflect.ValueOf(tt.dst).Elem().Interface(); dst != tt.expected {
			t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
		}
	}

	pointerAllocTests := []struct {
		src      pgtype.QChar
		dst      interface{}
		expected interface{}
	}{
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &pi8, expected: int8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &_pi8, expected: _int8(42)},
	}

	for i, tt := range pointerAllocTests {
		err := tt.src.AssignTo(tt.dst)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); dst != tt.expected {
			t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
		}
	}

	errorTests := []struct {
		src pgtype.QChar
		dst interface{}
	}{
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui8},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui16},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui32},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui64},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &i16},
	}

	for i, tt := range errorTests {
		err := tt.src.AssignTo(tt.dst)
		if err == nil {
			t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
		}
	}
}
<commit_msg>Test &pgtype.QChar<commit_after>package pgtype_test

import (
	"math"
	"reflect"
	"testing"

	"github.com/jackc/pgx/pgtype"
	"github.com/jackc/pgx/pgtype/testutil"
)

func TestQCharTranscode(t *testing.T) {
	testutil.TestPgxSuccessfulTranscodeEqFunc(t, `"char"`, []interface{}{
		&pgtype.QChar{Int: math.MinInt8, Status: pgtype.Present},
		&pgtype.QChar{Int: -1, Status: pgtype.Present},
		&pgtype.QChar{Int: 0, Status: pgtype.Present},
		&pgtype.QChar{Int: 1, Status: pgtype.Present},
		&pgtype.QChar{Int: math.MaxInt8, Status: pgtype.Present},
		&pgtype.QChar{Int: 0, Status: pgtype.Null},
	}, func(a, b interface{}) bool {
		return reflect.DeepEqual(a, b)
	})
}

func TestQCharSet(t *testing.T) {
	successfulTests := []struct {
		source interface{}
		result pgtype.QChar
	}{
		{source: int8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int16(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int32(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int64(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: int8(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int16(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int32(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: int64(-1), result: pgtype.QChar{Int: -1, Status: pgtype.Present}},
		{source: uint8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint16(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint32(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: uint64(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: "1", result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
		{source: _int8(1), result: pgtype.QChar{Int: 1, Status: pgtype.Present}},
	}

	for i, tt := range successfulTests {
		var r pgtype.QChar
		err := r.Set(tt.source)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if r != tt.result {
			t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
		}
	}
}

func TestQCharAssignTo(t *testing.T) {
	var i8 int8
	var i16 int16
	var i32 int32
	var i64 int64
	var i int
	var ui8 uint8
	var ui16 uint16
	var ui32 uint32
	var ui64 uint64
	var ui uint
	var pi8 *int8
	var _i8 _int8
	var _pi8 *_int8

	simpleTests := []struct {
		src      pgtype.QChar
		dst      interface{}
		expected interface{}
	}{
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i8, expected: int8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i16, expected: int16(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i32, expected: int32(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i64, expected: int64(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &i, expected: int(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui8, expected: uint8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui16, expected: uint16(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui32, expected: uint32(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui64, expected: uint64(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &ui, expected: uint(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &_i8, expected: _int8(42)},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &pi8, expected: ((*int8)(nil))},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &_pi8, expected: ((*_int8)(nil))},
	}

	for i, tt := range simpleTests {
		err := tt.src.AssignTo(tt.dst)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if dst := reflect.ValueOf(tt.dst).Elem().Interface(); dst != tt.expected {
			t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
		}
	}

	pointerAllocTests := []struct {
		src      pgtype.QChar
		dst      interface{}
		expected interface{}
	}{
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &pi8, expected: int8(42)},
		{src: pgtype.QChar{Int: 42, Status: pgtype.Present}, dst: &_pi8, expected: _int8(42)},
	}

	for i, tt := range pointerAllocTests {
		err := tt.src.AssignTo(tt.dst)
		if err != nil {
			t.Errorf("%d: %v", i, err)
		}

		if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); dst != tt.expected {
			t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst)
		}
	}

	errorTests := []struct {
		src pgtype.QChar
		dst interface{}
	}{
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui8},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui16},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui32},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui64},
		{src: pgtype.QChar{Int: -1, Status: pgtype.Present}, dst: &ui},
		{src: pgtype.QChar{Int: 0, Status: pgtype.Null}, dst: &i16},
	}

	for i, tt := range errorTests {
		err := tt.src.AssignTo(tt.dst)
		if err == nil {
			t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst)
		}
	}
}
<|endoftext|>


<commit_before>package websocket_test

import (
	"net/http"
	"net/url"
	"os"
	"strings"
	"testing"

	gorilla "github.com/spring1843/chat-server/libs/websocket"
	"github.com/spring1843/chat-server/src/chat"
	"github.com/spring1843/chat-server/src/config"
	"github.com/spring1843/chat-server/src/drivers/websocket"
)

func TestCantStartAndConnect(t *testing.T) {
	if os.Getenv("SKIP_NETWORK") == "1" {
		t.Skipf("Skipping test SKIP_NETWORK set to %q", os.Getenv("SKIPNETWORK"))
	}
	config := config.Config{
		WebAddress: "127.0.0.1:4003",
	}

	chatServer := chat.NewServer()
	chatServer.Listen()
	websocket.SetWebSocket(chatServer)

	http.HandleFunc("/ws1", websocket.Handler)

	go func() {
		if err := http.ListenAndServe(config.WebAddress, nil); err != nil {
			t.Fatalf("Failed listening to Websocet on %s. Error: %s", config.WebAddress, err)
		}
	}()
	u := url.URL{Scheme: "ws", Host: config.WebAddress, Path: "/ws1"}

	conn, _, err := gorilla.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		t.Fatalf("Websocket Dial error: %s", err.Error())
	}

	_, message, err := conn.ReadMessage()
	if err != nil {
		t.Fatalf("Error while reading connection %s", err.Error())
	}

	if !strings.Contains(string(message), "Welcome") {
		t.Error("Could not receive welcome message")
	}

	if err := conn.WriteMessage(1, []byte(`User1`)); err != nil {
		t.Fatalf("Error writing to connection. Error %s", err)
	}

	_, message, err = conn.ReadMessage()
	if err != nil {
		t.Fatalf("Error while reading connection. Error %s", err.Error())
	}

	expect := "Welcome User1"
	if !strings.Contains(string(message), expect) {
		t.Fatalf("Could not set user nickname, expected 'Thanks User1' got %s", expect)
	}

	if err := conn.WriteMessage(1, []byte(`/quit`)); err != nil {
		t.Fatalf("Error writing to connection. Error %s", err)
	}

	_, message, err = conn.ReadMessage()
	if !strings.Contains(string(message), "Good Bye") {
		t.Fatalf("Could not quit from server. Expected 'Good Bye' got %s", string(message))
	}

	if chatServer.IsUserConnected("User1") {
		t.Fatal("User is still connected to server after quiting")
	}
}
<commit_msg>Redial on test<commit_after>package websocket_test

import (
	"net/http"
	"net/url"
	"os"
	"strings"
	"testing"

	gorilla "github.com/spring1843/chat-server/libs/websocket"
	"github.com/spring1843/chat-server/src/chat"
	"github.com/spring1843/chat-server/src/config"
	"github.com/spring1843/chat-server/src/drivers/websocket"
	"github.com/spring1843/chat-server/src/shared/logs"
)

const dialAttempts = 3

func TestCantStartAndConnect(t *testing.T) {
	if os.Getenv("SKIP_NETWORK") == "1" {
		t.Skipf("Skipping test SKIP_NETWORK set to %q", os.Getenv("SKIPNETWORK"))
	}
	config := config.Config{
		WebAddress: "127.0.0.1:4003",
	}

	chatServer := chat.NewServer()
	chatServer.Listen()
	websocket.SetWebSocket(chatServer)

	http.HandleFunc("/ws1", websocket.Handler)

	go func() {
		if err := http.ListenAndServe(config.WebAddress, nil); err != nil {
			t.Fatalf("Failed listening to Websocet on %s. Error: %s", config.WebAddress, err)
		}
	}()
	u := url.URL{Scheme: "ws", Host: config.WebAddress, Path: "/ws1"}

	var err error
	var conn *gorilla.Conn
	for i := 0; i < dialAttempts; i++ {
		conn, _, err = gorilla.DefaultDialer.Dial(u.String(), nil)
		if err != nil {
			logs.ErrIfErrf(err, "Dial attempt %d failed", i)
		}
	}
	if err != nil {
		t.Fatalf("Websocket dial attempt failed after %d times. error: %s", dialAttempts, err.Error())
	}

	_, message, err := conn.ReadMessage()
	if err != nil {
		t.Fatalf("Error while reading connection %s", err.Error())
	}

	if !strings.Contains(string(message), "Welcome") {
		t.Error("Could not receive welcome message")
	}

	if err := conn.WriteMessage(1, []byte(`User1`)); err != nil {
		t.Fatalf("Error writing to connection. Error %s", err)
	}

	_, message, err = conn.ReadMessage()
	if err != nil {
		t.Fatalf("Error while reading connection. Error %s", err.Error())
	}

	expect := "Welcome User1"
	if !strings.Contains(string(message), expect) {
		t.Fatalf("Could not set user nickname, expected 'Thanks User1' got %s", expect)
	}

	if err := conn.WriteMessage(1, []byte(`/quit`)); err != nil {
		t.Fatalf("Error writing to connection. Error %s", err)
	}

	_, message, err = conn.ReadMessage()
	if !strings.Contains(string(message), "Good Bye") {
		t.Fatalf("Could not quit from server. Expected 'Good Bye' got %s", string(message))
	}

	if chatServer.IsUserConnected("User1") {
		t.Fatal("User is still connected to server after quiting")
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package perfschema

import (
	"strings"
	"sync/atomic"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/expression"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/util/codec"
	"github.com/syndtr/goleveldb/leveldb"
)

// InsertValues is the rest part of insert/replace into statement.
type InsertValues struct {
	ColNames   []string
	Lists      [][]expression.Expression
	TableIdent table.Ident
	Setlist    []*expression.Assignment
}

// Simulate the behavior of an INSERT statement.
func (ps *perfSchema) ExecInsert(insertVals *InsertValues) error {
	t := ps.getTable(insertVals.TableIdent)
	if t == nil {
		return errors.Errorf("INSERT INTO %s: operation not permitted", insertVals.TableIdent)
	}

	cols, err := ps.getColumns(insertVals, t.Columns)
	if err != nil {
		return errors.Trace(err)
	}

	rows, err := ps.getRows(insertVals, t, cols)
	if err != nil {
		return errors.Trace(err)
	}

	return ps.addRecords(insertVals.TableIdent, rows)
}

func (ps *perfSchema) addRecords(tableIdent table.Ident, rows [][]interface{}) error {
	var store *leveldb.DB
	var lastLsn uint64

	// Same as MySQL, we only support INSERT operations for setup_actors & setup_objects.
	name := strings.ToUpper(tableIdent.Name.O)
	switch name {
	case TableSetupActors:
		store = ps.stores[TableSetupActors]
		lastLsn = atomic.AddUint64(ps.lsns[TableSetupActors], uint64(len(rows)))
	case TableSetupObjects:
		store = ps.stores[TableSetupObjects]
		lastLsn = atomic.AddUint64(ps.lsns[TableSetupObjects], uint64(len(rows)))
	default:
		return errors.Errorf("INSERT INTO %s: operation not permitted", tableIdent)
	}

	batch := pool.Get().(*leveldb.Batch)
	defer func() {
		batch.Reset()
		pool.Put(batch)
	}()

	for i, row := range rows {
		lsn := lastLsn - uint64(len(rows)) + uint64(i)
		rawKey := []interface{}{uint64(lsn)}
		key, err := codec.EncodeKey(nil, rawKey...)
		if err != nil {
			return errors.Trace(err)
		}
		val, err := codec.EncodeValue(nil, row...)
		if err != nil {
			return errors.Trace(err)
		}
		batch.Put(key, val)
	}

	err := store.Write(batch, nil)
	return errors.Trace(err)
}

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

	return nil
}

func fillRowData(t *model.TableInfo, cols []*model.ColumnInfo, vals []interface{}) ([]interface{}, error) {
	row := make([]interface{}, len(t.Columns))
	marked := make(map[int]struct{}, len(vals))
	for i, v := range vals {
		offset := cols[i].Offset
		row[offset] = v
		marked[offset] = struct{}{}
	}
	err := initDefaultValues(t, row, marked)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if err = castValues(row, cols); err != nil {
		return nil, errors.Trace(err)
	}
	if err = checkNotNulls(t.Columns, row); err != nil {
		return nil, errors.Trace(err)
	}
	return row, nil
}

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

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

	return nil
}

func getColumnDefaultValues(cols []*model.ColumnInfo) (map[interface{}]interface{}, error) {
	defaultValMap := map[interface{}]interface{}{}
	for _, col := range cols {
		if value, ok, err := getColDefaultValue(col); ok {
			if err != nil {
				return nil, errors.Trace(err)
			}

			defaultValMap[col.Name.L] = value
		}
	}

	return defaultValMap, nil
}

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

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

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

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

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

	return cols, nil
}

func (ps *perfSchema) getRows(insertVals *InsertValues, t *model.TableInfo, cols []*model.ColumnInfo) (rows [][]interface{}, err error) {
	// process `insert|replace ... set x=y...`
	if err = fillValueList(insertVals); err != nil {
		return nil, errors.Trace(err)
	}

	evalMap, err := getColumnDefaultValues(cols)
	if err != nil {
		return nil, errors.Trace(err)
	}

	rows = make([][]interface{}, len(insertVals.Lists))
	for i, list := range insertVals.Lists {
		if err = checkValueCount(insertVals, len(insertVals.Lists[0]), len(list), i, cols); err != nil {
			return nil, errors.Trace(err)
		}

		vals := make([]interface{}, len(list))
		for j, expr := range list {
			// For "insert into t values (default)" Default Eval.
			evalMap[expression.ExprEvalDefaultName] = cols[j].Name.O

			vals[j], err = expr.Eval(nil, evalMap)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}

		rows[i], err = fillRowData(t, cols, vals)
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return
}

func (ps *perfSchema) getTable(tableIdent table.Ident) *model.TableInfo {
	tbName := strings.ToUpper(tableIdent.Name.O)

	// Same as MySQL, we only support INSERT operations for setup_actors & setup_objects.
	switch tbName {
	case TableSetupActors:
	case TableSetupObjects:
	default:
		return nil
	}
	return ps.tables[tbName]
}

func initDefaultValues(t *model.TableInfo, row []interface{}, marked map[int]struct{}) error {
	var defaultValueCols []*model.ColumnInfo
	for i, c := range t.Columns {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}
		// If the nil value is evaluated in insert list, we will use nil.
		if _, ok := marked[i]; ok {
			continue
		}

		var value interface{}
		value, _, err := getColDefaultValue(c)
		if err != nil {
			return errors.Trace(err)
		}
		row[i] = value
		defaultValueCols = append(defaultValueCols, c)
	}

	if err := castValues(row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}
	return nil
}
<commit_msg>performance_schema: revised according to cuiqiu's comments<commit_after>// Copyright 2016 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package perfschema

import (
	"strings"
	"sync/atomic"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/expression"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/table"
	"github.com/pingcap/tidb/util/codec"
	"github.com/syndtr/goleveldb/leveldb"
)

// InsertValues is the rest part of insert/replace into statement.
type InsertValues struct {
	ColNames   []string
	Lists      [][]expression.Expression
	TableIdent table.Ident
	Setlist    []*expression.Assignment
}

// Simulate the behavior of an INSERT statement.
func (ps *perfSchema) ExecInsert(insertVals *InsertValues) error {
	name := strings.ToUpper(insertVals.TableIdent.Name.O)
	t := ps.getTable(name)
	if t == nil {
		return errors.Errorf("INSERT INTO %s: operation not permitted", insertVals.TableIdent)
	}

	cols, err := ps.getColumns(insertVals, t.Columns)
	if err != nil {
		return errors.Trace(err)
	}

	rows, err := ps.getRows(insertVals, t, cols)
	if err != nil {
		return errors.Trace(err)
	}

	return ps.addRecords(name, rows)
}

func (ps *perfSchema) addRecords(tbName string, rows [][]interface{}) error {
	var store *leveldb.DB
	var lastLsn uint64

	// Same as MySQL, we only support INSERT operations for setup_actors & setup_objects.
	switch tbName {
	case TableSetupActors:
		store = ps.stores[TableSetupActors]
		lastLsn = atomic.AddUint64(ps.lsns[TableSetupActors], uint64(len(rows)))
	case TableSetupObjects:
		store = ps.stores[TableSetupObjects]
		lastLsn = atomic.AddUint64(ps.lsns[TableSetupObjects], uint64(len(rows)))
	default:
		return errors.Errorf("INSERT INTO %s.%s: operation not permitted", Name, tbName)
	}

	batch := pool.Get().(*leveldb.Batch)
	defer func() {
		batch.Reset()
		pool.Put(batch)
	}()

	for i, row := range rows {
		lsn := lastLsn - uint64(len(rows)) + uint64(i)
		rawKey := []interface{}{uint64(lsn)}
		key, err := codec.EncodeKey(nil, rawKey...)
		if err != nil {
			return errors.Trace(err)
		}
		val, err := codec.EncodeValue(nil, row...)
		if err != nil {
			return errors.Trace(err)
		}
		batch.Put(key, val)
	}

	err := store.Write(batch, nil)
	return errors.Trace(err)
}

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

	return nil
}

func fillRowData(t *model.TableInfo, cols []*model.ColumnInfo, vals []interface{}) ([]interface{}, error) {
	row := make([]interface{}, len(t.Columns))
	marked := make(map[int]struct{}, len(vals))
	for i, v := range vals {
		offset := cols[i].Offset
		row[offset] = v
		marked[offset] = struct{}{}
	}
	err := initDefaultValues(t, row, marked)
	if err != nil {
		return nil, errors.Trace(err)
	}
	if err = castValues(row, cols); err != nil {
		return nil, errors.Trace(err)
	}
	if err = checkNotNulls(t.Columns, row); err != nil {
		return nil, errors.Trace(err)
	}
	return row, nil
}

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

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

	return nil
}

func getColumnDefaultValues(cols []*model.ColumnInfo) (map[interface{}]interface{}, error) {
	defaultValMap := map[interface{}]interface{}{}
	for _, col := range cols {
		if value, ok, err := getColDefaultValue(col); ok {
			if err != nil {
				return nil, errors.Trace(err)
			}

			defaultValMap[col.Name.L] = value
		}
	}

	return defaultValMap, nil
}

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

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

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

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

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

	return cols, nil
}

func (ps *perfSchema) getRows(insertVals *InsertValues, t *model.TableInfo, cols []*model.ColumnInfo) (rows [][]interface{}, err error) {
	// process `insert|replace ... set x=y...`
	if err = fillValueList(insertVals); err != nil {
		return nil, errors.Trace(err)
	}

	evalMap, err := getColumnDefaultValues(cols)
	if err != nil {
		return nil, errors.Trace(err)
	}

	rows = make([][]interface{}, len(insertVals.Lists))
	for i, list := range insertVals.Lists {
		if err = checkValueCount(insertVals, len(insertVals.Lists[0]), len(list), i, cols); err != nil {
			return nil, errors.Trace(err)
		}

		vals := make([]interface{}, len(list))
		for j, expr := range list {
			// For "insert into t values (default)" Default Eval.
			evalMap[expression.ExprEvalDefaultName] = cols[j].Name.O

			vals[j], err = expr.Eval(nil, evalMap)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}

		rows[i], err = fillRowData(t, cols, vals)
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return
}

func (ps *perfSchema) getTable(tbName string) *model.TableInfo {
	// Same as MySQL, we only support INSERT operations for setup_actors & setup_objects.
	switch tbName {
	case TableSetupActors:
	case TableSetupObjects:
	default:
		return nil
	}
	return ps.tables[tbName]
}

func initDefaultValues(t *model.TableInfo, row []interface{}, marked map[int]struct{}) error {
	var defaultValueCols []*model.ColumnInfo
	for i, c := range t.Columns {
		if row[i] != nil {
			// Column value is not nil, continue.
			continue
		}
		// If the nil value is evaluated in insert list, we will use nil.
		if _, ok := marked[i]; ok {
			continue
		}

		var value interface{}
		value, _, err := getColDefaultValue(c)
		if err != nil {
			return errors.Trace(err)
		}
		row[i] = value
		defaultValueCols = append(defaultValueCols, c)
	}

	if err := castValues(row, defaultValueCols); err != nil {
		return errors.Trace(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package server

import (
	"os"
	"text/template"

	"github.com/urfave/cli"

	"github.com/drone/drone-cli/drone/internal"
)

var serverListCmd = cli.Command{
	Name:      "ls",
	Usage:     "list all servers",
	ArgsUsage: " ",
	Action:    serverList,
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "a",
			Usage: "show all servers",
		},
		cli.StringFlag{
			Name:   "format",
			Usage:  "format output",
			Value:  tmplServerList,
			Hidden: true,
		},
	},
}

func serverList(c *cli.Context) error {
	client, err := internal.NewAutoscaleClient(c)
	if err != nil {
		return err
	}
	all := c.Bool("a")

	servers, err := client.ServerList()
	if err != nil || len(servers) == 0 {
		return err
	}

	tmpl, err := template.New("_").Parse(c.String("format") + "\n")
	if err != nil {
		return err
	}
	for _, server := range servers {
		if !all && server.State == "stopped" {
			continue
		}
		tmpl.Execute(os.Stdout, server)
	}
	return nil
}

// template for server list items
var tmplServerList = `{{ .Name }}`
<commit_msg>server list columns and headers<commit_after>package server

import (
	"fmt"
	"os"
	"text/tabwriter"
	"text/template"
	"time"

	"github.com/docker/go-units"
	"github.com/urfave/cli"

	"github.com/drone/drone-cli/drone/internal"
	"github.com/drone/drone-go/drone"
)

var serverListCmd = cli.Command{
	Name:      "ls",
	Usage:     "list all servers",
	ArgsUsage: " ",
	Action:    serverList,
	Flags: []cli.Flag{
		cli.BoolFlag{
			Name:  "a",
			Usage: "include stopped servers",
		},
		cli.BoolFlag{
			Name:  "l",
			Usage: "list in long format",
		},
		cli.BoolTFlag{
			Name:  "H",
			Usage: "include columne headers",
		},
		cli.StringFlag{
			Name:   "format",
			Usage:  "format output",
			Value:  tmplServerList,
			Hidden: true,
		},
	},
}

func serverList(c *cli.Context) error {
	client, err := internal.NewAutoscaleClient(c)
	if err != nil {
		return err
	}
	a := c.Bool("a")
	l := c.Bool("l")
	h := c.BoolT("H")

	servers, err := client.ServerList()
	if err != nil || len(servers) == 0 {
		return err
	}

	if l && h {
		printLong(servers, a, h)
		return nil
	}

	tmpl, err := template.New("_").Parse(c.String("format") + "\n")
	if err != nil {
		return err
	}

	for _, server := range servers {
		if !a && server.State == "stopped" {
			continue
		}
		tmpl.Execute(os.Stdout, server)
	}
	return nil
}

func printLong(servers []*drone.Server, a, h bool) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)
	if h {
		fmt.Fprintln(w, "Name\tAddress\tState\tCreated")
	}
	for _, server := range servers {
		if !a && server.State == "stopped" {
			continue
		}
		fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\n",
			server.Name,
			server.Address,
			server.State,
			units.HumanDuration(
				time.Now().Sub(
					time.Unix(server.Created, 0),
				),
			),
		)
	}
	w.Flush()
}

// template for server list items
var tmplServerList = `{{ .Name }}`
<|endoftext|>


<commit_before>package contour

// Only non-core settings are updateable. Flags must use Override* to update
// settings.
func (c *Cfg) updateE(k string, v interface{}) error {
	// if can't update, a false will also return an error explaining why.
	_, err := c.canUpdate(k)
	if err != nil {
		return err
	}
	c.RWMutex.Lock()
	defer c.RWMutex.Unlock()
	s, _ := c.settings[k]
	s.Value = v
	c.settings[k] = s
	return nil
}

// UpdateBoolE updates a bool setting, returning any error that occurs.
func UpdateBoolE(k string, v bool) error { return appCfg.UpdateBoolE(k, v) }
func (c *Cfg) UpdateBoolE(k string, v bool) error {
	return c.updateE(k, v)
}

// UpdateBool calls UpdateBoolE and drops the error.
func UpdateBool(k string, v bool) { appCfg.UpdateBool(k, v) }
func (c *Cfg) UpdateBool(k string, v bool) {
	c.UpdateBoolE(k, v)
}

// UpdateIntE updates a int setting, returning any error that occurs.
func UpdateIntE(k string, v int) error { return appCfg.UpdateIntE(k, v) }
func (c *Cfg) UpdateIntE(k string, v int) error {
	return c.updateE(k, v)
}

// UpdateInt calls UpdateIntE and drops the error.
func UpdateInt(k string, v int) { appCfg.UpdateInt(k, v) }
func (c *Cfg) UpdateInt(k string, v int) {
	c.UpdateIntE(k, v)
}

// UpdateInt64E updates a int64 setting, returning any error that occurs.
func UpdateInt64E(k string, v int64) error { return appCfg.UpdateInt64E(k, v) }
func (c *Cfg) UpdateInt64E(k string, v int64) error {
	return c.updateE(k, v)
}

// UpdateInt64 calls UpdateInt64E and drops the error.
func UpdateInt64(k string, v int64) { appCfg.UpdateInt64(k, v) }
func (c *Cfg) UpdateInt64(k string, v int64) {
	c.UpdateInt64E(k, v)
}

// UpdateStringE updates a string setting, returning any error that occurs.
func UpdateStringE(k string, v string) error { return appCfg.UpdateStringE(k, v) }
func (c *Cfg) UpdateStringE(k, v string) error {
	return c.updateE(k, v)
}

// UpdateBool calls UpdateStringE and drops the error.
func UpdateString(k string, v string) { appCfg.UpdateString(k, v) }
func (c *Cfg) UpdateString(k, v string) {
	c.UpdateStringE(k, v)
}
<commit_msg>add ability to update cfgfilename<commit_after>package contour

// Only non-core settings are updateable. Flags must use Override* to update
// settings.
func (c *Cfg) updateE(k string, v interface{}) error {
	// if can't update, a false will also return an error explaining why.
	_, err := c.canUpdate(k)
	if err != nil {
		return err
	}
	c.RWMutex.Lock()
	defer c.RWMutex.Unlock()
	s, _ := c.settings[k]
	s.Value = v
	c.settings[k] = s
	return nil
}

// UpdateBoolE updates a bool setting, returning any error that occurs.
func UpdateBoolE(k string, v bool) error { return appCfg.UpdateBoolE(k, v) }
func (c *Cfg) UpdateBoolE(k string, v bool) error {
	return c.updateE(k, v)
}

// UpdateBool calls UpdateBoolE and drops the error.
func UpdateBool(k string, v bool) { appCfg.UpdateBool(k, v) }
func (c *Cfg) UpdateBool(k string, v bool) {
	c.UpdateBoolE(k, v)
}

// UpdateIntE updates a int setting, returning any error that occurs.
func UpdateIntE(k string, v int) error { return appCfg.UpdateIntE(k, v) }
func (c *Cfg) UpdateIntE(k string, v int) error {
	return c.updateE(k, v)
}

// UpdateInt calls UpdateIntE and drops the error.
func UpdateInt(k string, v int) { appCfg.UpdateInt(k, v) }
func (c *Cfg) UpdateInt(k string, v int) {
	c.UpdateIntE(k, v)
}

// UpdateInt64E updates a int64 setting, returning any error that occurs.
func UpdateInt64E(k string, v int64) error { return appCfg.UpdateInt64E(k, v) }
func (c *Cfg) UpdateInt64E(k string, v int64) error {
	return c.updateE(k, v)
}

// UpdateInt64 calls UpdateInt64E and drops the error.
func UpdateInt64(k string, v int64) { appCfg.UpdateInt64(k, v) }
func (c *Cfg) UpdateInt64(k string, v int64) {
	c.UpdateInt64E(k, v)
}

// UpdateStringE updates a string setting, returning any error that occurs.
func UpdateStringE(k string, v string) error { return appCfg.UpdateStringE(k, v) }
func (c *Cfg) UpdateStringE(k, v string) error {
	return c.updateE(k, v)
}

// UpdateBool calls UpdateStringE and drops the error.
func UpdateString(k string, v string) { appCfg.UpdateString(k, v) }
func (c *Cfg) UpdateString(k, v string) {
	c.UpdateStringE(k, v)
}

// UpdateCfgFile updates the set config file information.  This only sets
// the filename, the format is not changed.  This does the update
// directly because the cfg filename is a core setting; it will fail the
// canUpdate check.
//
// It is assumed that RegisterCfgFile has already been called, if it hasn't
// nothing will be done.
func UpdateCfgFile(v string) { appCfg.UpdateCfgFile(v) }
func (c *Cfg) UpdateCfgFile(v string) {
	c.RWMutex.Lock()
	defer c.RWMutex.Unlock()
	s, ok := c.settings[k]
	if !ok {
		return
	}
	s.Value = v
	c.settings[k] = s
}
<|endoftext|>