<commit_before>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package tmux

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"sync"
	"syscall"
)

const (
	ImsgfHasFD = 1

	IbufReadLen = 65535
	MaxImsgLen  = 16384
	cmsgBufLen  = 4096
)

var (
	imsgHeaderLen = (&ImsgHeader{}).WireLen()

	ImsgBufferClosed = fmt.Errorf("Buffer channel closed")
)

type WireSerializer interface {
	InitFromWireBytes([]byte) error
	WireBytes([]byte) error
	WireLen() int
}

type rawBuf struct {
	data []byte
	fds  []*os.File
}

type Imsg struct {
	Header ImsgHeader
	Data   []byte
	FD     *os.File
}

// ImsgHeader describes the current message.
type ImsgHeader struct {
	Type   uint32
	Len    uint16
	Flags  uint16
	PeerID uint32
	Pid    uint32
}

// header length is used often, calc it once
func (ihdr *ImsgHeader) WireLen() int {
	return 16
}

func (ihdr *ImsgHeader) WireBytes(buf []byte) error {
	var err error
	var bb bytes.Buffer

	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Type); err != nil {
		return fmt.Errorf("Write(Type): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Len); err != nil {
		return fmt.Errorf("Write(Len): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Flags); err != nil {
		return fmt.Errorf("Write(Flags): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.PeerID); err != nil {
		return fmt.Errorf("Write(PeerID): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Pid); err != nil {
		return fmt.Errorf("Write(Pid): %s", err)
	}
	bbuf := bb.Bytes()
	if len(buf) < len(bbuf) {
		return fmt.Errorf("ImsgHeader 1 bad len %d/%d/16", len(buf), len(bbuf))
	}
	copy(buf, bbuf)
	//log.Printf("hdr(%#v) bytes : %#v", ihdr, bbuf)
	return nil
}

func (ihdr *ImsgHeader) InitFromWireBytes(buf []byte) error {
	if len(buf) != 16 {
		return fmt.Errorf("ImsgHeader 2 bad len %d/16", len(buf))
	}
	ihdr.Type = binary.LittleEndian.Uint32(buf[0:4])
	ihdr.Len = binary.LittleEndian.Uint16(buf[4:6])
	ihdr.Flags = binary.LittleEndian.Uint16(buf[6:8])
	ihdr.PeerID = binary.LittleEndian.Uint32(buf[8:12])
	ihdr.Pid = binary.LittleEndian.Uint32(buf[12:16])
	return nil
}

type ImsgBuffer struct {
	conn   *net.UnixConn
	mu     sync.Mutex
	wQueue []Imsg
	msgs   chan *Imsg
	// Linux kernel defines pid_t as a 32-bit signed int in
	// include/uapi/asm-generic/posix_types.h
	pid int32
}

func NewImsgBuffer(path string) (*ImsgBuffer, error) {
	addr, err := net.ResolveUnixAddr("unix", path)
	if err != nil {
		return nil, fmt.Errorf("ResolveAddrUnix(%s): %s", path, err)
	}
	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		return nil, fmt.Errorf("DialUnix(%s): %s", path, err)
	}
	ibuf := &ImsgBuffer{
		conn: conn,
		pid:  int32(os.Getpid()),
		msgs: make(chan *Imsg),
	}

	between := make(chan rawBuf)
	go ibuf.readSocket(between)
	go ibuf.reader(between)

	return ibuf, nil
}

func (ibuf *ImsgBuffer) Compose(kind, peerID, pid uint32, data WireSerializer, fd *os.File) error {
	var err error
	size := imsgHeaderLen + data.WireLen()
	header := ImsgHeader{
		Type:   kind,
		Len:    uint16(size),
		PeerID: peerID,
		Pid:    pid,
	}
	if header.Pid == 0 {
		header.Pid = uint32(ibuf.pid)
	}
	buf := make([]byte, size)

	if err = header.WireBytes(buf[0:imsgHeaderLen]); err != nil {
		return fmt.Errorf("header.WireBytes: %s", err)
	}
	if err = data.WireBytes(buf[imsgHeaderLen:]); err != nil {
		return fmt.Errorf("header.WireBytes: %s", err)
	}

	ibuf.mu.Lock()
	ibuf.wQueue = append(ibuf.wQueue, Imsg{Data: buf, FD: fd})
	ibuf.mu.Unlock()

	return nil
}

// Flush writes all pending buffers to the socket
func (ibuf *ImsgBuffer) Flush() {
	ibuf.mu.Lock()
	defer ibuf.mu.Unlock()

	for _, buf := range ibuf.wQueue {
		var cmsgBuf []byte
		if buf.FD != nil {
			cmsgBuf = syscall.UnixRights(int(buf.FD.Fd()))
			defer buf.FD.Close()
		}
		n, _, err := ibuf.conn.WriteMsgUnix(buf.Data, cmsgBuf, nil)
		if err != nil {
			log.Printf("ibuf.conn.Write: %s", err)
		} else if n != len(buf.Data) {
			log.Printf("ibuf.conn.Write short: %d/%d", n, len(buf.Data))
		}
	}
	ibuf.wQueue = nil
}

func (ibuf *ImsgBuffer) Get() (*Imsg, error) {
	result := <-ibuf.msgs
	if result == nil {
		return nil, ImsgBufferClosed
	}

	return result, nil
}

func (ibuf *ImsgBuffer) Close() {
	ibuf.conn.Close()
}

func zero(buf []byte) {
	for i := range buf {
		buf[i] = 0
	}
}

// fd -> chan []byte
// []byte chan -> imsg chan

func (ibuf *ImsgBuffer) readSocket(out chan<- rawBuf) {
	cmsgBuf := make([]byte, cmsgBufLen)
	imsgBuf := make([]byte, IbufReadLen)

	for {
		// TODO: not necessary
		zero(cmsgBuf)
		zero(imsgBuf)

		n, cn, _, _, err := ibuf.conn.ReadMsgUnix(imsgBuf, cmsgBuf)
		if err != nil {
			if err == io.EOF {
				close(ibuf.msgs)
			}
			// if we have a read error, its probably
			// because our connection closed, just quietly
			// exit.
			return
		}
		log.Printf("read %d", n)

		// copy into a new buffer, so we can safely pass it to
		// another goroutine
		buf := make([]byte, n)
		copy(buf, imsgBuf)

		var files []*os.File

		// TODO: not sure how this works.  a Read might return
		// multiple messages coalessed into one.  How does
		// that correspond to socket control messages?
		if cn > 0 {
			cmsgs, err := syscall.ParseSocketControlMessage(cmsgBuf)
			if err != nil {
				log.Printf("ParseSocketControlMessage: %s", err)
				return
			}
			log.Printf("n cmsgs: %d", len(cmsgs))
			for _, cmsg := range cmsgs {
				fds, err := syscall.ParseUnixRights(&cmsg)
				if err != nil {
					log.Printf("ParseUnixRights: %s", err)
				}
				for _, fd := range fds {
					files = append(files, os.NewFile(uintptr(fd), "<from tmux>"))
				}
			}
		}

		// TODO: remove debugging
		if len(files) > 0 {
			log.Printf("FDs: %#v", files)
		}

		out <- rawBuf{buf, files}
	}
}

func (ibuf *ImsgBuffer) reader(in <-chan rawBuf) {
	var inbetween bytes.Buffer
	hBytes := make([]byte, imsgHeaderLen)
	readHeader := true

	var header ImsgHeader

	for {
		fmt.Printf("waiting\n")
		rawBuf := <-in
		inbetween.Write(rawBuf.data)
		fmt.Printf("got something\n")

		for {
			// if we're just waiting for more payload
			// data, we don't want to re-read the header.
			if readHeader {
				zero(hBytes)

				// didn't read a full header?  wait for more data
				if inbetween.Len() < imsgHeaderLen {
					break
				}
				n, err := inbetween.Read(hBytes)
				if err != nil {
					log.Printf("inbetween.Read: %s", err)
					return
				} else if n != imsgHeaderLen {
					// short read - should never happen
					log.Printf("inbetween.Read short: %d/%d",
						n, imsgHeaderLen)
					return
				}
				if err = header.InitFromWireBytes(hBytes); err != nil {
					log.Printf("InitFromWireBytes: %s", err)
					return
				}
				readHeader = false
			}

			var payload []byte
			payloadLen := int(header.Len) - imsgHeaderLen
			if payloadLen > 0 {
				// wait for more data
				if inbetween.Len() < payloadLen {
					fmt.Printf("need more for payload %d/%d\n",
						inbetween.Len(), payloadLen)
					break
				}
				payload = make([]byte, payloadLen)
				n, err := inbetween.Read(payload)
				if err != nil {
					log.Printf("inbetween.Read 2: %s", err)
					return
				} else if n != payloadLen {
					log.Printf("inbetween.Read 2 short: %d/%d", n, payloadLen)
					return
				}
			}
			var fd *os.File
			if len(rawBuf.fds) > 0 {
				fd = rawBuf.fds[0]
			}
			// TODO: this FD handling isn't quite right
			imsg := &Imsg{header, payload, fd}
			log.Printf("imsg: %s", MsgType(imsg.Header.Type))
			ibuf.msgs <- imsg
			readHeader = true
		}
	}
}

type String struct {
	S string
}

func (s *String) WireLen() int {
	return len(s.S)
}

func (s *String) WireBytes(buf []byte) error {
	sBytes := []byte(s.S)
	if len(buf) < len(sBytes)+1 {
		return fmt.Errorf("String bad len %d/%d", len(buf), len(sBytes)+1)
	}

	copy(buf, sBytes)
	// make sure its null terminated
	buf[len(sBytes)] = 0

	return nil
}

func (s *String) InitFromWireBytes(buf []byte) error {
	if len(buf) > 0 && buf[len(buf)-1] == 0 {
		buf = buf[:len(buf)-1]
	}
	s.S = string(buf)

	return nil
}

type Int32 struct {
	int32
}

func (i *Int32) WireLen() int {
	return 4
}

func (i *Int32) WireBytes(buf []byte) error {
	var err error
	if len(buf) < 4 {
		return fmt.Errorf("Int32 1 bad len %d/4", len(buf))
	}
	var bb bytes.Buffer

	if err = binary.Write(&bb, binary.LittleEndian, int32(i.int32)); err != nil {
		return fmt.Errorf("i(%d) write: %s", int32(i.int32), err)
	}

	bbuf := bb.Bytes()
	copy(buf, bbuf)

	return nil
}

func (i *Int32) InitFromWireBytes(buf []byte) error {
	if len(buf) != 4 {
		return fmt.Errorf("Int32 bad len %d/16", len(buf))
	}
	i.int32 = int32(binary.LittleEndian.Uint32(buf))

	return nil
}

type Nil struct{}

func (n Nil) WireLen() int {
	return 0
}

func (n Nil) WireBytes(buf []byte) error {
	return nil
}

func (n Nil) InitFromWireBytes(buf []byte) error {
	return nil
}
<commit_msg>get rid of a few debugging statements<commit_after>// Copyright 2015 Bobby Powers. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package tmux

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"sync"
	"syscall"
)

const (
	ImsgfHasFD = 1

	IbufReadLen = 65535
	MaxImsgLen  = 16384
	cmsgBufLen  = 4096
)

var (
	imsgHeaderLen = (&ImsgHeader{}).WireLen()

	ImsgBufferClosed = fmt.Errorf("Buffer channel closed")
)

type WireSerializer interface {
	InitFromWireBytes([]byte) error
	WireBytes([]byte) error
	WireLen() int
}

type rawBuf struct {
	data []byte
	fds  []*os.File
}

type Imsg struct {
	Header ImsgHeader
	Data   []byte
	FD     *os.File
}

// ImsgHeader describes the current message.
type ImsgHeader struct {
	Type   uint32
	Len    uint16
	Flags  uint16
	PeerID uint32
	Pid    uint32
}

// header length is used often, calc it once
func (ihdr *ImsgHeader) WireLen() int {
	return 16
}

func (ihdr *ImsgHeader) WireBytes(buf []byte) error {
	var err error
	var bb bytes.Buffer

	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Type); err != nil {
		return fmt.Errorf("Write(Type): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Len); err != nil {
		return fmt.Errorf("Write(Len): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Flags); err != nil {
		return fmt.Errorf("Write(Flags): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.PeerID); err != nil {
		return fmt.Errorf("Write(PeerID): %s", err)
	}
	if err = binary.Write(&bb, binary.LittleEndian, ihdr.Pid); err != nil {
		return fmt.Errorf("Write(Pid): %s", err)
	}
	bbuf := bb.Bytes()
	if len(buf) < len(bbuf) {
		return fmt.Errorf("ImsgHeader 1 bad len %d/%d/16", len(buf), len(bbuf))
	}
	copy(buf, bbuf)
	//log.Printf("hdr(%#v) bytes : %#v", ihdr, bbuf)
	return nil
}

func (ihdr *ImsgHeader) InitFromWireBytes(buf []byte) error {
	if len(buf) != 16 {
		return fmt.Errorf("ImsgHeader 2 bad len %d/16", len(buf))
	}
	ihdr.Type = binary.LittleEndian.Uint32(buf[0:4])
	ihdr.Len = binary.LittleEndian.Uint16(buf[4:6])
	ihdr.Flags = binary.LittleEndian.Uint16(buf[6:8])
	ihdr.PeerID = binary.LittleEndian.Uint32(buf[8:12])
	ihdr.Pid = binary.LittleEndian.Uint32(buf[12:16])
	return nil
}

type ImsgBuffer struct {
	conn   *net.UnixConn
	mu     sync.Mutex
	wQueue []Imsg
	msgs   chan *Imsg
	// Linux kernel defines pid_t as a 32-bit signed int in
	// include/uapi/asm-generic/posix_types.h
	pid int32
}

func NewImsgBuffer(path string) (*ImsgBuffer, error) {
	addr, err := net.ResolveUnixAddr("unix", path)
	if err != nil {
		return nil, fmt.Errorf("ResolveAddrUnix(%s): %s", path, err)
	}
	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		return nil, fmt.Errorf("DialUnix(%s): %s", path, err)
	}
	ibuf := &ImsgBuffer{
		conn: conn,
		pid:  int32(os.Getpid()),
		msgs: make(chan *Imsg),
	}

	between := make(chan rawBuf)
	go ibuf.readSocket(between)
	go ibuf.reader(between)

	return ibuf, nil
}

func (ibuf *ImsgBuffer) Compose(kind, peerID, pid uint32, data WireSerializer, fd *os.File) error {
	var err error
	size := imsgHeaderLen + data.WireLen()
	header := ImsgHeader{
		Type:   kind,
		Len:    uint16(size),
		PeerID: peerID,
		Pid:    pid,
	}
	if header.Pid == 0 {
		header.Pid = uint32(ibuf.pid)
	}
	buf := make([]byte, size)

	if err = header.WireBytes(buf[0:imsgHeaderLen]); err != nil {
		return fmt.Errorf("header.WireBytes: %s", err)
	}
	if err = data.WireBytes(buf[imsgHeaderLen:]); err != nil {
		return fmt.Errorf("header.WireBytes: %s", err)
	}

	ibuf.mu.Lock()
	ibuf.wQueue = append(ibuf.wQueue, Imsg{Data: buf, FD: fd})
	ibuf.mu.Unlock()

	return nil
}

// Flush writes all pending buffers to the socket
func (ibuf *ImsgBuffer) Flush() {
	ibuf.mu.Lock()
	defer ibuf.mu.Unlock()

	for _, buf := range ibuf.wQueue {
		var cmsgBuf []byte
		if buf.FD != nil {
			cmsgBuf = syscall.UnixRights(int(buf.FD.Fd()))
			defer buf.FD.Close()
		}
		n, _, err := ibuf.conn.WriteMsgUnix(buf.Data, cmsgBuf, nil)
		if err != nil {
			log.Printf("ibuf.conn.Write: %s", err)
		} else if n != len(buf.Data) {
			log.Printf("ibuf.conn.Write short: %d/%d", n, len(buf.Data))
		}
	}
	ibuf.wQueue = nil
}

func (ibuf *ImsgBuffer) Get() (*Imsg, error) {
	result := <-ibuf.msgs
	if result == nil {
		return nil, ImsgBufferClosed
	}

	return result, nil
}

func (ibuf *ImsgBuffer) Close() {
	ibuf.conn.Close()
}

func zero(buf []byte) {
	for i := range buf {
		buf[i] = 0
	}
}

// fd -> chan []byte
// []byte chan -> imsg chan

func (ibuf *ImsgBuffer) readSocket(out chan<- rawBuf) {
	cmsgBuf := make([]byte, cmsgBufLen)
	imsgBuf := make([]byte, IbufReadLen)

	for {
		// TODO: not necessary
		zero(cmsgBuf)
		zero(imsgBuf)

		n, cn, _, _, err := ibuf.conn.ReadMsgUnix(imsgBuf, cmsgBuf)
		if err != nil {
			if err == io.EOF {
				close(ibuf.msgs)
			}
			// if we have a read error, its probably
			// because our connection closed, just quietly
			// exit.
			return
		}
		log.Printf("read %d", n)

		// copy into a new buffer, so we can safely pass it to
		// another goroutine
		buf := make([]byte, n)
		copy(buf, imsgBuf)

		var files []*os.File

		// TODO: not sure how this works.  a Read might return
		// multiple messages coalessed into one.  How does
		// that correspond to socket control messages?
		if cn > 0 {
			cmsgs, err := syscall.ParseSocketControlMessage(cmsgBuf)
			if err != nil {
				log.Printf("ParseSocketControlMessage: %s", err)
				return
			}
			log.Printf("n cmsgs: %d", len(cmsgs))
			for _, cmsg := range cmsgs {
				fds, err := syscall.ParseUnixRights(&cmsg)
				if err != nil {
					log.Printf("ParseUnixRights: %s", err)
				}
				for _, fd := range fds {
					files = append(files, os.NewFile(uintptr(fd), "<from tmux>"))
				}
			}
		}

		// TODO: remove debugging
		if len(files) > 0 {
			log.Printf("FDs: %#v", files)
		}

		out <- rawBuf{buf, files}
	}
}

func (ibuf *ImsgBuffer) reader(in <-chan rawBuf) {
	var inbetween bytes.Buffer
	hBytes := make([]byte, imsgHeaderLen)
	readHeader := true

	var header ImsgHeader

	for {
		rawBuf := <-in
		inbetween.Write(rawBuf.data)

		for {
			// if we're just waiting for more payload
			// data, we don't want to re-read the header.
			if readHeader {
				zero(hBytes)

				// didn't read a full header?  wait for more data
				if inbetween.Len() < imsgHeaderLen {
					break
				}
				n, err := inbetween.Read(hBytes)
				if err != nil {
					log.Printf("inbetween.Read: %s", err)
					return
				} else if n != imsgHeaderLen {
					// short read - should never happen
					log.Printf("inbetween.Read short: %d/%d",
						n, imsgHeaderLen)
					return
				}
				if err = header.InitFromWireBytes(hBytes); err != nil {
					log.Printf("InitFromWireBytes: %s", err)
					return
				}
				readHeader = false
			}

			var payload []byte
			payloadLen := int(header.Len) - imsgHeaderLen
			if payloadLen > 0 {
				// wait for more data
				if inbetween.Len() < payloadLen {
					fmt.Printf("need more for payload %d/%d\n",
						inbetween.Len(), payloadLen)
					break
				}
				payload = make([]byte, payloadLen)
				n, err := inbetween.Read(payload)
				if err != nil {
					log.Printf("inbetween.Read 2: %s", err)
					return
				} else if n != payloadLen {
					log.Printf("inbetween.Read 2 short: %d/%d", n, payloadLen)
					return
				}
			}
			var fd *os.File
			if len(rawBuf.fds) > 0 {
				fd = rawBuf.fds[0]
			}
			// TODO: this FD handling isn't quite right
			imsg := &Imsg{header, payload, fd}
			log.Printf("imsg: %s", MsgType(imsg.Header.Type))
			ibuf.msgs <- imsg
			readHeader = true
		}
	}
}

type String struct {
	S string
}

func (s *String) WireLen() int {
	return len(s.S)
}

func (s *String) WireBytes(buf []byte) error {
	sBytes := []byte(s.S)
	if len(buf) < len(sBytes)+1 {
		return fmt.Errorf("String bad len %d/%d", len(buf), len(sBytes)+1)
	}

	copy(buf, sBytes)
	// make sure its null terminated
	buf[len(sBytes)] = 0

	return nil
}

func (s *String) InitFromWireBytes(buf []byte) error {
	if len(buf) > 0 && buf[len(buf)-1] == 0 {
		buf = buf[:len(buf)-1]
	}
	s.S = string(buf)

	return nil
}

type Int32 struct {
	int32
}

func (i *Int32) WireLen() int {
	return 4
}

func (i *Int32) WireBytes(buf []byte) error {
	var err error
	if len(buf) < 4 {
		return fmt.Errorf("Int32 1 bad len %d/4", len(buf))
	}
	var bb bytes.Buffer

	if err = binary.Write(&bb, binary.LittleEndian, int32(i.int32)); err != nil {
		return fmt.Errorf("i(%d) write: %s", int32(i.int32), err)
	}

	bbuf := bb.Bytes()
	copy(buf, bbuf)

	return nil
}

func (i *Int32) InitFromWireBytes(buf []byte) error {
	if len(buf) != 4 {
		return fmt.Errorf("Int32 bad len %d/16", len(buf))
	}
	i.int32 = int32(binary.LittleEndian.Uint32(buf))

	return nil
}

type Nil struct{}

func (n Nil) WireLen() int {
	return 0
}

func (n Nil) WireBytes(buf []byte) error {
	return nil
}

func (n Nil) InitFromWireBytes(buf []byte) error {
	return nil
}
<|endoftext|>


<commit_before>package smoke

import (
	"fmt"
	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"
)

var _ = Describe("Loggregator:", func() {
	var testConfig = GetConfig()
	var useExistingApp = (testConfig.LoggingApp != "")
	var appName string

	Describe("cf logs", func() {
		BeforeEach(func() {
			appName = testConfig.LoggingApp
			if !useExistingApp {
				appName = generator.RandomName()
				Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		AfterEach(func() {
			if !useExistingApp {
				Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		It("can see app messages in the logs", func() {
			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
				return appLogsSession
			}, 5).Should(Say(`\[App/0\]`))
		})
	})

	Describe("Syslog drains", func() {
		var drainListener *syslogDrainListener
		var serviceName string
		var appUrl string

		BeforeEach(func() {
			syslogDrainAddress := fmt.Sprintf("%s:%d", testConfig.SyslogIpAddress, testConfig.SyslogDrainPort)

			drainListener = &syslogDrainListener{port: testConfig.SyslogDrainPort}
			drainListener.StartListener()
			go drainListener.AcceptConnections()

			// verify listener is reachable via configured public IP
			var conn net.Conn

			var err error
			conn, err = net.Dial("tcp", syslogDrainAddress)
			Expect(err).ToNot(HaveOccurred())

			defer conn.Close()

			randomMessage := "random-message-" + generator.RandomName()
			_, err = conn.Write([]byte(randomMessage))
			Expect(err).ToNot(HaveOccurred())

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())

			appName = generator.RandomName()
			appUrl = appName + "." + testConfig.AppsDomain
			Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			syslogDrainUrl := "syslog://" + syslogDrainAddress
			serviceName = "service-" + generator.RandomName()

			Expect(cf.Cf("cups", serviceName, "-l", syslogDrainUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("bind-service", appName, serviceName).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("restage", appName).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
		})

		AfterEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("delete-service", serviceName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("delete-orphaned-routes", "-f").Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			drainListener.Stop()
		})

		It("forwards app messages to registered syslog drains", func() {
			randomMessage := "random-message-" + generator.RandomName()
			http.Get("http://" + appUrl + "/log/" + randomMessage)

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())
		})
	})
})

type syslogDrainListener struct {
	sync.Mutex
	port             int
	listener         net.Listener
	receivedMessages string
}

func (s *syslogDrainListener) StartListener() {
	listenAddress := fmt.Sprintf(":%d", s.port)
	var err error
	s.listener, err = net.Listen("tcp", listenAddress)
	Expect(err).ToNot(HaveOccurred())
}

func (s *syslogDrainListener) AcceptConnections() {
	defer GinkgoRecover()

	for {
		conn, err := s.listener.Accept()
		if err != nil {
			return
		}
		go s.handleConnection(conn)
	}
}

func (s *syslogDrainListener) Stop() {
	s.listener.Close()
}

func (s *syslogDrainListener) DidReceive(message string) bool {
	s.Lock()
	defer s.Unlock()

	return strings.Contains(s.receivedMessages, message)
}

func (s *syslogDrainListener) handleConnection(conn net.Conn) {
	defer GinkgoRecover()
	buffer := make([]byte, 65536)
	for {
		n, err := conn.Read(buffer)

		if err == io.EOF {
			return
		}
		Expect(err).ToNot(HaveOccurred())

		s.Lock()
		s.receivedMessages += string(buffer[0:n])
		s.Unlock()
	}
}
<commit_msg>loggregator test cleanup deletes service only if created [#79719716]<commit_after>package smoke

import (
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"
	"sync"

	"github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("Loggregator:", func() {
	var testConfig = GetConfig()
	var useExistingApp = (testConfig.LoggingApp != "")
	var appName string

	Describe("cf logs", func() {
		BeforeEach(func() {
			appName = testConfig.LoggingApp
			if !useExistingApp {
				appName = generator.RandomName()
				Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		AfterEach(func() {
			if !useExistingApp {
				Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
		})

		It("can see app messages in the logs", func() {
			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
				return appLogsSession
			}, 5).Should(Say(`\[App/0\]`))
		})
	})

	Describe("Syslog drains", func() {
		var drainListener *syslogDrainListener
		var serviceName string
		var appUrl string

		BeforeEach(func() {
			syslogDrainAddress := fmt.Sprintf("%s:%d", testConfig.SyslogIpAddress, testConfig.SyslogDrainPort)

			drainListener = &syslogDrainListener{port: testConfig.SyslogDrainPort}
			drainListener.StartListener()
			go drainListener.AcceptConnections()

			// verify listener is reachable via configured public IP
			var conn net.Conn

			var err error
			conn, err = net.Dial("tcp", syslogDrainAddress)
			Expect(err).ToNot(HaveOccurred())

			defer conn.Close()

			randomMessage := "random-message-" + generator.RandomName()
			_, err = conn.Write([]byte(randomMessage))
			Expect(err).ToNot(HaveOccurred())

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())

			appName = generator.RandomName()
			appUrl = appName + "." + testConfig.AppsDomain
			Expect(cf.Cf("push", appName, "-p", SIMPLE_RUBY_APP_BITS_PATH).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			syslogDrainUrl := "syslog://" + syslogDrainAddress
			serviceName = "service-" + generator.RandomName()

			Expect(cf.Cf("cups", serviceName, "-l", syslogDrainUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("bind-service", appName, serviceName).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			Expect(cf.Cf("restage", appName).Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))
		})

		AfterEach(func() {
			Expect(cf.Cf("delete", appName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			if serviceName != "" {
				Expect(cf.Cf("delete-service", serviceName, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0))
			}
			Expect(cf.Cf("delete-orphaned-routes", "-f").Wait(CF_PUSH_TIMEOUT_IN_SECONDS)).To(Exit(0))

			drainListener.Stop()
		})

		It("forwards app messages to registered syslog drains", func() {
			randomMessage := "random-message-" + generator.RandomName()
			http.Get("http://" + appUrl + "/log/" + randomMessage)

			Eventually(func() bool {
				return drainListener.DidReceive(randomMessage)
			}).Should(BeTrue())
		})
	})
})

type syslogDrainListener struct {
	sync.Mutex
	port             int
	listener         net.Listener
	receivedMessages string
}

func (s *syslogDrainListener) StartListener() {
	listenAddress := fmt.Sprintf(":%d", s.port)
	var err error
	s.listener, err = net.Listen("tcp", listenAddress)
	Expect(err).ToNot(HaveOccurred())
}

func (s *syslogDrainListener) AcceptConnections() {
	defer GinkgoRecover()

	for {
		conn, err := s.listener.Accept()
		if err != nil {
			return
		}
		go s.handleConnection(conn)
	}
}

func (s *syslogDrainListener) Stop() {
	s.listener.Close()
}

func (s *syslogDrainListener) DidReceive(message string) bool {
	s.Lock()
	defer s.Unlock()

	return strings.Contains(s.receivedMessages, message)
}

func (s *syslogDrainListener) handleConnection(conn net.Conn) {
	defer GinkgoRecover()
	buffer := make([]byte, 65536)
	for {
		n, err := conn.Read(buffer)

		if err == io.EOF {
			return
		}
		Expect(err).ToNot(HaveOccurred())

		s.Lock()
		s.receivedMessages += string(buffer[0:n])
		s.Unlock()
	}
}
<|endoftext|>


<commit_before>package eveapi

import (
	"fmt"

	"golang.org/x/oauth2"
)

// CharacterInfo returned data from XML API
type CorporationSheetXML struct {
	xmlAPIFrame
	CorporationID   int64  `xml:"result>corporationID"`
	CorporationName string `xml:"result>corporationName"`
	Ticker          string `xml:"result>ricker"`
	CEOID           int64  `xml:"result>ceoID"`
	CEOName         string `xml:"result>ceoName"`
	StationID       int64  `xml:"result>stationID"`
	StationName     string `xml:"result>stationName"`
	Description     string `xml:"result>description"`
	AllianceID      int64  `xml:"result>allianceID"`
	AllianceName    string `xml:"result>allianceName"`
	FactionID       int64  `xml:"result>factionID"`
	URL             string `xml:"result>url"`
	MemberCount     int64  `xml:"result>memberCount"`
	Shares          int64  `xml:"result>shares"`
	Logo            struct {
		GraphicID int64 `xml:"grapicID,attr"`
		Shape1    int64 `xml:"shape1,attr"`
		Shape2    int64 `xml:"shape2,attr"`
		Shape3    int64 `xml:"shape3,attr"`
		Color1    int64 `xml:"color1,attr"`
		Color2    int64 `xml:"color2,attr"`
		Color3    int64 `xml:"color3,attr"`
	} `xml:"result>logo"`
}

// GetCharacterInfo queries the XML API for a given characterID.
func (c *EVEAPIClient) CorporationPublicSheetXML(corporationID int64) (*CorporationSheetXML, error) {
	w := &CorporationSheetXML{}

	url := c.base.XML + fmt.Sprintf("corp/CorporationSheet.xml.aspx?corporationID=%d", corporationID)
	_, err := c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationIndustryJobsXML struct {
	xmlAPIFrame
	Entries []struct {
		JobID                int64      `xml:"jobID,attr"`
		InstallerID          int64      `xml:"installerID,attr"`
		InstallerName        string     `xml:"installerName,attr"`
		FacilityID           int64      `xml:"facilityID,attr"`
		SolarSystemName      string     `xml:"solarSystemName,attr"`
		SolarSystemID        int64      `xml:"solarSystemID,attr"`
		StationID            int64      `xml:"stationID,attr"`
		ActivityID           int64      `xml:"activityID,attr"`
		BlueprintID          int64      `xml:"blueprintID,attr"`
		BlueprintTypeID      int64      `xml:"blueprintTypeID,attr"`
		BlueprintTypeName    string     `xml:"blueprintTypeName,attr"`
		BlueprintLocationID  int64      `xml:"blueprintLocationID,attr"`
		OutputLocationID     int64      `xml:"outputLocationID,attr"`
		ProductTypeID        int64      `xml:"productTypeID,attr"`
		Runs                 int64      `xml:"runs,attr"`
		Cost                 float64    `xml:"cost,attr"`
		LicensedRuns         int64      `xml:"licensedRuns,attr"`
		Probability          float64    `xml:"probability,attr"`
		ProductTypeName      string     `xml:"productTypeName,attr"`
		Status               int64      `xml:"status,attr"`
		TimeInSeconds        int64      `xml:"timeInSeconds,attr"`
		StartDate            EVEXMLTime `xml:"startDate,attr"`
		EndDate              EVEXMLTime `xml:"endDate,attr"`
		PauseDate            EVEXMLTime `xml:"pauseDate,attr"`
		CompletedDate        EVEXMLTime `xml:"completedDate,attr"`
		CompletedCharacterID int64      `xml:"completedCharacterID,attr"`
		SuccessfulRuns       int64      `xml:"successfulRuns,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationIndustryJobsXML queries the XML API for active industry jobs for corporationID.
func (c *EVEAPIClient) CorporationIndustryJobsXML(auth oauth2.TokenSource, corporationID int64) (*CorporationIndustryJobsXML, error) {
	w := &CorporationIndustryJobsXML{}
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/IndustryJobs.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

// CorporationIndustryJobsHistoryXML queries the XML API for finished industry jobs for corporationID.
func (c *EVEAPIClient) CorporationIndustryJobsHistoryXML(auth oauth2.TokenSource, corporationID int64) (*CorporationIndustryJobsXML, error) {
	w := &CorporationIndustryJobsXML{}
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/IndustryJobsHistory.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationBlueprintsXML struct {
	xmlAPIFrame
	Entries []struct {
		ItemID             int64  `xml:"itemID,attr"`
		LocationID         int64  `xml:"locationID,attr"`
		TypeID             int64  `xml:"typeID,attr"`
		TypeName           string `xml:"typeName,attr"`
		Quantity           int64  `xml:"quantity,attr"`
		FlagID             int64  `xml:"flagID,attr"`
		TimeEfficiency     int64  `xml:"timeEfficiency,attr"`
		MaterialEfficiency int64  `xml:"materialEfficiency,attr"`
		Runs               int64  `xml:"runs,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationBlueprintsXML queries the XML API for blueprints owned by corporationID.
func (c *EVEAPIClient) CorporationBlueprintsXML(auth oauth2.TokenSource, corporationID int64) (*CorporationBlueprintsXML, error) {
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/Blueprints.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	w := &CorporationBlueprintsXML{}
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}
<commit_msg>Add CorporationSheetDetail and MarketOrder xml endpoints<commit_after>package eveapi

import (
	"fmt"

	"golang.org/x/oauth2"
)

// CorporationSheetXML contains parsed data from XML API
type CorporationSheetXML struct {
	xmlAPIFrame
	CorporationID   int64  `xml:"result>corporationID"`
	CorporationName string `xml:"result>corporationName"`
	Ticker          string `xml:"result>ticker"`
	CEOID           int64  `xml:"result>ceoID"`
	CEOName         string `xml:"result>ceoName"`
	StationID       int64  `xml:"result>stationID"`
	StationName     string `xml:"result>stationName"`
	Description     string `xml:"result>description"`
	AllianceID      int64  `xml:"result>allianceID"`
	AllianceName    string `xml:"result>allianceName"`
	FactionID       int64  `xml:"result>factionID"`
	URL             string `xml:"result>url"`
	MemberCount     int64  `xml:"result>memberCount"`
	Shares          int64  `xml:"result>shares"`
	Logo            struct {
		GraphicID int64 `xml:"grapicID,attr"`
		Shape1    int64 `xml:"shape1,attr"`
		Shape2    int64 `xml:"shape2,attr"`
		Shape3    int64 `xml:"shape3,attr"`
		Color1    int64 `xml:"color1,attr"`
		Color2    int64 `xml:"color2,attr"`
		Color3    int64 `xml:"color3,attr"`
	} `xml:"result>logo"`
}

// CorporationPublicSheetXML queries the XML API for a given corporationID.
func (c *EVEAPIClient) CorporationPublicSheetXML(corporationID int64) (*CorporationSheetXML, error) {
	w := &CorporationSheetXML{}

	url := c.base.XML + fmt.Sprintf("corp/CorporationSheet.xml.aspx?corporationID=%d", corporationID)
	_, err := c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationSheetDetailXML struct {
	CorporationSheetXML
	Divisions []struct {
		Name     string `xml:"name,attr"`
		Accounts []struct {
			Key         string `xml:"accountKey,attr"`
			Description string `xml:"description,attr"`
		} `xml:"row"`
	} `xml:"result>rowset"`
}

// CorporationSheetXML queries the XML API for details of the token's corporation.
func (c *EVEAPIClient) CorporationSheetXML(auth oauth2.TokenSource) (*CorporationSheetDetailXML, error) {
	w := &CorporationSheetDetailXML{}
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/CorporationSheet.xml.aspx?accessToken=%s&accessType=corporation", tok.AccessToken)
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationIndustryJobsXML struct {
	xmlAPIFrame
	Entries []struct {
		JobID                int64      `xml:"jobID,attr"`
		InstallerID          int64      `xml:"installerID,attr"`
		InstallerName        string     `xml:"installerName,attr"`
		FacilityID           int64      `xml:"facilityID,attr"`
		SolarSystemName      string     `xml:"solarSystemName,attr"`
		SolarSystemID        int64      `xml:"solarSystemID,attr"`
		StationID            int64      `xml:"stationID,attr"`
		ActivityID           int64      `xml:"activityID,attr"`
		BlueprintID          int64      `xml:"blueprintID,attr"`
		BlueprintTypeID      int64      `xml:"blueprintTypeID,attr"`
		BlueprintTypeName    string     `xml:"blueprintTypeName,attr"`
		BlueprintLocationID  int64      `xml:"blueprintLocationID,attr"`
		OutputLocationID     int64      `xml:"outputLocationID,attr"`
		ProductTypeID        int64      `xml:"productTypeID,attr"`
		Runs                 int64      `xml:"runs,attr"`
		Cost                 float64    `xml:"cost,attr"`
		LicensedRuns         int64      `xml:"licensedRuns,attr"`
		Probability          float64    `xml:"probability,attr"`
		ProductTypeName      string     `xml:"productTypeName,attr"`
		Status               int64      `xml:"status,attr"`
		TimeInSeconds        int64      `xml:"timeInSeconds,attr"`
		StartDate            EVEXMLTime `xml:"startDate,attr"`
		EndDate              EVEXMLTime `xml:"endDate,attr"`
		PauseDate            EVEXMLTime `xml:"pauseDate,attr"`
		CompletedDate        EVEXMLTime `xml:"completedDate,attr"`
		CompletedCharacterID int64      `xml:"completedCharacterID,attr"`
		SuccessfulRuns       int64      `xml:"successfulRuns,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationIndustryJobsXML queries the XML API for active industry jobs for corporationID.
func (c *EVEAPIClient) CorporationIndustryJobsXML(auth oauth2.TokenSource, corporationID int64) (*CorporationIndustryJobsXML, error) {
	w := &CorporationIndustryJobsXML{}
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/IndustryJobs.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

// CorporationIndustryJobsHistoryXML queries the XML API for finished industry jobs for corporationID.
func (c *EVEAPIClient) CorporationIndustryJobsHistoryXML(auth oauth2.TokenSource, corporationID int64) (*CorporationIndustryJobsXML, error) {
	w := &CorporationIndustryJobsXML{}
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/IndustryJobsHistory.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationBlueprintsXML struct {
	xmlAPIFrame
	Entries []struct {
		ItemID             int64  `xml:"itemID,attr"`
		LocationID         int64  `xml:"locationID,attr"`
		TypeID             int64  `xml:"typeID,attr"`
		TypeName           string `xml:"typeName,attr"`
		Quantity           int64  `xml:"quantity,attr"`
		FlagID             int64  `xml:"flagID,attr"`
		TimeEfficiency     int64  `xml:"timeEfficiency,attr"`
		MaterialEfficiency int64  `xml:"materialEfficiency,attr"`
		Runs               int64  `xml:"runs,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationBlueprintsXML queries the XML API for blueprints owned by corporationID.
func (c *EVEAPIClient) CorporationBlueprintsXML(auth oauth2.TokenSource, corporationID int64) (*CorporationBlueprintsXML, error) {
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/Blueprints.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	w := &CorporationBlueprintsXML{}
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationAssetsXML struct {
	xmlAPIFrame
	Entries []struct {
		ItemID      int64 `xml:"itemID,attr"`
		LocationID  int64 `xml:"locationID,attr"`
		TypeID      int64 `xml:"typeID,attr"`
		Quantity    int64 `xml:"quantity,attr"`
		FlagID      int64 `xml:"flagID,attr"`
		Singleton   bool  `xml:"singleton,attr"`
		RawQuantity int64 `xml:"rawQuantity,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationAssetsXML queries the XML API for assets owned by corporationID.
func (c *EVEAPIClient) CorporationAssetsXML(auth oauth2.TokenSource, corporationID int64) (*CorporationAssetsXML, error) {
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/AssetList.xml.aspx?corporationID=%d&accessToken=%s&flat=1", corporationID, tok.AccessToken)
	w := &CorporationAssetsXML{}
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

type CorporationMarketOrdersXML struct {
	xmlAPIFrame
	Entries []struct {
		OrderID      int64      `xml:"orderID,attr"`
		CharID       int64      `xml:"charID,attr"`
		StationID    int64      `xml:"stationID,attr"`
		VolEntered   int32      `xml:"volEntered,attr"`
		VolRemaining int32      `xml:"volRemaining,attr"`
		MinVolume    int32      `xml:"minVolume,attr"`
		OrderState   int32      `xml:"orderState,attr"`
		TypeID       int64      `xml:"typeID,attr"`
		Range        int32      `xml:"range,attr"`
		AccountKey   int32      `xml:"accountKey,attr"`
		Duration     int32      `xml:"duration,attr"`
		Escrow       float64    `xml:"escrow,attr"`
		Price        float64    `xml:"price,attr"`
		Bid          bool       `xml:"bid,attr"`
		Issued       EVEXMLTime `xml:"issued,attr"`
	} `xml:"result>rowset>row"`
}

// CorporationMarketOrdersXML queries the XML API for orders placed by characters in corporationID.
func (c *EVEAPIClient) CorporationMarketOrdersXML(auth oauth2.TokenSource, corporationID int64) (*CorporationMarketOrdersXML, error) {
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/MarketOrders.xml.aspx?corporationID=%d&accessToken=%s", corporationID, tok.AccessToken)
	w := &CorporationMarketOrdersXML{}
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}

// CorporationMarketOrdersXML queries the XML API for a specific order.
func (c *EVEAPIClient) CorporationMarketOrderXML(auth oauth2.TokenSource, corporationID, orderID int64) (*CorporationMarketOrdersXML, error) {
	tok, err := auth.Token()
	if err != nil {
		return nil, err
	}
	url := c.base.XML + fmt.Sprintf("corp/MarketOrders.xml.aspx?corporationID=%d&orderID=%d&accessToken=%s", corporationID, orderID, tok.AccessToken)
	w := &CorporationMarketOrdersXML{}
	_, err = c.doXML("GET", url, nil, w)
	if err != nil {
		return nil, err
	}
	return w, nil
}
<|endoftext|>


<commit_before>package haproxy

import (
	"github.com/bcicen/go-haproxy/kvcodec"
)

type Info struct {
	Name                       string `kv:"Name"`
	Version                    string `kv:"Version"`
	ReleaseDate                string `kv:"Release_date"`
	Nbproc                     uint64 `kv:"Nbproc"`
	ProcessNum                 uint64 `kv:"Process_num"`
	Pid                        uint64 `kv:"Pid"`
	Uptime                     string `kv:"Uptime"`
	UptimeSec                  uint64 `kv:"Uptime_sec"`
	MemMaxMB                   uint64 `kv:"Memmax_MB"`
	UlimitN                    uint64 `kv:"Ulimit-n"`
	Maxsock                    uint64 `kv:"Maxsock"`
	Maxconn                    uint64 `kv:"Maxconn"`
	HardMaxconn                uint64 `kv:"Hard_maxconn"`
	CurrConns                  uint64 `kv:"CurrConns"`
	CumConns                   uint64 `kv:"CumConns"`
	CumReq                     uint64 `kv:"CumReq"`
	MaxSslConns                uint64 `kv:"MaxSslConns"`
	CurrSslConns               uint64 `kv:"CurrSslConns"`
	CumSslConns                uint64 `kv:"CumSslConns"`
	Maxpipes                   uint64 `kv:"Maxpipes"`
	PipesUsed                  uint64 `kv:"PipesUsed"`
	PipesFree                  uint64 `kv:"PipesFree"`
	ConnRate                   uint64 `kv:"ConnRate"`
	ConnRateLimit              uint64 `kv:"ConnRateLimit"`
	MaxConnRate                uint64 `kv:"MaxConnRate"`
	SessRate                   uint64 `kv:"SessRate"`
	SessRateLimit              uint64 `kv:"SessRateLimit"`
	MaxSessRate                uint64 `kv:"MaxSessRate"`
	SslRate                    uint64 `kv:"SslRate"`
	SslRateLimit               uint64 `kv:"SslRateLimit"`
	MaxSslRate                 uint64 `kv:"MaxSslRate"`
	SslFrontendKeyRate         uint64 `kv:"SslFrontendKeyRate"`
	SslFrontendMaxKeyRate      uint64 `kv:"SslFrontendMaxKeyRate"`
	SslFrontendSessionReusePct uint64 `kv:"SslFrontendSessionReuse_pct"`
	SslBackendKeyRate          uint64 `kv:"SslBackendKeyRate"`
	SslBackendMaxKeyRate       uint64 `kv:"SslBackendMaxKeyRate"`
	SslCacheLookups            uint64 `kv:"SslCacheLookups"`
	SslCacheMisses             uint64 `kv:"SslCacheMisses"`
	CompressBpsIn              uint64 `kv:"CompressBpsIn"`
	CompressBpsOut             uint64 `kv:"CompressBpsOut"`
	CompressBpsRateLim         uint64 `kv:"CompressBpsRateLim"`
	ZlibMemUsage               uint64 `kv:"ZlibMemUsage"`
	MaxZlibMemUsage            uint64 `kv:"MaxZlibMemUsage"`
	Tasks                      uint64 `kv:"Tasks"`
	RunQueue                   uint64 `kv:"Run_queue"`
	IdlePct                    uint64 `kv:"Idle_pct"`
	node                       string `kv:"node"`
	description                string `kv:"description"`
}

// Equivalent to HAProxy "show info" command.
func (h *HAProxyClient) Info() (*Info, error) {
	res, err := h.RunCommand("show info")
	if err != nil {
		return nil, err
	}
	info := &Info{}
	kvcodec.Unmarshal(res, info)
	return info, nil
}
<commit_msg>export node, description fields<commit_after>package haproxy

import (
	"github.com/bcicen/go-haproxy/kvcodec"
)

type Info struct {
	Name                       string `kv:"Name"`
	Version                    string `kv:"Version"`
	ReleaseDate                string `kv:"Release_date"`
	Nbproc                     uint64 `kv:"Nbproc"`
	ProcessNum                 uint64 `kv:"Process_num"`
	Pid                        uint64 `kv:"Pid"`
	Uptime                     string `kv:"Uptime"`
	UptimeSec                  uint64 `kv:"Uptime_sec"`
	MemMaxMB                   uint64 `kv:"Memmax_MB"`
	UlimitN                    uint64 `kv:"Ulimit-n"`
	Maxsock                    uint64 `kv:"Maxsock"`
	Maxconn                    uint64 `kv:"Maxconn"`
	HardMaxconn                uint64 `kv:"Hard_maxconn"`
	CurrConns                  uint64 `kv:"CurrConns"`
	CumConns                   uint64 `kv:"CumConns"`
	CumReq                     uint64 `kv:"CumReq"`
	MaxSslConns                uint64 `kv:"MaxSslConns"`
	CurrSslConns               uint64 `kv:"CurrSslConns"`
	CumSslConns                uint64 `kv:"CumSslConns"`
	Maxpipes                   uint64 `kv:"Maxpipes"`
	PipesUsed                  uint64 `kv:"PipesUsed"`
	PipesFree                  uint64 `kv:"PipesFree"`
	ConnRate                   uint64 `kv:"ConnRate"`
	ConnRateLimit              uint64 `kv:"ConnRateLimit"`
	MaxConnRate                uint64 `kv:"MaxConnRate"`
	SessRate                   uint64 `kv:"SessRate"`
	SessRateLimit              uint64 `kv:"SessRateLimit"`
	MaxSessRate                uint64 `kv:"MaxSessRate"`
	SslRate                    uint64 `kv:"SslRate"`
	SslRateLimit               uint64 `kv:"SslRateLimit"`
	MaxSslRate                 uint64 `kv:"MaxSslRate"`
	SslFrontendKeyRate         uint64 `kv:"SslFrontendKeyRate"`
	SslFrontendMaxKeyRate      uint64 `kv:"SslFrontendMaxKeyRate"`
	SslFrontendSessionReusePct uint64 `kv:"SslFrontendSessionReuse_pct"`
	SslBackendKeyRate          uint64 `kv:"SslBackendKeyRate"`
	SslBackendMaxKeyRate       uint64 `kv:"SslBackendMaxKeyRate"`
	SslCacheLookups            uint64 `kv:"SslCacheLookups"`
	SslCacheMisses             uint64 `kv:"SslCacheMisses"`
	CompressBpsIn              uint64 `kv:"CompressBpsIn"`
	CompressBpsOut             uint64 `kv:"CompressBpsOut"`
	CompressBpsRateLim         uint64 `kv:"CompressBpsRateLim"`
	ZlibMemUsage               uint64 `kv:"ZlibMemUsage"`
	MaxZlibMemUsage            uint64 `kv:"MaxZlibMemUsage"`
	Tasks                      uint64 `kv:"Tasks"`
	RunQueue                   uint64 `kv:"Run_queue"`
	IdlePct                    uint64 `kv:"Idle_pct"`
	Node                       string `kv:"node"`
	Description                string `kv:"description"`
}

// Equivalent to HAProxy "show info" command.
func (h *HAProxyClient) Info() (*Info, error) {
	res, err := h.RunCommand("show info")
	if err != nil {
		return nil, err
	}
	info := &Info{}
	kvcodec.Unmarshal(res, info)
	return info, nil
}
<|endoftext|>


<commit_before>package event

import (
	"testing"
	"time"
)

func TestHandler(t *testing.T) {
	updateCh := make(chan struct{})
	if UpdateLoop(60, updateCh) != nil {
		t.Fatalf("UpdateLoop failed")
	}
	triggers := 0
	Bind(Enter, 0, func(CID, interface{}) int {
		triggers++
		return 0
	})
	sleep()
	if triggers != 1 {
		t.Fatalf("expected update loop to increment triggers")
	}
	<-updateCh
	sleep()
	if triggers != 2 {
		t.Fatalf("expected update loop to increment triggers")
	}
	if FramesElapsed() != 2 {
		t.Fatalf("expected 2 update frames to have elapsed")
	}
	if SetTick(1) != nil {
		t.Fatalf("SetTick failed")
	}
	<-updateCh
	if Stop() != nil {
		t.Fatalf("Stop failed")
	}
	sleep()
	sleep()
	select {
	case <-updateCh:
		t.Fatal("Handler should be closed")
	default:
	}
	if Update() != nil {
		t.Fatalf("Update failed")
	}
	sleep()

	if triggers != 4 {
		t.Fatalf("expected update to increment triggers")
	}
	if Flush() != nil {
		t.Fatalf("Flush failed")
	}

	Flush()
	sleep()
	if Update() != nil {
		t.Fatalf("final Update failed")
	}
	sleep()
	sleep()
	Reset()
}

func BenchmarkHandler(b *testing.B) {
	triggers := 0
	entities := 10
	go DefaultBus.ResolvePending()
	for i := 0; i < entities; i++ {
		DefaultBus.GlobalBind(Enter, func(CID, interface{}) int {
			triggers++
			return 0
		})
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		<-DefaultBus.TriggerBack(Enter, DefaultBus.framesElapsed)
	}
}

func TestPauseAndResume(t *testing.T) {
	b := NewBus()
	b.ResolvePending()
	triggerCt := 0
	b.Bind("EnterFrame", 0, func(CID, interface{}) int {
		triggerCt++
		return 0
	})
	ch := make(chan struct{}, 1000)
	b.UpdateLoop(60, ch)
	time.Sleep(1 * time.Second)
	b.Pause()
	time.Sleep(1 * time.Second)
	oldCt := triggerCt
	time.Sleep(1 * time.Second)
	if oldCt != triggerCt {
		t.Fatalf("pause did not stop enter frame from triggering: expected %v got %v", oldCt, triggerCt)
	}

	b.Resume()
	time.Sleep(1 * time.Second)
	newCt := triggerCt
	if newCt == oldCt {
		t.Fatalf("resume did not resume enter frame triggering: expected %v got %v", oldCt, newCt)
	}
}
<commit_msg>event: increase flexibility of handler test<commit_after>package event

import (
	"testing"
	"time"
)

func TestHandler(t *testing.T) {
	updateCh := make(chan struct{})
	if UpdateLoop(60, updateCh) != nil {
		t.Fatalf("UpdateLoop failed")
	}
	triggers := 0
	Bind(Enter, 0, func(CID, interface{}) int {
		triggers++
		return 0
	})
	sleep()
	if triggers != 1 {
		t.Fatalf("expected update loop to increment triggers")
	}
	<-updateCh
	sleep()
	if triggers != 2 {
		t.Fatalf("expected update loop to increment triggers")
	}
	if FramesElapsed() != 2 {
		t.Fatalf("expected 2 update frames to have elapsed")
	}
	if SetTick(1) != nil {
		t.Fatalf("SetTick failed")
	}
	<-updateCh
	if Stop() != nil {
		t.Fatalf("Stop failed")
	}
	sleep()
	sleep()
	select {
	case <-updateCh:
		t.Fatal("Handler should be closed")
	default:
	}
	expectedTriggers := triggers + 1
	if Update() != nil {
		t.Fatalf("Update failed")
	}
	sleep()

	if triggers != expectedTriggers {
		t.Fatalf("expected update to increment triggers")
	}
	if Flush() != nil {
		t.Fatalf("Flush failed")
	}

	Flush()
	sleep()
	if Update() != nil {
		t.Fatalf("final Update failed")
	}
	sleep()
	sleep()
	Reset()
}

func BenchmarkHandler(b *testing.B) {
	triggers := 0
	entities := 10
	go DefaultBus.ResolvePending()
	for i := 0; i < entities; i++ {
		DefaultBus.GlobalBind(Enter, func(CID, interface{}) int {
			triggers++
			return 0
		})
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		<-DefaultBus.TriggerBack(Enter, DefaultBus.framesElapsed)
	}
}

func TestPauseAndResume(t *testing.T) {
	b := NewBus()
	b.ResolvePending()
	triggerCt := 0
	b.Bind("EnterFrame", 0, func(CID, interface{}) int {
		triggerCt++
		return 0
	})
	ch := make(chan struct{}, 1000)
	b.UpdateLoop(60, ch)
	time.Sleep(1 * time.Second)
	b.Pause()
	time.Sleep(1 * time.Second)
	oldCt := triggerCt
	time.Sleep(1 * time.Second)
	if oldCt != triggerCt {
		t.Fatalf("pause did not stop enter frame from triggering: expected %v got %v", oldCt, triggerCt)
	}

	b.Resume()
	time.Sleep(1 * time.Second)
	newCt := triggerCt
	if newCt == oldCt {
		t.Fatalf("resume did not resume enter frame triggering: expected %v got %v", oldCt, newCt)
	}
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
  fmt.Println("Hello")
  fmt.Println("Hallo")
  fmt.Println("Hola")
  fmt.Println("End my suffering")
  fmt.Println("Heisann")
  fmt.Println("Bonjour")
}
<commit_msg>La til morn<commit_after>package main

import "fmt"

func main() {
  fmt.Println("Hello")
  fmt.Println("Hallo")
  fmt.Println("Hola")
  fmt.Println("End my suffering")
  fmt.Println("Heisann")
  fmt.Println("Morn")
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/GeertJohan/go.rice"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"net/http"
	"os"
	"runtime"
	"strings"
)

var conns []*websocket.Conn

type User struct {
	Id   int
	Name string
	Age  int
}

type postBodySwitchMode struct {
	Address string `json: address`
	Mode    string `json: mode`
}

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

// Format command for settings a input to multiple outputs
func inputToOutputs(input int, outputs ...int) string {
	command := fmt.Sprintf("x%dAV", input)
	outputStrs := make([]string, len(outputs))
	for i, output := range outputs {
		outputStrs[i] = fmt.Sprintf("x%d", output)
	}
	return command + strings.Join(outputStrs, ",")
}

func sendSignal(address string, commands []string) {
	logNPush(fmt.Sprintf("Sending signals... -> %s\n", address))

	logNPush(fmt.Sprintf("Dialing %s...", address))

	conn, err := net.Dial("tcp", address)
	if nil != err {
		logNPush(err.Error())
		return
	}

	defer conn.Close()

	readBuffer := bufio.NewReader(conn)

	logNPush("// Reading some lines")

	for i := 0; i < 2; i++ {
		response, err := readBuffer.ReadString('\n')
		if nil != err {
			logNPush(err.Error())
		}

		logNPush(response)
	}

	logNPush("// Read some lines...")

	for _, command := range commands {
		logNPush("-> " + command)
		fmt.Fprintln(conn, command+"\r")

		// Discard two lines
		_, err := readBuffer.ReadString('\n')
		_, err = readBuffer.ReadString('\n')
		response, err := readBuffer.ReadString('\n')

		if err != nil {
			logNPush("<- " + err.Error())
		} else {
			logNPush("<- " + response)
		}
	}
}

var lineCh chan string

func logNPush(line string) {
	log.Println(line)
	lineCh <- line
}

func switchMode(mode, address string) {
	log.Println("Switching mode...", mode, address)
	input := 0

	switch mode {
	case "mac-mini":
		input = 1
	case "apple-tv":
		input = 2
	case "x":
		input = 3
	case "chromecast":
		input = 4
	}

	sendSignal(address, []string{
		inputToOutputs(input, 1, 2, 3, 4),
	})
}

func toJson(data interface{}) string {
	json, _ := json.MarshalIndent(data, "", "  ")
	return string(json)
}

func main() {
	log.Println("Starting...")
	runtime.GOMAXPROCS(runtime.NumCPU())

	r := mux.NewRouter()

	r.HandleFunc("/socket", func(w http.ResponseWriter, req *http.Request) {
		conn, err := upgrader.Upgrade(w, req, nil)
		if err != nil {
			log.Println(err)
			return
		}

		conns = append(conns, conn)
	})

	r.Methods("POST").Path("/switch-mode").HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		var post postBodySwitchMode
		dec := json.NewDecoder(req.Body)
		err := dec.Decode(&post)

		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		switchMode(post.Mode, post.Address)
	})

	n := negroni.New(
		negroni.NewRecovery(),
		negroni.NewLogger(),
		negroni.NewStatic(rice.MustFindBox("public").HTTPBox()),
	)
	n.UseHandler(r)
	listen := os.Getenv("LISTEN")
	if listen == "" {
		listen = ":3000"
	}

	lineCh = make(chan string, 32)

	go func() {
		for line := range lineCh {
			for _, conn := range conns {
				err := conn.WriteMessage(websocket.TextMessage, []byte(line))
				if nil != err {
					log.Println(err)
				}
			}
		}
	}()

	n.Run(listen)
}
<commit_msg>Dial tcp connection with timeout<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/GeertJohan/go.rice"
	"github.com/codegangsta/negroni"
	"github.com/gorilla/mux"
	"github.com/gorilla/websocket"
	"log"
	"net"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"
)

var conns []*websocket.Conn

type User struct {
	Id   int
	Name string
	Age  int
}

type postBodySwitchMode struct {
	Address string `json: address`
	Mode    string `json: mode`
}

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

// Format command for settings a input to multiple outputs
func inputToOutputs(input int, outputs ...int) string {
	command := fmt.Sprintf("x%dAV", input)
	outputStrs := make([]string, len(outputs))
	for i, output := range outputs {
		outputStrs[i] = fmt.Sprintf("x%d", output)
	}
	return command + strings.Join(outputStrs, ",")
}

func sendSignal(address string, commands []string) {
	logNPush(fmt.Sprintf("Sending signals... -> %s\n", address))

	logNPush(fmt.Sprintf("Dialing %s...", address))

	conn, err := net.DialTimeout("tcp", address, 7*time.Second)
	if nil != err {
		logNPush(err.Error())
		return
	}

	defer conn.Close()

	readBuffer := bufio.NewReader(conn)

	logNPush("// Reading some lines")

	for i := 0; i < 2; i++ {
		response, err := readBuffer.ReadString('\n')
		if nil != err {
			logNPush(err.Error())
		}

		logNPush(response)
	}

	logNPush("// Read some lines...")

	for _, command := range commands {
		logNPush("-> " + command)
		fmt.Fprintln(conn, command+"\r")

		// Discard two lines
		_, err := readBuffer.ReadString('\n')
		_, err = readBuffer.ReadString('\n')
		response, err := readBuffer.ReadString('\n')

		if err != nil {
			logNPush("<- " + err.Error())
		} else {
			logNPush("<- " + response)
		}
	}
}

var lineCh chan string

func logNPush(line string) {
	log.Println(line)
	lineCh <- line
}

func switchMode(mode, address string) {
	log.Println("Switching mode...", mode, address)
	input := 0

	switch mode {
	case "mac-mini":
		input = 1
	case "apple-tv":
		input = 2
	case "x":
		input = 3
	case "chromecast":
		input = 4
	}

	sendSignal(address, []string{
		inputToOutputs(input, 1, 2, 3, 4),
	})
}

func toJson(data interface{}) string {
	json, _ := json.MarshalIndent(data, "", "  ")
	return string(json)
}

func main() {
	log.Println("Starting...")
	runtime.GOMAXPROCS(runtime.NumCPU())

	r := mux.NewRouter()

	r.HandleFunc("/socket", func(w http.ResponseWriter, req *http.Request) {
		conn, err := upgrader.Upgrade(w, req, nil)
		if err != nil {
			log.Println(err)
			return
		}

		conns = append(conns, conn)
	})

	r.Methods("POST").Path("/switch-mode").HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		var post postBodySwitchMode
		dec := json.NewDecoder(req.Body)
		err := dec.Decode(&post)

		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		switchMode(post.Mode, post.Address)
	})

	n := negroni.New(
		negroni.NewRecovery(),
		negroni.NewLogger(),
		negroni.NewStatic(rice.MustFindBox("public").HTTPBox()),
	)
	n.UseHandler(r)
	listen := os.Getenv("LISTEN")
	if listen == "" {
		listen = ":3000"
	}

	lineCh = make(chan string, 32)

	go func() {
		for line := range lineCh {
			for _, conn := range conns {
				err := conn.WriteMessage(websocket.TextMessage, []byte(line))
				if nil != err {
					log.Println(err)
				}
			}
		}
	}()

	n.Run(listen)
}
<|endoftext|>


<commit_before>package main

import (
	"C"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/ry/v8worker"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"regexp"
	"runtime"
)

type module struct {
	Err      error  `json:"err"`
	Source   string `json:"source"`
	Id       string `json:"id"`
	Filename string `json:"filename"`
	Dirname  string `json:"dirname"`
	main     bool
}

var (
	jsExtensionRe = regexp.MustCompile(`\.js$`)
	jsFile        = flag.String("f", "server.js", "js file to run")
)

// Adapted from node.js source:
// see https://github.com/nodejs/node/blob/master/src/node.js#L871
const nativeModule = `
	'use strict';

	function NativeModule(rawModule) {
		this.filename = rawModule.filename;
		this.dirname = rawModule.dirname;
		this.id = rawModule.id;
		this.exports = {};
		this.loaded = false;
		this._source = rawModule.source;
	}

	NativeModule.require = function(id) {
                console.log("ID:", id)
		var rawModule = JSON.parse($sendSync(id));
		if (rawModule.err) {
			throw new RangeError(JSON.stringify(rawModule.err));
		}

		var nativeModule = new NativeModule(rawModule);

		nativeModule.compile();

		return nativeModule.exports;
	};

	NativeModule.prototype.compile = function() {
		var fn = eval(this._source);
		fn(this.exports, NativeModule.require, this, this.filename, this.dirname);
		this.loaded = true;
	};
	`

func (m *module) load() {
	filename := jsExtensionRe.ReplaceAllString(m.Id, "") + ".js"
	if wd, err := os.Getwd(); err == nil {
		m.Filename = path.Join(wd, filename)
	} else {
		m.Err = err
		return
	}
	file, err := ioutil.ReadFile(filename)
	if err != nil {
		m.Err = err
		return
	}
	m.Dirname = path.Dir(m.Filename)
	var b bytes.Buffer
	if m.main {
		b.WriteString(fmt.Sprintf(
			"var main = new NativeModule({ id: '%s', filename: '%s', dirname: '%s' });\n",
			m.Id, m.Filename, m.Dirname))
	}
	b.WriteString("(function (exports, require, module, __filename, __dirname) { ")
	if m.main {
		b.WriteString("\nrequire.main = module;")
	}
	b.Write(file)
	if m.main {
		b.WriteString("\n}")
		b.WriteString("(main.exports, NativeModule.require, main, main.filename, main.dirname));")
		b.WriteString("\n$send('exit');") // exit when main returns
	} else {
		b.WriteString("\n});")
	}
	m.Source = b.String()
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	worker := v8worker.New(func(msg string) {
		w.Write([]byte(msg))
	}, func(msg string) string {
		m := module{Id: msg, main: false}
		m.load()
		bytes, _ := json.Marshal(m)
		return string(bytes)
	})

	defer func() {
		worker.TerminateExecution()
	}()

	if err := worker.Load("native-module.js", nativeModule); err != nil {
		log.Println(err)
		return
	}
	JSCode := `
        $send("Hello world from V8\n");
    `
	if err := worker.Load("code.js", JSCode); err != nil {
		log.Printf("failed to load js file. error: %v", err)
	}
}

func main() {
	fmt.Println("Go version:", runtime.Version())

	http.HandleFunc("/", rootHandler)
	http.ListenAndServe(":8014", nil)
}

func loadMainModule(w *v8worker.Worker, id string) error {
	m := module{Id: id, main: true}
	m.load()
	if m.Err != nil {
		return m.Err
	}
	return w.Load(m.Filename, m.Source)
}
<commit_msg>print out server port<commit_after>package main

import (
	"C"
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/ry/v8worker"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"regexp"
	"runtime"
)

type module struct {
	Err      error  `json:"err"`
	Source   string `json:"source"`
	Id       string `json:"id"`
	Filename string `json:"filename"`
	Dirname  string `json:"dirname"`
	main     bool
}

var (
	jsExtensionRe = regexp.MustCompile(`\.js$`)
	jsFile        = flag.String("f", "server.js", "js file to run")
)

// Adapted from node.js source:
// see https://github.com/nodejs/node/blob/master/src/node.js#L871
const nativeModule = `
	'use strict';

	function NativeModule(rawModule) {
		this.filename = rawModule.filename;
		this.dirname = rawModule.dirname;
		this.id = rawModule.id;
		this.exports = {};
		this.loaded = false;
		this._source = rawModule.source;
	}

	NativeModule.require = function(id) {
                console.log("ID:", id)
		var rawModule = JSON.parse($sendSync(id));
		if (rawModule.err) {
			throw new RangeError(JSON.stringify(rawModule.err));
		}

		var nativeModule = new NativeModule(rawModule);

		nativeModule.compile();

		return nativeModule.exports;
	};

	NativeModule.prototype.compile = function() {
		var fn = eval(this._source);
		fn(this.exports, NativeModule.require, this, this.filename, this.dirname);
		this.loaded = true;
	};
	`

func (m *module) load() {
	filename := jsExtensionRe.ReplaceAllString(m.Id, "") + ".js"
	if wd, err := os.Getwd(); err == nil {
		m.Filename = path.Join(wd, filename)
	} else {
		m.Err = err
		return
	}
	file, err := ioutil.ReadFile(filename)
	if err != nil {
		m.Err = err
		return
	}
	m.Dirname = path.Dir(m.Filename)
	var b bytes.Buffer
	if m.main {
		b.WriteString(fmt.Sprintf(
			"var main = new NativeModule({ id: '%s', filename: '%s', dirname: '%s' });\n",
			m.Id, m.Filename, m.Dirname))
	}
	b.WriteString("(function (exports, require, module, __filename, __dirname) { ")
	if m.main {
		b.WriteString("\nrequire.main = module;")
	}
	b.Write(file)
	if m.main {
		b.WriteString("\n}")
		b.WriteString("(main.exports, NativeModule.require, main, main.filename, main.dirname));")
		b.WriteString("\n$send('exit');") // exit when main returns
	} else {
		b.WriteString("\n});")
	}
	m.Source = b.String()
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	worker := v8worker.New(func(msg string) {
		w.Write([]byte(msg))
	}, func(msg string) string {
		m := module{Id: msg, main: false}
		m.load()
		bytes, _ := json.Marshal(m)
		return string(bytes)
	})

	defer func() {
		worker.TerminateExecution()
	}()

	if err := worker.Load("native-module.js", nativeModule); err != nil {
		log.Println(err)
		return
	}
	JSCode := `
        $send("Hello world from V8\n");
    `
	if err := worker.Load("code.js", JSCode); err != nil {
		log.Printf("failed to load js file. error: %v", err)
	}
}

func main() {
	fmt.Println("Go version:", runtime.Version())
	fmt.Println("Server listening on port 8014")

	http.HandleFunc("/", rootHandler)
	http.ListenAndServe(":8014", nil)
}

func loadMainModule(w *v8worker.Worker, id string) error {
	m := module{Id: id, main: true}
	m.load()
	if m.Err != nil {
		return m.Err
	}
	return w.Load(m.Filename, m.Source)
}
<|endoftext|>


<commit_before>package postgres

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"

	"github.com/caarlos0/env"
	"github.com/jmoiron/sqlx"
	// Used pg drive on sqlx
	_ "github.com/lib/pq"

	"database/sql"

	"github.com/nuveo/prest/api"
	"github.com/nuveo/prest/config"
)

const (
	pageNumberKey   = "_page"
	pageSizeKey     = "_page_size"
	defaultPageSize = "10"
)

// Conn connect on PostgreSQL
// Used sqlx
func Conn() (db *sqlx.DB) {
	cfg := config.Prest{}
	env.Parse(&cfg)

	db, err := sqlx.Connect("postgres", fmt.Sprintf("user=%s dbname=%s sslmode=disable", cfg.PGUser, cfg.PGDatabase))
	if err != nil {
		panic(fmt.Sprintf("Unable to connection to database: %v\n", err))
	}
	return
}

// WhereByRequest create interface for queries + where
func WhereByRequest(r *http.Request) (whereSyntax string) {
	u, _ := url.Parse(r.URL.String())
	where := []string{}
	for key, val := range u.Query() {
		if !strings.HasPrefix(key, "_") {
			where = append(where, fmt.Sprintf("%s='%s'", key, val[0]))
		}
	}

	whereSyntax = strings.Join(where, " and ")
	return
}

// Query process queries
func Query(SQL string, params ...interface{}) (jsonData []byte, err error) {
	db := Conn()
	rows, err := db.Queryx(SQL, params...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	columns, err := rows.Columns()
	if err != nil {
		return nil, err
	}

	count := len(columns)
	tableData := make([]map[string]interface{}, 0)
	values := make([]interface{}, count)
	valuePtrs := make([]interface{}, count)
	for rows.Next() {
		for i := 0; i < count; i++ {
			valuePtrs[i] = &values[i]
		}
		rows.Scan(valuePtrs...)
		entry := make(map[string]interface{})
		for i, col := range columns {
			var v interface{}
			val := values[i]
			b, ok := val.([]byte)
			if ok {
				v = string(b)
			} else {
				v = val
			}
			entry[col] = v
		}
		tableData = append(tableData, entry)
	}
	jsonData, err = json.Marshal(tableData)

	return
}

// PaginateIfPossible func
func PaginateIfPossible(r *http.Request) (paginatedQuery string) {
	u, _ := url.Parse(r.URL.String())
	values := u.Query()
	if _, ok := values[pageNumberKey]; !ok {
		paginatedQuery = ""
		return
	}
	pageNumber := values[pageNumberKey][0]
	pageSize := defaultPageSize
	if size, ok := values[pageSizeKey]; ok {
		pageSize = size[0]
	}
	paginatedQuery = fmt.Sprintf("LIMIT %s OFFSET(%s - 1) * %s", pageSize, pageNumber, pageSize)
	return
}

// Insert execute insert sql into a table
func Insert(database, schema, table string, body api.Request) (jsonData []byte, err error) {
	var result sql.Result
	var rowsAffected int64

	fields := make([]string, 0)
	values := make([]string, 0)
	for key, value := range body.Data {
		fields = append(fields, key)
		values = append(values, value)
	}
	colsName := strings.Join(fields, ", ")
	colsValue := strings.Join(values, "', '")
	sql := fmt.Sprintf("INSERT INTO %s.%s.%s (%s) VALUES ('%s')", database, schema, table, colsName, colsValue)

	db := Conn()
	result, err = db.Exec(sql)
	if err != nil {
		return
	}
	rowsAffected, err = result.RowsAffected()
	if err != nil {
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	jsonData, err = json.Marshal(data)
	return
}

// Delete execute delete sql into a table
func Delete(database, schema, table, where string) (jsonData []byte, err error) {
	var result sql.Result
	var rowsAffected int64

	sql := fmt.Sprintf("DELETE FROM %s.%s.%s", database, schema, table)
	if where != "" {
		sql = fmt.Sprint(
			sql,
			" WHERE ",
			where)
	}

	db := Conn()
	result, err = db.Exec(sql)
	if err != nil {
		return
	}
	rowsAffected, err = result.RowsAffected()
	if err != nil {
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	jsonData, err = json.Marshal(data)
	return
}
<commit_msg>update logic implementation<commit_after>package postgres

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"

	"github.com/caarlos0/env"
	"github.com/jmoiron/sqlx"
	// Used pg drive on sqlx
	_ "github.com/lib/pq"

	"database/sql"

	"github.com/nuveo/prest/api"
	"github.com/nuveo/prest/config"
)

const (
	pageNumberKey   = "_page"
	pageSizeKey     = "_page_size"
	defaultPageSize = "10"
)

// Conn connect on PostgreSQL
// Used sqlx
func Conn() (db *sqlx.DB) {
	cfg := config.Prest{}
	env.Parse(&cfg)

	db, err := sqlx.Connect("postgres", fmt.Sprintf("user=%s dbname=%s sslmode=disable", cfg.PGUser, cfg.PGDatabase))
	if err != nil {
		panic(fmt.Sprintf("Unable to connection to database: %v\n", err))
	}
	return
}

// WhereByRequest create interface for queries + where
func WhereByRequest(r *http.Request) (whereSyntax string) {
	u, _ := url.Parse(r.URL.String())
	where := []string{}
	for key, val := range u.Query() {
		if !strings.HasPrefix(key, "_") {
			where = append(where, fmt.Sprintf("%s='%s'", key, val[0]))
		}
	}

	whereSyntax = strings.Join(where, " and ")
	return
}

// Query process queries
func Query(SQL string, params ...interface{}) (jsonData []byte, err error) {
	db := Conn()
	rows, err := db.Queryx(SQL, params...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	columns, err := rows.Columns()
	if err != nil {
		return nil, err
	}

	count := len(columns)
	tableData := make([]map[string]interface{}, 0)
	values := make([]interface{}, count)
	valuePtrs := make([]interface{}, count)
	for rows.Next() {
		for i := 0; i < count; i++ {
			valuePtrs[i] = &values[i]
		}
		rows.Scan(valuePtrs...)
		entry := make(map[string]interface{})
		for i, col := range columns {
			var v interface{}
			val := values[i]
			b, ok := val.([]byte)
			if ok {
				v = string(b)
			} else {
				v = val
			}
			entry[col] = v
		}
		tableData = append(tableData, entry)
	}
	jsonData, err = json.Marshal(tableData)

	return
}

// PaginateIfPossible func
func PaginateIfPossible(r *http.Request) (paginatedQuery string) {
	u, _ := url.Parse(r.URL.String())
	values := u.Query()
	if _, ok := values[pageNumberKey]; !ok {
		paginatedQuery = ""
		return
	}
	pageNumber := values[pageNumberKey][0]
	pageSize := defaultPageSize
	if size, ok := values[pageSizeKey]; ok {
		pageSize = size[0]
	}
	paginatedQuery = fmt.Sprintf("LIMIT %s OFFSET(%s - 1) * %s", pageSize, pageNumber, pageSize)
	return
}

// Insert execute insert sql into a table
func Insert(database, schema, table string, body api.Request) (jsonData []byte, err error) {
	var result sql.Result
	var rowsAffected int64

	fields := make([]string, 0)
	values := make([]string, 0)
	for key, value := range body.Data {
		fields = append(fields, key)
		values = append(values, value)
	}
	colsName := strings.Join(fields, ", ")
	colsValue := strings.Join(values, "', '")
	sql := fmt.Sprintf("INSERT INTO %s.%s.%s (%s) VALUES ('%s')", database, schema, table, colsName, colsValue)

	db := Conn()
	result, err = db.Exec(sql)
	if err != nil {
		return
	}
	rowsAffected, err = result.RowsAffected()
	if err != nil {
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	jsonData, err = json.Marshal(data)
	return
}

// Delete execute delete sql into a table
func Delete(database, schema, table, where string) (jsonData []byte, err error) {
	var result sql.Result
	var rowsAffected int64

	sql := fmt.Sprintf("DELETE FROM %s.%s.%s", database, schema, table)
	if where != "" {
		sql = fmt.Sprint(
			sql,
			" WHERE ",
			where)
	}

	db := Conn()
	result, err = db.Exec(sql)
	if err != nil {
		return
	}
	rowsAffected, err = result.RowsAffected()
	if err != nil {
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	jsonData, err = json.Marshal(data)
	return
}

// Update execute update sql into a table
func Update(database, schema, table, where string, body api.Request) (jsonData []byte, err error) {
	var result sql.Result
	var rowsAffected int64

	fields := []string{}
	for key, value := range body.Data {
		fields = append(fields, fmt.Sprintf("%s='%s'", key, value))
	}
	setSyntax := strings.Join(fields, ", ")

	sql := fmt.Sprintf("UPDATE %s.%s.%s SET %s", database, schema, table, setSyntax)

	if where != "" {
		sql = fmt.Sprint(
			sql,
			" WHERE ",
			where)
	}

	db := Conn()
	result, err = db.Exec(sql)
	if err != nil {
		return
	}
	rowsAffected, err = result.RowsAffected()
	if err != nil {
		return
	}

	data := make(map[string]interface{})
	data["rows_affected"] = rowsAffected
	jsonData, err = json.Marshal(data)
	return
}
<|endoftext|>


<commit_before>package axslogparser

import (
	"strings"
	"time"

	"github.com/Songmu/go-ltsv"
	"github.com/pkg/errors"
)

// LTSV access log parser
type LTSV struct {
}

// Parse for Parser interface
func (lv *LTSV) Parse(line string) (*Log, error) {
	l := &Log{}
	err := ltsv.Unmarshal([]byte(line), l)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to parse ltsvlog: %s", line)
	}
	l.Time, _ = time.Parse(clfTimeLayout, strings.Trim(l.TimeStr, "[]"))
	if err := l.breakdownRequest(); err != nil {
		return nil, errors.Wrap(err, "failed to parse ltsvlog")
	}
	return l, nil
}
<commit_msg>include the log in error<commit_after>package axslogparser

import (
	"strings"
	"time"

	"github.com/Songmu/go-ltsv"
	"github.com/pkg/errors"
)

// LTSV access log parser
type LTSV struct {
}

// Parse for Parser interface
func (lv *LTSV) Parse(line string) (*Log, error) {
	l := &Log{}
	err := ltsv.Unmarshal([]byte(line), l)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to parse ltsvlog: %s", line)
	}
	l.Time, _ = time.Parse(clfTimeLayout, strings.Trim(l.TimeStr, "[]"))
	if err := l.breakdownRequest(); err != nil {
		return nil, errors.Wrap(err, "failed to parse ltsvlog: %s")
	}
	return l, nil
}
<|endoftext|>


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

package vfs

import (
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	pathpkg "path"
	"path/filepath"
	"runtime"
)

// We expose a new variable because otherwise we need to copy the findGOROOT logic again
// from cmd/godoc which is already copied twice from the standard library.

// GOROOT returns the GOROOT path under which the godoc binary is running.
// It is needed to check whether a filesystem root is under GOROOT or not.
// This is set from cmd/godoc/main.go
var GOROOT = runtime.GOROOT()

// OS returns an implementation of FileSystem reading from the
// tree rooted at root.  Recording a root is convenient everywhere
// but necessary on Windows, because the slash-separated path
// passed to Open has no way to specify a drive letter.  Using a root
// lets code refer to OS(`c:\`), OS(`d:\`) and so on.
func OS(root string) FileSystem {
	var t RootType
	switch {
	case root == GOROOT:
		t = RootTypeGoRoot
	case isGoPath(root):
		t = RootTypeGoPath
	}
	return osFS{rootPath: root, rootType: t}
}

type osFS struct {
	rootPath string
	rootType RootType
}

func isGoPath(path string) bool {
	for _, bp := range filepath.SplitList(build.Default.GOPATH) {
		for _, gp := range filepath.SplitList(path) {
			if bp == gp {
				return true
			}
		}
	}
	return false
}

func (root osFS) String() string { return "os(" + root.rootPath + ")" }

// RootType returns the root type for the filesystem.
//
// Note that we ignore the path argument because roottype is a property of
// this filesystem. But for other filesystems, the roottype might need to be
// dynamically deduced at call time.
func (root osFS) RootType(path string) RootType {
	return root.rootType
}

func (root osFS) resolve(path string) string {
	// Clean the path so that it cannot possibly begin with ../.
	// If it did, the result of filepath.Join would be outside the
	// tree rooted at root.  We probably won't ever see a path
	// with .. in it, but be safe anyway.
	path = pathpkg.Clean("/" + path)

	return filepath.Join(root.rootPath, path)
}

func (root osFS) Open(path string) (ReadSeekCloser, error) {
	f, err := os.Open(root.resolve(path))
	if err != nil {
		return nil, err
	}
	fi, err := f.Stat()
	if err != nil {
		f.Close()
		return nil, err
	}
	if fi.IsDir() {
		f.Close()
		return nil, fmt.Errorf("Open: %s is a directory", path)
	}
	return f, nil
}

func (root osFS) Lstat(path string) (os.FileInfo, error) {
	return os.Lstat(root.resolve(path))
}

func (root osFS) Stat(path string) (os.FileInfo, error) {
	return os.Stat(root.resolve(path))
}

func (root osFS) ReadDir(path string) ([]os.FileInfo, error) {
	return ioutil.ReadDir(root.resolve(path)) // is sorted
}
<commit_msg>godoc/vfs: improve comment on GOROOT<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package vfs

import (
	"fmt"
	"go/build"
	"io/ioutil"
	"os"
	pathpkg "path"
	"path/filepath"
	"runtime"
)

// We expose a new variable because otherwise we need to copy the findGOROOT logic again
// from cmd/godoc which is already copied twice from the standard library.

// GOROOT is the GOROOT path under which the godoc binary is running.
// It is needed to check whether a filesystem root is under GOROOT or not.
// This is set from cmd/godoc/main.go.
var GOROOT = runtime.GOROOT()

// OS returns an implementation of FileSystem reading from the
// tree rooted at root.  Recording a root is convenient everywhere
// but necessary on Windows, because the slash-separated path
// passed to Open has no way to specify a drive letter.  Using a root
// lets code refer to OS(`c:\`), OS(`d:\`) and so on.
func OS(root string) FileSystem {
	var t RootType
	switch {
	case root == GOROOT:
		t = RootTypeGoRoot
	case isGoPath(root):
		t = RootTypeGoPath
	}
	return osFS{rootPath: root, rootType: t}
}

type osFS struct {
	rootPath string
	rootType RootType
}

func isGoPath(path string) bool {
	for _, bp := range filepath.SplitList(build.Default.GOPATH) {
		for _, gp := range filepath.SplitList(path) {
			if bp == gp {
				return true
			}
		}
	}
	return false
}

func (root osFS) String() string { return "os(" + root.rootPath + ")" }

// RootType returns the root type for the filesystem.
//
// Note that we ignore the path argument because roottype is a property of
// this filesystem. But for other filesystems, the roottype might need to be
// dynamically deduced at call time.
func (root osFS) RootType(path string) RootType {
	return root.rootType
}

func (root osFS) resolve(path string) string {
	// Clean the path so that it cannot possibly begin with ../.
	// If it did, the result of filepath.Join would be outside the
	// tree rooted at root.  We probably won't ever see a path
	// with .. in it, but be safe anyway.
	path = pathpkg.Clean("/" + path)

	return filepath.Join(root.rootPath, path)
}

func (root osFS) Open(path string) (ReadSeekCloser, error) {
	f, err := os.Open(root.resolve(path))
	if err != nil {
		return nil, err
	}
	fi, err := f.Stat()
	if err != nil {
		f.Close()
		return nil, err
	}
	if fi.IsDir() {
		f.Close()
		return nil, fmt.Errorf("Open: %s is a directory", path)
	}
	return f, nil
}

func (root osFS) Lstat(path string) (os.FileInfo, error) {
	return os.Lstat(root.resolve(path))
}

func (root osFS) Stat(path string) (os.FileInfo, error) {
	return os.Stat(root.resolve(path))
}

func (root osFS) ReadDir(path string) ([]os.FileInfo, error) {
	return ioutil.ReadDir(root.resolve(path)) // is sorted
}
<|endoftext|>


<commit_before>/*
Copyright 2013 Tamás Gulácsi

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 godrv implements a Go Oracle driver.
package godrv

import (
	"database/sql"
	"database/sql/driver"
	"io"
	"log"
	"strconv"
	"strings"
	"unsafe"

	"github.com/tgulacsi/goracle/oracle"
	"gopkg.in/errgo.v1"
)

var (
	// NotImplemented prints Not implemented
	NotImplemented = errgo.New("Not implemented")
	// IsDebug should we print debug logs?
	IsDebug bool
)

type conn struct {
	cx *oracle.Connection
}

type stmt struct {
	cu        *oracle.Cursor //Stmt ?
	statement string
}

// filterErr filters the error, returns driver.ErrBadConn if appropriate
func filterErr(err error) error {
	if oraErr, ok := errgo.Cause(err).(*oracle.Error); ok {
		switch oraErr.Code {
		case 115, 451, 452, 609, 1090, 1092, 1073, 3113, 3114, 3135, 3136, 12153, 12161, 12170, 12224, 12230, 12233, 12510, 12511, 12514, 12518, 12526, 12527, 12528, 12539: //connection errors - try again!
			return driver.ErrBadConn
		}
	}
	return err
}

// Prepare the query for execution, return a prepared statement and error
func (c conn) Prepare(query string) (driver.Stmt, error) {
	cu := c.cx.NewCursor()
	if strings.Index(query, ":1") < 0 && strings.Index(query, "?") >= 0 {
		q := strings.Split(query, "?")
		q2 := make([]string, 0, 2*len(q)-1)
		for i := 0; i < len(q); i++ {
			if i > 0 {
				q2 = append(q2, ":"+strconv.Itoa(i))
			}
			q2 = append(q2, q[i])
		}
		query = strings.Join(q2, "")
	}
	debug("%p.Prepare(%s)", cu, query)
	err := cu.Prepare(query, "")
	if err != nil {
		return nil, filterErr(err)
	}
	return stmt{cu: cu, statement: query}, nil
}

// closes the connection
func (c conn) Close() error {
	err := c.cx.Close()
	c.cx = nil
	return err
}

type tx struct {
	cx *oracle.Connection //Transaction ?
}

// begins a transaction
func (c conn) Begin() (driver.Tx, error) {
	if !c.cx.IsConnected() {
		if err := c.cx.Connect(0, false); err != nil {
			return nil, filterErr(err)
		}
	}
	return tx{cx: c.cx}, nil
}

// commits currently opened transaction
func (t tx) Commit() error {
	if t.cx != nil {
		return t.cx.Commit()
	}
	return nil
}

// rolls back current transaction
func (t tx) Rollback() error {
	if t.cx != nil {
		return t.cx.Rollback()
	}
	return nil
}

// closes statement
func (s stmt) Close() error {
	if s.cu != nil {
		debug("CLOSEing statement %p (%s)", s.cu, s.statement)
		s.cu.Close()
		s.cu = nil
	}
	return nil
}

// number of input parameters
func (s stmt) NumInput() int {
	names, err := s.cu.GetBindNames()
	if err != nil {
		log.Printf("error getting bind names of %p: %s", s.cu, err)
		return -1
	}
	return len(names)
}

// NewVar creates a new Variable, for out binds.
func (s stmt) NewVar(value interface{}) (*oracle.Variable, error) {
	return s.cu.NewVar(value)
}

type rowsRes struct {
	cu   *oracle.Cursor
	cols []oracle.VariableDescription
}

// executes the statement
func (s stmt) run(args []driver.Value) (*rowsRes, error) {
	//A driver Value is a value that drivers must be able to handle.
	//A Value is either nil or an instance of one of these types:
	//int64
	//float64
	//bool
	//[]byte
	//string   [*] everywhere except from Rows.Next.
	//time.Time

	var err error
	a := (*[]interface{})(unsafe.Pointer(&args))
	debug("%p.run(%s, %v)", s.cu, s.statement, *a)
	if err = s.cu.Execute(s.statement, *a, nil); err != nil {
		return nil, filterErr(err)
	}

	var cols []oracle.VariableDescription
	if !s.cu.IsDDL() {
		cols, err = s.cu.GetDescription()
		debug("cols: %+v err: %s", cols, err)
		if err != nil {
			return nil, errgo.Mask(err)
		}
	}
	return &rowsRes{cu: s.cu, cols: cols}, nil
}

func (s stmt) Exec(args []driver.Value) (driver.Result, error) {
	return s.run(args)
}

func (s stmt) Query(args []driver.Value) (driver.Rows, error) {
	return s.run(args)
}

func (r rowsRes) LastInsertId() (int64, error) {
	return -1, NotImplemented
}

func (r rowsRes) RowsAffected() (int64, error) {
	return int64(r.cu.GetRowCount()), nil
}

// resultset column names
func (r rowsRes) Columns() []string {
	cls := make([]string, len(r.cols))
	for i, c := range r.cols {
		cls[i] = c.Name
	}
	return cls
}

// closes the resultset
func (r rowsRes) Close() error {
	if r.cu != nil {
		debug("CLOSEing result %p", r.cu)
		// r.cu.Close() // FIXME
		r.cu = nil
	}
	return nil
}

// DATE, DATETIME, TIMESTAMP are treated as they are in Local time zone
func (r rowsRes) Next(dest []driver.Value) error {
	row := (*[]interface{})(unsafe.Pointer(&dest))
	// log.Printf("FetcOneInto(%p %+v len=%d) %T", row, *row, len(*row), *row)
	err := r.cu.FetchOneInto(*row...)
	debug("fetched row=%p %#v (len=%d) err=%v", row, *row, len(*row), err)
	if err != nil {
		if err == io.EOF {
			return io.EOF
		}
		return errgo.Mask(err)
	}
	return nil
}

// Driver implements a Driver
type Driver struct {
	// Defaults
	user, passwd, db string

	initCmds   []string
	autocommit bool
}

// Open new connection. The uri need to have the following syntax:
//
//   USER/PASSWD@SID
//
// SID (database identifier) can be a DSN (see goracle/oracle.MakeDSN)
func (d *Driver) Open(uri string) (driver.Conn, error) {
	d.user, d.passwd, d.db = oracle.SplitDSN(uri)

	// Establish the connection
	cx, err := oracle.NewConnection(d.user, d.passwd, d.db, d.autocommit)
	if err == nil {
		err = cx.Connect(0, false)
	}
	if err != nil {
		return nil, errgo.Mask(err)
	}
	return &conn{cx: cx}, nil
}

// use log.Printf for log messages if IsDebug
func debug(fmt string, args ...interface{}) {
	if IsDebug {
		log.Printf(fmt, args...)
	}
}

// Driver automatically registered in database/sql
var d = Driver{}

// SetAutoCommit sets auto commit mode for future connections
// true is open autocommit, default false
func SetAutoCommit(b bool) {
	d.autocommit = b
}

func init() {
	sql.Register("goracle", &d)
}
<commit_msg>oracle/lob_test: add concurrency test<commit_after>/*
Copyright 2013 Tamás Gulácsi

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 godrv implements a Go Oracle driver.
package godrv

import (
	"database/sql"
	"database/sql/driver"
	"io"
	"log"
	"strconv"
	"strings"
	"unsafe"

	"github.com/tgulacsi/goracle/oracle"
	"gopkg.in/errgo.v1"
)

var (
	// NotImplemented prints Not implemented
	NotImplemented = errgo.New("Not implemented")
	// IsDebug should we print debug logs?
	IsDebug bool
)

type conn struct {
	cx *oracle.Connection
}

type stmt struct {
	cu        *oracle.Cursor //Stmt ?
	statement string
}

// filterErr filters the error, returns driver.ErrBadConn if appropriate
func filterErr(err error) error {
	if oraErr, ok := errgo.Cause(err).(*oracle.Error); ok {
		switch oraErr.Code {
		case 115, 451, 452, 609, 1090, 1092, 1073, 3113, 3114, 3135, 3136, 12153, 12161, 12170, 12224, 12230, 12233, 12510, 12511, 12514, 12518, 12526, 12527, 12528, 12539: //connection errors - try again!
			return driver.ErrBadConn
		}
	}
	return err
}

// Prepare the query for execution, return a prepared statement and error
func (c conn) Prepare(query string) (driver.Stmt, error) {
	cu := c.cx.NewCursor()
	if strings.Index(query, ":1") < 0 && strings.Index(query, "?") >= 0 {
		q := strings.Split(query, "?")
		q2 := make([]string, 0, 2*len(q)-1)
		for i := 0; i < len(q); i++ {
			if i > 0 {
				q2 = append(q2, ":"+strconv.Itoa(i))
			}
			q2 = append(q2, q[i])
		}
		query = strings.Join(q2, "")
	}
	debug("%p.Prepare(%s)", cu, query)
	err := cu.Prepare(query, "")
	if err != nil {
		return nil, filterErr(err)
	}
	return stmt{cu: cu, statement: query}, nil
}

// closes the connection
func (c conn) Close() error {
	err := c.cx.Close()
	c.cx = nil
	return err
}

type tx struct {
	cx *oracle.Connection //Transaction ?
}

// begins a transaction
func (c conn) Begin() (driver.Tx, error) {
	if !c.cx.IsConnected() {
		if err := c.cx.Connect(0, false); err != nil {
			return nil, filterErr(err)
		}
	}
	return tx{cx: c.cx}, nil
}

// commits currently opened transaction
func (t tx) Commit() error {
	if t.cx != nil {
		return t.cx.Commit()
	}
	return nil
}

// rolls back current transaction
func (t tx) Rollback() error {
	if t.cx != nil {
		return t.cx.Rollback()
	}
	return nil
}

// closes statement
func (s stmt) Close() error {
	if s.cu != nil {
		debug("CLOSEing statement %p (%s)", s.cu, s.statement)
		s.cu.Close()
		s.cu = nil
	}
	return nil
}

// number of input parameters
func (s stmt) NumInput() int {
	names, err := s.cu.GetBindNames()
	if err != nil {
		log.Printf("error getting bind names of %p: %s", s.cu, err)
		return -1
	}
	return len(names)
}

// NewVar creates a new Variable, for out binds.
func (s stmt) NewVar(value interface{}) (*oracle.Variable, error) {
	return s.cu.NewVar(value)
}

type rowsRes struct {
	cu   *oracle.Cursor
	cols []oracle.VariableDescription
}

// executes the statement
func (s stmt) run(args []driver.Value) (*rowsRes, error) {
	//A driver Value is a value that drivers must be able to handle.
	//A Value is either nil or an instance of one of these types:
	//int64
	//float64
	//bool
	//[]byte
	//string   [*] everywhere except from Rows.Next.
	//time.Time

	var err error
	// driver.Value = interface{}, convert []driver.Value to []interface{}
	a := (*[]interface{})(unsafe.Pointer(&args))
	debug("%p.run(%s, %v)", s.cu, s.statement, *a)
	if err = s.cu.Execute(s.statement, *a, nil); err != nil {
		return nil, filterErr(err)
	}

	var cols []oracle.VariableDescription
	if !s.cu.IsDDL() {
		cols, err = s.cu.GetDescription()
		debug("cols: %+v err: %s", cols, err)
		if err != nil {
			return nil, errgo.Mask(err)
		}
	}
	return &rowsRes{cu: s.cu, cols: cols}, nil
}

func (s stmt) Exec(args []driver.Value) (driver.Result, error) {
	return s.run(args)
}

func (s stmt) Query(args []driver.Value) (driver.Rows, error) {
	return s.run(args)
}

func (r rowsRes) LastInsertId() (int64, error) {
	return -1, NotImplemented
}

func (r rowsRes) RowsAffected() (int64, error) {
	return int64(r.cu.GetRowCount()), nil
}

// resultset column names
func (r rowsRes) Columns() []string {
	cls := make([]string, len(r.cols))
	for i, c := range r.cols {
		cls[i] = c.Name
	}
	return cls
}

// closes the resultset
func (r rowsRes) Close() error {
	if r.cu != nil {
		debug("CLOSEing result %p", r.cu)
		r.cu.Close() // FIXME
		r.cu = nil
	}
	return nil
}

// DATE, DATETIME, TIMESTAMP are treated as they are in Local time zone
func (r rowsRes) Next(dest []driver.Value) error {
	row := (*[]interface{})(unsafe.Pointer(&dest))
	// log.Printf("FetcOneInto(%p %+v len=%d) %T", row, *row, len(*row), *row)
	err := r.cu.FetchOneInto(*row...)
	debug("fetched row=%p %#v (len=%d) err=%v", row, *row, len(*row), err)
	if err != nil {
		if err == io.EOF {
			return io.EOF
		}
		return errgo.Mask(err)
	}
	return nil
}

// Driver implements a Driver
type Driver struct {
	// Defaults
	user, passwd, db string

	initCmds   []string
	autocommit bool
}

// Open new connection. The uri need to have the following syntax:
//
//   USER/PASSWD@SID
//
// SID (database identifier) can be a DSN (see goracle/oracle.MakeDSN)
func (d *Driver) Open(uri string) (driver.Conn, error) {
	d.user, d.passwd, d.db = oracle.SplitDSN(uri)

	// Establish the connection
	cx, err := oracle.NewConnection(d.user, d.passwd, d.db, d.autocommit)
	if err == nil {
		err = cx.Connect(0, false)
	}
	if err != nil {
		return nil, errgo.Mask(err)
	}
	return &conn{cx: cx}, nil
}

// use log.Printf for log messages if IsDebug
func debug(fmt string, args ...interface{}) {
	if IsDebug {
		log.Printf(fmt, args...)
	}
}

// Driver automatically registered in database/sql
var d = Driver{}

// SetAutoCommit sets auto commit mode for future connections
// true is open autocommit, default false
func SetAutoCommit(b bool) {
	d.autocommit = b
}

func init() {
	sql.Register("goracle", &d)
}
<|endoftext|>