<commit_before>package pwshandler

import (
	"net/http"

	"github.com/gorilla/websocket"
)

// Environment is common data for connections in one pool
type Environment interface{}

// ConnPool is common interface for a structures which merge websocket
// connections in a pools with access to common environment data such
// as context for starting other goroutines or something else
type ConnPool interface {
	// AddConn creates connection to pool and returns environment data
	AddConn(*websocket.Conn) (Environment, error)
	// DelConn removes passed connection from pool if exists
	DelConn(*websocket.Conn)
}

// RequestVerifier verifies request
type RequestVerifier interface {
	Verify(*http.Request) error
}

// ConnManager contains methods for processing websocket connections
// with passed environment data
type ConnManager interface {
	// Handle handles connection using passed environment data
	Handle(*websocket.Conn, Environment) error
	// HandleError processes an errors
	HandleError(http.ResponseWriter, *http.Request, error)
}

// PoolHandler is handler which receives websocket requests and joins
// connections in a pools with common data in order with passed pool
// manager
type PoolHandler struct {
	verifier RequestVerifier
	manager  ConnManager
	pool     ConnPool
	upgrader *websocket.Upgrader
}

// NewPoolHandler creates new pool handler with passed connection
// manager and connection pool for storage and merging connections
func NewPoolHandler(manager ConnManager, pool ConnPool,
	upgrader *websocket.Upgrader) *PoolHandler {
	return &PoolHandler{nil, manager, pool, upgrader}
}

// SetupVerifier adds request verifier
func (ph *PoolHandler) SetupVerifier(verifier RequestVerifier) {
	if verifier != nil {
		ph.verifier = verifier
	}
}

// Implementing http.Handler interface
func (ph *PoolHandler) ServeHTTP(w http.ResponseWriter,
	r *http.Request) {

	var err error
	// Verify request
	if ph.verifier != nil {
		if err = ph.verifier.Verify(r); err != nil {
			ph.manager.HandleError(w, r, err)
			return
		}
	}

	// Upgrade connection to websocket
	var conn *websocket.Conn
	if conn, err = ph.upgrader.Upgrade(w, r, nil); err != nil {
		ph.manager.HandleError(w, r, err)
		return
	}

	// Create connection to pool and get envitonment data
	var env Environment
	if env, err = ph.pool.AddConn(conn); err != nil {
		ph.manager.HandleError(w, r, err)
		return
	}

	// Handle connection
	if err = ph.manager.Handle(conn, env); err != nil {
		ph.manager.HandleError(w, r, err)
	}

	// Delete connection from pool
	ph.pool.DelConn(conn)
}
<commit_msg>sm fx<commit_after>package pwshandler

import (
	"net/http"

	"github.com/gorilla/websocket"
)

// Environment is a common data for connections in one pool
type Environment interface{}

// ConnPool is common interface for a structures which merge websocket
// connections in a pools with access to common environment data such
// as context for starting other goroutines or something else
type ConnPool interface {
	// AddConn creates connection to pool and returns environment data
	AddConn(*websocket.Conn) (Environment, error)
	// DelConn removes passed connection from pool if exists
	DelConn(*websocket.Conn)
}

// RequestVerifier verifies requests
type RequestVerifier interface {
	Verify(*http.Request) error
}

// ConnManager contains methods for processing websocket connections
// with passed environment data
type ConnManager interface {
	// Handle handles connection using passed environment data
	Handle(*websocket.Conn, Environment) error
	// HandleError processes an errors
	HandleError(http.ResponseWriter, *http.Request, error)
}

// PoolHandler is handler which receives websocket requests and joins
// connections in a pools with common data in order with passed pool
// manager
type PoolHandler struct {
	verifier RequestVerifier
	manager  ConnManager
	pool     ConnPool
	upgrader *websocket.Upgrader
}

// NewPoolHandler creates new pool handler with passed connection
// manager and pool manager for storage and merging connections
func NewPoolHandler(manager ConnManager, pool ConnPool,
	upgrader *websocket.Upgrader) *PoolHandler {
	return &PoolHandler{nil, manager, pool, upgrader}
}

// SetupVerifier adds request verifier
func (ph *PoolHandler) SetupVerifier(verifier RequestVerifier) {
	if verifier != nil {
		ph.verifier = verifier
	}
}

// Implementing http.Handler interface
func (ph *PoolHandler) ServeHTTP(w http.ResponseWriter,
	r *http.Request) {

	var err error
	// Verify request
	if ph.verifier != nil {
		if err = ph.verifier.Verify(r); err != nil {
			ph.manager.HandleError(w, r, err)
			return
		}
	}

	// Upgrade connection to websocket
	var conn *websocket.Conn
	if conn, err = ph.upgrader.Upgrade(w, r, nil); err != nil {
		ph.manager.HandleError(w, r, err)
		return
	}

	// Create connection to pool and get envitonment data
	var env Environment
	if env, err = ph.pool.AddConn(conn); err != nil {
		ph.manager.HandleError(w, r, err)
		return
	}

	// Handle connection
	if err = ph.manager.Handle(conn, env); err != nil {
		ph.manager.HandleError(w, r, err)
	}

	// Delete connection from pool
	ph.pool.DelConn(conn)
}
<|endoftext|>


<commit_before>// Copyright 2013 mongoapi 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 main

import (
	"code.google.com/p/go.crypto/pbkdf2"
	"crypto/sha512"
	"encoding/json"
	"fmt"
	"labix.org/v2/mgo/bson"
	"net/http"
)

func newPassword() string {
	password := bson.NewObjectId().Hex()
	salt := []byte("mongoapi")
	return fmt.Sprintf("%x", pbkdf2.Key([]byte(password), salt, 4096, len(salt)*8, sha512.New))
}

func Add(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusCreated)
}

func Bind(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	database := session().DB(name)
	err := database.AddUser(name, "", false)
	if err != nil {
		return err
	}
	data := map[string]string{
		"MONGO_URI":           coalesceEnv("127.0.0.1:27017", "MONGODB_PUBLIC_URI", "MONGODB_URI"),
		"MONGO_USER":          name,
		"MONGO_PASSWORD":      newPassword(),
		"MONGO_DATABASE_NAME": name,
	}
	b, err := json.Marshal(&data)
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusCreated)
	_, err = w.Write(b)
	return err
}

func Unbind(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	database := session().DB(name)
	err := database.RemoveUser(name)
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusOK)
	return nil
}

func Remove(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	err := session().DB(name).DropDatabase()
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusOK)
	return nil
}

func Status(w http.ResponseWriter, r *http.Request) error {
	if err := session().Ping(); err != nil {
		return err
	}
	w.WriteHeader(http.StatusNoContent)
	return nil
}

type Handler func(http.ResponseWriter, *http.Request) error

func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if err := fn(w, r); err != nil {
		http.Error(w, err.Error(), 500)
	}
}
<commit_msg>handler: simplify password generation<commit_after>// Copyright 2013 mongoapi 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 main

import (
	"crypto/rand"
	"crypto/sha512"
	"encoding/json"
	"fmt"
	"labix.org/v2/mgo/bson"
	"net/http"
)

func newPassword() string {
	var random [32]byte
	rand.Read(random[:])
	h := sha512.New()
	h.Sum([]byte(bson.NewObjectId().Hex()))
	h.Sum(random[:])
	return fmt.Sprintf("%x", h.Sum(nil))
}

func Add(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusCreated)
}

func Bind(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	database := session().DB(name)
	err := database.AddUser(name, "", false)
	if err != nil {
		return err
	}
	data := map[string]string{
		"MONGO_URI":           coalesceEnv("127.0.0.1:27017", "MONGODB_PUBLIC_URI", "MONGODB_URI"),
		"MONGO_USER":          name,
		"MONGO_PASSWORD":      newPassword(),
		"MONGO_DATABASE_NAME": name,
	}
	b, err := json.Marshal(&data)
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusCreated)
	_, err = w.Write(b)
	return err
}

func Unbind(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	database := session().DB(name)
	err := database.RemoveUser(name)
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusOK)
	return nil
}

func Remove(w http.ResponseWriter, r *http.Request) error {
	name := r.URL.Query().Get(":name")
	err := session().DB(name).DropDatabase()
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusOK)
	return nil
}

func Status(w http.ResponseWriter, r *http.Request) error {
	if err := session().Ping(); err != nil {
		return err
	}
	w.WriteHeader(http.StatusNoContent)
	return nil
}

type Handler func(http.ResponseWriter, *http.Request) error

func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if err := fn(w, r); err != nil {
		http.Error(w, err.Error(), 500)
	}
}
<|endoftext|>


<commit_before>package stats_api

import (
	"encoding/json"
	"io"
	"net/http"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// Stats represents activity status of Go.
type Stats struct {
	Time int64 `json:"time"`
	// runtime
	GoVersion    string `json:"go_version"`
	GoOs         string `json:"go_os"`
	GoArch       string `json:"go_arch"`
	CpuNum       int    `json:"cpu_num"`
	GoroutineNum int    `json:"goroutine_num"`
	Gomaxprocs   int    `json:"gomaxprocs"`
	CgoCallNum   int64  `json:"cgo_call_num"`
	// memory
	MemoryAlloc      uint64 `json:"memory_alloc"`
	MemoryTotalAlloc uint64 `json:"memory_total_alloc"`
	MemorySys        uint64 `json:"memory_sys"`
	MemoryLookups    uint64 `json:"memory_lookups"`
	MemoryMallocs    uint64 `json:"memory_mallocs"`
	MemoryFrees      uint64 `json:"memory_frees"`
	// stack
	StackInUse uint64 `json:"memory_stack"`
	// heap
	HeapAlloc    uint64 `json:"heap_alloc"`
	HeapSys      uint64 `json:"heap_sys"`
	HeapIdle     uint64 `json:"heap_idle"`
	HeapInuse    uint64 `json:"heap_inuse"`
	HeapReleased uint64 `json:"heap_released"`
	HeapObjects  uint64 `json:"heap_objects"`
	// garbage collection
	GcNext           uint64    `json:"gc_next"`
	GcLast           uint64    `json:"gc_last"`
	GcNum            uint32    `json:"gc_num"`
	GcPerSecond      float64   `json:"gc_per_second"`
	GcPausePerSecond float64   `json:"gc_pause_per_second"`
	GcPause          []float64 `json:"gc_pause"`
}

var lastSampleTime time.Time
var lastPauseNs uint64 = 0
var lastNumGc uint32 = 0

var nsInMs float64 = float64(time.Millisecond)

var statsMux sync.Mutex

func GetStats() *Stats {
	statsMux.Lock()
	defer statsMux.Unlock()

	var mem runtime.MemStats
	runtime.ReadMemStats(&mem)

	now := time.Now()

	var gcPausePerSecond float64

	if lastPauseNs > 0 {
		pauseSinceLastSample := mem.PauseTotalNs - lastPauseNs
		gcPausePerSecond = float64(pauseSinceLastSample) / nsInMs
	}

	lastPauseNs = mem.PauseTotalNs

	countGc := int(mem.NumGC - lastNumGc)

	var gcPerSecond float64

	if lastNumGc > 0 {
		diff := float64(countGc)
		diffTime := now.Sub(lastSampleTime).Seconds()
		gcPerSecond = diff / diffTime
	}

	if countGc > 256 {
		// lagging GC pause times
		countGc = 256
	}

	gcPause := make([]float64, countGc)

	for i := 0; i < countGc; i++ {
		idx := int((mem.NumGC-uint32(i))+255) % 256
		pause := float64(mem.PauseNs[idx])
		gcPause[i] = pause / nsInMs
	}

	lastNumGc = mem.NumGC
	lastSampleTime = time.Now()

	return &Stats{
		Time:         now.UnixNano(),
		GoVersion:    runtime.Version(),
		GoOs:         runtime.GOOS,
		GoArch:       runtime.GOARCH,
		CpuNum:       runtime.NumCPU(),
		GoroutineNum: runtime.NumGoroutine(),
		Gomaxprocs:   runtime.GOMAXPROCS(0),
		CgoCallNum:   runtime.NumCgoCall(),
		// memory
		MemoryAlloc:      mem.Alloc,
		MemoryTotalAlloc: mem.TotalAlloc,
		MemorySys:        mem.Sys,
		MemoryLookups:    mem.Lookups,
		MemoryMallocs:    mem.Mallocs,
		MemoryFrees:      mem.Frees,
		// stack
		StackInUse: mem.StackInuse,
		// heap
		HeapAlloc:    mem.HeapAlloc,
		HeapSys:      mem.HeapSys,
		HeapIdle:     mem.HeapIdle,
		HeapInuse:    mem.HeapInuse,
		HeapReleased: mem.HeapReleased,
		HeapObjects:  mem.HeapObjects,
		// garbage collection
		GcNext:           mem.NextGC,
		GcLast:           mem.LastGC,
		GcNum:            mem.NumGC,
		GcPerSecond:      gcPerSecond,
		GcPausePerSecond: gcPausePerSecond,
		GcPause:          gcPause,
	}
}

var newLineTerm bool = false
var prettyPrint bool = false

// NewLineTermEnabled enable termination with newline for response body.
func NewLineTermEnabled() {
	newLineTerm = true
}

// NewLineTermDisabled disable termination with newline for response body.
func NewLineTermDisabled() {
	newLineTerm = false
}

// PrettyPrintEnabled enable pretty-print for response body.
func PrettyPrintEnabled() {
	prettyPrint = true
}

// PrettyPrintDisabled disable pritty-print for response body.
func PrettyPrintDisabled() {
	prettyPrint = false
}

// Handler returns activity status of Go.
func Handler(w http.ResponseWriter, r *http.Request) {
	var mem runtime.MemStats
	runtime.ReadMemStats(&mem)

	var jsonBytes []byte
	var jsonErr error
	if prettyPrint {
		jsonBytes, jsonErr = json.MarshalIndent(GetStats(), "", "  ")
	} else {
		jsonBytes, jsonErr = json.Marshal(GetStats())
	}
	var body string
	if jsonErr != nil {
		body = jsonErr.Error()
	} else {
		body = string(jsonBytes)
	}

	if newLineTerm {
		body += "\n"
	}

	headers := make(map[string]string)
	headers["Content-Type"] = "application/json"
	headers["Content-Length"] = strconv.Itoa(len(body))
	for name, value := range headers {
		w.Header().Set(name, value)
	}

	if jsonErr != nil {
		w.WriteHeader(http.StatusInternalServerError)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	io.WriteString(w, body)
}
<commit_msg>Remove unused variable in Handler<commit_after>package stats_api

import (
	"encoding/json"
	"io"
	"net/http"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// Stats represents activity status of Go.
type Stats struct {
	Time int64 `json:"time"`
	// runtime
	GoVersion    string `json:"go_version"`
	GoOs         string `json:"go_os"`
	GoArch       string `json:"go_arch"`
	CpuNum       int    `json:"cpu_num"`
	GoroutineNum int    `json:"goroutine_num"`
	Gomaxprocs   int    `json:"gomaxprocs"`
	CgoCallNum   int64  `json:"cgo_call_num"`
	// memory
	MemoryAlloc      uint64 `json:"memory_alloc"`
	MemoryTotalAlloc uint64 `json:"memory_total_alloc"`
	MemorySys        uint64 `json:"memory_sys"`
	MemoryLookups    uint64 `json:"memory_lookups"`
	MemoryMallocs    uint64 `json:"memory_mallocs"`
	MemoryFrees      uint64 `json:"memory_frees"`
	// stack
	StackInUse uint64 `json:"memory_stack"`
	// heap
	HeapAlloc    uint64 `json:"heap_alloc"`
	HeapSys      uint64 `json:"heap_sys"`
	HeapIdle     uint64 `json:"heap_idle"`
	HeapInuse    uint64 `json:"heap_inuse"`
	HeapReleased uint64 `json:"heap_released"`
	HeapObjects  uint64 `json:"heap_objects"`
	// garbage collection
	GcNext           uint64    `json:"gc_next"`
	GcLast           uint64    `json:"gc_last"`
	GcNum            uint32    `json:"gc_num"`
	GcPerSecond      float64   `json:"gc_per_second"`
	GcPausePerSecond float64   `json:"gc_pause_per_second"`
	GcPause          []float64 `json:"gc_pause"`
}

var lastSampleTime time.Time
var lastPauseNs uint64 = 0
var lastNumGc uint32 = 0

var nsInMs float64 = float64(time.Millisecond)

var statsMux sync.Mutex

func GetStats() *Stats {
	statsMux.Lock()
	defer statsMux.Unlock()

	var mem runtime.MemStats
	runtime.ReadMemStats(&mem)

	now := time.Now()

	var gcPausePerSecond float64

	if lastPauseNs > 0 {
		pauseSinceLastSample := mem.PauseTotalNs - lastPauseNs
		gcPausePerSecond = float64(pauseSinceLastSample) / nsInMs
	}

	lastPauseNs = mem.PauseTotalNs

	countGc := int(mem.NumGC - lastNumGc)

	var gcPerSecond float64

	if lastNumGc > 0 {
		diff := float64(countGc)
		diffTime := now.Sub(lastSampleTime).Seconds()
		gcPerSecond = diff / diffTime
	}

	if countGc > 256 {
		// lagging GC pause times
		countGc = 256
	}

	gcPause := make([]float64, countGc)

	for i := 0; i < countGc; i++ {
		idx := int((mem.NumGC-uint32(i))+255) % 256
		pause := float64(mem.PauseNs[idx])
		gcPause[i] = pause / nsInMs
	}

	lastNumGc = mem.NumGC
	lastSampleTime = time.Now()

	return &Stats{
		Time:         now.UnixNano(),
		GoVersion:    runtime.Version(),
		GoOs:         runtime.GOOS,
		GoArch:       runtime.GOARCH,
		CpuNum:       runtime.NumCPU(),
		GoroutineNum: runtime.NumGoroutine(),
		Gomaxprocs:   runtime.GOMAXPROCS(0),
		CgoCallNum:   runtime.NumCgoCall(),
		// memory
		MemoryAlloc:      mem.Alloc,
		MemoryTotalAlloc: mem.TotalAlloc,
		MemorySys:        mem.Sys,
		MemoryLookups:    mem.Lookups,
		MemoryMallocs:    mem.Mallocs,
		MemoryFrees:      mem.Frees,
		// stack
		StackInUse: mem.StackInuse,
		// heap
		HeapAlloc:    mem.HeapAlloc,
		HeapSys:      mem.HeapSys,
		HeapIdle:     mem.HeapIdle,
		HeapInuse:    mem.HeapInuse,
		HeapReleased: mem.HeapReleased,
		HeapObjects:  mem.HeapObjects,
		// garbage collection
		GcNext:           mem.NextGC,
		GcLast:           mem.LastGC,
		GcNum:            mem.NumGC,
		GcPerSecond:      gcPerSecond,
		GcPausePerSecond: gcPausePerSecond,
		GcPause:          gcPause,
	}
}

var newLineTerm bool = false
var prettyPrint bool = false

// NewLineTermEnabled enable termination with newline for response body.
func NewLineTermEnabled() {
	newLineTerm = true
}

// NewLineTermDisabled disable termination with newline for response body.
func NewLineTermDisabled() {
	newLineTerm = false
}

// PrettyPrintEnabled enable pretty-print for response body.
func PrettyPrintEnabled() {
	prettyPrint = true
}

// PrettyPrintDisabled disable pritty-print for response body.
func PrettyPrintDisabled() {
	prettyPrint = false
}

// Handler returns activity status of Go.
func Handler(w http.ResponseWriter, r *http.Request) {
	var jsonBytes []byte
	var jsonErr error
	if prettyPrint {
		jsonBytes, jsonErr = json.MarshalIndent(GetStats(), "", "  ")
	} else {
		jsonBytes, jsonErr = json.Marshal(GetStats())
	}
	var body string
	if jsonErr != nil {
		body = jsonErr.Error()
	} else {
		body = string(jsonBytes)
	}

	if newLineTerm {
		body += "\n"
	}

	headers := make(map[string]string)
	headers["Content-Type"] = "application/json"
	headers["Content-Length"] = strconv.Itoa(len(body))
	for name, value := range headers {
		w.Header().Set(name, value)
	}

	if jsonErr != nil {
		w.WriteHeader(http.StatusInternalServerError)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	io.WriteString(w, body)
}
<|endoftext|>


<commit_before>package constants

// THIS FILE IS GENERATED AUTOMATICALLY, NO TOUCHING!!!!!

const (
	AWSBOSHURL      = "https://s3.amazonaws.com/bbl-precompiled-bosh-releases/release-bosh-260-on-ubuntu-trusty-stemcell-3312.7.tgz"
	AWSBOSHSHA1     = "79f4b07d9e8f3134987f06c6d0eba0ada440142c"
	BOSHAWSCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-aws-cpi-release?v=62"
	BOSHAWSCPISHA1  = "f36967927ceae09e5663a41fdda199edfe649dc6"
	AWSStemcellURL  = "https://s3.amazonaws.com/bosh-aws-light-stemcells/light-bosh-stemcell-3312.7-aws-xen-hvm-ubuntu-trusty-go_agent.tgz"
	AWSStemcellSHA1 = "e11da993d8bad4305e4bc51117f1de88a63f76bb"
	GCPBOSHURL      = "https://bosh.io/d/github.com/cloudfoundry/bosh?v=260"
	GCPBOSHSHA1     = "f8f086974d9769263078fb6cb7927655744dacbc"
	BOSHGCPCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-google-cpi-release?v=25.6.1"
	BOSHGCPCPISHA1  = "fc8c7025c3ba3aef66e005a4bdf7fd3d5e997974"
	GCPStemcellURL  = "https://s3.amazonaws.com/bosh-core-stemcells/google/bosh-stemcell-3312.8-google-kvm-ubuntu-trusty-go_agent.tgz"
	GCPStemcellSHA1 = "773c77df02370942d52be09c2132ed374db42ca9"
)
<commit_msg>Update constants<commit_after>package constants

// THIS FILE IS GENERATED AUTOMATICALLY, NO TOUCHING!!!!!

const (
	AWSBOSHURL      = "https://s3.amazonaws.com/bbl-precompiled-bosh-releases/release-bosh-260-on-ubuntu-trusty-stemcell-3312.8.tgz"
	AWSBOSHSHA1     = "76a4198741dc717b0cd2deb76394ee588e7ff209"
	BOSHAWSCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-aws-cpi-release?v=62"
	BOSHAWSCPISHA1  = "f36967927ceae09e5663a41fdda199edfe649dc6"
	AWSStemcellURL  = "https://s3.amazonaws.com/bosh-aws-light-stemcells/light-bosh-stemcell-3312.8-aws-xen-hvm-ubuntu-trusty-go_agent.tgz"
	AWSStemcellSHA1 = "50fb9765d92b5f38407bc248a2477152cbe80ebf"
	GCPBOSHURL      = "https://bosh.io/d/github.com/cloudfoundry/bosh?v=260"
	GCPBOSHSHA1     = "f8f086974d9769263078fb6cb7927655744dacbc"
	BOSHGCPCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-google-cpi-release?v=25.6.1"
	BOSHGCPCPISHA1  = "fc8c7025c3ba3aef66e005a4bdf7fd3d5e997974"
	GCPStemcellURL  = "https://s3.amazonaws.com/bosh-core-stemcells/google/bosh-stemcell-3312.8-google-kvm-ubuntu-trusty-go_agent.tgz"
	GCPStemcellSHA1 = "773c77df02370942d52be09c2132ed374db42ca9"
)
<|endoftext|>


<commit_before>package constants

// THIS FILE IS GENERATED AUTOMATICALLY, NO TOUCHING!!!!!

const (
	BOSHURL         = "https://s3.amazonaws.com/bbl-precompiled-bosh-releases/release-bosh-261.2-on-ubuntu-trusty-stemcell-3363.9.tgz"
	BOSHSHA1        = "84afe35981fd880b812d42a83e1f123d80fc28a6"
	BOSHAWSCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-aws-cpi-release?v=62"
	BOSHAWSCPISHA1  = "f36967927ceae09e5663a41fdda199edfe649dc6"
	AWSStemcellURL  = "https://s3.amazonaws.com/bosh-aws-light-stemcells/light-bosh-stemcell-3363.9-aws-xen-hvm-ubuntu-trusty-go_agent.tgz"
	AWSStemcellSHA1 = "c5a61384178efaade80210de7ebf994d70e6ca25"
	BOSHGCPCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-google-cpi-release?v=25.6.2"
	BOSHGCPCPISHA1  = "b4865397d867655fdcc112bc5a7f9a5025cdf311"
	GCPStemcellURL  = "https://s3.amazonaws.com/bosh-gce-light-stemcells/light-bosh-stemcell-3363.9-google-kvm-ubuntu-trusty-go_agent.tgz"
	GCPStemcellSHA1 = "dc0b2d32d004e999acf7f4805c34f7d31b67203c"
)
<commit_msg>Roll back stemcell to a known working state<commit_after>package constants

// THIS FILE IS GENERATED AUTOMATICALLY, NO TOUCHING!!!!!

const (
	BOSHURL         = "https://s3.amazonaws.com/bbl-precompiled-bosh-releases/release-bosh-261-on-ubuntu-trusty-stemcell-3312.18.tgz"
	BOSHSHA1        = "d86b9ba0e78cc311f1f3a46f0ea2b2103011e0bf"
	BOSHAWSCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-aws-cpi-release?v=62"
	BOSHAWSCPISHA1  = "f36967927ceae09e5663a41fdda199edfe649dc6"
	AWSStemcellURL  = "https://s3.amazonaws.com/bosh-aws-light-stemcells/light-bosh-stemcell-3312.18-aws-xen-hvm-ubuntu-trusty-go_agent.tgz"
	AWSStemcellSHA1 = "9dfcccffd831f8f06e8132324ce8c6c074450082"
	BOSHGCPCPIURL   = "https://bosh.io/d/github.com/cloudfoundry-incubator/bosh-google-cpi-release?v=25.6.2"
	BOSHGCPCPISHA1  = "b4865397d867655fdcc112bc5a7f9a5025cdf311"
	GCPStemcellURL  = "https://s3.amazonaws.com/bosh-gce-light-stemcells/light-bosh-stemcell-3312.18-google-kvm-ubuntu-trusty-go_agent.tgz"
	GCPStemcellSHA1 = "a0f19414d61deff1bf6439bb1598bd6a732712df"
)
<|endoftext|>


<commit_before>package controllers

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

	"github.com/gorilla/mux"
	"github.com/nuveo/prest/adapters/postgres"
	"github.com/nuveo/prest/statements"
)

// GetTables list all (or filter) tables
func GetTables(w http.ResponseWriter, r *http.Request) {
	requestWhere := postgres.WhereByRequest(r)
	sqlTables := statements.Tables
	if requestWhere != "" {
		sqlTables = fmt.Sprint(
			statements.TablesSelect,
			statements.TablesWhere,
			" AND ",
			requestWhere,
			statements.TablesOrderBy)
	}

	object, err := postgres.Query(sqlTables)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}

// GetTablesByDatabaseAndSchema list all (or filter) tables based on database and schema
func GetTablesByDatabaseAndSchema(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	database, ok := vars["database"]
	if !ok {
		log.Println("Unable to parse database in URI")
		http.Error(w, "Unable to parse database in URI", http.StatusInternalServerError)
		return
	}
	schema, ok := vars["schema"]
	if !ok {
		log.Println("Unable to parse schema in URI")
		http.Error(w, "Unable to parse schema in URI", http.StatusInternalServerError)
		return
	}
	requestWhere := postgres.WhereByRequest(r)
	sqlSchemaTables := statements.SchemaTables
	if requestWhere != "" {
		sqlSchemaTables = fmt.Sprint(
			statements.SchemaTablesSelect,
			statements.SchemaTablesWhere,
			" AND ",
			requestWhere,
			statements.SchemaTablesOrderBy)
	}
	sqlSchemaTables = fmt.Sprint(sqlSchemaTables, " ", postgres.PaginateIfPossible(r))

	object, err := postgres.Query(sqlSchemaTables, database, schema)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}

// SelectFromTables perform select in database
func SelectFromTables(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	database, ok := vars["database"]
	if !ok {
		log.Println("Unable to parse database in URI")
		http.Error(w, "Unable to parse database in URI", http.StatusInternalServerError)
		return
	}
	schema, ok := vars["schema"]
	if !ok {
		log.Println("Unable to parse schema in URI")
		http.Error(w, "Unable to parse schema in URI", http.StatusInternalServerError)
		return
	}
	table, ok := vars["table"]
	if !ok {
		log.Println("Unable to parse table in URI")
		http.Error(w, "Unable to parse table in URI", http.StatusInternalServerError)
		return
	}

	query := fmt.Sprintf("%s %s.%s.%s", statements.SelectInTable, database, schema, table)
	requestWhere := postgres.WhereByRequest(r)
	sqlSelect := query
	if requestWhere != "" {
		sqlSelect = fmt.Sprint(
			query,
			" WHERE ",
			requestWhere)
	}
	sqlSelect = fmt.Sprint(sqlSelect, " ", postgres.PaginateIfPossible(r))

	object, err := postgres.Query(sqlSelect)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}
<commit_msg>insert controller implementation<commit_after>package controllers

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

	"encoding/json"

	"github.com/gorilla/mux"
	"github.com/nuveo/prest/adapters/postgres"
	"github.com/nuveo/prest/api"
	"github.com/nuveo/prest/statements"
)

// GetTables list all (or filter) tables
func GetTables(w http.ResponseWriter, r *http.Request) {
	requestWhere := postgres.WhereByRequest(r)
	sqlTables := statements.Tables
	if requestWhere != "" {
		sqlTables = fmt.Sprint(
			statements.TablesSelect,
			statements.TablesWhere,
			" AND ",
			requestWhere,
			statements.TablesOrderBy)
	}

	object, err := postgres.Query(sqlTables)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}

// GetTablesByDatabaseAndSchema list all (or filter) tables based on database and schema
func GetTablesByDatabaseAndSchema(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	database, ok := vars["database"]
	if !ok {
		log.Println("Unable to parse database in URI")
		http.Error(w, "Unable to parse database in URI", http.StatusInternalServerError)
		return
	}
	schema, ok := vars["schema"]
	if !ok {
		log.Println("Unable to parse schema in URI")
		http.Error(w, "Unable to parse schema in URI", http.StatusInternalServerError)
		return
	}
	requestWhere := postgres.WhereByRequest(r)
	sqlSchemaTables := statements.SchemaTables
	if requestWhere != "" {
		sqlSchemaTables = fmt.Sprint(
			statements.SchemaTablesSelect,
			statements.SchemaTablesWhere,
			" AND ",
			requestWhere,
			statements.SchemaTablesOrderBy)
	}
	sqlSchemaTables = fmt.Sprint(sqlSchemaTables, " ", postgres.PaginateIfPossible(r))

	object, err := postgres.Query(sqlSchemaTables, database, schema)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}

// SelectFromTables perform select in database
func SelectFromTables(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	database, ok := vars["database"]
	if !ok {
		log.Println("Unable to parse database in URI")
		http.Error(w, "Unable to parse database in URI", http.StatusInternalServerError)
		return
	}
	schema, ok := vars["schema"]
	if !ok {
		log.Println("Unable to parse schema in URI")
		http.Error(w, "Unable to parse schema in URI", http.StatusInternalServerError)
		return
	}
	table, ok := vars["table"]
	if !ok {
		log.Println("Unable to parse table in URI")
		http.Error(w, "Unable to parse table in URI", http.StatusInternalServerError)
		return
	}

	query := fmt.Sprintf("%s %s.%s.%s", statements.SelectInTable, database, schema, table)
	requestWhere := postgres.WhereByRequest(r)
	sqlSelect := query
	if requestWhere != "" {
		sqlSelect = fmt.Sprint(
			query,
			" WHERE ",
			requestWhere)
	}
	sqlSelect = fmt.Sprint(sqlSelect, " ", postgres.PaginateIfPossible(r))

	object, err := postgres.Query(sqlSelect)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}

// InsertInTables perform insert in specific table
func InsertInTables(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	database, ok := vars["database"]
	if !ok {
		log.Println("Unable to parse database in URI")
		http.Error(w, "Unable to parse database in URI", http.StatusInternalServerError)
		return
	}
	schema, ok := vars["schema"]
	if !ok {
		log.Println("Unable to parse schema in URI")
		http.Error(w, "Unable to parse schema in URI", http.StatusInternalServerError)
		return
	}
	table, ok := vars["table"]
	if !ok {
		log.Println("Unable to parse table in URI")
		http.Error(w, "Unable to parse table in URI", http.StatusInternalServerError)
		return
	}
	req := api.Request{}
	err := json.NewDecoder(r.Body).Decode(&req)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	object, err := postgres.Insert(database, schema, table, req)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Write(object)
}
<|endoftext|>


<commit_before>package telemetry

import (
	"fmt"
	"net"
	"os"

	"github.com/bahadley/esp/log"
	"github.com/bahadley/esp/operator"
)

const (
	defaultAddr = "127.0.0.1"
	defaultPort = "22221"

	envsaddr = "ESP_ADDR"
	envport  = "ESP_PORT"

    chanbufsz = 10
)

var (
	op chan string
)

func Ingest() {
	saddr, err := resolveAddr()
	if err != nil {
		log.Logfatalerror(err)
	}

	conn, err := net.ListenUDP("udp", saddr)
	if err != nil {
		log.Logoutput(log.ErrPrefix, err.Error())
	}
	defer conn.Close()

	buf := make([]byte, 1024)
	for {
		n, caddr, err := conn.ReadFromUDP(buf)
		if err != nil {
			log.Logoutput(log.ErrPrefix, err.Error())
			continue
		}

		msg := string(buf[0:n])
		log.Logoutput(log.InfoPrefix, fmt.Sprintf("Recv(%s): %s", caddr, msg))
		op <- msg
	}
}

func init() {
	op = make(chan string, chanbufsz)
	go operator.Window(op)
}

func resolveAddr() (*net.UDPAddr, error) {
	addr := os.Getenv(envsaddr)
	if len(addr) == 0 {
		addr = defaultAddr
	}

	port := os.Getenv(envport)
	if len(port) == 0 {
		port = defaultPort
	}

	return net.ResolveUDPAddr("udp", addr+":"+port)
}
<commit_msg>Formatted<commit_after>package telemetry

import (
	"fmt"
	"net"
	"os"

	"github.com/bahadley/esp/log"
	"github.com/bahadley/esp/operator"
)

const (
	defaultAddr = "localhost"
	defaultPort = "22221"

	envsaddr = "ESP_ADDR"
	envport  = "ESP_PORT"

	chanbufsz = 10
)

var (
	op chan string
)

func Ingest() {
	saddr, err := resolveAddr()
	if err != nil {
		log.Logfatalerror(err)
	}

	conn, err := net.ListenUDP("udp", saddr)
	if err != nil {
		log.Logoutput(log.ErrPrefix, err.Error())
	}
	defer conn.Close()

	buf := make([]byte, 1024)
	for {
		n, caddr, err := conn.ReadFromUDP(buf)
		if err != nil {
			log.Logoutput(log.ErrPrefix, err.Error())
			continue
		}

		msg := string(buf[0:n])
		log.Logoutput(log.InfoPrefix, fmt.Sprintf("Recv(%s): %s", caddr, msg))
		op <- msg
	}
}

func init() {
	op = make(chan string, chanbufsz)
	go operator.Window(op)
}

func resolveAddr() (*net.UDPAddr, error) {
	addr := os.Getenv(envsaddr)
	if len(addr) == 0 {
		addr = defaultAddr
	}

	port := os.Getenv(envport)
	if len(port) == 0 {
		port = defaultPort
	}

	return net.ResolveUDPAddr("udp", addr+":"+port)
}
<|endoftext|>


<commit_before>package blackbox

import (
	"os"

	"github.com/ActiveState/tail"

	"github.com/concourse/blackbox/syslog"
)

type Tailer struct {
	Source  SyslogSource
	Drainer syslog.Drainer
}

func (tailer *Tailer) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	t, err := tail.TailFile(tailer.Source.Path, tail.Config{
		Follow: true,
		ReOpen: true,
		Location: &tail.SeekInfo{
			Offset: 0,
			Whence: os.SEEK_END,
		},
	})

	if err != nil {
		return err
	}
	defer tail.Cleanup()

	close(ready)

	for {
		select {
		case line, ok := <-t.Lines:
			if !ok {
				println("lines flushed; exiting tailer")
				return nil
			}

			tailer.Drainer.Drain(line.Text, tailer.Source.Tag)
		case <-signals:
			return t.Stop()
		}
	}

	return nil
}
<commit_msg>switch to polling<commit_after>package blackbox

import (
	"log"
	"os"
	"time"

	"github.com/ActiveState/tail"
	"github.com/ActiveState/tail/watch"

	"github.com/concourse/blackbox/syslog"
)

type Tailer struct {
	Source  SyslogSource
	Drainer syslog.Drainer
}

func (tailer *Tailer) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	watch.POLL_DURATION = 1 * time.Second

	t, err := tail.TailFile(tailer.Source.Path, tail.Config{
		Follow: true,
		ReOpen: true,
		Poll:   true,
		Location: &tail.SeekInfo{
			Offset: 0,
			Whence: os.SEEK_END,
		},
	})

	if err != nil {
		return err
	}
	defer tail.Cleanup()

	close(ready)

	for {
		select {
		case line, ok := <-t.Lines:
			if !ok {
				log.Println("lines flushed; exiting tailer")
				return nil
			}

			tailer.Drainer.Drain(line.Text, tailer.Source.Tag)
		case <-signals:
			return t.Stop()
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package kkpm

import "github.com/jackc/pgx"

const (
	insert = "INSERT INTO private_msg(id,from_userid,to_userid,message,at) VALUES($1,$2,$3,$4,$5)"
)

// dbPool the pgx database pool.
var dbPool *pgx.ConnPool

// prepareDB to prepare the database.
func prepareDB() error {
	s := `CREATE TABLE IF NOT EXISTS private_msg (
	id uuid primary key,
	from_userid integer,
    to_userid integer,
	read boolean DEFAULT false,
    message text,
    at integer);
    CREATE INDEX IF NOT EXISTS index_private_msg_to_userid ON private_msg (to_userid);
    CREATE INDEX IF NOT EXISTS index_private_msg_from_userid ON private_msg (from_userid);
    CREATE INDEX IF NOT EXISTS index_private_msg_at ON private_msg (at);`

	_, err := dbPool.Exec(s)
	return err
}

// insertMessage to insert a message to database.
func insertMessage(info *MessageInfo) error {
	_, err := dbPool.Exec(insert, info.MessageID, info.FromUser, info.ToUser, info.Message, info.At)
	return err
}

// getUnreadCount to get the count of unread messages.
func getUnreadCount(toid int32) (int32, error) {
	s := "SELECT COUNT(1) FROM private_msg WHERE to_userid=$1 AND read=false"
	var count int64
	if err := dbPool.QueryRow(s, toid).Scan(&count); err != nil {
		return 0, err
	}
	return int32(count), nil
}

// readFrom to mark all as read form the id.
func readFrom(toid, fromid int32) error {
	s := "UPDATE private_msg SET read=true WHERE to_userid=$1 AND from_userid=$2 AND read=false"
	if _, err := dbPool.Exec(s, toid, fromid); err != nil {
		return err
	}
	return nil
}

// getMessagesFromUser to get the messages sent by the user with fromid.
// utime the unixtime, the messages will be got after that time.
func getMessagesFrom(fromid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,to_userid,message,at FROM private_msg WHERE from_userid=$1 AND at>=$2"
	rows, _ := dbPool.Query(s, fromid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.ToUser), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.FromUser = fromid
		result = append(result, one)
	}

	return result, rows.Err()
}

// getMessagesToUser to get the messages received by the user with toid.
// utime the unixtime, the messages will be got after that time.
func getMessagesTo(toid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,from_userid,message,at FROM private_msg WHERE to_userid=$1 AND at>=$2"
	rows, _ := dbPool.Query(s, toid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.FromUser), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.ToUser = toid
		result = append(result, one)
	}

	return result, rows.Err()
}

// getMessagesFromTo to get messages with a single user.
// utime the unixtime, the messages will be got after that time.
func getMessagesFromTo(fromid, toid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,message,at FROM private_msg WHERE to_userid=$1 AND from_userid=$2 AND at>=$3"
	rows, _ := dbPool.Query(s, toid, fromid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.FromUser = fromid
		one.ToUser = toid
		result = append(result, one)
	}

	return result, rows.Err()
}
<commit_msg>Change db compare to larger than.<commit_after>package kkpm

import "github.com/jackc/pgx"

const (
	insert = "INSERT INTO private_msg(id,from_userid,to_userid,message,at) VALUES($1,$2,$3,$4,$5)"
)

// dbPool the pgx database pool.
var dbPool *pgx.ConnPool

// prepareDB to prepare the database.
func prepareDB() error {
	s := `CREATE TABLE IF NOT EXISTS private_msg (
	id uuid primary key,
	from_userid integer,
    to_userid integer,
	read boolean DEFAULT false,
    message text,
    at integer);
    CREATE INDEX IF NOT EXISTS index_private_msg_to_userid ON private_msg (to_userid);
    CREATE INDEX IF NOT EXISTS index_private_msg_from_userid ON private_msg (from_userid);
    CREATE INDEX IF NOT EXISTS index_private_msg_at ON private_msg (at);`

	_, err := dbPool.Exec(s)
	return err
}

// insertMessage to insert a message to database.
func insertMessage(info *MessageInfo) error {
	_, err := dbPool.Exec(insert, info.MessageID, info.FromUser, info.ToUser, info.Message, info.At)
	return err
}

// getUnreadCount to get the count of unread messages.
func getUnreadCount(toid int32) (int32, error) {
	s := "SELECT COUNT(1) FROM private_msg WHERE to_userid=$1 AND read=false"
	var count int64
	if err := dbPool.QueryRow(s, toid).Scan(&count); err != nil {
		return 0, err
	}
	return int32(count), nil
}

// readFrom to mark all as read form the id.
func readFrom(toid, fromid int32) error {
	s := "UPDATE private_msg SET read=true WHERE to_userid=$1 AND from_userid=$2 AND read=false"
	if _, err := dbPool.Exec(s, toid, fromid); err != nil {
		return err
	}
	return nil
}

// getMessagesFromUser to get the messages sent by the user with fromid.
// utime the unixtime, the messages will be got after that time.
func getMessagesFrom(fromid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,to_userid,message,at FROM private_msg WHERE from_userid=$1 AND at>$2"
	rows, _ := dbPool.Query(s, fromid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.ToUser), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.FromUser = fromid
		result = append(result, one)
	}

	return result, rows.Err()
}

// getMessagesToUser to get the messages received by the user with toid.
// utime the unixtime, the messages will be got after that time.
func getMessagesTo(toid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,from_userid,message,at FROM private_msg WHERE to_userid=$1 AND at>$2"
	rows, _ := dbPool.Query(s, toid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.FromUser), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.ToUser = toid
		result = append(result, one)
	}

	return result, rows.Err()
}

// getMessagesFromTo to get messages with a single user.
// utime the unixtime, the messages will be got after that time.
func getMessagesFromTo(fromid, toid, utime int32) ([]MessageInfo, error) {
	s := "SELECT id,message,at FROM private_msg WHERE to_userid=$1 AND from_userid=$2 AND at>$3"
	rows, _ := dbPool.Query(s, toid, fromid, utime)

	var result []MessageInfo
	for rows.Next() {
		var one MessageInfo
		err := rows.Scan(&(one.MessageID), &(one.Message), &(one.At))
		if err != nil {
			return result, err
		}
		one.FromUser = fromid
		one.ToUser = toid
		result = append(result, one)
	}

	return result, rows.Err()
}
<|endoftext|>


<commit_before>// Package db implements an immutable, consistent, im-memory key/value
// database.
package db

import (
	"errors"
	"sync"
	"sync/atomic"
	"unsafe"

	"github.com/azmodb/llrb"
)

var (
	// errRevisionNotFound is returned when trying to access a revision
	// that has not been created.
	errRevisionNotFound = errors.New("revision not found")

	// errKeyNotFound is returned when trying to access a key that has
	// not been created.
	errKeyNotFound = errors.New("key not found")

	// errIncompatibleValue is returned when trying create or delete a
	// value on an imcompatible key.
	errIncompatibleValue = errors.New("incompatible value")
)

// DB represents an immutable, consistent, im-memory key/value database.
// All access is performed through a batch with can be obtained through
// the database.
type DB struct {
	archive sync.Mutex // exclusive archive transaction
	writer  sync.Mutex // exclusive writer transaction
	tree    unsafe.Pointer

	mu  sync.RWMutex // protects notifier registry
	reg map[string]*notifier
}

type tree struct {
	root *llrb.Tree
	rev  int64
}

// New returns an immutable, consistent, im-memory key/value database.
func New() *DB { return newDB(nil) }

func newDB(t *tree) *DB {
	if t == nil {
		t = &tree{root: &llrb.Tree{}}
	}
	return &DB{
		reg:  make(map[string]*notifier),
		tree: unsafe.Pointer(t),
	}
}

func (db *DB) store(t *tree) {
	atomic.StorePointer(&db.tree, unsafe.Pointer(t))
}

func (db *DB) load() *tree {
	return (*tree)(atomic.LoadPointer(&db.tree))
}

// Rev returns the current revision of the database.
func (db *DB) Rev() int64 {
	tree := db.load()
	return tree.rev
}

// Len returns the number of keys inside the database.
func (db *DB) Len() int {
	tree := db.load()
	return tree.root.Len()
}

func bcopy(src []byte) []byte {
	dst := make([]byte, len(src))
	copy(dst, src)
	return dst
}

func grow(dst, src []byte) []byte {
	n := len(src)
	if cap(dst) < n {
		dst = make([]byte, n)
	}
	dst = dst[:n]
	copy(dst, src)
	return dst
}
<commit_msg>fix typo<commit_after>// Package db implements an immutable, consistent, in-memory key/value
// database.
package db

import (
	"errors"
	"sync"
	"sync/atomic"
	"unsafe"

	"github.com/azmodb/llrb"
)

var (
	// errRevisionNotFound is returned when trying to access a revision
	// that has not been created.
	errRevisionNotFound = errors.New("revision not found")

	// errKeyNotFound is returned when trying to access a key that has
	// not been created.
	errKeyNotFound = errors.New("key not found")

	// errIncompatibleValue is returned when trying create or delete a
	// value on an imcompatible key.
	errIncompatibleValue = errors.New("incompatible value")
)

// DB represents an immutable, consistent, in-memory key/value database.
// All access is performed through a batch with can be obtained through
// the database.
type DB struct {
	archive sync.Mutex // exclusive archive transaction
	writer  sync.Mutex // exclusive writer transaction
	tree    unsafe.Pointer

	mu  sync.RWMutex // protects notifier registry
	reg map[string]*notifier
}

type tree struct {
	root *llrb.Tree
	rev  int64
}

// New returns an immutable, consistent, in-memory key/value database.
func New() *DB { return newDB(nil) }

func newDB(t *tree) *DB {
	if t == nil {
		t = &tree{root: &llrb.Tree{}}
	}
	return &DB{
		reg:  make(map[string]*notifier),
		tree: unsafe.Pointer(t),
	}
}

func (db *DB) store(t *tree) {
	atomic.StorePointer(&db.tree, unsafe.Pointer(t))
}

func (db *DB) load() *tree {
	return (*tree)(atomic.LoadPointer(&db.tree))
}

// Rev returns the current revision of the database.
func (db *DB) Rev() int64 {
	tree := db.load()
	return tree.rev
}

// Len returns the number of keys inside the database.
func (db *DB) Len() int {
	tree := db.load()
	return tree.root.Len()
}

func bcopy(src []byte) []byte {
	dst := make([]byte, len(src))
	copy(dst, src)
	return dst
}

func grow(dst, src []byte) []byte {
	n := len(src)
	if cap(dst) < n {
		dst = make([]byte, n)
	}
	dst = dst[:n]
	copy(dst, src)
	return dst
}
<|endoftext|>


<commit_before>package pg // import "gopkg.in/pg.v5"

import (
	"io"
	"time"

	"gopkg.in/pg.v5/internal"
	"gopkg.in/pg.v5/internal/pool"
	"gopkg.in/pg.v5/orm"
	"gopkg.in/pg.v5/types"
)

// Connect connects to a database using provided options.
//
// The returned DB is safe for concurrent use by multiple goroutines
// and maintains its own connection pool.
func Connect(opt *Options) *DB {
	opt.init()
	return &DB{
		opt:  opt,
		pool: newConnPool(opt),
	}
}

// DB is a database handle representing a pool of zero or more
// underlying connections. It's safe for concurrent use by multiple
// goroutines.
type DB struct {
	opt  *Options
	pool *pool.ConnPool
}

var _ orm.DB = (*DB)(nil)

// Options returns read-only Options that were used to connect to the DB.
func (db *DB) Options() *Options {
	return db.opt
}

// WithTimeout returns a DB that uses d as the read/write timeout.
func (db *DB) WithTimeout(d time.Duration) *DB {
	newopt := *db.opt
	newopt.ReadTimeout = d
	newopt.WriteTimeout = d
	return &DB{
		opt:  &newopt,
		pool: db.pool,
	}
}

func (db *DB) conn() (*pool.Conn, error) {
	cn, _, err := db.pool.Get()
	if err != nil {
		return nil, err
	}

	if !cn.Inited {
		if err := db.initConn(cn); err != nil {
			_ = db.pool.Remove(cn, err)
			return nil, err
		}
	}

	cn.SetReadTimeout(db.opt.ReadTimeout)
	cn.SetWriteTimeout(db.opt.WriteTimeout)
	return cn, nil
}

func (db *DB) initConn(cn *pool.Conn) error {
	if db.opt.TLSConfig != nil {
		if err := enableSSL(cn, db.opt.TLSConfig); err != nil {
			return err
		}
	}

	err := startup(cn, db.opt.User, db.opt.Password, db.opt.Database)
	if err != nil {
		return err
	}

	cn.Inited = true
	return nil
}

func (db *DB) freeConn(cn *pool.Conn, err error) error {
	if !isBadConn(err, false) {
		return db.pool.Put(cn)
	}
	return db.pool.Remove(cn, err)
}

func (db *DB) shouldRetry(err error) bool {
	if err == nil {
		return false
	}
	if pgerr, ok := err.(Error); ok {
		switch pgerr.Field('C') {
		case "40001": // serialization_failure
			return true
		case "57014": // statement_timeout
			return db.opt.RetryStatementTimeout
		default:
			return false
		}
	}
	return isNetworkError(err)
}

// Close closes the database client, releasing any open resources.
//
// It is rare to Close a DB, as the DB handle is meant to be
// long-lived and shared between many goroutines.
func (db *DB) Close() error {
	st := db.pool.Stats()
	if st.TotalConns != st.FreeConns {
		internal.Logf(
			"connection leaking detected: total_conns=%d free_conns=%d",
			st.TotalConns, st.FreeConns,
		)
	}
	return db.pool.Close()
}

// Exec executes a query ignoring returned rows. The params are for any
// placeholder parameters in the query.
func (db *DB) Exec(query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; ; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQuery(cn, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			break
		}
		if !db.shouldRetry(err) {
			break
		}

		time.Sleep(internal.RetryBackoff << uint(i))
	}
	return res, err
}

// ExecOne acts like Exec, but query must affect only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) ExecOne(query interface{}, params ...interface{}) (*types.Result, error) {
	res, err := db.Exec(query, params...)
	if err != nil {
		return nil, err
	}

	if err := internal.AssertOneRow(res.RowsAffected()); err != nil {
		return nil, err
	}
	return res, nil
}

// Query executes a query that returns rows, typically a SELECT.
// The params are for any placeholder parameters in the query.
func (db *DB) Query(model, query interface{}, params ...interface{}) (res *types.Result, err error) {
	var mod orm.Model
	for i := 0; i < 3; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, mod, err = simpleQueryData(cn, model, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			break
		}
		if !db.shouldRetry(err) {
			break
		}

		time.Sleep(internal.RetryBackoff << uint(i))
	}
	if err != nil {
		return nil, err
	}

	if res.RowsReturned() > 0 && mod != nil {
		if err = mod.AfterQuery(db); err != nil {
			return res, err
		}
	}

	return res, nil
}

// QueryOne acts like Query, but query must return only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (*types.Result, error) {
	mod, err := orm.NewModel(model)
	if err != nil {
		return nil, err
	}

	res, err := db.Query(mod, query, params...)
	if err != nil {
		return nil, err
	}

	if err := internal.AssertOneRow(res.RowsAffected()); err != nil {
		return nil, err
	}
	return res, nil
}

// Listen listens for notifications sent by NOTIFY statement.
func (db *DB) Listen(channels ...string) (*Listener, error) {
	l := &Listener{
		db: db,
	}
	if err := l.Listen(channels...); err != nil {
		l.Close()
		return nil, err
	}
	return l, nil
}

// CopyFrom copies data from reader to a table.
func (db *DB) CopyFrom(reader io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	res, err := copyFrom(cn, reader, query, params...)
	db.freeConn(cn, err)
	return res, err
}

// CopyTo copies data from a table to writer.
func (db *DB) CopyTo(writer io.Writer, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		db.pool.Put(cn)
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	if err := readCopyOutResponse(cn); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	res, err := readCopyData(cn, writer)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	db.pool.Put(cn)
	return res, nil
}

// Model returns new query for the model.
func (db *DB) Model(model ...interface{}) *orm.Query {
	return orm.NewQuery(db, model...)
}

// Select selects the model by primary key.
func (db *DB) Select(model interface{}) error {
	return orm.Select(db, model)
}

// Insert inserts the model updating primary keys if they are empty.
func (db *DB) Insert(model ...interface{}) error {
	return orm.Insert(db, model...)
}

// Update updates the model by primary key.
func (db *DB) Update(model interface{}) error {
	return orm.Update(db, model)
}

// Delete deletes the model by primary key.
func (db *DB) Delete(model interface{}) error {
	return orm.Delete(db, model)
}

// CreateTable creates table for the model in db.
func (db *DB) CreateTable(model interface{}, opt *orm.CreateTableOptions) error {
	_, err := orm.CreateTable(db, model, opt)
	return err
}

func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte {
	return orm.Formatter{}.Append(dst, query, params...)
}

func (db *DB) cancelRequest(processId, secretKey int32) error {
	cn, err := db.pool.NewConn()
	if err != nil {
		return err
	}

	writeCancelRequestMsg(cn.Wr, processId, secretKey)
	if err = cn.Wr.Flush(); err != nil {
		return err
	}
	cn.Close()

	return nil
}

func simpleQuery(cn *pool.Conn, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readSimpleQuery(cn)
}

func simpleQueryData(
	cn *pool.Conn, model, query interface{}, params ...interface{},
) (*types.Result, orm.Model, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, nil, err
	}

	return readSimpleQueryData(cn, model)
}

func copyFrom(cn *pool.Conn, r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	if err := readCopyInResponse(cn); err != nil {
		return nil, err
	}

	for {
		if _, err := writeCopyData(cn.Wr, r); err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		if err := cn.Wr.Flush(); err != nil {
			return nil, err
		}
	}

	writeCopyDone(cn.Wr)
	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readReadyForQuery(cn)
}
<commit_msg>Retry on invisible tuple.<commit_after>package pg // import "gopkg.in/pg.v5"

import (
	"io"
	"time"

	"gopkg.in/pg.v5/internal"
	"gopkg.in/pg.v5/internal/pool"
	"gopkg.in/pg.v5/orm"
	"gopkg.in/pg.v5/types"
)

// Connect connects to a database using provided options.
//
// The returned DB is safe for concurrent use by multiple goroutines
// and maintains its own connection pool.
func Connect(opt *Options) *DB {
	opt.init()
	return &DB{
		opt:  opt,
		pool: newConnPool(opt),
	}
}

// DB is a database handle representing a pool of zero or more
// underlying connections. It's safe for concurrent use by multiple
// goroutines.
type DB struct {
	opt  *Options
	pool *pool.ConnPool
}

var _ orm.DB = (*DB)(nil)

// Options returns read-only Options that were used to connect to the DB.
func (db *DB) Options() *Options {
	return db.opt
}

// WithTimeout returns a DB that uses d as the read/write timeout.
func (db *DB) WithTimeout(d time.Duration) *DB {
	newopt := *db.opt
	newopt.ReadTimeout = d
	newopt.WriteTimeout = d
	return &DB{
		opt:  &newopt,
		pool: db.pool,
	}
}

func (db *DB) conn() (*pool.Conn, error) {
	cn, _, err := db.pool.Get()
	if err != nil {
		return nil, err
	}

	if !cn.Inited {
		if err := db.initConn(cn); err != nil {
			_ = db.pool.Remove(cn, err)
			return nil, err
		}
	}

	cn.SetReadTimeout(db.opt.ReadTimeout)
	cn.SetWriteTimeout(db.opt.WriteTimeout)
	return cn, nil
}

func (db *DB) initConn(cn *pool.Conn) error {
	if db.opt.TLSConfig != nil {
		if err := enableSSL(cn, db.opt.TLSConfig); err != nil {
			return err
		}
	}

	err := startup(cn, db.opt.User, db.opt.Password, db.opt.Database)
	if err != nil {
		return err
	}

	cn.Inited = true
	return nil
}

func (db *DB) freeConn(cn *pool.Conn, err error) error {
	if !isBadConn(err, false) {
		return db.pool.Put(cn)
	}
	return db.pool.Remove(cn, err)
}

func (db *DB) shouldRetry(err error) bool {
	if err == nil {
		return false
	}
	if pgerr, ok := err.(Error); ok {
		switch pgerr.Field('C') {
		case "40001": // serialization_failure
			return true
		case "55000": // attempted to delete invisible tuple
			return true
		case "57014": // statement_timeout
			return db.opt.RetryStatementTimeout
		default:
			return false
		}
	}
	return isNetworkError(err)
}

// Close closes the database client, releasing any open resources.
//
// It is rare to Close a DB, as the DB handle is meant to be
// long-lived and shared between many goroutines.
func (db *DB) Close() error {
	st := db.pool.Stats()
	if st.TotalConns != st.FreeConns {
		internal.Logf(
			"connection leaking detected: total_conns=%d free_conns=%d",
			st.TotalConns, st.FreeConns,
		)
	}
	return db.pool.Close()
}

// Exec executes a query ignoring returned rows. The params are for any
// placeholder parameters in the query.
func (db *DB) Exec(query interface{}, params ...interface{}) (res *types.Result, err error) {
	for i := 0; ; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, err = simpleQuery(cn, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			break
		}
		if !db.shouldRetry(err) {
			break
		}

		time.Sleep(internal.RetryBackoff << uint(i))
	}
	return res, err
}

// ExecOne acts like Exec, but query must affect only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) ExecOne(query interface{}, params ...interface{}) (*types.Result, error) {
	res, err := db.Exec(query, params...)
	if err != nil {
		return nil, err
	}

	if err := internal.AssertOneRow(res.RowsAffected()); err != nil {
		return nil, err
	}
	return res, nil
}

// Query executes a query that returns rows, typically a SELECT.
// The params are for any placeholder parameters in the query.
func (db *DB) Query(model, query interface{}, params ...interface{}) (res *types.Result, err error) {
	var mod orm.Model
	for i := 0; i < 3; i++ {
		var cn *pool.Conn

		cn, err = db.conn()
		if err != nil {
			return nil, err
		}

		res, mod, err = simpleQueryData(cn, model, query, params...)
		db.freeConn(cn, err)

		if i >= db.opt.MaxRetries {
			break
		}
		if !db.shouldRetry(err) {
			break
		}

		time.Sleep(internal.RetryBackoff << uint(i))
	}
	if err != nil {
		return nil, err
	}

	if res.RowsReturned() > 0 && mod != nil {
		if err = mod.AfterQuery(db); err != nil {
			return res, err
		}
	}

	return res, nil
}

// QueryOne acts like Query, but query must return only one row. It
// returns ErrNoRows error when query returns zero rows or
// ErrMultiRows when query returns multiple rows.
func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (*types.Result, error) {
	mod, err := orm.NewModel(model)
	if err != nil {
		return nil, err
	}

	res, err := db.Query(mod, query, params...)
	if err != nil {
		return nil, err
	}

	if err := internal.AssertOneRow(res.RowsAffected()); err != nil {
		return nil, err
	}
	return res, nil
}

// Listen listens for notifications sent by NOTIFY statement.
func (db *DB) Listen(channels ...string) (*Listener, error) {
	l := &Listener{
		db: db,
	}
	if err := l.Listen(channels...); err != nil {
		l.Close()
		return nil, err
	}
	return l, nil
}

// CopyFrom copies data from reader to a table.
func (db *DB) CopyFrom(reader io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	res, err := copyFrom(cn, reader, query, params...)
	db.freeConn(cn, err)
	return res, err
}

// CopyTo copies data from a table to writer.
func (db *DB) CopyTo(writer io.Writer, query interface{}, params ...interface{}) (*types.Result, error) {
	cn, err := db.conn()
	if err != nil {
		return nil, err
	}

	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		db.pool.Put(cn)
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	if err := readCopyOutResponse(cn); err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	res, err := readCopyData(cn, writer)
	if err != nil {
		db.freeConn(cn, err)
		return nil, err
	}

	db.pool.Put(cn)
	return res, nil
}

// Model returns new query for the model.
func (db *DB) Model(model ...interface{}) *orm.Query {
	return orm.NewQuery(db, model...)
}

// Select selects the model by primary key.
func (db *DB) Select(model interface{}) error {
	return orm.Select(db, model)
}

// Insert inserts the model updating primary keys if they are empty.
func (db *DB) Insert(model ...interface{}) error {
	return orm.Insert(db, model...)
}

// Update updates the model by primary key.
func (db *DB) Update(model interface{}) error {
	return orm.Update(db, model)
}

// Delete deletes the model by primary key.
func (db *DB) Delete(model interface{}) error {
	return orm.Delete(db, model)
}

// CreateTable creates table for the model in db.
func (db *DB) CreateTable(model interface{}, opt *orm.CreateTableOptions) error {
	_, err := orm.CreateTable(db, model, opt)
	return err
}

func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte {
	return orm.Formatter{}.Append(dst, query, params...)
}

func (db *DB) cancelRequest(processId, secretKey int32) error {
	cn, err := db.pool.NewConn()
	if err != nil {
		return err
	}

	writeCancelRequestMsg(cn.Wr, processId, secretKey)
	if err = cn.Wr.Flush(); err != nil {
		return err
	}
	cn.Close()

	return nil
}

func simpleQuery(cn *pool.Conn, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readSimpleQuery(cn)
}

func simpleQueryData(
	cn *pool.Conn, model, query interface{}, params ...interface{},
) (*types.Result, orm.Model, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, nil, err
	}

	return readSimpleQueryData(cn, model)
}

func copyFrom(cn *pool.Conn, r io.Reader, query interface{}, params ...interface{}) (*types.Result, error) {
	if err := writeQueryMsg(cn.Wr, query, params...); err != nil {
		return nil, err
	}

	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	if err := readCopyInResponse(cn); err != nil {
		return nil, err
	}

	for {
		if _, err := writeCopyData(cn.Wr, r); err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		if err := cn.Wr.Flush(); err != nil {
			return nil, err
		}
	}

	writeCopyDone(cn.Wr)
	if err := cn.Wr.Flush(); err != nil {
		return nil, err
	}

	return readReadyForQuery(cn)
}
<|endoftext|>


<commit_before>/*

	cyle's simple graph database, version 0.1

*/

package main

import "fmt"
import "net/http"
import "os"
import "io/ioutil"
import "bufio"
import "encoding/json" // documentation: http://golang.org/pkg/encoding/json/

// using gorest: https://code.google.com/p/gorest/wiki/GettingStarted?tm=6
import "code.google.com/p/gorest"

type AllTheData struct {
	Name string
	Nodes []Node
	Connections []Connection
}

type Node struct {
	Id int
	Name string
	ExtraJSONBytes []byte
	ExtraJSON []interface{}
}

type Connection struct {
	Id int
	Name string
	Source int
	Target int
}

var db_filename string = "ALLTHEDATA.json"
var theData AllTheData

func main() {

	theData.Name = "The Graph Database"

	fmt.Println("Oh dear, a graph database...")

	/*
	// create some dummy nodes!
	for i := 1; i <= 10; i++ {
		tmpNode := Node{ i, "Node "+fmt.Sprintf("%d", i), nil, nil }
		theData.Nodes = append(theData.Nodes, tmpNode)
	}
	// create some dummy connections!
	connOne := Connection{ 1, "Node 1 to 2", 1, 2 }
	connTwo := Connection{ 2, "Node 2 to 4", 2, 4 }
	connThree := Connection{ 3, "Node 4 to 5", 4, 5 }
	connFour := Connection{ 4, "Node 2 to 3", 2, 3 }
	connFive := Connection{ 5, "Node 3 to 5", 3, 5 }
	// add connections to the big data pool
	theData.Connections = append(theData.Connections, connOne, connTwo, connThree, connFour, connFive)
	*/

	// if the database file exists, load it
	check, _ := doesFileExist(db_filename);
	if check {
		loadAllTheData()
	}

	// start the REST service to access the data
	gorest.RegisterService(new(GraphService))
	http.Handle("/", gorest.Handle())
	http.ListenAndServe(":8777", nil)
}

type GraphService struct{
    // service level config
    gorest.RestService `root:"/" consumes:"application/json" produces:"application/json"`
	// define routes

	// deal with the root
    rootHandler gorest.EndPoint `method:"GET" path:"/" output:"string"`

	// node stuff
	getNodesHandler gorest.EndPoint `method:"GET" path:"/nodes" output:"[]Node"`
	getNodeHandler gorest.EndPoint `method:"GET" path:"/node/{Id:int}" output:"Node"`
	postNodeHandler gorest.EndPoint `method:"POST" path:"/node" postdata:"Node"`
	deleteNodeHandler gorest.EndPoint `method:"DELETE" path:"/node/{Id:int}"`
	getConnectionsForNodeHandler gorest.EndPoint `method:"GET" path:"/node/{Id:int}/connections" output:"[]Connection"`

	// connections stuff
	getConnectionsHandler gorest.EndPoint `method:"GET" path:"/connections" output:"[]Connection"`
	getConnectionHandler gorest.EndPoint `method:"GET" path:"/connection/{Id:int}" output:"Connection"`
	postConnectionHandler gorest.EndPoint `method:"POST" path:"/connection" postdata:"Connection"`
	deleteConnectionHandler gorest.EndPoint `method:"DELETE" path:"/connection/{Id:int}"`

	// save the database
	saveDatabaseHandler gorest.EndPoint `method:"GET" path:"/save" output:"string"`
}

func (serv GraphService) RootHandler() string {
	return "Simple Graph Database, v0.1"
}

func (serv GraphService) SaveDatabaseHandler() string {
	fmt.Println("Saving database to file")
	saveAllTheData();
	fmt.Println("Saved database to file")
	return "okay"
}

/*

	node functions

*/

func (serv GraphService) GetNodesHandler() []Node {
	fmt.Println("Sending along current list of nodes")
	return theData.Nodes
}

func (serv GraphService) GetNodeHandler(Id int) (n Node){

	fmt.Printf("Asking for node ID: %d \n", Id)

	for _, value := range theData.Nodes {
		if value.Id == Id {
			n = value
			fmt.Printf("Giving: %+v \n", n)
			return
		}
	}

	/*
	n.Id = Id
	n.Name = "Some Node"
	n.ExtraJSONBytes = []byte(`[{"Name": "Platypus", "Order": "Monotremata"}]`)
	// this technique of taking arbitrary JSON and turning it into something usable came from: http://blog.golang.org/json-and-go
	var tmp interface {}
	err := json.Unmarshal(n.ExtraJSONBytes, &tmp)
	if err != nil {
		fmt.Println("error:", err)
	}
	//fmt.Printf("JSON: %T %+v \n", tmp, tmp)
	n.ExtraJSON = tmp.([]interface{})
	n.ExtraJSONBytes = nil
	*/

	// could not find it! send 404
    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
    return
}

func (serv GraphService) PostNodeHandler(n Node) {
	fmt.Printf("Just got: %+v \n", n)
	// check if this already exists. if so, update it.
	for key, value := range theData.Nodes {
		if value.Id == n.Id {
			fmt.Printf("Updating node ID %d \n", n.Id)
			theData.Nodes[key] = n
			serv.ResponseBuilder().SetResponseCode(200)
			return
		}
	}
	// doesn't exist? create it.
	fmt.Println("Creating new node based on input")
	n.Id = len(theData.Nodes) + 1 // +1 because it's 1-based instead of 0-based
	theData.Nodes = append(theData.Nodes, n)
	serv.ResponseBuilder().SetResponseCode(201)
	return
}

func (serv GraphService) DeleteNodeHandler(Id int) {
	fmt.Printf("Trying to delete node ID %d \n", Id)
	thekey := -1
	for key, value := range theData.Nodes {
		if value.Id == Id {
			thekey = key
		}
	}
	// look at all of this bullshit we have to do because of memory management
	if thekey > -1 {
		//fmt.Printf("Found the node to delete: %d \n", thekey)
		var tmpWhatever []Node
		if thekey == 0 {
			tmpWhatever = make([]Node, len(theData.Nodes) - 1)
			lastPartOfSlice := theData.Nodes[1:] // copy everything AFTER the node
			for _, value := range lastPartOfSlice {
				//fmt.Printf("Copying node: %+v \n", value)
				tmpWhatever = append(tmpWhatever, value)
			}
		} else {
			tmpWhatever = make([]Node, thekey)
			firstPartOfSlice := theData.Nodes[:thekey]
			copy(tmpWhatever, firstPartOfSlice) // copy everything BEFORE the node
			//fmt.Printf("Nodes so far: %+v \n", tmpWhatever)
			theNextKey := thekey + 1
			lastPartOfSlice := theData.Nodes[theNextKey:] // copy everything AFTER the node
			for _, value := range lastPartOfSlice {
				//fmt.Printf("Copying node: %+v \n", value)
				tmpWhatever = append(tmpWhatever, value)
			}
		}
		//fmt.Printf("Nodes so far: %+v \n", tmpWhatever)
		theData.Nodes = tmpWhatever
		//fmt.Printf("Nodes should be copied now!\n")
		fmt.Println("Node deleted")
	} else {
		fmt.Println("Could not find that node ID to delete, weird")
	}
	serv.ResponseBuilder().SetResponseCode(200)
	return
}

func (serv GraphService) GetConnectionsForNodeHandler(Id int) (connections []Connection) {
	// get the connections attached to a given node based on the node's ID
	fmt.Printf("Asking for connections for node ID: %d \n", Id)

	for _, conn := range theData.Connections {
		if conn.Source == Id || conn.Target == Id {
			connections = append(connections, conn)
		}
	}

	if len(connections) > 0 {
		return connections
	} else {
		// could not find any! send 404
	    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
	    return
	}

}

/*

	connection functions

*/

func (serv GraphService) GetConnectionsHandler() []Connection {
	fmt.Println("Sending along current list of connections")
	return theData.Connections
}

func (serv GraphService) GetConnectionHandler(Id int) (c Connection){

	fmt.Printf("Asking for connection ID: %d \n", Id)

	for _, value := range theData.Connections {
		if value.Id == Id {
			c = value
			fmt.Printf("Giving: %+v \n", c)
			return
		}
	}

	// could not find it! send 404
    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
    return
}

func (serv GraphService) PostConnectionHandler(c Connection) {
	fmt.Printf("Just got: %+v \n", c)
	// make sure it's not invalid
	if c.Source == c.Target {
		fmt.Println("Cannot create connection where SOURCE and TARGET are the same")
		serv.ResponseBuilder().SetResponseCode(400).Overide(true)
		return
	}
	// check to see if connection already exists
	for key, value := range theData.Connections {
		if value.Id == c.Id {
			fmt.Printf("Updating connection ID %d \n", c.Id)
			theData.Connections[key] = c
			serv.ResponseBuilder().SetResponseCode(200)
			return
		}
	}
	// does not exist! create a new connection.
	fmt.Println("Creating new connection based on input")
	c.Id = len(theData.Connections) + 1 // +1 because it's 1-based instead of 0-based
	theData.Connections = append(theData.Connections, c)
	serv.ResponseBuilder().SetResponseCode(201)
	return
}

func (serv GraphService) DeleteConnectionHandler(Id int) {
	fmt.Printf("Trying to delete connection ID %d", Id)
	thekey := -1
	for key, value := range theData.Connections {
		if value.Id == Id {
			thekey = key
		}
	}
	if thekey > -1 {
		var tmpWhatever []Connection
		if thekey == 0 {
			tmpWhatever = make([]Connection, len(theData.Connections) - 1)
			lastPartOfSlice := theData.Connections[1:] // copy everything AFTER
			for _, value := range lastPartOfSlice {
				tmpWhatever = append(tmpWhatever, value)
			}
		} else {
			tmpWhatever = make([]Connection, thekey)
			firstPartOfSlice := theData.Connections[:thekey]
			copy(tmpWhatever, firstPartOfSlice) // copy everything BEFORE
			theNextKey := thekey + 1
			lastPartOfSlice := theData.Connections[theNextKey:] // copy everything AFTER
			for _, value := range lastPartOfSlice {
				tmpWhatever = append(tmpWhatever, value)
			}
		}
		theData.Connections = tmpWhatever
		fmt.Println("Connection deleted")
	} else {
		fmt.Println("Could not find that connection ID to delete, weird")
	}
	serv.ResponseBuilder().SetResponseCode(200)
	return
}

/*

	save and load the data

*/

func saveAllTheData() {
	// spit data out to JSON into a file
	// open output file
    fo, err := os.Create(db_filename)
    if err != nil { panic(err) }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()
    // make a write buffer
    w := bufio.NewWriter(fo)
	allTheDataJSON, err := json.Marshal(theData)
	if err != nil { panic(err) }
	_, err = w.Write(allTheDataJSON)
	if (err != nil) { panic(err) }
	if err = w.Flush(); err != nil { panic(err) }
}

func loadAllTheData() {
	// ingest data via JSON from a file
	allJSON, err := ioutil.ReadFile(db_filename)
	if err != nil { panic(err) }
	unmarshal_err := json.Unmarshal(allJSON, &theData)
	if unmarshal_err != nil { panic(unmarshal_err) }
}

/*

	helper functions

*/

// exists returns whether the given file or directory exists or not
// from: http://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-denoted-by-a-path-exists-in-golang
func doesFileExist(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil { return true, nil }
    if os.IsNotExist(err) { return false, nil }
    return false, err
}<commit_msg>- if no data on file, make dummy data<commit_after>/*

	cyle's simple graph database, version 0.1

*/

package main

import "fmt"
import "net/http"
import "os"
import "io/ioutil"
import "bufio"
import "encoding/json" // documentation: http://golang.org/pkg/encoding/json/

// using gorest: https://code.google.com/p/gorest/wiki/GettingStarted?tm=6
import "code.google.com/p/gorest"

type AllTheData struct {
	Name string
	Nodes []Node
	Connections []Connection
}

type Node struct {
	Id int
	Name string
	ExtraJSONBytes []byte
	ExtraJSON []interface{}
}

type Connection struct {
	Id int
	Name string
	Source int
	Target int
}

var db_filename string = "ALLTHEDATA.json"
var theData AllTheData

func main() {

	theData.Name = "The Graph Database"

	fmt.Println("Oh dear, a graph database...")

	// if the database file exists, load it
	check, _ := doesFileExist(db_filename);
	if check {
		loadAllTheData()
	} else {
		// create some dummy nodes!
		for i := 1; i <= 10; i++ {
			tmpNode := Node{ i, "Node "+fmt.Sprintf("%d", i), nil, nil }
			theData.Nodes = append(theData.Nodes, tmpNode)
		}
		// create some dummy connections!
		connOne := Connection{ 1, "Node 1 to 2", 1, 2 }
		connTwo := Connection{ 2, "Node 2 to 3", 2, 3 }
		connThree := Connection{ 3, "Node 3 to 4", 3, 4 }
		connFour := Connection{ 4, "Node 4 to 5", 4, 5 }
		connFive := Connection{ 5, "Node 5 to 6", 5, 6 }
		connSix := Connection{ 5, "Node 3 to 9", 3, 9 }
		connSeven := Connection{ 5, "Node 9 to 8", 9, 8 }
		connEight := Connection{ 5, "Node 8 to 3", 8, 3 }
		connNine := Connection{ 5, "Node 3 to 7", 3, 7 }
		connTen := Connection{ 5, "Node 7 to 5", 7, 5 }
		// add connections to the big data pool
		theData.Connections = append(theData.Connections, connOne, connTwo, connThree, connFour, connFive)
		// save this dummy data for future use
		saveAllTheData()
	}

	// start the REST service to access the data
	gorest.RegisterService(new(GraphService))
	http.Handle("/", gorest.Handle())
	http.ListenAndServe(":8777", nil)
}

type GraphService struct{
    // service level config
    gorest.RestService `root:"/" consumes:"application/json" produces:"application/json"`
	// define routes

	// deal with the root
    rootHandler gorest.EndPoint `method:"GET" path:"/" output:"string"`

	// node stuff
	getNodesHandler gorest.EndPoint `method:"GET" path:"/nodes" output:"[]Node"`
	getNodeHandler gorest.EndPoint `method:"GET" path:"/node/{Id:int}" output:"Node"`
	postNodeHandler gorest.EndPoint `method:"POST" path:"/node" postdata:"Node"`
	deleteNodeHandler gorest.EndPoint `method:"DELETE" path:"/node/{Id:int}"`
	getConnectionsForNodeHandler gorest.EndPoint `method:"GET" path:"/node/{Id:int}/connections" output:"[]Connection"`

	// connections stuff
	getConnectionsHandler gorest.EndPoint `method:"GET" path:"/connections" output:"[]Connection"`
	getConnectionHandler gorest.EndPoint `method:"GET" path:"/connection/{Id:int}" output:"Connection"`
	postConnectionHandler gorest.EndPoint `method:"POST" path:"/connection" postdata:"Connection"`
	deleteConnectionHandler gorest.EndPoint `method:"DELETE" path:"/connection/{Id:int}"`

	// save the database
	saveDatabaseHandler gorest.EndPoint `method:"GET" path:"/save" output:"string"`
}

func (serv GraphService) RootHandler() string {
	return "Simple Graph Database, v0.1"
}

func (serv GraphService) SaveDatabaseHandler() string {
	fmt.Println("Saving database to file")
	saveAllTheData();
	fmt.Println("Saved database to file")
	return "okay"
}

/*

	node functions

*/

func (serv GraphService) GetNodesHandler() []Node {
	fmt.Println("Sending along current list of nodes")
	return theData.Nodes
}

func (serv GraphService) GetNodeHandler(Id int) (n Node){

	fmt.Printf("Asking for node ID: %d \n", Id)

	for _, value := range theData.Nodes {
		if value.Id == Id {
			n = value
			fmt.Printf("Giving: %+v \n", n)
			return
		}
	}

	/*
	n.Id = Id
	n.Name = "Some Node"
	n.ExtraJSONBytes = []byte(`[{"Name": "Platypus", "Order": "Monotremata"}]`)
	// this technique of taking arbitrary JSON and turning it into something usable came from: http://blog.golang.org/json-and-go
	var tmp interface {}
	err := json.Unmarshal(n.ExtraJSONBytes, &tmp)
	if err != nil {
		fmt.Println("error:", err)
	}
	//fmt.Printf("JSON: %T %+v \n", tmp, tmp)
	n.ExtraJSON = tmp.([]interface{})
	n.ExtraJSONBytes = nil
	*/

	// could not find it! send 404
    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
    return
}

func (serv GraphService) PostNodeHandler(n Node) {
	fmt.Printf("Just got: %+v \n", n)
	// check if this already exists. if so, update it.
	for key, value := range theData.Nodes {
		if value.Id == n.Id {
			fmt.Printf("Updating node ID %d \n", n.Id)
			theData.Nodes[key] = n
			serv.ResponseBuilder().SetResponseCode(200)
			return
		}
	}
	// doesn't exist? create it.
	fmt.Println("Creating new node based on input")
	n.Id = len(theData.Nodes) + 1 // +1 because it's 1-based instead of 0-based
	theData.Nodes = append(theData.Nodes, n)
	serv.ResponseBuilder().SetResponseCode(201)
	return
}

func (serv GraphService) DeleteNodeHandler(Id int) {
	fmt.Printf("Trying to delete node ID %d \n", Id)
	thekey := -1
	for key, value := range theData.Nodes {
		if value.Id == Id {
			thekey = key
		}
	}
	// look at all of this bullshit we have to do because of memory management
	if thekey > -1 {
		//fmt.Printf("Found the node to delete: %d \n", thekey)
		var tmpWhatever []Node
		if thekey == 0 {
			tmpWhatever = make([]Node, len(theData.Nodes) - 1)
			lastPartOfSlice := theData.Nodes[1:] // copy everything AFTER the node
			for _, value := range lastPartOfSlice {
				//fmt.Printf("Copying node: %+v \n", value)
				tmpWhatever = append(tmpWhatever, value)
			}
		} else {
			tmpWhatever = make([]Node, thekey)
			firstPartOfSlice := theData.Nodes[:thekey]
			copy(tmpWhatever, firstPartOfSlice) // copy everything BEFORE the node
			//fmt.Printf("Nodes so far: %+v \n", tmpWhatever)
			theNextKey := thekey + 1
			lastPartOfSlice := theData.Nodes[theNextKey:] // copy everything AFTER the node
			for _, value := range lastPartOfSlice {
				//fmt.Printf("Copying node: %+v \n", value)
				tmpWhatever = append(tmpWhatever, value)
			}
		}
		//fmt.Printf("Nodes so far: %+v \n", tmpWhatever)
		theData.Nodes = tmpWhatever
		//fmt.Printf("Nodes should be copied now!\n")
		fmt.Println("Node deleted")
	} else {
		fmt.Println("Could not find that node ID to delete, weird")
	}
	serv.ResponseBuilder().SetResponseCode(200)
	return
}

func (serv GraphService) GetConnectionsForNodeHandler(Id int) (connections []Connection) {
	// get the connections attached to a given node based on the node's ID
	fmt.Printf("Asking for connections for node ID: %d \n", Id)

	for _, conn := range theData.Connections {
		if conn.Source == Id || conn.Target == Id {
			connections = append(connections, conn)
		}
	}

	if len(connections) > 0 {
		return connections
	} else {
		// could not find any! send 404
	    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
	    return
	}

}

/*

	connection functions

*/

func (serv GraphService) GetConnectionsHandler() []Connection {
	fmt.Println("Sending along current list of connections")
	return theData.Connections
}

func (serv GraphService) GetConnectionHandler(Id int) (c Connection){

	fmt.Printf("Asking for connection ID: %d \n", Id)

	for _, value := range theData.Connections {
		if value.Id == Id {
			c = value
			fmt.Printf("Giving: %+v \n", c)
			return
		}
	}

	// could not find it! send 404
    serv.ResponseBuilder().SetResponseCode(404).Overide(true)  //Overide causes the entity returned by the method to be ignored. Other wise it would send back zeroed object
    return
}

func (serv GraphService) PostConnectionHandler(c Connection) {
	fmt.Printf("Just got: %+v \n", c)
	// make sure it's not invalid
	if c.Source == c.Target {
		fmt.Println("Cannot create connection where SOURCE and TARGET are the same")
		serv.ResponseBuilder().SetResponseCode(400).Overide(true)
		return
	}
	// check to see if connection already exists
	for key, value := range theData.Connections {
		if value.Id == c.Id {
			fmt.Printf("Updating connection ID %d \n", c.Id)
			theData.Connections[key] = c
			serv.ResponseBuilder().SetResponseCode(200)
			return
		}
	}
	// does not exist! create a new connection.
	fmt.Println("Creating new connection based on input")
	c.Id = len(theData.Connections) + 1 // +1 because it's 1-based instead of 0-based
	theData.Connections = append(theData.Connections, c)
	serv.ResponseBuilder().SetResponseCode(201)
	return
}

func (serv GraphService) DeleteConnectionHandler(Id int) {
	fmt.Printf("Trying to delete connection ID %d", Id)
	thekey := -1
	for key, value := range theData.Connections {
		if value.Id == Id {
			thekey = key
		}
	}
	if thekey > -1 {
		var tmpWhatever []Connection
		if thekey == 0 {
			tmpWhatever = make([]Connection, len(theData.Connections) - 1)
			lastPartOfSlice := theData.Connections[1:] // copy everything AFTER
			for _, value := range lastPartOfSlice {
				tmpWhatever = append(tmpWhatever, value)
			}
		} else {
			tmpWhatever = make([]Connection, thekey)
			firstPartOfSlice := theData.Connections[:thekey]
			copy(tmpWhatever, firstPartOfSlice) // copy everything BEFORE
			theNextKey := thekey + 1
			lastPartOfSlice := theData.Connections[theNextKey:] // copy everything AFTER
			for _, value := range lastPartOfSlice {
				tmpWhatever = append(tmpWhatever, value)
			}
		}
		theData.Connections = tmpWhatever
		fmt.Println("Connection deleted")
	} else {
		fmt.Println("Could not find that connection ID to delete, weird")
	}
	serv.ResponseBuilder().SetResponseCode(200)
	return
}

/*

	save and load the data

*/

func saveAllTheData() {
	// spit data out to JSON into a file
	// open output file
    fo, err := os.Create(db_filename)
    if err != nil { panic(err) }
    // close fo on exit and check for its returned error
    defer func() {
        if err := fo.Close(); err != nil {
            panic(err)
        }
    }()
    // make a write buffer
    w := bufio.NewWriter(fo)
	allTheDataJSON, err := json.Marshal(theData)
	if err != nil { panic(err) }
	_, err = w.Write(allTheDataJSON)
	if (err != nil) { panic(err) }
	if err = w.Flush(); err != nil { panic(err) }
}

func loadAllTheData() {
	// ingest data via JSON from a file
	allJSON, err := ioutil.ReadFile(db_filename)
	if err != nil { panic(err) }
	unmarshal_err := json.Unmarshal(allJSON, &theData)
	if unmarshal_err != nil { panic(unmarshal_err) }
}

/*

	helper functions

*/

// exists returns whether the given file or directory exists or not
// from: http://stackoverflow.com/questions/10510691/how-to-check-whether-a-file-or-directory-denoted-by-a-path-exists-in-golang
func doesFileExist(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil { return true, nil }
    if os.IsNotExist(err) { return false, nil }
    return false, err
}<|endoftext|>


<commit_before>// An introspect page is mapped into a Collection which is basically a
// list of Element.

package main

import "fmt"
import "log"

import "github.com/moovweb/gokogiri/xml"

// A Collection describes and contains a list of Elements.
type Collection struct {
	url      string
	descCol  DescCollection
	doc      *xml.XmlDocument
	node     xml.Node
	elements []Element
}

type Elements []Element

type Element struct {
	node xml.Node
	desc DescElement
}

// This contains informations to generate and query a Collection
type DescCollection struct {
	// Names of arguments required from the user to get datas from
	// introspect
	PageArgs    []string
	// A function that takes the list of arguments specified by
	// the user
	PageBuilder (func([]string) Sourcer)
	// The root Xpath
	BaseXpath   string
	// Description of Collection's Elements
	DescElt     DescElement
	// Name of the attribute used to search in the collection
	SearchAttribute string
	// A function that generate a Xpath based on the attribute
	// provided by the user
	SearchXpath (func(string) string)
}

type DescElement struct {
	// Xpath used to generate the short version of an element
	ShortDetailXpath string
	// Used to generate the long version of an element
	LongDetail       LongFormatter
}

func (col *Collection) Init() {
	ss, _ := col.node.Search(col.descCol.BaseXpath + "/*")
	col.elements = make([]Element, len(ss))
	for i, s := range ss {
		col.elements[i] = Element{node: s, desc: col.descCol.DescElt}
	}
}

func (col *Collection) Search(pattern string) Elements {
	ss, _ := col.node.Search(col.descCol.BaseXpath + "/" + col.descCol.SearchXpath(pattern))
	var elements []Element = make([]Element, len(ss))
	for i, s := range ss {
		elements[i] = Element{node: s, desc: col.descCol.DescElt}
	}
	return Elements(elements)
}

// Several representations of resources
type Shower interface {
	Long()
	Short()
	Xml()
}

func (e Element) Xml() {
	fmt.Printf("%s", e.node)
}
func (elts Elements) Xml() {
	for _, e := range elts {
		e.Xml()
	}
}
func (c Collection) Xml() {
	fmt.Printf("%s", c.node)
}

func (e Element) Short() {
	s, _ := e.node.Search(e.desc.ShortDetailXpath)
	if len(s) != 1 {
		log.Fatal("Xpath '" + e.desc.ShortDetailXpath + "' is not valid (verify ShortDetailXpath)")
	}
	fmt.Printf("%s\n", s[0])
}
func (col Collection) Short() {
	Elements(col.elements).Short()
}
func (elts Elements) Short() {
	for _, e := range elts {
		e.Short()
	}
}
func (e Element) Long() {
	e.desc.LongDetail.LongFormat(e)
}
func (col Collection) Long() {
	Elements(col.elements).Long()
}
func (elts Elements) Long() {
	for _, e := range elts {
		e.Long()
		fmt.Printf("\n")
	}
}

// This is used to show the long version of an Element.
type LongFormatter interface {
	LongFormat(e Element)
}

type LongFormatFn (func(Element))
type LongFormatXpaths []string

func (fn LongFormatFn) LongFormat(e Element) {
	fn(e)
}
func (xpaths LongFormatXpaths) LongFormat(e Element) {
	for _, xpath := range xpaths {
		s, _ := e.node.Search(xpath)
		fmt.Printf("%s ", s[0])
	}
}

<commit_msg>Only print fields if available<commit_after>// An introspect page is mapped into a Collection which is basically a
// list of Element.

package main

import "fmt"
import "log"

import "github.com/moovweb/gokogiri/xml"

// A Collection describes and contains a list of Elements.
type Collection struct {
	url      string
	descCol  DescCollection
	doc      *xml.XmlDocument
	node     xml.Node
	elements []Element
}

type Elements []Element

type Element struct {
	node xml.Node
	desc DescElement
}

// This contains informations to generate and query a Collection
type DescCollection struct {
	// Names of arguments required from the user to get datas from
	// introspect
	PageArgs    []string
	// A function that takes the list of arguments specified by
	// the user
	PageBuilder (func([]string) Sourcer)
	// The root Xpath
	BaseXpath   string
	// Description of Collection's Elements
	DescElt     DescElement
	// Name of the attribute used to search in the collection
	SearchAttribute string
	// A function that generate a Xpath based on the attribute
	// provided by the user
	SearchXpath (func(string) string)
}

type DescElement struct {
	// Xpath used to generate the short version of an element
	ShortDetailXpath string
	// Used to generate the long version of an element
	LongDetail       LongFormatter
}

func (col *Collection) Init() {
	ss, _ := col.node.Search(col.descCol.BaseXpath + "/*")
	col.elements = make([]Element, len(ss))
	for i, s := range ss {
		col.elements[i] = Element{node: s, desc: col.descCol.DescElt}
	}
}

func (col *Collection) Search(pattern string) Elements {
	ss, _ := col.node.Search(col.descCol.BaseXpath + "/" + col.descCol.SearchXpath(pattern))
	var elements []Element = make([]Element, len(ss))
	for i, s := range ss {
		elements[i] = Element{node: s, desc: col.descCol.DescElt}
	}
	return Elements(elements)
}

// Several representations of resources
type Shower interface {
	Long()
	Short()
	Xml()
}

func (e Element) Xml() {
	fmt.Printf("%s", e.node)
}
func (elts Elements) Xml() {
	for _, e := range elts {
		e.Xml()
	}
}
func (c Collection) Xml() {
	fmt.Printf("%s", c.node)
}

func (e Element) Short() {
	s, _ := e.node.Search(e.desc.ShortDetailXpath)
	if len(s) != 1 {
		log.Fatal("Xpath '" + e.desc.ShortDetailXpath + "' is not valid (verify ShortDetailXpath)")
	}
	fmt.Printf("%s\n", s[0])
}
func (col Collection) Short() {
	Elements(col.elements).Short()
}
func (elts Elements) Short() {
	for _, e := range elts {
		e.Short()
	}
}
func (e Element) Long() {
	e.desc.LongDetail.LongFormat(e)
}
func (col Collection) Long() {
	Elements(col.elements).Long()
}
func (elts Elements) Long() {
	for _, e := range elts {
		e.Long()
		fmt.Printf("\n")
	}
}

// This is used to show the long version of an Element.
type LongFormatter interface {
	LongFormat(e Element)
}

type LongFormatFn (func(Element))
type LongFormatXpaths []string

func (fn LongFormatFn) LongFormat(e Element) {
	fn(e)
}
func (xpaths LongFormatXpaths) LongFormat(e Element) {
	for _, xpath := range xpaths {
		s, _ := e.node.Search(xpath)
		if len(s) == 1 {
			fmt.Printf("%s ", s[0])
		}
	}
}

<|endoftext|>


<commit_before>package template_metrics

import (
	"time"
)

// print infomation on each request
var Verbose = false

// Set Enable = false if you want to turn off the instrumentation
var Enable = true

// a set of proxies
var proxyRegistry = make(map[templateInterface](*Template))

// a set of metrics
var metricsRegistry = make(map[string](*Metrics))

//Wrap  instrument template
func WrapTemplate(name string, template templateInterface) *Template {
	metrics := metricsRegistry[name]
	if metrics == nil {
		metrics = newMetrics(name)
		metricsRegistry[name] = metrics
	}
	proxy := proxyRegistry[template]
	if proxy == nil {
		proxy = newTemplate(template, metrics)
		proxyRegistry[template] = proxy
	}
	return proxy
}

//Print  print the metrics in each second
func Print(duration int) {
	timeDuration := time.Duration(duration)
	go func() {
		time.Sleep(timeDuration * time.Second)
		for {
			startTime := time.Now()
			for _, metrics := range metricsRegistry {
				metrics.printMetrics(duration)
			}
			elapsedTime := time.Now().Sub(startTime)
			time.Sleep(timeDuration*time.Second - elapsedTime)
		}
	}()
}
<commit_msg>Add Flush()<commit_after>package template_metrics

import (
	"time"
)

// print infomation on each request
var Verbose = false

// Set Enable = false if you want to turn off the instrumentation
var Enable = true

// a set of proxies
var proxyRegistry = make(map[templateInterface](*Template))

// a set of metrics
var metricsRegistry = make(map[string](*Metrics))

//Wrap  instrument template
func WrapTemplate(name string, template templateInterface) *Template {
	metrics := metricsRegistry[name]
	if metrics == nil {
		metrics = newMetrics(name)
		metricsRegistry[name] = metrics
	}
	proxy := proxyRegistry[template]
	if proxy == nil {
		proxy = newTemplate(template, metrics)
		proxyRegistry[template] = proxy
	}
	return proxy
}

//Flush  print the metrics
func Flush() {
	for _, metrics := range metricsRegistry {
		metrics.printMetrics(-1)
	}
}

//Print  print the metrics in each duration
func Print(duration int) {
	timeDuration := time.Duration(duration)
	go func() {
		time.Sleep(timeDuration * time.Second)
		for {
			startTime := time.Now()
			for _, metrics := range metricsRegistry {
				metrics.printMetrics(duration)
			}
			elapsedTime := time.Now().Sub(startTime)
			time.Sleep(timeDuration*time.Second - elapsedTime)
		}
	}()
}
<|endoftext|>


<commit_before>package valida

import (
	"fmt"
	"testing"
)

func ExampleJMBG() {
	ok := JMBG("0308964384007")
	fmt.Println(ok)
	// Output:
	// true
}

func ExampleMID() {
	ok := MID("1333")
	fmt.Println(ok)
	// Output:
	// true
}

func ExampleOIB() {
	ok := OIB("69435151530")
	fmt.Println(ok)
	// Output:
	// true
}

func TestJMBG(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"0308964384007", true},
		// too short
		{"123", false},
		// invalid
		{"1234567890123", false},
		// not number
		{"123a567b90123", false},
		// last invalid
		{"123456789012a", false},
		// all zeros
		{"0000000000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := JMBG(tt.in); got != tt.want {
			t.Errorf("JMBG(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestMBS(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"01130234", true},
		{"011302340123", true},
		// too short
		{"123", false},
		// invalid
		{"12345678", false},
		// not number
		{"1a23b567", false},
		// last invalid
		{"1234567x", false},
		// all zeros
		{"00000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := MBS(tt.in); got != tt.want {
			t.Errorf("MBS(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestMID(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"1333", true},
		{"4880", true},
		// too short
		{"123", false},
		// invalid
		{"1234", false},
		// not number
		{"1a23", false},
		// last invalid
		{"012a", false},
		// all zeros
		{"0000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := MID(tt.in); got != tt.want {
			t.Errorf("MID(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestOIB(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"69435151530", true},
		// too short
		{"123", false},
		// invalid
		{"12345678901", false},
		// not number
		{"123a5b7c901", false},
		// last invalid
		{"1234567890a", false},
		// all zeros
		{"00000000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := OIB(tt.in); got != tt.want {
			t.Errorf("OIB(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}
<commit_msg>Add ExampleMBS<commit_after>package valida

import (
	"fmt"
	"testing"
)

func ExampleJMBG() {
	ok := JMBG("0308964384007")
	fmt.Println(ok)
	// Output:
	// true
}

func ExampleMBS() {
	okShort := MBS("01130234")
	okLong := MBS("011302340123")
	fmt.Println(okShort)
	fmt.Println(okLong)
	// Output:
	// true
	// true
}

func ExampleMID() {
	ok := MID("1333")
	fmt.Println(ok)
	// Output:
	// true
}

func ExampleOIB() {
	ok := OIB("69435151530")
	fmt.Println(ok)
	// Output:
	// true
}

func TestJMBG(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"0308964384007", true},
		// too short
		{"123", false},
		// invalid
		{"1234567890123", false},
		// not number
		{"123a567b90123", false},
		// last invalid
		{"123456789012a", false},
		// all zeros
		{"0000000000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := JMBG(tt.in); got != tt.want {
			t.Errorf("JMBG(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestMBS(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"01130234", true},
		{"011302340123", true},
		// too short
		{"123", false},
		// invalid
		{"12345678", false},
		// not number
		{"1a23b567", false},
		// last invalid
		{"1234567x", false},
		// all zeros
		{"00000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := MBS(tt.in); got != tt.want {
			t.Errorf("MBS(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestMID(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"1333", true},
		{"4880", true},
		// too short
		{"123", false},
		// invalid
		{"1234", false},
		// not number
		{"1a23", false},
		// last invalid
		{"012a", false},
		// all zeros
		{"0000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := MID(tt.in); got != tt.want {
			t.Errorf("MID(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}

func TestOIB(t *testing.T) {
	var tests = []struct {
		in   string
		want bool
	}{
		// valid
		{"69435151530", true},
		// too short
		{"123", false},
		// invalid
		{"12345678901", false},
		// not number
		{"123a5b7c901", false},
		// last invalid
		{"1234567890a", false},
		// all zeros
		{"00000000000", false},
		// empty
		{"", false},
	}
	for _, tt := range tests {
		if got := OIB(tt.in); got != tt.want {
			t.Errorf("OIB(\"%v\") = %v; want %v",
				tt.in, got, tt.want)
		}
	}
}
<|endoftext|>