<commit_before>package controllers

import (
	"github.com/golang/glog"
	"github.com/astaxie/beego"
)

type ApiController struct {
	beego.Controller
}

/* Create acount */
func (c *ApiController) CreateAccount() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetActiveBuilds() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetSearchBuilds() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetBuildLog() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetBuildLogPart() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) CreateProject() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetProjects() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) CreateImage() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetImages() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetImage() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetTasks() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) FinishTask() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

func (c *ApiController) GetWorkers() {
	glog.Info("Creat accout")

	c.Ctx.WriteString("")
}

<commit_msg>Initialize all the api<commit_after>package controllers

import (
	"github.com/golang/glog"
	"github.com/astaxie/beego"
)

type ApiController struct {
	beego.Controller
}

/* Create acount */
func (c *ApiController) CreateAccount() {
	glog.Info("Creat accout")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get active builds */
func (c *ApiController) GetActiveBuilds() {
	glog.Info("Get active builds")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get search builds */
func (c *ApiController) GetSearchBuilds() {
	glog.Info("Get search builds")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get build log by id */
func (c *ApiController) GetBuildLog() {
	glog.Info("Get build log")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get build log part by part id */
func (c *ApiController) GetBuildLogPart() {
	glog.Info("Get build log part")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Create project */
func (c *ApiController) CreateProject() {
	glog.Info("Creat project")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get projects */
func (c *ApiController) GetProjects() {
	glog.Info("Get projects")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Create image */
func (c *ApiController) CreateImage() {
	glog.Info("Create image")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get images */
func (c *ApiController) GetImages() {
	glog.Info("Get images")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get image by id */
func (c *ApiController) GetImage() {
	glog.Info("Get image")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get tasks */
func (c *ApiController) GetTasks() {
	glog.Info("Get tasks")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Finish task */
func (c *ApiController) FinishTask() {
	glog.Info("Finish task")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

/* Get workers */
func (c *ApiController) GetWorkers() {
	glog.Info("Get workers")

	result := "{data: 1}"
	c.Ctx.WriteString(result)
}

<|endoftext|>


<commit_before>package config

import (
	"bufio"
	"html/template"
	"os"

	"github.com/vivace-io/gonfig"
)

var t = template.Must(template.ParseGlob("response.tmpl"))
var input = bufio.NewReader(os.Stdin)

// LoadConfig reads the configuration file and returns it,
// marshalled in to Config
func LoadConfig() (*Configuration, error) {
	cfg := &Configuration{}
	err := gonfig.Load(cfg)
	return cfg, err
}

// Configuration defines zk2s' configuration
type Configuration struct {
	UserAgent string    `json:"userAgent"`
	BotToken  string    `json:"botToken"`
	Channels  []Channel `json:"channels"`
}

// File returns the file name/path for gonfig interface
func (c *Configuration) File() string {
	return "cfg.zk2s.json"
}

// Save the configuration file
func (c *Configuration) Save() error {
	return gonfig.Save(c)
}

// Channel defines the configuration for a slack channel, including its filters
type Channel struct {
	Name                string   `json:"channelName"`
	MinimumValue        int      `json:"minimumValue"`
	MaximumValue        int      `json:"maximumValue"`
	IncludeCharacters   []string `json:"includeCharacters"`
	IncludeCorporations []string `json:"includeCorporations"`
	IncludeAlliances    []string `json:"includeAlliance"`
	ExcludedShips       []string `json:"excludedShips"`
}
<commit_msg>multi-team support in configuration, read/write protection on configuration<commit_after>package config

import (
	"sync"

	"github.com/urfave/cli"
	"github.com/vivace-io/gonfig"
)

var (
	CONFIG *Configuration
)

func Init(c *cli.Context) error {
	return nil
}

// Configuration contains returns the Application configuration in its current state,
// and protects it to be safe for use in goroutines.
type Configuration struct {
	*sync.RWMutex
	app *Application
}

func (this *Configuration) Get() (app Application, err error) {
	if app == nil {
		this.Lock()
		defer this.Unlock()
		return *this.app, gonfig.Load(this.app)
	}
	this.RLock()
	defer this.RUnlock()
	return *this.app, nil
}

type Application struct {
	UserAgent string `json:"userAgent"`
	Teams     []Team `json:"teams"`
}

// File returns the file name/path for gonfig interface
func (this *Application) File() string {
	return "cfg.zk2s.json"
}

// Save the configuration file
func (this *Application) Save() error {
	return gonfig.Save(c)
}

type Team struct {
	BotToken string    `json:"botToken"`
	Channels []Channel `json:"channels"`
}

// Channel defines the configuration for a slack channel in a team, including its filters
type Channel struct {
	Name                string   `json:"channelName"`
	MinimumValue        int      `json:"minimumValue"`
	MaximumValue        int      `json:"maximumValue"`
	IncludeCharacters   []string `json:"includeCharacters"`
	IncludeCorporations []string `json:"includeCorporations"`
	IncludeAlliances    []string `json:"includeAlliance"`
	ExcludedShips       []string `json:"excludedShips"`
}
<|endoftext|>


<commit_before>package transmogrifier

import (
	"encoding/csv"
	_ "fmt"
	"io"
	"os"
	_ "path/filepath"
	_ "strconv"
	_ "strings"
)

// CSV is a struct for representing and working with csv data.
type CSV struct {
	// source information.
	source resource
	// sink information
	sink resource
	// Variables consistent with stdlib's Reader struct in the csv package,
	// with the exception of csv.Reader.TrailingComma, which is ommitted
	// since it is ignored.
	//
	// Anything set here will override the Reader's default value set by
	// csv.NewReader(). Please check golang.org/pkg/encoding/csv for more
	// info about the variables.
	comma            rune
	comment          rune
	fieldsPerRecord  int
	lazyQuotes       bool
	trimLeadingSpace bool
	// hasHeader: whether the csv data includes a header row as its
	// first row. If the csv data does not include header data, the header
	// data must be provided via template, e.g. false implies
	// 'useFormat' == true. True does not have any implications on using
	// the format file.
	hasHeader bool
	// The csv file data:
	// headerRow contains the header row information. This is when a format
	// has been supplied, the header row information is set.
	headerRow []string
	// table is the parsed csv data
	rows [][]string
}

// NewCSV returns an initialize CSV object. It still needs to be configured
// for use.
func NewCSV() *CSV {
	C := &CSV{
		source:    resource{},
		sink:      resource{},
		hasHeader: true,
		headerRow: []string{},
		rows:      [][]string{},
	}
	return C
}

// NewCSVSource creates a new *CSV with its source set,
func NewCSVSource(s string) *CSV {
	c := NewCSV()
	c.SetSource(s)
	return c
}

// ReadAll takes a reader, and reads the data connected with it as CSV data.
// If there is a header row, CSV.hasHeader == true, the headerRow field is
// populated with the first row of the source.  This reads the entire file at
// once.  If an error occurs, it is returned
func (c *CSV) Read(r io.Reader) error {
	var err error
	cr := csv.NewReader(r)
	c.rows, err = cr.ReadAll()
	if err != nil {
		return err
	}
	if c.hasHeader {
		c.headerRow = c.rows[0]
		c.rows = c.rows[1:]
	}
	return nil
}

// ReadFile takes a path, reads the contents of the file and returns any error
// encountered. The entire file will be read at once.
func (c *CSV) ReadFile(f string) error {
	if f == "" {
		return ErrNoSource
	}
	file, err := os.Open(f)
	if err != nil {
		return err
	}
	// because we don't want to forget or worry about hanldling close prior
	// to every return.
	defer file.Close()
	// Read the file into csv
	return c.Read(file)
}

func (c *CSV) ReadSource() error {
	return c.ReadFile(c.source.String())
}

// SetSource sets the source and has the formatFile updated, if applicable.
func (c *CSV) SetSource(s string) {
	c.source = resource{Name: s, Path: s}
}

// Source returns the source string
func (c *CSV) Source() string {
	return c.source.String()
}

func (c *CSV) SetHasHeader(b bool) {
	c.hasHeader = b
}

// HasHeader returns the hasHeader bool
func (c *CSV) HasHeader() bool {
	return c.hasHeader
}

// HeaderRow returns the header row, if it exists.
func (c *CSV) HeaderRow() []string {
	return c.headerRow
}

// Rows returns the csv rows.
func (c *CSV) Rows() [][]string {
	return c.rows
}
<commit_msg>fix resource creation on CSV<commit_after>package transmogrifier

import (
	"encoding/csv"
	"io"
	"os"
	_ "path/filepath"
	_ "strconv"
	_ "strings"
)

// CSV is a struct for representing and working with csv data.
type CSV struct {
	// source information.
	source resource
	// sink information
	sink resource
	// Variables consistent with stdlib's Reader struct in the csv package,
	// with the exception of csv.Reader.TrailingComma, which is ommitted
	// since it is ignored.
	//
	// Anything set here will override the Reader's default value set by
	// csv.NewReader(). Please check golang.org/pkg/encoding/csv for more
	// info about the variables.
	comma            rune
	comment          rune
	fieldsPerRecord  int
	lazyQuotes       bool
	trimLeadingSpace bool
	// hasHeader: whether the csv data includes a header row as its
	// first row. If the csv data does not include header data, the header
	// data must be provided via template, e.g. false implies
	// 'useFormat' == true. True does not have any implications on using
	// the format file.
	hasHeader bool
	// The csv file data:
	// headerRow contains the header row information. This is when a format
	// has been supplied, the header row information is set.
	headerRow []string
	// table is the parsed csv data
	rows [][]string
}

// NewCSV returns an initialize CSV object. It still needs to be configured
// for use.
func NewCSV() *CSV {
	C := &CSV{
		source:    resource{},
		sink:      resource{},
		hasHeader: true,
		headerRow: []string{},
		rows:      [][]string{},
	}
	return C
}

// NewCSVSource creates a new *CSV with its source set,
func NewCSVSource(s string) *CSV {
	c := NewCSV()
	c.SetSource(s)
	return c
}

// ReadAll takes a reader, and reads the data connected with it as CSV data.
// If there is a header row, CSV.hasHeader == true, the headerRow field is
// populated with the first row of the source.  This reads the entire file at
// once.  If an error occurs, it is returned
func (c *CSV) Read(r io.Reader) error {
	var err error
	cr := csv.NewReader(r)
	c.rows, err = cr.ReadAll()
	if err != nil {
		return err
	}
	if c.hasHeader {
		c.headerRow = c.rows[0]
		c.rows = c.rows[1:]
	}
	return nil
}

// ReadFile takes a path, reads the contents of the file and returns any error
// encountered. The entire file will be read at once.
func (c *CSV) ReadFile(f string) error {
	if f == "" {
		return ErrNoSource
	}
	file, err := os.Open(f)
	if err != nil {
		return err
	}
	// because we don't want to forget or worry about hanldling close prior
	// to every return.
	defer file.Close()
	// Read the file into csv
	return c.Read(file)
}

func (c *CSV) ReadSource() error {
	return c.ReadFile(c.source.String())
}

// SetSource sets the source and has the formatFile updated, if applicable.
func (c *CSV) SetSource(s string) {
	c.source = NewResource(s)
}

// Source returns the source string
func (c *CSV) Source() string {
	return c.source.String()
}

func (c *CSV) SetHasHeader(b bool) {
	c.hasHeader = b
}

// HasHeader returns the hasHeader bool
func (c *CSV) HasHeader() bool {
	return c.hasHeader
}

// HeaderRow returns the header row, if it exists.
func (c *CSV) HeaderRow() []string {
	return c.headerRow
}

// Rows returns the csv rows.
func (c *CSV) Rows() [][]string {
	return c.rows
}
<|endoftext|>


<commit_before>package convert

import (
	"fmt"
	"strconv"
)

func Int(val interface{}) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		case string:
			ret, err := strconv.Atoi(val.(string))
			if err != nil {
				return 0
			} else {
				return int64(ret)
			}
		}
	}
	return 0
}

func IntWith(val interface{}, defaultValue int64) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		case string:
			ret, err := strconv.Atoi(val.(string))
			if err == nil {
				return int64(ret)
			}
		}
	}
	return defaultValue
}

func String(val interface{}) string {
	switch val.(type) {
	case string:
		return val.(string)
	case []byte:
		return string(val.([]byte))
	case nil:
		return ""
	default:
		return fmt.Sprintf("%v", val)
	}
}
<commit_msg>Add MD5<commit_after>package convert

import (
	"crypto/md5"
	"fmt"
	"io"
	"strconv"
)

func Int(val interface{}) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		case string:
			ret, err := strconv.Atoi(val.(string))
			if err != nil {
				return 0
			} else {
				return int64(ret)
			}
		}
	}
	return 0
}

func IntWith(val interface{}, defaultValue int64) int64 {
	if val != nil {
		switch val.(type) {
		case float64:
			return int64(val.(float64))
		case int64:
			return val.(int64)
		case string:
			ret, err := strconv.Atoi(val.(string))
			if err == nil {
				return int64(ret)
			}
		}
	}
	return defaultValue
}

func String(val interface{}) string {
	switch val.(type) {
	case string:
		return val.(string)
	case []byte:
		return string(val.([]byte))
	case nil:
		return ""
	default:
		return fmt.Sprintf("%v", val)
	}
}

func MD5(src string) string {
	h := md5.New()
	io.WriteString(h, src)
	return h.Sum(nil)
}
<|endoftext|>


<commit_before>package actions

import (
	"net/http"
	"os"

	"github.com/gopheracademy/gcon/actions/admin"
	"github.com/gopheracademy/gcon/models"
	"github.com/markbates/buffalo"
	"github.com/markbates/buffalo/middleware"
	"github.com/markbates/going/defaults"
)

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() http.Handler {
	env := defaults.String(os.Getenv("GO_ENV"), "development")
	a := buffalo.Automatic(buffalo.Options{
		Env: env,
	})
	buffalo.Logger.Info("Environment", env)

	a.Use(middleware.PopTransaction(models.DB))
	a.ServeFiles("/assets", assetsPath())
	a.GET("/", HomeHandler)
	adm := a.Group("/admin")
	adm.GET("/", admin.AdminHandler)

	return a
}
<commit_msg>logger doesn't work the way you think it works<commit_after>package actions

import (
	"log"
	"net/http"
	"os"

	"github.com/gopheracademy/gcon/actions/admin"
	"github.com/gopheracademy/gcon/models"
	"github.com/markbates/buffalo"
	"github.com/markbates/buffalo/middleware"
	"github.com/markbates/going/defaults"
)

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() http.Handler {
	env := defaults.String(os.Getenv("GO_ENV"), "development")
	a := buffalo.Automatic(buffalo.Options{
		Env: env,
	})
	log.Println("Environment:", env)

	a.Use(middleware.PopTransaction(models.DB))
	a.ServeFiles("/assets", assetsPath())
	a.GET("/", HomeHandler)
	adm := a.Group("/admin")
	adm.GET("/", admin.AdminHandler)

	return a
}
<|endoftext|>


<commit_before>package actor

import (
	"github.com/morikuni/flower/log"
	"sync"
)

type Behavior interface {
	Init()
	Receive(self Actor, msg interface{})
}

type Actor interface {
	Path() Path
	Send() chan<- Message
	Monitor(target Actor)

	init()
	start()
	restart(reason interface{})
	stop()
	receive(msg Message)
}

type notifyMe struct {
	actor Actor
}

type actor struct {
	path     Path
	behavior Behavior
	monitors []Actor
	msgChan  chan Message
	stopChan chan struct{}

	mu      sync.Mutex
	running bool
}

func (actor *actor) Path() Path {
	return actor.path
}

func (actor *actor) Send() chan<- Message {
	return actor.msgChan
}

func (actor *actor) Monitor(target Actor) {
	target.Send() <- notifyMe{actor}
}

func (actor *actor) stop() {
	actor.mu.Lock()
	running := actor.running
	actor.running = false
	actor.mu.Unlock()
	if running {
		actor.stopChan <- struct{}{}
	}
}

func (actor *actor) init() {
	actor.behavior.Init()
}

func (actor *actor) start() {
	actor.mu.Lock()
	defer actor.mu.Unlock()
	if actor.running {
		return
	}
	actor.running = true
	log.Debug(actor.path, "start")
	go func() {
		defer func() {
			actor.mu.Lock()
			actor.running = false
			actor.mu.Unlock()
			log.Debug(actor.path, "stop")

			err := recover()
			if err != nil {
				p := Panic{
					Actor:  actor,
					Reason: err,
				}

				for _, m := range actor.monitors {
					m.Send() <- p
				}
			}
		}()

	LOOP:
		for {
			select {
			case msg := <-actor.msgChan:
				actor.receive(msg)
			case <-actor.stopChan:
				break LOOP
			}
		}
	}()
}

func (actor *actor) restart(_ interface{}) {
	actor.init()
	actor.start()
}

func (actor *actor) receive(msg Message) {
	if req, ok := msg.(notifyMe); ok {
		actor.monitors = append(actor.monitors, req.actor)
		log.Debug(actor.path, "notify events to", req.actor.Path())
		return
	}
	actor.behavior.Receive(actor, msg)
}

func newActor(name string, behavior Behavior, path Path) *actor {
	a := &actor{
		path:     path.join(name),
		behavior: behavior,
		monitors: []Actor{},
		msgChan:  make(chan Message),
		stopChan: make(chan struct{}),
	}
	a.init()
	a.start()
	return a
}
<commit_msg>Actor.stop wait until actor stop<commit_after>package actor

import (
	"github.com/morikuni/flower/log"
	"sync"
)

type Behavior interface {
	Init()
	Receive(self Actor, msg interface{})
}

type Actor interface {
	Path() Path
	Send() chan<- Message
	Monitor(target Actor)

	init()
	start()
	restart(reason interface{})
	stop()
	receive(msg Message)
}

type notifyMe struct {
	actor Actor
}

type actor struct {
	path        Path
	behavior    Behavior
	monitors    []Actor
	msgChan     chan Message
	stopChan    chan struct{}
	stoppedChan chan struct{}

	mu      sync.Mutex
	running bool
}

func (actor *actor) Path() Path {
	return actor.path
}

func (actor *actor) Send() chan<- Message {
	return actor.msgChan
}

func (actor *actor) Monitor(target Actor) {
	target.Send() <- notifyMe{actor}
}

func (actor *actor) stop() {
	actor.mu.Lock()
	running := actor.running
	actor.mu.Unlock()
	if running {
		actor.stopChan <- struct{}{}
		<-actor.stoppedChan
	}
}

func (actor *actor) init() {
	actor.behavior.Init()
}

func (actor *actor) start() {
	actor.mu.Lock()
	defer actor.mu.Unlock()
	if actor.running {
		return
	}
	actor.running = true
	log.Debug(actor.path, "start")
	go func() {
		defer func() {
			actor.mu.Lock()
			actor.running = false
			actor.mu.Unlock()
			log.Debug(actor.path, "stop")

			err := recover()
			if err != nil {
				p := Panic{
					Actor:  actor,
					Reason: err,
				}

				for _, m := range actor.monitors {
					m.Send() <- p
				}
			} else {
				actor.stoppedChan <- struct{}{}
			}
		}()

	LOOP:
		for {
			select {
			case <-actor.stopChan:
				break LOOP
			case msg := <-actor.msgChan:
				actor.receive(msg)
			}
		}
	}()
}

func (actor *actor) restart(_ interface{}) {
	actor.init()
	actor.start()
}

func (actor *actor) receive(msg Message) {
	if req, ok := msg.(notifyMe); ok {
		actor.monitors = append(actor.monitors, req.actor)
		log.Debug(actor.path, "notify events to", req.actor.Path())
		return
	}
	actor.behavior.Receive(actor, msg)
}

func newActor(name string, behavior Behavior, path Path) *actor {
	a := &actor{
		path:        path.join(name),
		behavior:    behavior,
		monitors:    []Actor{},
		msgChan:     make(chan Message),
		stopChan:    make(chan struct{}),
		stoppedChan: make(chan struct{}),
	}
	a.init()
	a.start()
	return a
}
<|endoftext|>


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

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"

	"golang.org/x/net/context"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/driveactivity/v2"
)

// Retrieve a token, saves the token, then returns the generated client.
func getClient(config *oauth2.Config) *http.Client {
	// The file token.json stores the user's access and refresh tokens, and is
	// created automatically when the authorization flow completes for the first
	// time.
	tokFile := "token.json"
	tok, err := tokenFromFile(tokFile)
	if err != nil {
		tok = getTokenFromWeb(config)
		saveToken(tokFile, tok)
	}
	return config.Client(context.Background(), tok)
}

// Request a token from the web, then returns the retrieved token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
	fmt.Printf("Go to the following link in your browser then type the "+
		"authorization code: \n%v\n", authURL)

	var authCode string
	if _, err := fmt.Scan(&authCode); err != nil {
		log.Fatalf("Unable to read authorization code: %v", err)
	}

	tok, err := config.Exchange(context.TODO(), authCode)
	if err != nil {
		log.Fatalf("Unable to retrieve token from web: %v", err)
	}
	return tok
}

// Retrieves a token from a local file.
func tokenFromFile(file string) (*oauth2.Token, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	tok := &oauth2.Token{}
	err = json.NewDecoder(f).Decode(tok)
	return tok, err
}

// Saves a token to a file path.
func saveToken(path string, token *oauth2.Token) {
	fmt.Printf("Saving credential file to: %s\n", path)
	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		log.Fatalf("Unable to cache oauth token: %v", err)
	}
	defer f.Close()
	json.NewEncoder(f).Encode(token)
}

// Returns a string representation of the first elements in a list.
func truncated(array []string) string {
	return truncatedTo(array, 2)
}

// Returns a string representation of the first elements in a list.
func truncatedTo(array []string, limit int) string {
	var contents string
	var more string
	if len(array) <= limit {
		contents = strings.Join(array, ", ")
		more = ""
	} else {
		contents = strings.Join(array[0:limit], ", ")
		more = ", ..."
	}
	return fmt.Sprintf("[%s%s]", contents, more)
}

// Returns the name of a set property in an object, or else "unknown".
func getOneOf(m interface{}) string {
	v := reflect.ValueOf(m)
	for i := 0; i < v.NumField(); i++ {
		if !v.Field(i).IsNil() {
			return v.Type().Field(i).Name
		}
	}
	return "unknown"
}

// Returns a time associated with an activity.
func getTimeInfo(activity *driveactivity.DriveActivity) string {
	if activity.Timestamp != "" {
		return activity.Timestamp
	}
	if activity.TimeRange != nil {
		return activity.TimeRange.EndTime
	}
	return "unknown"
}

// Returns the type of action.
func getActionInfo(action *driveactivity.ActionDetail) string {
	return getOneOf(*action)
}

// Returns user information, or the type of user if not a known user.
func getUserInfo(user *driveactivity.User) string {
	if user.KnownUser != nil {
		if user.KnownUser.IsCurrentUser {
			return "people/me"
		}
		return user.KnownUser.PersonName
	}
	return getOneOf(*user)
}

// Returns actor information, or the type of actor if not a user.
func getActorInfo(actor *driveactivity.Actor) string {
	if actor.User != nil {
		return getUserInfo(actor.User)
	}
	return getOneOf(*actor)
}

// Returns information for a list of actors.
func getActorsInfo(actors []*driveactivity.Actor) []string {
	actorsInfo := make([]string, len(actors))
	for i := range actors {
		actorsInfo[i] = getActorInfo(actors[i])
	}
	return actorsInfo
}

// Returns the type of a target and an associated title.
func getTargetInfo(target *driveactivity.Target) string {
	if target.DriveItem != nil {
		return fmt.Sprintf("driveItem:\"%s\"", target.DriveItem.Title)
	}
	if target.TeamDrive != nil {
		return fmt.Sprintf("teamDrive:\"%s\"", target.TeamDrive.Title)
	}
	if target.FileComment != nil {
		parent := target.FileComment.Parent
		if parent != nil {
			return fmt.Sprintf("fileComment:\"%s\"", parent.Title)
		}
		return "fileComment:unknown"
	}
	return getOneOf(*target)
}

// Returns information for a list of targets.
func getTargetsInfo(targets []*driveactivity.Target) []string {
	targetsInfo := make([]string, len(targets))
	for i := range targets {
		targetsInfo[i] = getTargetInfo(targets[i])
	}
	return targetsInfo
}

func main() {
	b, err := ioutil.ReadFile("credentials.json")
	if err != nil {
		log.Fatalf("Unable to read client secret file: %v", err)
	}

	// If modifying these scopes, delete your previously saved token.json.
	config, err := google.ConfigFromJSON(b, driveactivity.DriveActivityReadonlyScope)
	if err != nil {
		log.Fatalf("Unable to parse client secret file to config: %v", err)
	}
	client := getClient(config)

	srv, err := driveactivity.New(client)
	if err != nil {
		log.Fatalf("Unable to retrieve driveactivity Client %v", err)
	}

	q := driveactivity.QueryDriveActivityRequest{PageSize: 10}
	r, err := srv.Activity.Query(&q).Do()
	if err != nil {
		log.Fatalf("Unable to retrieve list of activities. %v", err)
	}

	fmt.Println("Recent Activity:")
	if len(r.Activities) > 0 {
		for _, a := range r.Activities {
			time := getTimeInfo(a)
			action := getActionInfo(a.PrimaryActionDetail)
			actors := getActorsInfo(a.Actors)
			targets := getTargetsInfo(a.Targets)
			fmt.Printf("%s: %s, %s, %s\n", time, truncated(actors), action, truncated(targets))
		}
	} else {
		fmt.Print("No activity.")
	}
}

// [END drive_activity_v2_quickstart]
<commit_msg>Update Drive Activity v2 sample code to use the new "drive" elements.<commit_after>/**
 * @license
 * Copyright Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// [START drive_activity_v2_quickstart]
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"

	"golang.org/x/net/context"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/driveactivity/v2"
)

// Retrieve a token, saves the token, then returns the generated client.
func getClient(config *oauth2.Config) *http.Client {
	// The file token.json stores the user's access and refresh tokens, and is
	// created automatically when the authorization flow completes for the first
	// time.
	tokFile := "token.json"
	tok, err := tokenFromFile(tokFile)
	if err != nil {
		tok = getTokenFromWeb(config)
		saveToken(tokFile, tok)
	}
	return config.Client(context.Background(), tok)
}

// Request a token from the web, then returns the retrieved token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
	fmt.Printf("Go to the following link in your browser then type the "+
		"authorization code: \n%v\n", authURL)

	var authCode string
	if _, err := fmt.Scan(&authCode); err != nil {
		log.Fatalf("Unable to read authorization code: %v", err)
	}

	tok, err := config.Exchange(context.TODO(), authCode)
	if err != nil {
		log.Fatalf("Unable to retrieve token from web: %v", err)
	}
	return tok
}

// Retrieves a token from a local file.
func tokenFromFile(file string) (*oauth2.Token, error) {
	f, err := os.Open(file)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	tok := &oauth2.Token{}
	err = json.NewDecoder(f).Decode(tok)
	return tok, err
}

// Saves a token to a file path.
func saveToken(path string, token *oauth2.Token) {
	fmt.Printf("Saving credential file to: %s\n", path)
	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		log.Fatalf("Unable to cache oauth token: %v", err)
	}
	defer f.Close()
	json.NewEncoder(f).Encode(token)
}

// Returns a string representation of the first elements in a list.
func truncated(array []string) string {
	return truncatedTo(array, 2)
}

// Returns a string representation of the first elements in a list.
func truncatedTo(array []string, limit int) string {
	var contents string
	var more string
	if len(array) <= limit {
		contents = strings.Join(array, ", ")
		more = ""
	} else {
		contents = strings.Join(array[0:limit], ", ")
		more = ", ..."
	}
	return fmt.Sprintf("[%s%s]", contents, more)
}

// Returns the name of a set property in an object, or else "unknown".
func getOneOf(m interface{}) string {
	v := reflect.ValueOf(m)
	for i := 0; i < v.NumField(); i++ {
		if !v.Field(i).IsNil() {
			return v.Type().Field(i).Name
		}
	}
	return "unknown"
}

// Returns a time associated with an activity.
func getTimeInfo(activity *driveactivity.DriveActivity) string {
	if activity.Timestamp != "" {
		return activity.Timestamp
	}
	if activity.TimeRange != nil {
		return activity.TimeRange.EndTime
	}
	return "unknown"
}

// Returns the type of action.
func getActionInfo(action *driveactivity.ActionDetail) string {
	return getOneOf(*action)
}

// Returns user information, or the type of user if not a known user.
func getUserInfo(user *driveactivity.User) string {
	if user.KnownUser != nil {
		if user.KnownUser.IsCurrentUser {
			return "people/me"
		}
		return user.KnownUser.PersonName
	}
	return getOneOf(*user)
}

// Returns actor information, or the type of actor if not a user.
func getActorInfo(actor *driveactivity.Actor) string {
	if actor.User != nil {
		return getUserInfo(actor.User)
	}
	return getOneOf(*actor)
}

// Returns information for a list of actors.
func getActorsInfo(actors []*driveactivity.Actor) []string {
	actorsInfo := make([]string, len(actors))
	for i := range actors {
		actorsInfo[i] = getActorInfo(actors[i])
	}
	return actorsInfo
}

// Returns the type of a target and an associated title.
func getTargetInfo(target *driveactivity.Target) string {
	if target.DriveItem != nil {
		return fmt.Sprintf("driveItem:\"%s\"", target.DriveItem.Title)
	}
	if target.Drive != nil {
		return fmt.Sprintf("drive:\"%s\"", target.Drive.Title)
	}
	if target.FileComment != nil {
		parent := target.FileComment.Parent
		if parent != nil {
			return fmt.Sprintf("fileComment:\"%s\"", parent.Title)
		}
		return "fileComment:unknown"
	}
	return getOneOf(*target)
}

// Returns information for a list of targets.
func getTargetsInfo(targets []*driveactivity.Target) []string {
	targetsInfo := make([]string, len(targets))
	for i := range targets {
		targetsInfo[i] = getTargetInfo(targets[i])
	}
	return targetsInfo
}

func main() {
	b, err := ioutil.ReadFile("credentials.json")
	if err != nil {
		log.Fatalf("Unable to read client secret file: %v", err)
	}

	// If modifying these scopes, delete your previously saved token.json.
	config, err := google.ConfigFromJSON(b, driveactivity.DriveActivityReadonlyScope)
	if err != nil {
		log.Fatalf("Unable to parse client secret file to config: %v", err)
	}
	client := getClient(config)

	srv, err := driveactivity.New(client)
	if err != nil {
		log.Fatalf("Unable to retrieve driveactivity Client %v", err)
	}

	q := driveactivity.QueryDriveActivityRequest{PageSize: 10}
	r, err := srv.Activity.Query(&q).Do()
	if err != nil {
		log.Fatalf("Unable to retrieve list of activities. %v", err)
	}

	fmt.Println("Recent Activity:")
	if len(r.Activities) > 0 {
		for _, a := range r.Activities {
			time := getTimeInfo(a)
			action := getActionInfo(a.PrimaryActionDetail)
			actors := getActorsInfo(a.Actors)
			targets := getTargetsInfo(a.Targets)
			fmt.Printf("%s: %s, %s, %s\n", time, truncated(actors), action, truncated(targets))
		}
	} else {
		fmt.Print("No activity.")
	}
}

// [END drive_activity_v2_quickstart]
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"os"
	"path/filepath"
	"regexp"
	"time"
)

var (
	ErrModified = errors.New("modified")
)

type FileInfo struct {
	Path string
	os.FileInfo
}

type WalkFunc func(<-chan struct{}, <-chan FileInfo, chan<- error)

func walkAll(paths []string, walkFn filepath.WalkFunc) error {
	for _, path := range paths {
		if err := walk(path, walkFn); err != nil {
			return err
		}
	}
	return nil
}

func walk(path string, walkFn filepath.WalkFunc) error {
	var (
		stack   []*FileInfo
		current *FileInfo
	)

	info, err := os.Lstat(path)
	if err != nil || !info.IsDir() {
		return walkFn(path, info, err)
	}

	stack = append(stack, &FileInfo{path, info})

	for pos := len(stack) - 1; pos > -1; pos = len(stack) - 1 {
		current, stack = stack[pos], stack[:pos]

		if err := walkFn(current.Path, current, nil); err != nil {
			if err != filepath.SkipDir {
				return err
			}
			continue
		}

		infos, err := readdir(current.Path)

		if err != nil {
			return err
		}

		for _, info := range infos {
			sub := filepath.Join(current.Path, info.Name())

			if info.IsDir() {
				stack = append(stack, &FileInfo{sub, info})
			} else if err := walkFn(sub, info, nil); err != nil && err != filepath.SkipDir {
				return err
			}
		}
	}

	return nil
}

func readdir(path string) ([]os.FileInfo, error) {
	f, err := os.Open(path)

	if err != nil {
		return nil, err
	}

	defer f.Close()

	return f.Readdir(-1)
}

func ModifiedSince(since time.Time, ignore *regexp.Regexp, files ...string) (bool, error) {
	err := walkAll(files, func(path string, info os.FileInfo, err error) error {
		if ignore != nil && ignore.MatchString(info.Name()) {
			if info.IsDir() {
				return filepath.SkipDir
			}

			return nil
		}

		if info.ModTime().After(since) {
			return ErrModified
		}

		return nil
	})

	if err == filepath.SkipDir {
		return false, nil
	}

	if err == ErrModified {
		return true, nil
	}

	return false, err
}
<commit_msg>Ignore error from readdir<commit_after>package main

import (
	"errors"
	"os"
	"path/filepath"
	"regexp"
	"time"
)

var (
	ErrModified = errors.New("modified")
)

type FileInfo struct {
	Path string
	os.FileInfo
}

type WalkFunc func(<-chan struct{}, <-chan FileInfo, chan<- error)

func walkAll(paths []string, walkFn filepath.WalkFunc) error {
	for _, path := range paths {
		if err := walk(path, walkFn); err != nil {
			return err
		}
	}
	return nil
}

func walk(path string, walkFn filepath.WalkFunc) error {
	var (
		stack   []*FileInfo
		current *FileInfo
	)

	info, err := os.Lstat(path)
	if err != nil || !info.IsDir() {
		return walkFn(path, info, err)
	}

	stack = append(stack, &FileInfo{path, info})

	for pos := len(stack) - 1; pos > -1; pos = len(stack) - 1 {
		current, stack = stack[pos], stack[:pos]

		if err := walkFn(current.Path, current, nil); err != nil {
			if err != filepath.SkipDir {
				return err
			}
			continue
		}

		infos, _ := readdir(current.Path)

		for _, info := range infos {
			sub := filepath.Join(current.Path, info.Name())

			if info.IsDir() {
				stack = append(stack, &FileInfo{sub, info})
			} else if err := walkFn(sub, info, nil); err != nil && err != filepath.SkipDir {
				return err
			}
		}
	}

	return nil
}

func readdir(path string) ([]os.FileInfo, error) {
	f, err := os.Open(path)

	if err != nil {
		return nil, err
	}

	defer f.Close()

	return f.Readdir(-1)
}

func ModifiedSince(since time.Time, ignore *regexp.Regexp, files ...string) (bool, error) {
	err := walkAll(files, func(path string, info os.FileInfo, err error) error {
		if ignore != nil && ignore.MatchString(info.Name()) {
			if info.IsDir() {
				return filepath.SkipDir
			}

			return nil
		}

		if info.ModTime().After(since) {
			return ErrModified
		}

		return nil
	})

	if err == filepath.SkipDir {
		return false, nil
	}

	if err == ErrModified {
		return true, nil
	}

	return false, err
}
<|endoftext|>


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

package strings_test

import (
	"fmt"
	"strings"
	"unicode"
)

func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
	// Output: Fields are: ["foo" "bar" "baz"]
}

func ExampleFieldsFunc() {
	f := func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
	}
	fmt.Printf("Fields are: %q", strings.FieldsFunc("  foo1;bar2,baz3...", f))
	// Output: Fields are: ["foo1" "bar2" "baz3"]
}

func ExampleContains() {
	fmt.Println(strings.Contains("seafood", "foo"))
	fmt.Println(strings.Contains("seafood", "bar"))
	fmt.Println(strings.Contains("seafood", ""))
	fmt.Println(strings.Contains("", ""))
	// Output:
	// true
	// false
	// true
	// true
}

func ExampleContainsAny() {
	fmt.Println(strings.ContainsAny("team", "i"))
	fmt.Println(strings.ContainsAny("failure", "u & i"))
	fmt.Println(strings.ContainsAny("foo", ""))
	fmt.Println(strings.ContainsAny("", ""))
	// Output:
	// false
	// true
	// false
	// false
}

func ExampleContainsRune() {
	// Finds whether a string contains a particular Unicode code point.
	// The code point for the lowercase letter "a", for example, is 97.
	fmt.Println(strings.ContainsRune("aardvark", 97))
	fmt.Println(strings.ContainsRune("timeout", 97))
	// Output:
	// true
	// false
}

func ExampleCount() {
	fmt.Println(strings.Count("cheese", "e"))
	fmt.Println(strings.Count("five", "")) // before & after each rune
	// Output:
	// 3
	// 5
}

func ExampleEqualFold() {
	fmt.Println(strings.EqualFold("Go", "go"))
	// Output: true
}

func ExampleHasPrefix() {
	fmt.Println(strings.HasPrefix("Gopher", "Go"))
	fmt.Println(strings.HasPrefix("Gopher", "C"))
	fmt.Println(strings.HasPrefix("Gopher", ""))
	// Output:
	// true
	// false
	// true
}

func ExampleHasSuffix() {
	fmt.Println(strings.HasSuffix("Amigo", "go"))
	fmt.Println(strings.HasSuffix("Amigo", "O"))
	fmt.Println(strings.HasSuffix("Amigo", "Ami"))
	fmt.Println(strings.HasSuffix("Amigo", ""))
	// Output:
	// true
	// false
	// false
	// true
}

func ExampleIndex() {
	fmt.Println(strings.Index("chicken", "ken"))
	fmt.Println(strings.Index("chicken", "dmr"))
	// Output:
	// 4
	// -1
}

func ExampleIndexFunc() {
	f := func(c rune) bool {
		return unicode.Is(unicode.Han, c)
	}
	fmt.Println(strings.IndexFunc("Hello, 世界", f))
	fmt.Println(strings.IndexFunc("Hello, world", f))
	// Output:
	// 7
	// -1
}

func ExampleIndexAny() {
	fmt.Println(strings.IndexAny("chicken", "aeiouy"))
	fmt.Println(strings.IndexAny("crwth", "aeiouy"))
	// Output:
	// 2
	// -1
}

func ExampleIndexByte() {
	fmt.Println(strings.IndexByte("golang", 'g'))
	fmt.Println(strings.IndexByte("gophers", 'h'))
	fmt.Println(strings.IndexByte("golang", 'x'))
	// Output:
	// 0
	// 3
	// -1
}
func ExampleIndexRune() {
	fmt.Println(strings.IndexRune("chicken", 'k'))
	fmt.Println(strings.IndexRune("chicken", 'd'))
	// Output:
	// 4
	// -1
}

func ExampleLastIndex() {
	fmt.Println(strings.Index("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "rodent"))
	// Output:
	// 0
	// 3
	// -1
}

func ExampleLastIndexAny() {
	fmt.Println(strings.LastIndexAny("go gopher", "go"))
	fmt.Println(strings.LastIndexAny("go gopher", "rodent"))
	fmt.Println(strings.LastIndexAny("go gopher", "fail"))
	// Output:
	// 4
	// 8
	// -1
}

func ExampleJoin() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
	// Output: foo, bar, baz
}

func ExampleRepeat() {
	fmt.Println("ba" + strings.Repeat("na", 2))
	// Output: banana
}

func ExampleReplace() {
	fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
	fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
	// Output:
	// oinky oinky oink
	// moo moo moo
}

func ExampleSplit() {
	fmt.Printf("%q\n", strings.Split("a,b,c", ","))
	fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
	fmt.Printf("%q\n", strings.Split(" xyz ", ""))
	fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
	// Output:
	// ["a" "b" "c"]
	// ["" "man " "plan " "canal panama"]
	// [" " "x" "y" "z" " "]
	// [""]
}

func ExampleSplitN() {
	fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
	z := strings.SplitN("a,b,c", ",", 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
	// Output:
	// ["a" "b,c"]
	// [] (nil = true)
}

func ExampleSplitAfter() {
	fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
	// Output: ["a," "b," "c"]
}

func ExampleSplitAfterN() {
	fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
	// Output: ["a," "b,c"]
}

func ExampleTitle() {
	fmt.Println(strings.Title("her royal highness"))
	// Output: Her Royal Highness
}

func ExampleToTitle() {
	fmt.Println(strings.ToTitle("loud noises"))
	fmt.Println(strings.ToTitle("хлеб"))
	// Output:
	// LOUD NOISES
	// ХЛЕБ
}

func ExampleTrim() {
	fmt.Printf("[%q]", strings.Trim(" !!! Achtung! Achtung! !!! ", "! "))
	// Output: ["Achtung! Achtung"]
}

func ExampleMap() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
}

func ExampleTrimSpace() {
	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
	// Output: a lone gopher
}

func ExampleNewReplacer() {
	r := strings.NewReplacer("<", "<", ">", ">")
	fmt.Println(r.Replace("This is HTML!"))
	// Output: This is <b>HTML</b>!
}

func ExampleToUpper() {
	fmt.Println(strings.ToUpper("Gopher"))
	// Output: GOPHER
}

func ExampleToLower() {
	fmt.Println(strings.ToLower("Gopher"))
	// Output: gopher
}

func ExampleTrimSuffix() {
	var s = "Hello, goodbye, etc!"
	s = strings.TrimSuffix(s, "goodbye, etc!")
	s = strings.TrimSuffix(s, "planet")
	fmt.Print(s, "world!")
	// Output: Hello, world!
}

func ExampleTrimPrefix() {
	var s = "Goodbye,, world!"
	s = strings.TrimPrefix(s, "Goodbye,")
	s = strings.TrimPrefix(s, "Howdy,")
	fmt.Print("Hello" + s)
	// Output: Hello, world!
}
<commit_msg>strings: add a example for Compare func<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package strings_test

import (
	"fmt"
	"strings"
	"unicode"
)

func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
	// Output: Fields are: ["foo" "bar" "baz"]
}

func ExampleFieldsFunc() {
	f := func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
	}
	fmt.Printf("Fields are: %q", strings.FieldsFunc("  foo1;bar2,baz3...", f))
	// Output: Fields are: ["foo1" "bar2" "baz3"]
}

func ExampleCompare() {
	fmt.Println(strings.Compare("a", "b"))
	fmt.Println(strings.Compare("a", "a"))
	fmt.Println(strings.Compare("b", "a"))
	// Output:
	// -1
	// 0
	// 1
}

func ExampleContains() {
	fmt.Println(strings.Contains("seafood", "foo"))
	fmt.Println(strings.Contains("seafood", "bar"))
	fmt.Println(strings.Contains("seafood", ""))
	fmt.Println(strings.Contains("", ""))
	// Output:
	// true
	// false
	// true
	// true
}

func ExampleContainsAny() {
	fmt.Println(strings.ContainsAny("team", "i"))
	fmt.Println(strings.ContainsAny("failure", "u & i"))
	fmt.Println(strings.ContainsAny("foo", ""))
	fmt.Println(strings.ContainsAny("", ""))
	// Output:
	// false
	// true
	// false
	// false
}

func ExampleContainsRune() {
	// Finds whether a string contains a particular Unicode code point.
	// The code point for the lowercase letter "a", for example, is 97.
	fmt.Println(strings.ContainsRune("aardvark", 97))
	fmt.Println(strings.ContainsRune("timeout", 97))
	// Output:
	// true
	// false
}

func ExampleCount() {
	fmt.Println(strings.Count("cheese", "e"))
	fmt.Println(strings.Count("five", "")) // before & after each rune
	// Output:
	// 3
	// 5
}

func ExampleEqualFold() {
	fmt.Println(strings.EqualFold("Go", "go"))
	// Output: true
}

func ExampleHasPrefix() {
	fmt.Println(strings.HasPrefix("Gopher", "Go"))
	fmt.Println(strings.HasPrefix("Gopher", "C"))
	fmt.Println(strings.HasPrefix("Gopher", ""))
	// Output:
	// true
	// false
	// true
}

func ExampleHasSuffix() {
	fmt.Println(strings.HasSuffix("Amigo", "go"))
	fmt.Println(strings.HasSuffix("Amigo", "O"))
	fmt.Println(strings.HasSuffix("Amigo", "Ami"))
	fmt.Println(strings.HasSuffix("Amigo", ""))
	// Output:
	// true
	// false
	// false
	// true
}

func ExampleIndex() {
	fmt.Println(strings.Index("chicken", "ken"))
	fmt.Println(strings.Index("chicken", "dmr"))
	// Output:
	// 4
	// -1
}

func ExampleIndexFunc() {
	f := func(c rune) bool {
		return unicode.Is(unicode.Han, c)
	}
	fmt.Println(strings.IndexFunc("Hello, 世界", f))
	fmt.Println(strings.IndexFunc("Hello, world", f))
	// Output:
	// 7
	// -1
}

func ExampleIndexAny() {
	fmt.Println(strings.IndexAny("chicken", "aeiouy"))
	fmt.Println(strings.IndexAny("crwth", "aeiouy"))
	// Output:
	// 2
	// -1
}

func ExampleIndexByte() {
	fmt.Println(strings.IndexByte("golang", 'g'))
	fmt.Println(strings.IndexByte("gophers", 'h'))
	fmt.Println(strings.IndexByte("golang", 'x'))
	// Output:
	// 0
	// 3
	// -1
}
func ExampleIndexRune() {
	fmt.Println(strings.IndexRune("chicken", 'k'))
	fmt.Println(strings.IndexRune("chicken", 'd'))
	// Output:
	// 4
	// -1
}

func ExampleLastIndex() {
	fmt.Println(strings.Index("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "rodent"))
	// Output:
	// 0
	// 3
	// -1
}

func ExampleLastIndexAny() {
	fmt.Println(strings.LastIndexAny("go gopher", "go"))
	fmt.Println(strings.LastIndexAny("go gopher", "rodent"))
	fmt.Println(strings.LastIndexAny("go gopher", "fail"))
	// Output:
	// 4
	// 8
	// -1
}

func ExampleJoin() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
	// Output: foo, bar, baz
}

func ExampleRepeat() {
	fmt.Println("ba" + strings.Repeat("na", 2))
	// Output: banana
}

func ExampleReplace() {
	fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
	fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
	// Output:
	// oinky oinky oink
	// moo moo moo
}

func ExampleSplit() {
	fmt.Printf("%q\n", strings.Split("a,b,c", ","))
	fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
	fmt.Printf("%q\n", strings.Split(" xyz ", ""))
	fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
	// Output:
	// ["a" "b" "c"]
	// ["" "man " "plan " "canal panama"]
	// [" " "x" "y" "z" " "]
	// [""]
}

func ExampleSplitN() {
	fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
	z := strings.SplitN("a,b,c", ",", 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
	// Output:
	// ["a" "b,c"]
	// [] (nil = true)
}

func ExampleSplitAfter() {
	fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
	// Output: ["a," "b," "c"]
}

func ExampleSplitAfterN() {
	fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
	// Output: ["a," "b,c"]
}

func ExampleTitle() {
	fmt.Println(strings.Title("her royal highness"))
	// Output: Her Royal Highness
}

func ExampleToTitle() {
	fmt.Println(strings.ToTitle("loud noises"))
	fmt.Println(strings.ToTitle("хлеб"))
	// Output:
	// LOUD NOISES
	// ХЛЕБ
}

func ExampleTrim() {
	fmt.Printf("[%q]", strings.Trim(" !!! Achtung! Achtung! !!! ", "! "))
	// Output: ["Achtung! Achtung"]
}

func ExampleMap() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
}

func ExampleTrimSpace() {
	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
	// Output: a lone gopher
}

func ExampleNewReplacer() {
	r := strings.NewReplacer("<", "<", ">", ">")
	fmt.Println(r.Replace("This is HTML!"))
	// Output: This is <b>HTML</b>!
}

func ExampleToUpper() {
	fmt.Println(strings.ToUpper("Gopher"))
	// Output: GOPHER
}

func ExampleToLower() {
	fmt.Println(strings.ToLower("Gopher"))
	// Output: gopher
}

func ExampleTrimSuffix() {
	var s = "Hello, goodbye, etc!"
	s = strings.TrimSuffix(s, "goodbye, etc!")
	s = strings.TrimSuffix(s, "planet")
	fmt.Print(s, "world!")
	// Output: Hello, world!
}

func ExampleTrimPrefix() {
	var s = "Goodbye,, world!"
	s = strings.TrimPrefix(s, "Goodbye,")
	s = strings.TrimPrefix(s, "Howdy,")
	fmt.Print("Hello" + s)
	// Output: Hello, world!
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net"
	"strconv"
	"strings"
	"time"

	"github.com/miekg/dns"
)

var dnsBinding = flag.String("dnsbind", "",
	"address to bind dns server to")
var dnsZone = flag.String("dnszone", "cbfs.",
	"DNS Zone for msgs/responses")

const cbfsSvc = "_cbfs._tcp"

const maxDnsResponses = 8

type dnsService struct{}

func (d dnsService) serviceDomain() string {
	return cbfsSvc + "." + *dnsZone
}

func (d dnsService) srvList(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	nl, err := findAllNodes()
	if err != nil {
		log.Printf("Error finding nodes: %v", err)
		return
	}

	for i, n := range nl {
		_, p, err := net.SplitHostPort(n.Address())
		if err != nil {
			continue
		}
		port := 8484
		tmp, err := strconv.Atoi(p)
		if err == nil {
			port = tmp
		}

		rr := &dns.RR_SRV{
			Hdr: dns.RR_Header{
				Name:   d.serviceDomain(),
				Rrtype: dns.TypeSRV,
				Class:  dns.ClassINET,
				Ttl:    5},
			Priority: uint16(i),
			Weight:   uint16(time.Since(n.Time).Seconds()),
			Port:     uint16(port),
			Target:   n.name + "." + *dnsZone,
		}

		msg.Answer = append(msg.Answer, rr)
		if len(msg.Answer) > maxDnsResponses {
			break
		}
	}

	msg.SetReply(r)
	w.Write(msg)
}

func (d dnsService) hostLookup(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	name := r.Question[0].Name
	name = name[:len(name)-len(*dnsZone)-1]

	node, err := findNode(name)
	if err == nil {
		msg.Answer = []dns.RR{&dns.RR_A{
			Hdr: dns.RR_Header{
				Name:   r.Question[0].Name,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    60,
			},
			A: net.ParseIP(node.Addr),
		}}
		msg.SetReply(r)
	} else {
		msg.SetRcode(r, dns.RcodeNameError)
	}

	w.Write(msg)
}

func (d dnsService) listHosts(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	nl, err := findAllNodes()
	if err != nil {
		log.Printf("Error finding nodes: %v", err)
		return
	}

	for _, n := range nl {
		rr := &dns.RR_A{
			Hdr: dns.RR_Header{
				Name:   *dnsZone,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    5},
			A: net.ParseIP(n.Addr),
		}

		msg.Answer = append(msg.Answer, rr)
		if len(msg.Answer) > maxDnsResponses {
			break
		}
	}

	msg.SetReply(r)
	w.Write(msg)
}

func (d dnsService) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
	q := dns.Question{}

	if len(r.Question) == 1 &&
		strings.HasSuffix(r.Question[0].Name, *dnsZone) {
		q = r.Question[0]
	}

	switch q.Qtype {
	case dns.TypeSRV:
		d.srvList(w, r)
	case dns.TypeA, dns.TypeANY:
		if q.Name == *dnsZone {
			d.listHosts(w, r)
		} else {
			d.hostLookup(w, r)
		}
	default:
		msg := &dns.Msg{}
		msg.SetRcode(r, dns.RcodeNotImplemented)
		w.Write(msg)
	}
}

func dnsServices() {
	if *dnsBinding == "" {
		return
	}

	log.Printf("Starting DNS services on %v.", *dnsBinding)

	d := dnsService{}

	serv := dns.Server{
		Net:     "udp",
		Addr:    *dnsBinding,
		Handler: d,
	}

	err := serv.ListenAndServe()
	if err != nil {
		log.Fatalf("DNS server failure: %v", err)
	}
}
<commit_msg>Include node resolution in SRV response extra section.<commit_after>package main

import (
	"flag"
	"log"
	"net"
	"strconv"
	"strings"
	"time"

	"github.com/miekg/dns"
)

var dnsBinding = flag.String("dnsbind", "",
	"address to bind dns server to")
var dnsZone = flag.String("dnszone", "cbfs.",
	"DNS Zone for msgs/responses")

const cbfsSvc = "_cbfs._tcp"

const maxDnsResponses = 8

type dnsService struct{}

func (d dnsService) serviceDomain() string {
	return cbfsSvc + "." + *dnsZone
}

func (d dnsService) srvList(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	nl, err := findAllNodes()
	if err != nil {
		log.Printf("Error finding nodes: %v", err)
		return
	}

	for i, n := range nl {
		_, p, err := net.SplitHostPort(n.Address())
		if err != nil {
			continue
		}
		port := 8484
		tmp, err := strconv.Atoi(p)
		if err == nil {
			port = tmp
		}

		rr := &dns.RR_SRV{
			Hdr: dns.RR_Header{
				Name:   d.serviceDomain(),
				Rrtype: dns.TypeSRV,
				Class:  dns.ClassINET,
				Ttl:    5},
			Priority: uint16(i),
			Weight:   uint16(time.Since(n.Time).Seconds()),
			Port:     uint16(port),
			Target:   n.name + "." + *dnsZone,
		}
		msg.Answer = append(msg.Answer, rr)

		arr := &dns.RR_A{
			Hdr: dns.RR_Header{
				Name:   n.name + "." + *dnsZone,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    60,
			},
			A: net.ParseIP(n.Addr),
		}

		msg.Extra = append(msg.Extra, arr)

		if len(msg.Answer) > maxDnsResponses {
			break
		}
	}

	msg.SetReply(r)
	w.Write(msg)
}

func (d dnsService) hostLookup(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	name := r.Question[0].Name
	name = name[:len(name)-len(*dnsZone)-1]

	node, err := findNode(name)
	if err == nil {
		msg.Answer = []dns.RR{&dns.RR_A{
			Hdr: dns.RR_Header{
				Name:   r.Question[0].Name,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    60,
			},
			A: net.ParseIP(node.Addr),
		}}
		msg.SetReply(r)
	} else {
		msg.SetRcode(r, dns.RcodeNameError)
	}

	w.Write(msg)
}

func (d dnsService) listHosts(w dns.ResponseWriter, r *dns.Msg) {
	msg := &dns.Msg{}

	nl, err := findAllNodes()
	if err != nil {
		log.Printf("Error finding nodes: %v", err)
		return
	}

	for _, n := range nl {
		rr := &dns.RR_A{
			Hdr: dns.RR_Header{
				Name:   *dnsZone,
				Rrtype: dns.TypeA,
				Class:  dns.ClassINET,
				Ttl:    5},
			A: net.ParseIP(n.Addr),
		}

		msg.Answer = append(msg.Answer, rr)
		if len(msg.Answer) > maxDnsResponses {
			break
		}
	}

	msg.SetReply(r)
	w.Write(msg)
}

func (d dnsService) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
	q := dns.Question{}

	if len(r.Question) == 1 &&
		strings.HasSuffix(r.Question[0].Name, *dnsZone) {
		q = r.Question[0]
	}

	switch q.Qtype {
	case dns.TypeSRV:
		d.srvList(w, r)
	case dns.TypeA, dns.TypeANY:
		if q.Name == *dnsZone {
			d.listHosts(w, r)
		} else {
			d.hostLookup(w, r)
		}
	default:
		msg := &dns.Msg{}
		msg.SetRcode(r, dns.RcodeNotImplemented)
		w.Write(msg)
	}
}

func dnsServices() {
	if *dnsBinding == "" {
		return
	}

	log.Printf("Starting DNS services on %v.", *dnsBinding)

	d := dnsService{}

	serv := dns.Server{
		Net:     "udp",
		Addr:    *dnsBinding,
		Handler: d,
	}

	err := serv.ListenAndServe()
	if err != nil {
		log.Fatalf("DNS server failure: %v", err)
	}
}
<|endoftext|>


<commit_before>// Package pgx is a PostgreSQL database driver.
/*
pgx provides lower level access to PostgreSQL than the standard database/sql
It remains as similar to the database/sql interface as possible while
providing better speed and access to PostgreSQL specific features. Import
github.com/jack/pgx/stdlib to use pgx as a database/sql compatible driver.

Query Interface

pgx implements Query and Scan in the familiar database/sql style.

    var sum int32

    // Send the query to the server. The returned rows MUST be closed
    // before conn can be used again.
    rows, err := conn.Query("select generate_series(1,$1)", 10)
    if err != nil {
        return err
    }

    // rows.Close is called by rows.Next when all rows are read
    // or an error occurs in Next or Scan. So it may optionally be
    // omitted if nothing in the rows.Next loop can panic. It is
    // safe to close rows multiple times.
    defer rows.Close()

    // Iterate through the result set
    for rows.Next() {
        var n int32
        err = rows.Scan(&n)
        if err != nil {
            return err
        }
        sum += n
    }

    // Any errors encountered by rows.Next or rows.Scan will be returned here
    if rows.Err() != nil {
        return err
    }

    // No errors found - do something with sum

pgx also implements QueryRow in the same style as database/sql.

    var name string
    var weight int64
    err := conn.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Use Exec to execute a query that does not return a result set.

    commandTag, err := conn.Exec("delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

Connection Pool

Connection pool usage is explicit and configurable. In pgx, a connection can
be created and managed directly, or a connection pool with a configurable
maximum connections can be used. Also, the connection pool offers an after
connect hook that allows every connection to be automatically setup before
being made available in the connection pool. This is especially useful to
ensure all connections have the same prepared statements available or to
change any other connection settings.

It delegates Query, QueryRow, Exec, and Begin functions to an automatically
checked out and released connection so you can avoid manually acquiring and
releasing connections when you do not need that level of control.

    var name string
    var weight int64
    err := pool.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Transactions

Transactions are started by calling Begin or BeginIso. The BeginIso variant
creates a transaction with a specified isolation level.

    tx, err := conn.Begin()
    if err != nil {
        return err
    }
    // Rollback is safe to call even if the tx is already closed, so if
    // the tx commits successfully, this is a no-op
    defer tx.Rollback()

    _, err = tx.Exec("insert into foo(id) values (1)")
    if err != nil {
        return err
    }

    err = tx.Commit()
    if err != nil {
        return err
    }

Copy Protocol

Use CopyTo to efficiently insert multiple rows at a time using the PostgreSQL
copy protocol. CopyTo accepts a CopyToSource interface. If the data is already
in a [][]interface{} use CopyToRows to wrap it in a CopyToSource interface. Or
implement CopyToSource to avoid buffering the entire data set in memory.

    rows := [][]interface{}{
        {"John", "Smith", int32(36)},
        {"Jane", "Doe", int32(29)},
    }

    copyCount, err := conn.CopyTo(
        "people",
        []string{"first_name", "last_name", "age"},
        pgx.CopyToRows(rows),
    )

CopyTo can be faster than an insert with as few as 5 rows.

Listen and Notify

pgx can listen to the PostgreSQL notification system with the
WaitForNotification function. It takes a maximum time to wait for a
notification.

    err := conn.Listen("channelname")
    if err != nil {
        return nil
    }

    if notification, err := conn.WaitForNotification(time.Second); err != nil {
        // do something with notification
    }

Null Mapping

pgx can map nulls in two ways. The first is Null* types that have a data field
and a valid field. They work in a similar fashion to database/sql. The second
is to use a pointer to a pointer.

    var foo pgx.NullString
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&a, &b)
    if err != nil {
        return err
    }

Array Mapping

pgx maps between int16, int32, int64, float32, float64, and string Go slices
and the equivalent PostgreSQL array type. Go slices of native types do not
support nulls, so if a PostgreSQL array that contains a null is read into a
native Go slice an error will occur.

Hstore Mapping

pgx includes an Hstore type and a NullHstore type. Hstore is simply a
map[string]string and is preferred when the hstore contains no nulls. NullHstore
follows the Null* pattern and supports null values.

JSON and JSONB Mapping

pgx includes built-in support to marshal and unmarshal between Go types and
the PostgreSQL JSON and JSONB.

Inet and Cidr Mapping

pgx encodes from net.IPNet to and from inet and cidr PostgreSQL types. In
addition, as a convenience pgx will encode from a net.IP; it will assume a /32
netmask for IPv4 and a /128 for IPv6.

Custom Type Support

pgx includes support for the common data types like integers, floats, strings,
dates, and times that have direct mappings between Go and SQL. Support can be
added for additional types like point, hstore, numeric, etc. that do not have
direct mappings in Go by the types implementing Scanner and Encoder.

Custom types can support text or binary formats. Binary format can provide a
large performance increase. The natural place for deciding the format for a
value would be in Scanner as it is responsible for decoding the returned data.
However, that is impossible as the query has already been sent by the time the
Scanner is invoked. The solution to this is the global DefaultTypeFormats. If a
custom type prefers binary format it should register it there.

        pgx.DefaultTypeFormats["point"] = pgx.BinaryFormatCode

Note that the type is referred to by name, not by OID. This is because custom
PostgreSQL types like hstore will have different OIDs on different servers. When
pgx establishes a connection it queries the pg_type table for all types. It then
matches the names in DefaultTypeFormats with the returned OIDs and stores it in
Conn.PgTypes.

See example_custom_type_test.go for an example of a custom type for the
PostgreSQL point type.

pgx also includes support for custom types implementing the database/sql.Scanner
and database/sql/driver.Valuer interfaces.

Raw Bytes Mapping

[]byte passed as arguments to Query, QueryRow, and Exec are passed unmodified
to PostgreSQL. In like manner, a *[]byte passed to Scan will be filled with
the raw bytes returned by PostgreSQL. This can be especially useful for reading
varchar, text, json, and jsonb values directly into a []byte and avoiding the
type conversion from string.

TLS

The pgx ConnConfig struct has a TLSConfig field. If this field is
nil, then TLS will be disabled. If it is present, then it will be used to
configure the TLS connection. This allows total configuration of the TLS
connection.

Logging

pgx defines a simple logger interface. Connections optionally accept a logger
that satisfies this interface. The log15 package
(http://gopkg.in/inconshreveable/log15.v2) satisfies this interface and it is
simple to define adapters for other loggers. Set LogLevel to control logging
verbosity.
*/
package pgx
<commit_msg>Add mapping information for core types.<commit_after>// Package pgx is a PostgreSQL database driver.
/*
pgx provides lower level access to PostgreSQL than the standard database/sql
It remains as similar to the database/sql interface as possible while
providing better speed and access to PostgreSQL specific features. Import
github.com/jack/pgx/stdlib to use pgx as a database/sql compatible driver.

Query Interface

pgx implements Query and Scan in the familiar database/sql style.

    var sum int32

    // Send the query to the server. The returned rows MUST be closed
    // before conn can be used again.
    rows, err := conn.Query("select generate_series(1,$1)", 10)
    if err != nil {
        return err
    }

    // rows.Close is called by rows.Next when all rows are read
    // or an error occurs in Next or Scan. So it may optionally be
    // omitted if nothing in the rows.Next loop can panic. It is
    // safe to close rows multiple times.
    defer rows.Close()

    // Iterate through the result set
    for rows.Next() {
        var n int32
        err = rows.Scan(&n)
        if err != nil {
            return err
        }
        sum += n
    }

    // Any errors encountered by rows.Next or rows.Scan will be returned here
    if rows.Err() != nil {
        return err
    }

    // No errors found - do something with sum

pgx also implements QueryRow in the same style as database/sql.

    var name string
    var weight int64
    err := conn.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Use Exec to execute a query that does not return a result set.

    commandTag, err := conn.Exec("delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

Connection Pool

Connection pool usage is explicit and configurable. In pgx, a connection can
be created and managed directly, or a connection pool with a configurable
maximum connections can be used. Also, the connection pool offers an after
connect hook that allows every connection to be automatically setup before
being made available in the connection pool. This is especially useful to
ensure all connections have the same prepared statements available or to
change any other connection settings.

It delegates Query, QueryRow, Exec, and Begin functions to an automatically
checked out and released connection so you can avoid manually acquiring and
releasing connections when you do not need that level of control.

    var name string
    var weight int64
    err := pool.QueryRow("select name, weight from widgets where id=$1", 42).Scan(&name, &weight)
    if err != nil {
        return err
    }

Base Type Mapping

pgx maps between all common base types directly between Go and PostgreSQL. In
particular:

    Go           PostgreSQL
    -----------------------
    string       varchar
                 text

    // Integers are automatically be converted to any other integer type if
    // it can be done without overflow or underflow.
    int8
    int16        smallint
    int32        int
    int64        bigint
    int
    uint8
    uint16
    uint32
    uint64
    uint

    // Floats are strict and do not automatically convert like integers.
    float32      float4
    float64      float8

    time.Time   date
                timestamp
                timestamptz

    []byte      bytea

Null Mapping

pgx can map nulls in two ways. The first is Null* types that have a data field
and a valid field. They work in a similar fashion to database/sql. The second
is to use a pointer to a pointer.

    var foo pgx.NullString
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&a, &b)
    if err != nil {
        return err
    }

Array Mapping

pgx maps between int16, int32, int64, float32, float64, and string Go slices
and the equivalent PostgreSQL array type. Go slices of native types do not
support nulls, so if a PostgreSQL array that contains a null is read into a
native Go slice an error will occur.

Hstore Mapping

pgx includes an Hstore type and a NullHstore type. Hstore is simply a
map[string]string and is preferred when the hstore contains no nulls. NullHstore
follows the Null* pattern and supports null values.

JSON and JSONB Mapping

pgx includes built-in support to marshal and unmarshal between Go types and
the PostgreSQL JSON and JSONB.

Inet and Cidr Mapping

pgx encodes from net.IPNet to and from inet and cidr PostgreSQL types. In
addition, as a convenience pgx will encode from a net.IP; it will assume a /32
netmask for IPv4 and a /128 for IPv6.

Custom Type Support

pgx includes support for the common data types like integers, floats, strings,
dates, and times that have direct mappings between Go and SQL. Support can be
added for additional types like point, hstore, numeric, etc. that do not have
direct mappings in Go by the types implementing Scanner and Encoder.

Custom types can support text or binary formats. Binary format can provide a
large performance increase. The natural place for deciding the format for a
value would be in Scanner as it is responsible for decoding the returned data.
However, that is impossible as the query has already been sent by the time the
Scanner is invoked. The solution to this is the global DefaultTypeFormats. If a
custom type prefers binary format it should register it there.

        pgx.DefaultTypeFormats["point"] = pgx.BinaryFormatCode

Note that the type is referred to by name, not by OID. This is because custom
PostgreSQL types like hstore will have different OIDs on different servers. When
pgx establishes a connection it queries the pg_type table for all types. It then
matches the names in DefaultTypeFormats with the returned OIDs and stores it in
Conn.PgTypes.

See example_custom_type_test.go for an example of a custom type for the
PostgreSQL point type.

pgx also includes support for custom types implementing the database/sql.Scanner
and database/sql/driver.Valuer interfaces.

Raw Bytes Mapping

[]byte passed as arguments to Query, QueryRow, and Exec are passed unmodified
to PostgreSQL. In like manner, a *[]byte passed to Scan will be filled with
the raw bytes returned by PostgreSQL. This can be especially useful for reading
varchar, text, json, and jsonb values directly into a []byte and avoiding the
type conversion from string.

Transactions

Transactions are started by calling Begin or BeginIso. The BeginIso variant
creates a transaction with a specified isolation level.

    tx, err := conn.Begin()
    if err != nil {
        return err
    }
    // Rollback is safe to call even if the tx is already closed, so if
    // the tx commits successfully, this is a no-op
    defer tx.Rollback()

    _, err = tx.Exec("insert into foo(id) values (1)")
    if err != nil {
        return err
    }

    err = tx.Commit()
    if err != nil {
        return err
    }

Copy Protocol

Use CopyTo to efficiently insert multiple rows at a time using the PostgreSQL
copy protocol. CopyTo accepts a CopyToSource interface. If the data is already
in a [][]interface{} use CopyToRows to wrap it in a CopyToSource interface. Or
implement CopyToSource to avoid buffering the entire data set in memory.

    rows := [][]interface{}{
        {"John", "Smith", int32(36)},
        {"Jane", "Doe", int32(29)},
    }

    copyCount, err := conn.CopyTo(
        "people",
        []string{"first_name", "last_name", "age"},
        pgx.CopyToRows(rows),
    )

CopyTo can be faster than an insert with as few as 5 rows.

Listen and Notify

pgx can listen to the PostgreSQL notification system with the
WaitForNotification function. It takes a maximum time to wait for a
notification.

    err := conn.Listen("channelname")
    if err != nil {
        return nil
    }

    if notification, err := conn.WaitForNotification(time.Second); err != nil {
        // do something with notification
    }

TLS

The pgx ConnConfig struct has a TLSConfig field. If this field is
nil, then TLS will be disabled. If it is present, then it will be used to
configure the TLS connection. This allows total configuration of the TLS
connection.

Logging

pgx defines a simple logger interface. Connections optionally accept a logger
that satisfies this interface. The log15 package
(http://gopkg.in/inconshreveable/log15.v2) satisfies this interface and it is
simple to define adapters for other loggers. Set LogLevel to control logging
verbosity.
*/
package pgx
<|endoftext|>


<commit_before>// Package bites deals with byte slices.
// Its purpose is to make it easier to marshal and unmarshal the various basic types to and from byte slices.
//
// Most of these methods do not allocate, and many of them are inlined.
// When a method does allocate, it is noted in the docs.
package bites
<commit_msg>Added doc.go<commit_after>// Most of its methods do not allocate unnecessarily, and many of them are inlined.
// When a method does allocate, it is noted in the docs.

// Package bites implements a way to easily pack and unpack any primitive type into a byte slice.
package bites
<|endoftext|>


<commit_before>/*
Foo bar.

Nomenclature

ID3 uses nomenclature that might be counterintuitive to people not
familiar with it. Because this library uses the same choice of words
the following list of clarifications is included.

  tag: In ID3, tag means the entire set of metadata, not just one
       field of it.

  frame: A frame describes a single piece of information, for example
         a song's title.

Supported versions

This library supports reading v2.3 and v2.4 tags, but only writing
v2.4 tags.

The primary reason for not allowing writing older versions is that
they cannot represent all data that is available with v2.4, and
designing the API in a way that's both user friendly and able to
reject data is not worth the trouble.

Automatic upgrading

The library's internal representation of tags matches that of v2.4.
When tags with an older version are being read, they will be
automatically converted to v2.4.

One consequence of this is that when you read a file with v2.3 tags
and immediately save it, it will now be a file with valid v2.4 tags.

The upgrade process makes the following changes to the tags:

  - TYER, TDAT and TIME get replaced by TDRC
  - TORY gets replaced by TDOR
  - XDOR gets replaced by TDOR
  - The slash as a separator for multiple values gets replaced by null bytes

One special case is the TRDA frame because there is no way to
automatically convert it to v2.4. The upgrade process will not
directly delete the frame, so that you can manually upgrade it if
desired, but it won't be written back to the file. The frame is rarely
used and insignificant, so it's not a big loss.

Accessing and manipulating frames

There are two ways to access frames: Using provided getter and setter
methods (there is one for every standard frame), and working directly
with the underlying frames.

For frames that usually support multiple values, e.g. languages, there
will be two different setters and getters: One that operates on slices
and one that operates on single values. When getting a single value,
it will return the first value from the underlying list. When setting
a single value, it will overwrite the list with a single value.

Text frames and user text frames can be manipulated with the
GetTextFrame* and SetTextFrame* class of functions. There are special
methods for working with integers, slices and times. This class of
functions expects the raw frame names (e.g. "TLEN"), with the special
case of user text frames ("TXXX") where it expects a format of the
kind "TXXX:The frame description" to address a specific user text
frame.

Encodings

While ID3v2 allows a variety of encodings (ISO-8859-1, UTF-16 and in
v2.4 also UTF-8), this library only supports writing UTF-8. When
reading frames with different encodings, they will be converted to
UTF-8.

The rationale behind this is that UTF-8 is the encoding assumed by
most of the Go standard library, and that the other encodings have no
realistic benefits over UTF-8.

Behaviour when encounterind invalid data

There are two kinds of invalid data that can be encountered: Data that
doesn't look like a valid frame, and data that is invalid in the
context of its frame.

An example for the first case is a frame identifier that doesn't
consist of only A-Z0-9. That usually happens when other programs wrote
invalid data. One common case are wrongly encoded sizes, which will
cause us to read random binary data.

An example for the second case is text that isn't valid according to
the specified encoding.

In the first case, parsing of the entire tag will be aborted because
it cannot be ensured that bad things won't happen.

In the second case only that specific frame will be dropped.

Unsupported frames

Unsupported frames, like extensions by Apple, will be left untouched,
meaning that they will be read and written as raw byte slices. If you
know how to handle them, you can write your own function to parse and
modify the content. All unsupported frames will be of type
UnsupportedFrame.

*/
package id3
<commit_msg>typo in documentation<commit_after>/*
Foo bar.

Nomenclature

ID3 uses nomenclature that might be counterintuitive to people not
familiar with it. Because this library uses the same choice of words
the following list of clarifications is included.

  tag: In ID3, tag means the entire set of metadata, not just one
       field of it.

  frame: A frame describes a single piece of information, for example
         a song's title.

Supported versions

This library supports reading v2.3 and v2.4 tags, but only writing
v2.4 tags.

The primary reason for not allowing writing older versions is that
they cannot represent all data that is available with v2.4, and
designing the API in a way that's both user friendly and able to
reject data is not worth the trouble.

Automatic upgrading

The library's internal representation of tags matches that of v2.4.
When tags with an older version are being read, they will be
automatically converted to v2.4.

One consequence of this is that when you read a file with v2.3 tags
and immediately save it, it will now be a file with valid v2.4 tags.

The upgrade process makes the following changes to the tags:

  - TYER, TDAT and TIME get replaced by TDRC
  - TORY gets replaced by TDOR
  - XDOR gets replaced by TDOR
  - The slash as a separator for multiple values gets replaced by null bytes

One special case is the TRDA frame because there is no way to
automatically convert it to v2.4. The upgrade process will not
directly delete the frame, so that you can manually upgrade it if
desired, but it won't be written back to the file. The frame is rarely
used and insignificant, so it's not a big loss.

Accessing and manipulating frames

There are two ways to access frames: Using provided getter and setter
methods (there is one for every standard frame), and working directly
with the underlying frames.

For frames that usually support multiple values, e.g. languages, there
will be two different setters and getters: One that operates on slices
and one that operates on single values. When getting a single value,
it will return the first value from the underlying list. When setting
a single value, it will overwrite the list with a single value.

Text frames and user text frames can be manipulated with the
GetTextFrame* and SetTextFrame* class of functions. There are special
methods for working with integers, slices and times. This class of
functions expects the raw frame names (e.g. "TLEN"), with the special
case of user text frames ("TXXX") where it expects a format of the
kind "TXXX:The frame description" to address a specific user text
frame.

Encodings

While ID3v2 allows a variety of encodings (ISO-8859-1, UTF-16 and in
v2.4 also UTF-8), this library only supports writing UTF-8. When
reading frames with different encodings, they will be converted to
UTF-8.

The rationale behind this is that UTF-8 is the encoding assumed by
most of the Go standard library, and that the other encodings have no
realistic benefits over UTF-8.

Behaviour when encountering invalid data

There are two kinds of invalid data that can be encountered: Data that
doesn't look like a valid frame, and data that is invalid in the
context of its frame.

An example for the first case is a frame identifier that doesn't
consist of only A-Z0-9. That usually happens when other programs wrote
invalid data. One common case are wrongly encoded sizes, which will
cause us to read random binary data.

An example for the second case is text that isn't valid according to
the specified encoding.

In the first case, parsing of the entire tag will be aborted because
it cannot be ensured that bad things won't happen.

In the second case only that specific frame will be dropped.

Unsupported frames

Unsupported frames, like extensions by Apple, will be left untouched,
meaning that they will be read and written as raw byte slices. If you
know how to handle them, you can write your own function to parse and
modify the content. All unsupported frames will be of type
UnsupportedFrame.

*/
package id3
<|endoftext|>


<commit_before>/*
tsuru is a command line tool for application developers.

It provide some commands that allow a developer to register himself/herself,
manage teams, apps and services.

Usage:

	% tsuru <command> [args]

The currently available commands are (grouped by subject):

    target            changes or retrive the current tsuru server

    user-create       creates a new user
    login             authenticates the user with tsuru server
    logout            finishes the session with tsuru server
    key-add           adds a public key to tsuru deploy server
    key-remove        removes a public key from tsuru deploy server

    team-create       creates a new team (adding the current user to it automatically)
    team-list         list teams that the user is member
    team-user-add     adds a user to a team
    team-user-remove  removes a user from a team

    app-create        creates an app
    app-remove        removes an app
    app-list          lists apps that the user has access (see app-grant and team-user-add)
    app-grant         allows a team to have access to an app
    app-revoke        revokes access to an app from a team
    log               shows log for an app
    run               runs a command in all units of an app
	restart           restarts the app's application server

    env-get           display environment variables for an app
    env-set           set environment variable(s) to an app
    env-unset         unset environment variable(s) from an app

    bind              binds an app to a service instance
    unbind            unbinds an app from a service instance

    service-list      list all services, and instances of each service
    service-add       creates a new instance of a service
    service-remove    removes a instance of a service
    service-status    checks the status of a service instance
    service-info      list instances of a service, and apps binded to each instance
    service-doc       displays documentation for a service

Use "tsuru help <command>" for more information about a command.

Change/retrieve remote tsuru server

Usage:

	% tsuru target [target]

This command should be used to get current tsuru target, or retrieve current
target.

The target is the tsuru server to which all operations will be directed to.

Create a user

Usage:

	% tsuru user-create <email>

user-create creates a user within tsuru remote server. It will ask for the
password before issue the request.

Authenticate within remote tsuru server

Usage:

	% tsuru login <email>

Login will ask for the password and check if the user is successfully
authenticated. If so, the token generated by the tsuru server will be stored in
${HOME}/.tsuru_token.

All tsuru actions require the user to be authenticated (except login and
user-create, obviously).

Logout from remote tsuru server

Usage:

	% tsuru logout

Logout will delete the token file and terminate the session within tsuru
server.

Add SSH public key to tsuru's git server

Usage:

	% tsuru key-add [${HOME}/.ssh/id_rsa.pub]

key-add sends your public key to tsuru's git server. By default, it will try
send a public RSA key, located at ${HOME}/.ssh/id_rsa.pub. If you want to send
other file, you can call it with the path to the file. For example:

	% tsuru key-add /etc/my-keys/id_dsa.pub

The key will be added to the current logged in user.

Remove SSH public key from tsuru's git server

Usage:

	% tsuru key-remove [${HOME}/.ssh/id_rsa.pub]

key-remove removes your public key from tsuru's git server. By default, it will
try to remove a key that match you public RSA key located at
${HOME}/.ssh/id_rsa.pub. If you want to remove a key located somewhere else,
you can pass it as parameter to key-remove:

	% tsuru key-remove /etc/my-keys/id_dsa.pub

The key will be removed from the current logged in user.

Create a new team for the user

Usage:

	% tsuru team-create <teamname>

team-create will create a team for the user. Tsuru requires a user to be a
member of at least one team in order to create an app or a service instance.

When you create a team, you're automatically member of this team.

List teams that the user is member of

Usage:

	% tsuru team-list

team-list will list all teams that you are member of.

Add a user to a team

Usage:

	% tsuru team-user-add <teamname> <useremail>

team-user-add adds a user to a team. You need to be a member of the team to be
able to add a user to it.

Remove a user from a team

Usage:

	% tsuru team-user-remove <teamname> <useremail>

team-user-remove removes a user from a team. You need to be a member of the
team to be able to remove a user from it.

A team can never have 0 users. If you are the last member of a team, you can't
remove yourself from it.
*/
package documentation
<commit_msg>cmd/tsuru: some more docs<commit_after>/*
tsuru is a command line tool for application developers.

It provide some commands that allow a developer to register himself/herself,
manage teams, apps and services.

Usage:

	% tsuru <command> [args]

The currently available commands are (grouped by subject):

    target            changes or retrive the current tsuru server

    user-create       creates a new user
    login             authenticates the user with tsuru server
    logout            finishes the session with tsuru server
    key-add           adds a public key to tsuru deploy server
    key-remove        removes a public key from tsuru deploy server

    team-create       creates a new team (adding the current user to it automatically)
    team-list         list teams that the user is member
    team-user-add     adds a user to a team
    team-user-remove  removes a user from a team

    app-create        creates an app
    app-remove        removes an app
    app-list          lists apps that the user has access (see app-grant and team-user-add)
    app-grant         allows a team to have access to an app
    app-revoke        revokes access to an app from a team
    log               shows log for an app
    run               runs a command in all units of an app
	restart           restarts the app's application server

    env-get           display environment variables for an app
    env-set           set environment variable(s) to an app
    env-unset         unset environment variable(s) from an app

    bind              binds an app to a service instance
    unbind            unbinds an app from a service instance

    service-list      list all services, and instances of each service
    service-add       creates a new instance of a service
    service-remove    removes a instance of a service
    service-status    checks the status of a service instance
    service-info      list instances of a service, and apps binded to each instance
    service-doc       displays documentation for a service

Use "tsuru help <command>" for more information about a command.

Change/retrieve remote tsuru server

Usage:

	% tsuru target [target]

This command should be used to get current tsuru target, or retrieve current
target.

The target is the tsuru server to which all operations will be directed to.

Create a user

Usage:

	% tsuru user-create <email>

user-create creates a user within tsuru remote server. It will ask for the
password before issue the request.

Authenticate within remote tsuru server

Usage:

	% tsuru login <email>

Login will ask for the password and check if the user is successfully
authenticated. If so, the token generated by the tsuru server will be stored in
${HOME}/.tsuru_token.

All tsuru actions require the user to be authenticated (except login and
user-create, obviously).

Logout from remote tsuru server

Usage:

	% tsuru logout

Logout will delete the token file and terminate the session within tsuru
server.

Add SSH public key to tsuru's git server

Usage:

	% tsuru key-add [${HOME}/.ssh/id_rsa.pub]

key-add sends your public key to tsuru's git server. By default, it will try
send a public RSA key, located at ${HOME}/.ssh/id_rsa.pub. If you want to send
other file, you can call it with the path to the file. For example:

	% tsuru key-add /etc/my-keys/id_dsa.pub

The key will be added to the current logged in user.

Remove SSH public key from tsuru's git server

Usage:

	% tsuru key-remove [${HOME}/.ssh/id_rsa.pub]

key-remove removes your public key from tsuru's git server. By default, it will
try to remove a key that match you public RSA key located at
${HOME}/.ssh/id_rsa.pub. If you want to remove a key located somewhere else,
you can pass it as parameter to key-remove:

	% tsuru key-remove /etc/my-keys/id_dsa.pub

The key will be removed from the current logged in user.

Create a new team for the user

Usage:

	% tsuru team-create <teamname>

team-create will create a team for the user. Tsuru requires a user to be a
member of at least one team in order to create an app or a service instance.

When you create a team, you're automatically member of this team.

List teams that the user is member of

Usage:

	% tsuru team-list

team-list will list all teams that you are member of.

Add a user to a team

Usage:

	% tsuru team-user-add <teamname> <useremail>

team-user-add adds a user to a team. You need to be a member of the team to be
able to add a user to it.

Remove a user from a team

Usage:

	% tsuru team-user-remove <teamname> <useremail>

team-user-remove removes a user from a team. You need to be a member of the
team to be able to remove a user from it.

A team can never have 0 users. If you are the last member of a team, you can't
remove yourself from it.

Create an app

Usage:

	% tsuru app-create <appname> <platform>

app-create will create a new app using the given name and platform. For tsuru,
a platform is a Juju charm. To check the available platforms/charms, check this
URL: https://github.com/timeredbull/charms/tree/master/centos.

In order to create an app, you need to be member of at least one team. All
teams that you are member (see "tsuru team-list") will be able to access the
app.

Remove an app

Usage:

	% tsuru app-remove <appname>

app-remove removes an app. If the app is binded to any service instance, it
will be unbinded before be removed (see "tsuru unbind"). You need to be a
member of a team that has access to the app to be able to remove it (you are
able to remove any app that you see in "tsuru app-list").

List apps that the user has access to

Usage:

	% tsuru app-list

app-list will list all apps that you have access to. App access is controlled
by teams. If your team has access to an app, then you have access to it.

Allow a team to access an app

Usage:

	% tsuru app-grant <appname> <teamname>

app-grant will allow a team to access an app. You need to be a member of a team
that has access to the app to allow another team to access it.

Revoke from a team access to an app

Usage:

	% tsuru app-revoke <appname> <teamname>

app-revoke will revoke the permission to access an app from a team. You need to
have access to the app to revoke access from a team.

An app cannot be orphaned, so it will always have at least one authorized team.

See app's logs

Usage:

	% tsuru log <appname>

Log will show log entries for an app. These logs are not related to the code of
the app itself, but to actions of the app in tsuru server (deployments,
restarts, etc.).

Run an arbitrary command in the app machine

Usage:

	% tsuru run <appname> <command> [commandarg1] [commandarg2] ... [commandargn]

Run will run an arbitrary command in the app machine. Base directory for all
commands is the root of the app. For example, in a Django app, "tsuru run" may
show the following output:

	% tsuru run polls ls -l
	app.conf
	brogui
	deploy
	foo
	__init__.py
	__init__.pyc
	main.go
	manage.py
	settings.py
	settings.pyc
	templates
	urls.py
	urls.pyc

Restart the app's application server

Usage:

	% tsuru restart <appname>

Restart will call the restart hook from the app platform (the "restart" hook
from the Juju charm).
*/
package documentation
<|endoftext|>


<commit_before>/*
Package gorocksdb provides the ability to create and access RocksDB databases.

gorocksdb.OpenDb opens and creates databases.

	opts := gorocksdb.NewDefaultOptions()
	opts.SetBlockCache(gorocksdb.NewLRUCache(3<<30))
	opts.SetCreateIfMissing(true)
	db, err := gorocksdb.OpenDb(opts, "/path/to/db")

The DB struct returned by OpenDb provides DB.Get, DB.Put, DB.Merge and DB.Delete to modify
and query the database.

	ro := gorocksdb.NewDefaultReadOptions()
	wo := gorocksdb.NewDefaultWriteOptions()
	// if ro and wo are not used again, be sure to Close them.
	err = db.Put(wo, []byte("foo"), []byte("bar"))
	...
	value, err := db.Get(ro, []byte("foo"))
	defer value.Free()
	...
	err = db.Delete(wo, []byte("foo"))

For bulk reads, use an Iterator. If you want to avoid disturbing your live
traffic while doing the bulk read, be sure to call SetFillCache(false) on the
ReadOptions you use when creating the Iterator.

	ro := gorocksdb.NewDefaultReadOptions()
	ro.SetFillCache(false)
	it := db.NewIterator(ro)
	defer it.Close()
	it.Seek([]byte("foo"))
	for it = it; it.Valid(); it.Next() {
		key := iter.Key()
		value := iter.Value()
		fmt.Printf("Key: %v Value: %v\n", key.Data(), value.Data())
		key.Free()
		value.Free()
	}
	if err := it.GetError(); err != nil {
		...
	}

Batched, atomic writes can be performed with a WriteBatch and
DB.Write.

	wb := gorocksdb.NewWriteBatch()
	// defer wb.Close or use wb.Clear and reuse.
	wb.Delete([]byte("foo"))
	wb.Put([]byte("foo"), []byte("bar"))
	wb.Put([]byte("bar"), []byte("foo"))
	err := db.Write(wo, wb)

If your working dataset does not fit in memory, you'll want to add a bloom
filter to your database. NewBloomFilter and Options.SetFilterPolicy is what
you want. NewBloomFilter is amount of bits in the filter to use per key in
your database.

	filter := gorocksdb.NewBloomFilter(10)
	opts.SetFilterPolicy(filter)
	db, err := gorocksdb.OpenDb(opts, "/path/to/db")

If you're using a custom comparator in your code, be aware you may have to
make your own filter policy object.

This documentation is not a complete discussion of RocksDB. Please read the
RocksDB documentation <http://rocksdb.org/> for information on its
operation. You'll find lots of goodies there.
*/
package gorocksdb
<commit_msg>fix typo in doc.go<commit_after>/*
Package gorocksdb provides the ability to create and access RocksDB databases.

gorocksdb.OpenDb opens and creates databases.

	opts := gorocksdb.NewDefaultOptions()
	opts.SetBlockCache(gorocksdb.NewLRUCache(3<<30))
	opts.SetCreateIfMissing(true)
	db, err := gorocksdb.OpenDb(opts, "/path/to/db")

The DB struct returned by OpenDb provides DB.Get, DB.Put, DB.Merge and DB.Delete to modify
and query the database.

	ro := gorocksdb.NewDefaultReadOptions()
	wo := gorocksdb.NewDefaultWriteOptions()
	// if ro and wo are not used again, be sure to Close them.
	err = db.Put(wo, []byte("foo"), []byte("bar"))
	...
	value, err := db.Get(ro, []byte("foo"))
	defer value.Free()
	...
	err = db.Delete(wo, []byte("foo"))

For bulk reads, use an Iterator. If you want to avoid disturbing your live
traffic while doing the bulk read, be sure to call SetFillCache(false) on the
ReadOptions you use when creating the Iterator.

	ro := gorocksdb.NewDefaultReadOptions()
	ro.SetFillCache(false)
	it := db.NewIterator(ro)
	defer it.Close()
	it.Seek([]byte("foo"))
	for it = it; it.Valid(); it.Next() {
		key := it.Key()
		value := it.Value()
		fmt.Printf("Key: %v Value: %v\n", key.Data(), value.Data())
		key.Free()
		value.Free()
	}
	if err := it.GetError(); err != nil {
		...
	}

Batched, atomic writes can be performed with a WriteBatch and
DB.Write.

	wb := gorocksdb.NewWriteBatch()
	// defer wb.Close or use wb.Clear and reuse.
	wb.Delete([]byte("foo"))
	wb.Put([]byte("foo"), []byte("bar"))
	wb.Put([]byte("bar"), []byte("foo"))
	err := db.Write(wo, wb)

If your working dataset does not fit in memory, you'll want to add a bloom
filter to your database. NewBloomFilter and Options.SetFilterPolicy is what
you want. NewBloomFilter is amount of bits in the filter to use per key in
your database.

	filter := gorocksdb.NewBloomFilter(10)
	opts.SetFilterPolicy(filter)
	db, err := gorocksdb.OpenDb(opts, "/path/to/db")

If you're using a custom comparator in your code, be aware you may have to
make your own filter policy object.

This documentation is not a complete discussion of RocksDB. Please read the
RocksDB documentation <http://rocksdb.org/> for information on its
operation. You'll find lots of goodies there.
*/
package gorocksdb
<|endoftext|>