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

package macaron

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/Unknwon/macaron/bpool"
)

const (
	ContentType    = "Content-Type"
	ContentLength  = "Content-Length"
	ContentBinary  = "application/octet-stream"
	ContentJSON    = "application/json"
	ContentHTML    = "text/html"
	ContentXHTML   = "application/xhtml+xml"
	ContentXML     = "text/xml"
	defaultCharset = "UTF-8"
)

var (
	// Provides a temporary buffer to execute templates into and catch errors.
	bufpool *bpool.BufferPool

	// Included helper functions for use when rendering html
	helperFuncs = template.FuncMap{
		"yield": func() (string, error) {
			return "", fmt.Errorf("yield called with no layout defined")
		},
		"current": func() (string, error) {
			return "", nil
		},
	}
)

type (
	// Delims represents a set of Left and Right delimiters for HTML template rendering
	Delims struct {
		// Left delimiter, defaults to {{
		Left string
		// Right delimiter, defaults to }}
		Right string
	}

	// RenderOptions represents a struct for specifying configuration options for the Render middleware.
	RenderOptions struct {
		// Directory to load templates. Default is "templates".
		Directory string
		// Layout template name. Will not render a layout if "". Default is to "".
		Layout string
		// Extensions to parse template files from. Defaults are [".tmpl", ".html"].
		Extensions []string
		// Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Default is [].
		Funcs []template.FuncMap
		// Delims sets the action delimiters to the specified strings in the Delims struct.
		Delims Delims
		// Appends the given charset to the Content-Type header. Default is "UTF-8".
		Charset string
		// Outputs human readable JSON.
		IndentJSON bool
		// Outputs human readable XML.
		IndentXML bool
		// Prefixes the JSON output with the given bytes.
		PrefixJSON []byte
		// Prefixes the XML output with the given bytes.
		PrefixXML []byte
		// Allows changing of output to XHTML instead of HTML. Default is "text/html"
		HTMLContentType string
	}

	// HTMLOptions is a struct for overriding some rendering Options for specific HTML call
	HTMLOptions struct {
		// Layout template name. Overrides Options.Layout.
		Layout string
	}
)

type Render interface {
	http.ResponseWriter
	RW() http.ResponseWriter

	JSON(int, interface{})
	JSONString(interface{}) (string, error)
	RawData(int, []byte)
	RenderData(int, []byte)
	HTML(int, string, interface{}, ...HTMLOptions)
	HTMLSet(int, string, string, interface{}, ...HTMLOptions)
	HTMLString(string, interface{}, ...HTMLOptions) (string, error)
	HTMLSetString(string, string, interface{}, ...HTMLOptions) (string, error)
	XML(int, interface{})
	Error(int, ...string)
	Status(int)
	Redirect(string, ...int)
}

func prepareOptions(options []RenderOptions) RenderOptions {
	var opt RenderOptions
	if len(options) > 0 {
		opt = options[0]
	}

	// Defaults.
	if len(opt.Directory) == 0 {
		opt.Directory = "templates"
	}
	if len(opt.Extensions) == 0 {
		opt.Extensions = []string{".tmpl", ".html"}
	}
	if len(opt.HTMLContentType) == 0 {
		opt.HTMLContentType = ContentHTML
	}

	return opt
}

func prepareCharset(charset string) string {
	if len(charset) != 0 {
		return "; charset=" + charset
	}

	return "; charset=" + defaultCharset
}

func getExt(s string) string {
	if strings.Index(s, ".") == -1 {
		return ""
	}
	return "." + strings.Join(strings.Split(s, ".")[1:], ".")
}

func compile(options RenderOptions) *template.Template {
	dir := options.Directory
	t := template.New(dir)
	t.Delims(options.Delims.Left, options.Delims.Right)
	// Parse an initial template in case we don't have any.
	template.Must(t.Parse("Macaron"))

	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		r, err := filepath.Rel(dir, path)
		if err != nil {
			return err
		}

		ext := getExt(r)

		for _, extension := range options.Extensions {
			if ext == extension {

				buf, err := ioutil.ReadFile(path)
				if err != nil {
					panic(err)
				}

				name := (r[0 : len(r)-len(ext)])
				tmpl := t.New(filepath.ToSlash(name))

				// add our funcmaps
				for _, funcs := range options.Funcs {
					tmpl.Funcs(funcs)
				}

				// Bomb out if parse fails. We don't want any silent server starts.
				template.Must(tmpl.Funcs(helperFuncs).Parse(string(buf)))
				break
			}
		}

		return nil
	})

	return t
}

// Renderer is a Middleware that maps a macaron.Render service into the Macaron handler chain.
// An single variadic macaron.RenderOptions struct can be optionally provided to configure
// HTML rendering. The default directory for templates is "templates" and the default
// file extension is ".tmpl" and ".html".
//
// If MACARON_ENV is set to "" or "development" then templates will be recompiled on every request. For more performance, set the
// MACARON_ENV environment variable to "production".
func Renderer(options ...RenderOptions) Handler {
	opt := prepareOptions(options)
	cs := prepareCharset(opt.Charset)
	t := compile(opt)
	bufpool = bpool.NewBufferPool(64)
	return func(ctx *Context, rw http.ResponseWriter, req *http.Request) {
		var tc *template.Template
		if Env == DEV {
			// recompile for easy development
			tc = compile(opt)
		} else {
			// use a clone of the initial template
			tc, _ = t.Clone()
		}
		r := &TplRender{
			ResponseWriter:  rw,
			Req:             req,
			t:               tc,
			Opt:             &opt,
			CompiledCharset: cs,
		}
		ctx.Data["TmplLoadTimes"] = func() string {
			if r.startTime.IsZero() {
				return ""
			}
			return fmt.Sprint(time.Since(r.startTime).Nanoseconds()/1e6) + "ms"
		}

		ctx.Render = r
		ctx.MapTo(r, (*Render)(nil))
	}
}

type TplRender struct {
	http.ResponseWriter
	Req             *http.Request
	t               *template.Template
	Opt             *RenderOptions
	CompiledCharset string

	startTime time.Time
}

func (r *TplRender) RW() http.ResponseWriter {
	return r.ResponseWriter
}

func (r *TplRender) JSON(status int, v interface{}) {
	var result []byte
	var err error
	if r.Opt.IndentJSON {
		result, err = json.MarshalIndent(v, "", "  ")
	} else {
		result, err = json.Marshal(v)
	}
	if err != nil {
		http.Error(r, err.Error(), 500)
		return
	}

	// json rendered fine, write out the result
	r.Header().Set(ContentType, ContentJSON+r.CompiledCharset)
	r.WriteHeader(status)
	if len(r.Opt.PrefixJSON) > 0 {
		r.Write(r.Opt.PrefixJSON)
	}
	r.Write(result)
}

func (r *TplRender) JSONString(v interface{}) (string, error) {
	var result []byte
	var err error
	if r.Opt.IndentJSON {
		result, err = json.MarshalIndent(v, "", "  ")
	} else {
		result, err = json.Marshal(v)
	}
	if err != nil {
		return "", err
	}
	return string(result), nil
}

func (r *TplRender) XML(status int, v interface{}) {
	var result []byte
	var err error
	if r.Opt.IndentXML {
		result, err = xml.MarshalIndent(v, "", "  ")
	} else {
		result, err = xml.Marshal(v)
	}
	if err != nil {
		http.Error(r, err.Error(), 500)
		return
	}

	// XML rendered fine, write out the result
	r.Header().Set(ContentType, ContentXML+r.CompiledCharset)
	r.WriteHeader(status)
	if len(r.Opt.PrefixXML) > 0 {
		r.Write(r.Opt.PrefixXML)
	}
	r.Write(result)
}

func (r *TplRender) data(status int, contentType string, v []byte) {
	if r.Header().Get(ContentType) == "" {
		r.Header().Set(ContentType, contentType)
	}
	r.WriteHeader(status)
	r.Write(v)
}

func (r *TplRender) RawData(status int, v []byte) {
	r.data(status, ContentBinary, v)
}

func (r *TplRender) RenderData(status int, v []byte) {
	r.data(status, ContentHTML, v)
}

func (r *TplRender) renderBytes(name string, binding interface{}, htmlOpt ...HTMLOptions) (*bytes.Buffer, error) {
	opt := r.prepareHTMLOptions(htmlOpt)

	if len(opt.Layout) > 0 {
		r.addYield(name, binding)
		name = opt.Layout
	}

	out, err := r.execute(name, binding)
	if err != nil {
		return nil, err
	}

	return out, nil
}

func (r *TplRender) HTML(status int, name string, binding interface{}, htmlOpt ...HTMLOptions) {
	r.startTime = time.Now()

	out, err := r.renderBytes(name, binding, htmlOpt...)
	if err != nil {
		http.Error(r, err.Error(), http.StatusInternalServerError)
		return
	}

	r.Header().Set(ContentType, r.Opt.HTMLContentType+r.CompiledCharset)
	r.WriteHeader(status)
	io.Copy(r, out)
	bufpool.Put(out)
}

func (r *TplRender) HTMLSet(status int, setName, name string, binding interface{}, htmlOpt ...HTMLOptions) {
	r.startTime = time.Now()

	out, err := r.renderBytes(name, binding, htmlOpt...)
	if err != nil {
		http.Error(r, err.Error(), http.StatusInternalServerError)
		return
	}

	r.Header().Set(ContentType, r.Opt.HTMLContentType+r.CompiledCharset)
	r.WriteHeader(status)
	io.Copy(r, out)
	bufpool.Put(out)
}

func (r *TplRender) HTMLString(name string, binding interface{}, htmlOpt ...HTMLOptions) (string, error) {
	if out, err := r.renderBytes(name, binding, htmlOpt...); err != nil {
		return "", err
	} else {
		return out.String(), nil
	}
}

func (r *TplRender) HTMLSetString(setName, name string, binding interface{}, htmlOpt ...HTMLOptions) (string, error) {
	if out, err := r.renderBytes(name, binding, htmlOpt...); err != nil {
		return "", err
	} else {
		return out.String(), nil
	}
}

// Error writes the given HTTP status to the current ResponseWriter
func (r *TplRender) Error(status int, message ...string) {
	r.WriteHeader(status)
	if len(message) > 0 {
		r.Write([]byte(message[0]))
	}
}

func (r *TplRender) Status(status int) {
	r.WriteHeader(status)
}

func (r *TplRender) Redirect(location string, status ...int) {
	code := http.StatusFound
	if len(status) == 1 {
		code = status[0]
	}

	http.Redirect(r, r.Req, location, code)
}

func (r *TplRender) execute(name string, binding interface{}) (*bytes.Buffer, error) {
	buf := bufpool.Get()
	return buf, r.t.ExecuteTemplate(buf, name, binding)
}

func (r *TplRender) addYield(name string, binding interface{}) {
	funcs := template.FuncMap{
		"yield": func() (template.HTML, error) {
			buf, err := r.execute(name, binding)
			// return safe html here since we are rendering our own template
			return template.HTML(buf.String()), err
		},
		"current": func() (string, error) {
			return name, nil
		},
	}
	r.t.Funcs(funcs)
}

func (r *TplRender) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions {
	if len(htmlOpt) > 0 {
		return htmlOpt[0]
	}

	return HTMLOptions{
		Layout: r.Opt.Layout,
	}
}
<commit_msg>bring back API<commit_after>// Copyright 2013 Martini Authors
// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package macaron

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/Unknwon/macaron/bpool"
)

const (
	ContentType    = "Content-Type"
	ContentLength  = "Content-Length"
	ContentBinary  = "application/octet-stream"
	ContentJSON    = "application/json"
	ContentHTML    = "text/html"
	ContentXHTML   = "application/xhtml+xml"
	ContentXML     = "text/xml"
	defaultCharset = "UTF-8"
)

var (
	// Provides a temporary buffer to execute templates into and catch errors.
	bufpool *bpool.BufferPool

	// Included helper functions for use when rendering html
	helperFuncs = template.FuncMap{
		"yield": func() (string, error) {
			return "", fmt.Errorf("yield called with no layout defined")
		},
		"current": func() (string, error) {
			return "", nil
		},
	}
)

type (
	// Delims represents a set of Left and Right delimiters for HTML template rendering
	Delims struct {
		// Left delimiter, defaults to {{
		Left string
		// Right delimiter, defaults to }}
		Right string
	}

	// RenderOptions represents a struct for specifying configuration options for the Render middleware.
	RenderOptions struct {
		// Directory to load templates. Default is "templates".
		Directory string
		// Layout template name. Will not render a layout if "". Default is to "".
		Layout string
		// Extensions to parse template files from. Defaults are [".tmpl", ".html"].
		Extensions []string
		// Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Default is [].
		Funcs []template.FuncMap
		// Delims sets the action delimiters to the specified strings in the Delims struct.
		Delims Delims
		// Appends the given charset to the Content-Type header. Default is "UTF-8".
		Charset string
		// Outputs human readable JSON.
		IndentJSON bool
		// Outputs human readable XML.
		IndentXML bool
		// Prefixes the JSON output with the given bytes.
		PrefixJSON []byte
		// Prefixes the XML output with the given bytes.
		PrefixXML []byte
		// Allows changing of output to XHTML instead of HTML. Default is "text/html"
		HTMLContentType string
	}

	// HTMLOptions is a struct for overriding some rendering Options for specific HTML call
	HTMLOptions struct {
		// Layout template name. Overrides Options.Layout.
		Layout string
	}
)

type Render interface {
	http.ResponseWriter
	RW() http.ResponseWriter

	JSON(int, interface{})
	JSONString(interface{}) (string, error)
	RawData(int, []byte)
	RenderData(int, []byte)
	HTML(int, string, interface{}, ...HTMLOptions)
	HTMLSet(int, string, string, interface{}, ...HTMLOptions)
	HTMLString(string, interface{}, ...HTMLOptions) (string, error)
	HTMLSetString(string, string, interface{}, ...HTMLOptions) (string, error)
	XML(int, interface{})
	Error(int, ...string)
	Status(int)
	Redirect(string, ...int)
	SetTemplatePath(string, string)
}

func prepareOptions(options []RenderOptions) RenderOptions {
	var opt RenderOptions
	if len(options) > 0 {
		opt = options[0]
	}

	// Defaults.
	if len(opt.Directory) == 0 {
		opt.Directory = "templates"
	}
	if len(opt.Extensions) == 0 {
		opt.Extensions = []string{".tmpl", ".html"}
	}
	if len(opt.HTMLContentType) == 0 {
		opt.HTMLContentType = ContentHTML
	}

	return opt
}

func prepareCharset(charset string) string {
	if len(charset) != 0 {
		return "; charset=" + charset
	}

	return "; charset=" + defaultCharset
}

func getExt(s string) string {
	if strings.Index(s, ".") == -1 {
		return ""
	}
	return "." + strings.Join(strings.Split(s, ".")[1:], ".")
}

func compile(options RenderOptions) *template.Template {
	dir := options.Directory
	t := template.New(dir)
	t.Delims(options.Delims.Left, options.Delims.Right)
	// Parse an initial template in case we don't have any.
	template.Must(t.Parse("Macaron"))

	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		r, err := filepath.Rel(dir, path)
		if err != nil {
			return err
		}

		ext := getExt(r)

		for _, extension := range options.Extensions {
			if ext == extension {

				buf, err := ioutil.ReadFile(path)
				if err != nil {
					panic(err)
				}

				name := (r[0 : len(r)-len(ext)])
				tmpl := t.New(filepath.ToSlash(name))

				// add our funcmaps
				for _, funcs := range options.Funcs {
					tmpl.Funcs(funcs)
				}

				// Bomb out if parse fails. We don't want any silent server starts.
				template.Must(tmpl.Funcs(helperFuncs).Parse(string(buf)))
				break
			}
		}

		return nil
	})

	return t
}

// Renderer is a Middleware that maps a macaron.Render service into the Macaron handler chain.
// An single variadic macaron.RenderOptions struct can be optionally provided to configure
// HTML rendering. The default directory for templates is "templates" and the default
// file extension is ".tmpl" and ".html".
//
// If MACARON_ENV is set to "" or "development" then templates will be recompiled on every request. For more performance, set the
// MACARON_ENV environment variable to "production".
func Renderer(options ...RenderOptions) Handler {
	opt := prepareOptions(options)
	cs := prepareCharset(opt.Charset)
	t := compile(opt)
	bufpool = bpool.NewBufferPool(64)
	return func(ctx *Context, rw http.ResponseWriter, req *http.Request) {
		var tc *template.Template
		if Env == DEV {
			// recompile for easy development
			tc = compile(opt)
		} else {
			// use a clone of the initial template
			tc, _ = t.Clone()
		}
		r := &TplRender{
			ResponseWriter:  rw,
			Req:             req,
			t:               tc,
			Opt:             &opt,
			CompiledCharset: cs,
		}
		ctx.Data["TmplLoadTimes"] = func() string {
			if r.startTime.IsZero() {
				return ""
			}
			return fmt.Sprint(time.Since(r.startTime).Nanoseconds()/1e6) + "ms"
		}

		ctx.Render = r
		ctx.MapTo(r, (*Render)(nil))
	}
}

type TplRender struct {
	http.ResponseWriter
	Req             *http.Request
	t               *template.Template
	Opt             *RenderOptions
	CompiledCharset string

	startTime time.Time
}

func (r *TplRender) RW() http.ResponseWriter {
	return r.ResponseWriter
}

func (r *TplRender) JSON(status int, v interface{}) {
	var result []byte
	var err error
	if r.Opt.IndentJSON {
		result, err = json.MarshalIndent(v, "", "  ")
	} else {
		result, err = json.Marshal(v)
	}
	if err != nil {
		http.Error(r, err.Error(), 500)
		return
	}

	// json rendered fine, write out the result
	r.Header().Set(ContentType, ContentJSON+r.CompiledCharset)
	r.WriteHeader(status)
	if len(r.Opt.PrefixJSON) > 0 {
		r.Write(r.Opt.PrefixJSON)
	}
	r.Write(result)
}

func (r *TplRender) JSONString(v interface{}) (string, error) {
	var result []byte
	var err error
	if r.Opt.IndentJSON {
		result, err = json.MarshalIndent(v, "", "  ")
	} else {
		result, err = json.Marshal(v)
	}
	if err != nil {
		return "", err
	}
	return string(result), nil
}

func (r *TplRender) XML(status int, v interface{}) {
	var result []byte
	var err error
	if r.Opt.IndentXML {
		result, err = xml.MarshalIndent(v, "", "  ")
	} else {
		result, err = xml.Marshal(v)
	}
	if err != nil {
		http.Error(r, err.Error(), 500)
		return
	}

	// XML rendered fine, write out the result
	r.Header().Set(ContentType, ContentXML+r.CompiledCharset)
	r.WriteHeader(status)
	if len(r.Opt.PrefixXML) > 0 {
		r.Write(r.Opt.PrefixXML)
	}
	r.Write(result)
}

func (r *TplRender) data(status int, contentType string, v []byte) {
	if r.Header().Get(ContentType) == "" {
		r.Header().Set(ContentType, contentType)
	}
	r.WriteHeader(status)
	r.Write(v)
}

func (r *TplRender) RawData(status int, v []byte) {
	r.data(status, ContentBinary, v)
}

func (r *TplRender) RenderData(status int, v []byte) {
	r.data(status, ContentHTML, v)
}

func (r *TplRender) renderBytes(name string, binding interface{}, htmlOpt ...HTMLOptions) (*bytes.Buffer, error) {
	opt := r.prepareHTMLOptions(htmlOpt)

	if len(opt.Layout) > 0 {
		r.addYield(name, binding)
		name = opt.Layout
	}

	out, err := r.execute(name, binding)
	if err != nil {
		return nil, err
	}

	return out, nil
}

func (r *TplRender) HTML(status int, name string, binding interface{}, htmlOpt ...HTMLOptions) {
	r.startTime = time.Now()

	out, err := r.renderBytes(name, binding, htmlOpt...)
	if err != nil {
		http.Error(r, err.Error(), http.StatusInternalServerError)
		return
	}

	r.Header().Set(ContentType, r.Opt.HTMLContentType+r.CompiledCharset)
	r.WriteHeader(status)
	io.Copy(r, out)
	bufpool.Put(out)
}

func (r *TplRender) HTMLSet(status int, setName, name string, binding interface{}, htmlOpt ...HTMLOptions) {
	r.startTime = time.Now()

	out, err := r.renderBytes(name, binding, htmlOpt...)
	if err != nil {
		http.Error(r, err.Error(), http.StatusInternalServerError)
		return
	}

	r.Header().Set(ContentType, r.Opt.HTMLContentType+r.CompiledCharset)
	r.WriteHeader(status)
	io.Copy(r, out)
	bufpool.Put(out)
}

func (r *TplRender) HTMLString(name string, binding interface{}, htmlOpt ...HTMLOptions) (string, error) {
	if out, err := r.renderBytes(name, binding, htmlOpt...); err != nil {
		return "", err
	} else {
		return out.String(), nil
	}
}

func (r *TplRender) HTMLSetString(setName, name string, binding interface{}, htmlOpt ...HTMLOptions) (string, error) {
	if out, err := r.renderBytes(name, binding, htmlOpt...); err != nil {
		return "", err
	} else {
		return out.String(), nil
	}
}

// Error writes the given HTTP status to the current ResponseWriter
func (r *TplRender) Error(status int, message ...string) {
	r.WriteHeader(status)
	if len(message) > 0 {
		r.Write([]byte(message[0]))
	}
}

func (r *TplRender) Status(status int) {
	r.WriteHeader(status)
}

func (r *TplRender) Redirect(location string, status ...int) {
	code := http.StatusFound
	if len(status) == 1 {
		code = status[0]
	}

	http.Redirect(r, r.Req, location, code)
}

func (r *TplRender) execute(name string, binding interface{}) (*bytes.Buffer, error) {
	buf := bufpool.Get()
	return buf, r.t.ExecuteTemplate(buf, name, binding)
}

func (r *TplRender) addYield(name string, binding interface{}) {
	funcs := template.FuncMap{
		"yield": func() (template.HTML, error) {
			buf, err := r.execute(name, binding)
			// return safe html here since we are rendering our own template
			return template.HTML(buf.String()), err
		},
		"current": func() (string, error) {
			return name, nil
		},
	}
	r.t.Funcs(funcs)
}

func (r *TplRender) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions {
	if len(htmlOpt) > 0 {
		return htmlOpt[0]
	}

	return HTMLOptions{
		Layout: r.Opt.Layout,
	}
}

func (r *TplRender) SetTemplatePath(setName, dir string) {

}
<|endoftext|>


<commit_before>/*
Package selenium provider a Selenium/Webdriver client.

Currently provides only WebDriver remote client.
This means you'll need to run the Selenium server by yourself (or use a service
like SauceLabs). The easiest way to do that is to grab the Selenium server jar
from http://www.seleniumhq.org/download/ and run it
	java -jar selenium-server-standalone-2.24.1.jar

Example usage:

	// Run some code on play.golang.org and display the result
	package main

	import (
		"fmt"
		"time"

		"github.com/tebeka/selenium"
	)

	var code = `
	package main
	import "fmt"

	func main() {
		fmt.Println("Hello WebDriver!\n")
	}
	`

	// Errors are ignored for brevity.

	func main() {
		// FireFox driver without specific version
		caps := selenium.Capabilities{"browserName": "firefox"}
		wd, _ := selenium.NewRemote(caps, "")
		defer wd.Quit()

		// Get simple playground interface
		wd.Get("http://play.golang.org/?simple=1")

		// Enter code in textarea
		elem, _ := wd.FindElement(selenium.ByCSSSelector, "#code")
		elem.Clear()
		elem.SendKeys(code)

		// Click the run button
		btn, _ := wd.FindElement(selenium.ByCSSSelector, "#run")
		btn.Click()

		// Get the result
		div, _ := wd.FindElement(selenium.ByCSSSelector, "#output")

		output := ""
		// Wait for run to finish
		for {
			output, _ = div.Text()
			if output != "Waiting for remote server..." {
				break
			}
			time.Sleep(time.Millisecond * 100)
		}

		fmt.Printf("Got: %s\n", output)
	}
*/
package selenium
<commit_msg>Added notes about possible need for gecko driver<commit_after>/*
Package selenium provider a Selenium/Webdriver client.

Currently provides only WebDriver remote client.
This means you'll need to run the Selenium server by yourself (or use a service
like SauceLabs). The easiest way to do that is to grab the Selenium server jar
from http://www.seleniumhq.org/download/ and run it
	java -jar selenium-server-standalone-2.24.1.jar

To use the webdriver with firefox, you may (depending on versions) require the
gecko driver package. You can download it here
        https://github.com/mozilla/geckodriver/releases
and configure the webdriver in your Go code like this
        caps := selenium.Capabilities{
            "browserName":            "firefox",
            "webdriver.gecko.driver": "/path/to/downloaded/geckodriver",
        }

Example usage:

	// Run some code on play.golang.org and display the result
	package main

	import (
		"fmt"
		"time"

		"github.com/tebeka/selenium"
	)

	var code = `
	package main
	import "fmt"

	func main() {
		fmt.Println("Hello WebDriver!\n")
	}
	`

	// Errors are ignored for brevity.

	func main() {
		// FireFox driver without specific version
		// *** Add gecko driver here if necessary (see notes above.) ***
		caps := selenium.Capabilities{"browserName": "firefox"}
		wd, err := selenium.NewRemote(caps, "")
		if err != nil {
			panic(err)
		}
		defer wd.Quit()

		// Get simple playground interface
		wd.Get("http://play.golang.org/?simple=1")

		// Enter code in textarea
		elem, _ := wd.FindElement(selenium.ByCSSSelector, "#code")
		elem.Clear()
		elem.SendKeys(code)

		// Click the run button
		btn, _ := wd.FindElement(selenium.ByCSSSelector, "#run")
		btn.Click()

		// Get the result
		div, _ := wd.FindElement(selenium.ByCSSSelector, "#output")

		output := ""
		// Wait for run to finish
		for {
			output, _ = div.Text()
			if output != "Waiting for remote server..." {
				break
			}
			time.Sleep(time.Millisecond * 100)
		}

		fmt.Printf("Got: %s\n", output)
	}
*/
package selenium
<|endoftext|>


<commit_before>package reopen

import (
	"bufio"
	"io"
	"os"
	"sync"
	"time"
)

// Reopener interface defines something that can be reopened
type Reopener interface {
	Reopen() error
}

// Writer is a writer that also can be reopened
type Writer interface {
	Reopener
	io.Writer
}

// WriteCloser is a io.WriteCloser that can also be reopened
type WriteCloser interface {
	Reopener
	io.Writer
	io.Closer
}

// FileWriter that can also be reopened
type FileWriter struct {
	mu   sync.Mutex // ensures close / reopen / write are not called at the same time, protects f
	f    *os.File
	Name string
}

// Close calls the underlyding File.Close()
func (f *FileWriter) Close() error {
	f.mu.Lock()
	err := f.f.Close()
	f.mu.Unlock()
	return err
}

// mutex free version
func (f *FileWriter) reopen() error {
	if f.f != nil {
		f.f.Close()
		f.f = nil
	}
	newf, err := os.OpenFile(f.Name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		f.f = nil
		return err
	}
	f.f = newf

	return nil
}

// Reopen the file
func (f *FileWriter) Reopen() error {
	f.mu.Lock()
	err := f.reopen()
	f.mu.Unlock()
	return err
}

// Write implements the stander io.Writer interface
func (f *FileWriter) Write(p []byte) (int, error) {
	f.mu.Lock()
	n, err := f.f.Write(p)
	f.mu.Unlock()
	return n, err
}

// NewFileWriter opens a file for appending and writing and can be reopened.
// it is a ReopenWriteCloser...
func NewFileWriter(name string) (*FileWriter, error) {
	writer := FileWriter{
		f:    nil,
		Name: name,
	}
	err := writer.reopen()
	if err != nil {
		return nil, err
	}
	return &writer, nil
}

// BufferedFileWriter is buffer writer than can be reopned
type BufferedFileWriter struct {
	mu         sync.Mutex
	OrigWriter *FileWriter
	BufWriter  *bufio.Writer
}

// Reopen implement Reopener
func (bw *BufferedFileWriter) Reopen() error {
	bw.mu.Lock()
	bw.BufWriter.Flush()

	// use non-mutex version since we are using this one
	err := bw.OrigWriter.reopen()

	bw.BufWriter.Reset(io.Writer(bw.OrigWriter))
	bw.mu.Unlock()

	return err
}

// Close flushes the internal buffer and closes the destination file
func (bw *BufferedFileWriter) Close() error {
	bw.mu.Lock()
	bw.BufWriter.Flush()
	bw.OrigWriter.f.Close()
	bw.mu.Unlock()
	return nil
}

// Write implements io.Writer (and reopen.Writer)
func (bw *BufferedFileWriter) Write(p []byte) (int, error) {
	bw.mu.Lock()
	n, err := bw.BufWriter.Write(p)

	// Special Case... if the used space in the buffer is LESS than
	// the input, then we did a flush in the middle of the line
	// and the full log line was not sent on its way.
	if bw.BufWriter.Buffered() < len(p) {
		bw.BufWriter.Flush()
	}

	bw.mu.Unlock()
	return n, err
}

// flushDaemon periodically flushes the log file buffers.
//  props to glog
func (bw *BufferedFileWriter) flushDaemon() {
	for range time.NewTicker(flushInterval).C {
		bw.mu.Lock()
		bw.BufWriter.Flush()
		bw.OrigWriter.f.Sync()
		bw.mu.Unlock()
	}
}

const bufferSize = 256 * 1024
const flushInterval = 30 * time.Second

// NewBufferedFileWriter opens a buffered file that is periodically
//  flushed.
// TODO: allow size and interval to be passed in.
func NewBufferedFileWriter(w *FileWriter) *BufferedFileWriter {
	bw := BufferedFileWriter{
		OrigWriter: w,
		BufWriter:  bufio.NewWriterSize(w, bufferSize),
	}
	go bw.flushDaemon()
	return &bw
}

type multiReopenWriter struct {
	writers []Writer
}

// Reopen reopens all child Reopeners
func (t *multiReopenWriter) Reopen() error {
	for _, w := range t.writers {
		err := w.Reopen()
		if err != nil {
			return err
		}
	}
	return nil
}

// Write implements standard io.Write and reopen.Write
func (t *multiReopenWriter) Write(p []byte) (int, error) {
	for _, w := range t.writers {
		n, err := w.Write(p)
		if err != nil {
			return n, err
		}
		if n != len(p) {
			return n, io.ErrShortWrite
		}
	}
	return len(p), nil
}

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
//  Also allow reopen
func MultiWriter(writers ...Writer) Writer {
	w := make([]Writer, len(writers))
	copy(w, writers)
	return &multiReopenWriter{w}
}

type nopReopenWriter struct {
	io.Writer
}

func (nopReopenWriter) Reopen() error {
	return nil
}

// NopWriter turns a normal writer into a ReopenWriter
//  by doing a NOP on Reopen
// TODO: better name
func NopWriter(w io.Writer) Writer {
	return nopReopenWriter{w}
}

// Reopenable versions of os.Stdout and os.Stderr (reopen does nothing)
var (
	Stdout = NopWriter(os.Stdin)
	Stderr = NopWriter(os.Stdin)
)
<commit_msg>allow file permission to be added to NewFileWriter<commit_after>package reopen

import (
	"bufio"
	"io"
	"os"
	"sync"
	"time"
)

// Reopener interface defines something that can be reopened
type Reopener interface {
	Reopen() error
}

// Writer is a writer that also can be reopened
type Writer interface {
	Reopener
	io.Writer
}

// WriteCloser is a io.WriteCloser that can also be reopened
type WriteCloser interface {
	Reopener
	io.Writer
	io.Closer
}

// FileWriter that can also be reopened
type FileWriter struct {
	mu   sync.Mutex // ensures close / reopen / write are not called at the same time, protects f
	f    *os.File
	mode os.FileMode
	name string
}

// Close calls the underlyding File.Close()
func (f *FileWriter) Close() error {
	f.mu.Lock()
	err := f.f.Close()
	f.mu.Unlock()
	return err
}

// mutex free version
func (f *FileWriter) reopen() error {
	if f.f != nil {
		f.f.Close()
		f.f = nil
	}
	newf, err := os.OpenFile(f.name, os.O_WRONLY|os.O_APPEND|os.O_CREATE, f.mode)
	if err != nil {
		f.f = nil
		return err
	}
	f.f = newf

	return nil
}

// Reopen the file
func (f *FileWriter) Reopen() error {
	f.mu.Lock()
	err := f.reopen()
	f.mu.Unlock()
	return err
}

// Write implements the stander io.Writer interface
func (f *FileWriter) Write(p []byte) (int, error) {
	f.mu.Lock()
	n, err := f.f.Write(p)
	f.mu.Unlock()
	return n, err
}

// NewFileWriter opens a file for appending and writing and can be reopened.
// it is a ReopenWriteCloser...
func NewFileWriter(name string) (*FileWriter, error) {
	// Standard default mode
	return NewFileWriterMode(name, 0666)
}

// NewFileWriterMode opens a Reopener file with a specific permission
func NewFileWriterMode(name string, mode os.FileMode) (*FileWriter, error) {
	writer := FileWriter{
		f:    nil,
		name: name,
		mode: mode,
	}
	err := writer.reopen()
	if err != nil {
		return nil, err
	}
	return &writer, nil
}

// BufferedFileWriter is buffer writer than can be reopned
type BufferedFileWriter struct {
	mu         sync.Mutex
	OrigWriter *FileWriter
	BufWriter  *bufio.Writer
}

// Reopen implement Reopener
func (bw *BufferedFileWriter) Reopen() error {
	bw.mu.Lock()
	bw.BufWriter.Flush()

	// use non-mutex version since we are using this one
	err := bw.OrigWriter.reopen()

	bw.BufWriter.Reset(io.Writer(bw.OrigWriter))
	bw.mu.Unlock()

	return err
}

// Close flushes the internal buffer and closes the destination file
func (bw *BufferedFileWriter) Close() error {
	bw.mu.Lock()
	bw.BufWriter.Flush()
	bw.OrigWriter.f.Close()
	bw.mu.Unlock()
	return nil
}

// Write implements io.Writer (and reopen.Writer)
func (bw *BufferedFileWriter) Write(p []byte) (int, error) {
	bw.mu.Lock()
	n, err := bw.BufWriter.Write(p)

	// Special Case... if the used space in the buffer is LESS than
	// the input, then we did a flush in the middle of the line
	// and the full log line was not sent on its way.
	if bw.BufWriter.Buffered() < len(p) {
		bw.BufWriter.Flush()
	}

	bw.mu.Unlock()
	return n, err
}

// flushDaemon periodically flushes the log file buffers.
//  props to glog
func (bw *BufferedFileWriter) flushDaemon() {
	for range time.NewTicker(flushInterval).C {
		bw.mu.Lock()
		bw.BufWriter.Flush()
		bw.OrigWriter.f.Sync()
		bw.mu.Unlock()
	}
}

const bufferSize = 256 * 1024
const flushInterval = 30 * time.Second

// NewBufferedFileWriter opens a buffered file that is periodically
//  flushed.
// TODO: allow size and interval to be passed in.
func NewBufferedFileWriter(w *FileWriter) *BufferedFileWriter {
	bw := BufferedFileWriter{
		OrigWriter: w,
		BufWriter:  bufio.NewWriterSize(w, bufferSize),
	}
	go bw.flushDaemon()
	return &bw
}

type multiReopenWriter struct {
	writers []Writer
}

// Reopen reopens all child Reopeners
func (t *multiReopenWriter) Reopen() error {
	for _, w := range t.writers {
		err := w.Reopen()
		if err != nil {
			return err
		}
	}
	return nil
}

// Write implements standard io.Write and reopen.Write
func (t *multiReopenWriter) Write(p []byte) (int, error) {
	for _, w := range t.writers {
		n, err := w.Write(p)
		if err != nil {
			return n, err
		}
		if n != len(p) {
			return n, io.ErrShortWrite
		}
	}
	return len(p), nil
}

// MultiWriter creates a writer that duplicates its writes to all the
// provided writers, similar to the Unix tee(1) command.
//  Also allow reopen
func MultiWriter(writers ...Writer) Writer {
	w := make([]Writer, len(writers))
	copy(w, writers)
	return &multiReopenWriter{w}
}

type nopReopenWriter struct {
	io.Writer
}

func (nopReopenWriter) Reopen() error {
	return nil
}

// NopWriter turns a normal writer into a ReopenWriter
//  by doing a NOP on Reopen
// TODO: better name
func NopWriter(w io.Writer) Writer {
	return nopReopenWriter{w}
}

// Reopenable versions of os.Stdout and os.Stderr (reopen does nothing)
var (
	Stdout = NopWriter(os.Stdin)
	Stderr = NopWriter(os.Stdin)
)
<|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/jackc/pgx/v4/stdlib to use pgx as a database/sql compatible driver.

Establishing a Connection

The primary way of establishing a connection is with `pgx.Connect`.

    conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))

The database connection string can be in URL or DSN format. Both PostgreSQL settings and pgx settings can be specified
here. In addition, a config struct can be created by `ParseConfig` and modified before establishing the connection with
`ConnectConfig` to configure settings such as tracing that cannot be configured with a connection string.

Connection Pool

`*pgx.Conn` represents a single connection to the database and is not concurrency safe. Use sub-package pgxpool for a
concurrency safe connection pool.

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(context.Background(), "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 rows.Err()
    }

    // No errors found - do something with sum

ForEachRow can be used to execute a callback function for every row. This is often easier than iterating over rows
directly.

    var sum, n int32
    rows, _ := conn.Query(context.Background(), "select generate_series(1,$1)", 10)
    _, err := pgx.ForEachRow(rows, []any{&n}, func(pgx.QueryFuncRow) error {
      sum += n
      return nil
    })
    if err != nil {
      return err
    }

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

    var name string
    var weight int64
    err := conn.QueryRow(context.Background(), "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(context.Background(), "delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

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 package pgtype provides types that have a data field and a status field.
They work in a similar fashion to database/sql. The second is to use a pointer to a pointer.

    var foo pgtype.Varchar
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&foo, &bar)
    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. The pgtype package includes many more array types for PostgreSQL types that do not directly
map to native Go types.

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 converts netip.Prefix and netip.Addr to and from inet and cidr PostgreSQL types.

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. In addition, pgx uses the github.com/jackc/pgtype library to support more types. See
documention for that library for instructions on how to implement custom types.

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.

If pgx does cannot natively encode a type and that type is a renamed type (e.g. type MyTime time.Time) pgx will attempt
to encode the underlying type. While this is usually desired behavior it can produce surprising behavior if one the
underlying type and the renamed type each implement database/sql interfaces and the other implements pgx interfaces. It
is recommended that this situation be avoided by implementing pgx interfaces on the renamed type.

Composite types and row values

Row values and composite types are represented as pgtype.Record
(https://pkg.go.dev/github.com/jackc/pgtype?tab=doc#Record). It is possible to get values of your custom type by
implementing DecodeBinary interface. Decoding into pgtype.Record first can simplify process by avoiding dealing with raw
protocol directly.

For example:

    type MyType struct {
        a int      // NULL will cause decoding error
        b *string  // there can be NULL in this position in SQL
    }

    func (t *MyType) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
        r := pgtype.Record{
            Fields: []pgtype.Value{&pgtype.Int4{}, &pgtype.Text{}},
        }

        if err := r.DecodeBinary(ci, src); err != nil {
            return err
        }

        if r.Status != pgtype.Present {
            return errors.New("BUG: decoding should not be called on NULL value")
        }

        a := r.Fields[0].(*pgtype.Int4)
        b := r.Fields[1].(*pgtype.Text)

        // type compatibility is checked by AssignTo
        // only lossless assignments will succeed
        if err := a.AssignTo(&t.a); err != nil {
            return err
        }

        // AssignTo also deals with null value handling
        if err := b.AssignTo(&t.b); err != nil {
            return err
        }
        return nil
    }

    result := MyType{}
    err := conn.QueryRow(context.Background(), "select row(1, 'foo'::text)", pgx.QueryResultFormats{pgx.BinaryFormatCode}).Scan(&r)

Transactions

Transactions are started by calling Begin.

    tx, err := conn.Begin(context.Background())
    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(context.Background())

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

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

The Tx returned from Begin also implements the Begin method. This can be used to implement pseudo nested transactions.
These are internally implemented with savepoints.

Use BeginTx to control the transaction mode.

BeginFunc and BeginTxFunc are functions that begin a transaction, execute a function, and commit or rollback the
transaction depending on the return value of the function. These can be simpler and less error prone to use.

    err = pgx.BeginFunc(context.Background(), conn, func(tx pgx.Tx) error {
        _, err := tx.Exec(context.Background(), "insert into foo(id) values (1)")
        return err
    })
    if err != nil {
        return err
    }

Prepared Statements

Prepared statements can be manually created with the Prepare method. However, this is rarely necessary because pgx
includes an automatic statement cache by default. Queries run through the normal Query, QueryRow, and Exec functions are
automatically prepared on first execution and the prepared statement is reused on subsequent executions. See ParseConfig
for information on how to customize or disable the statement cache.

Copy Protocol

Use CopyFrom to efficiently insert multiple rows at a time using the PostgreSQL copy protocol. CopyFrom accepts a
CopyFromSource interface. If the data is already in a [][]any use CopyFromRows to wrap it in a CopyFromSource interface.
Or implement CopyFromSource to avoid buffering the entire data set in memory.

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

    copyCount, err := conn.CopyFrom(
        context.Background(),
        pgx.Identifier{"people"},
        []string{"first_name", "last_name", "age"},
        pgx.CopyFromRows(rows),
    )

When you already have a typed array using CopyFromSlice can be more convenient.

    rows := []User{
        {"John", "Smith", 36},
        {"Jane", "Doe", 29},
    }

    copyCount, err := conn.CopyFrom(
        context.Background(),
        pgx.Identifier{"people"},
        []string{"first_name", "last_name", "age"},
        pgx.CopyFromSlice(len(rows), func(i int) ([]any, error) {
            return []any{rows[i].FirstName, rows[i].LastName, rows[i].Age}, nil
        }),
    )

CopyFrom 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 `Conn.WaitForNotification` method. It blocks until a
notification is received or the context is canceled.

    _, err := conn.Exec(context.Background(), "listen channelname")
    if err != nil {
        return nil
    }

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

Tracing and Logging

pgx supports tracing by setting ConnConfig.Tracer.

In addition, the tracelog package provides the TraceLog type which lets a traditional logger act as a Tracer.

Lower Level PostgreSQL Functionality

pgx is implemented on top of github.com/jackc/pgconn a lower level PostgreSQL driver. The Conn.PgConn() method can be
used to access this lower layer.

PgBouncer

By default pgx automatically uses prepared statements. Prepared statements are incompaptible with PgBouncer. This can be
disabled by setting a different QueryExecMode in ConnConfig.DefaultQueryExecMode.
*/
package pgx
<commit_msg>Update to new package path<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/jackc/pgx/v4/stdlib to use pgx as a database/sql compatible driver.

Establishing a Connection

The primary way of establishing a connection is with `pgx.Connect`.

    conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL"))

The database connection string can be in URL or DSN format. Both PostgreSQL settings and pgx settings can be specified
here. In addition, a config struct can be created by `ParseConfig` and modified before establishing the connection with
`ConnectConfig` to configure settings such as tracing that cannot be configured with a connection string.

Connection Pool

`*pgx.Conn` represents a single connection to the database and is not concurrency safe. Use sub-package pgxpool for a
concurrency safe connection pool.

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(context.Background(), "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 rows.Err()
    }

    // No errors found - do something with sum

ForEachRow can be used to execute a callback function for every row. This is often easier than iterating over rows
directly.

    var sum, n int32
    rows, _ := conn.Query(context.Background(), "select generate_series(1,$1)", 10)
    _, err := pgx.ForEachRow(rows, []any{&n}, func(pgx.QueryFuncRow) error {
      sum += n
      return nil
    })
    if err != nil {
      return err
    }

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

    var name string
    var weight int64
    err := conn.QueryRow(context.Background(), "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(context.Background(), "delete from widgets where id=$1", 42)
    if err != nil {
        return err
    }
    if commandTag.RowsAffected() != 1 {
        return errors.New("No row found to delete")
    }

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 package pgtype provides types that have a data field and a status field.
They work in a similar fashion to database/sql. The second is to use a pointer to a pointer.

    var foo pgtype.Varchar
    var bar *string
    err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&foo, &bar)
    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. The pgtype package includes many more array types for PostgreSQL types that do not directly
map to native Go types.

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 converts netip.Prefix and netip.Addr to and from inet and cidr PostgreSQL types.

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. In addition, pgx uses the github.com/jackc/pgx/v5/pgtype library to support more types. See
documention for that library for instructions on how to implement custom types.

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.

If pgx does cannot natively encode a type and that type is a renamed type (e.g. type MyTime time.Time) pgx will attempt
to encode the underlying type. While this is usually desired behavior it can produce surprising behavior if one the
underlying type and the renamed type each implement database/sql interfaces and the other implements pgx interfaces. It
is recommended that this situation be avoided by implementing pgx interfaces on the renamed type.

Composite types and row values

Row values and composite types are represented as pgtype.Record
(https://pkg.go.dev/github.com/jackc/pgtype?tab=doc#Record). It is possible to get values of your custom type by
implementing DecodeBinary interface. Decoding into pgtype.Record first can simplify process by avoiding dealing with raw
protocol directly.

For example:

    type MyType struct {
        a int      // NULL will cause decoding error
        b *string  // there can be NULL in this position in SQL
    }

    func (t *MyType) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error {
        r := pgtype.Record{
            Fields: []pgtype.Value{&pgtype.Int4{}, &pgtype.Text{}},
        }

        if err := r.DecodeBinary(ci, src); err != nil {
            return err
        }

        if r.Status != pgtype.Present {
            return errors.New("BUG: decoding should not be called on NULL value")
        }

        a := r.Fields[0].(*pgtype.Int4)
        b := r.Fields[1].(*pgtype.Text)

        // type compatibility is checked by AssignTo
        // only lossless assignments will succeed
        if err := a.AssignTo(&t.a); err != nil {
            return err
        }

        // AssignTo also deals with null value handling
        if err := b.AssignTo(&t.b); err != nil {
            return err
        }
        return nil
    }

    result := MyType{}
    err := conn.QueryRow(context.Background(), "select row(1, 'foo'::text)", pgx.QueryResultFormats{pgx.BinaryFormatCode}).Scan(&r)

Transactions

Transactions are started by calling Begin.

    tx, err := conn.Begin(context.Background())
    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(context.Background())

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

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

The Tx returned from Begin also implements the Begin method. This can be used to implement pseudo nested transactions.
These are internally implemented with savepoints.

Use BeginTx to control the transaction mode.

BeginFunc and BeginTxFunc are functions that begin a transaction, execute a function, and commit or rollback the
transaction depending on the return value of the function. These can be simpler and less error prone to use.

    err = pgx.BeginFunc(context.Background(), conn, func(tx pgx.Tx) error {
        _, err := tx.Exec(context.Background(), "insert into foo(id) values (1)")
        return err
    })
    if err != nil {
        return err
    }

Prepared Statements

Prepared statements can be manually created with the Prepare method. However, this is rarely necessary because pgx
includes an automatic statement cache by default. Queries run through the normal Query, QueryRow, and Exec functions are
automatically prepared on first execution and the prepared statement is reused on subsequent executions. See ParseConfig
for information on how to customize or disable the statement cache.

Copy Protocol

Use CopyFrom to efficiently insert multiple rows at a time using the PostgreSQL copy protocol. CopyFrom accepts a
CopyFromSource interface. If the data is already in a [][]any use CopyFromRows to wrap it in a CopyFromSource interface.
Or implement CopyFromSource to avoid buffering the entire data set in memory.

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

    copyCount, err := conn.CopyFrom(
        context.Background(),
        pgx.Identifier{"people"},
        []string{"first_name", "last_name", "age"},
        pgx.CopyFromRows(rows),
    )

When you already have a typed array using CopyFromSlice can be more convenient.

    rows := []User{
        {"John", "Smith", 36},
        {"Jane", "Doe", 29},
    }

    copyCount, err := conn.CopyFrom(
        context.Background(),
        pgx.Identifier{"people"},
        []string{"first_name", "last_name", "age"},
        pgx.CopyFromSlice(len(rows), func(i int) ([]any, error) {
            return []any{rows[i].FirstName, rows[i].LastName, rows[i].Age}, nil
        }),
    )

CopyFrom 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 `Conn.WaitForNotification` method. It blocks until a
notification is received or the context is canceled.

    _, err := conn.Exec(context.Background(), "listen channelname")
    if err != nil {
        return nil
    }

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

Tracing and Logging

pgx supports tracing by setting ConnConfig.Tracer.

In addition, the tracelog package provides the TraceLog type which lets a traditional logger act as a Tracer.

Lower Level PostgreSQL Functionality

pgx is implemented on top of github.com/jackc/pgconn a lower level PostgreSQL driver. The Conn.PgConn() method can be
used to access this lower layer.

PgBouncer

By default pgx automatically uses prepared statements. Prepared statements are incompaptible with PgBouncer. This can be
disabled by setting a different QueryExecMode in ConnConfig.DefaultQueryExecMode.
*/
package pgx
<|endoftext|>


<commit_before>// TODO
package anolis
<commit_msg>making golint happy<commit_after>// Package anolis is an irc bot
package anolis
<|endoftext|>


<commit_before>// Package gobatch contains a batch processor. The main class is Batch,
// which can be created using New.
//
// The MinTime, MinItems, MaxTime, and MaxItems configuration parameters
// in BatchConfig are used to specify when and how many items are processed
// at once.
//
// These parameters may conflict, however; for example, during a slow time,
// MaxTime may be reached before MinItems are read. Thus it is necessary
// to prioritize the parameters. They are prioritized as follows (with EOF
// signifying the end of the input data):
//
//    MaxTime = MaxItems > EOF > MinItems > MinTime
//
// A few examples:
//
// MinTime = 2s. After 1s the input channel is closed. The items are
// processed right away.
//
// MinItems = 10, MinTime = 2s. After 1s, 10 items have been read. They are
// not processed until 2s has passed (along with all other items that have
// been read up to the 2s mark).
//
// MaxItems = 10, MinTime = 2s. After 1s, 10 items have been read. They are
// processed right away.
//
// Note that in all cases, the time and item counter is relative to the last
// batch.
package gobatch
<commit_msg>Update doc<commit_after>// Package gobatch contains a batch processor. The main class is Batch,
// which can be created using New. It reads from an implementation of the
// source.Source interface, and items are processed in batches by an
// implementation of the processor.Processor interface. Some Source and
// Processor implementations are provided in the source and processor
// packages, respectively, or you can create your own custom one.
//
// Batch uses the MinTime, MinItems, MaxTime, and MaxItems configuration
// parameters in BatchConfig to determine when and how many items are
// processed at once.
//
// These parameters may conflict, however; for example, during a slow time,
// MaxTime may be reached before MinItems are read. Thus it is necessary
// to prioritize the parameters in some way. They are prioritized as follows
// (with EOF signifying the end of the input data):
//
//    MaxTime = MaxItems > EOF > MinItems > MinTime
//
// A few examples:
//
// MinTime = 2s. After 1s the input channel is closed. The items are
// processed right away.
//
// MinItems = 10, MinTime = 2s. After 1s, 10 items have been read. They are
// not processed until 2s has passed (along with all other items that have
// been read up to the 2s mark).
//
// MaxItems = 10, MinTime = 2s. After 1s, 10 items have been read. They are
// processed right away.
//
// Note that the time and item counters are relative to when the last batch
// started processing.
package gobatch
<|endoftext|>


<commit_before>/*
Package sqlr is designed to reduce the effort required to implement
common operations performed with SQL databases. It is intended for programmers
who are comfortable with writing SQL, but would like assistance with the
sometimes tedious process of preparing SQL queries for tables that have a
large number of columns, or have a variable number of input parameters.

This GoDoc summary provides an overview of how to use this package. For
more detailed documentation, see https://jjeffery.github.io/sqlr.

Prepare SQL queries based on row structures

Preparing SQL queries with many placeholder arguments is tedious and error-prone. The following
insert query has a dozen placeholders, and it is difficult to match up the columns with the
placeholders. It is not uncommon to have tables with many more columns than this example, and the
level of difficulty increases with the number of columns in the table.
 insert into users(id,given_name,family_name,dob,ssn,street,locality,postcode,
 country,phone,mobile,fax) values(?,?,?,?,?,?,?,?,?,?,?,?)
This package uses reflection to simplify the construction of SQL queries. Supplementary information
about each database column is stored in the structure tag of the associated field.
 type User struct {
     ID          int       `sql:"primary key"`
     GivenName   string
     FamilyName  string
     DOB         time.Time
     SSN         string
     Street      string
     Locality    string
     Postcode    string
     Country     string
     Phone       string
     Mobile      string
     Facsimile   string    `sql:"fax"` // "fax" overrides the column name
 }
The calling program creates a schema, which describes rules for generating SQL statements. These
rules include specifying the SQL dialect (eg MySQL, Postgres, SQLite) and the naming convention
used to convert Go struct field names into column names (eg "GivenName" => "given_name"). The schema
is usually created during program initialization. Once created, a schema is immutable and can be
called concurrently from multiple goroutines.
 schema := MustCreateSchema(
   WithDialect(MySQL),
   WithNamingConvention(SnakeCase),
 )
A session is created using a context, a database connection (eg *sql.DB, *sql.Tx, *sql.Conn), and a
schema. A session is inexpensive to create, and is intended to last no longer than a single request
(which might be a HTTP request, in the case of a HTTP server). A session is bounded by the lifetime
of its context.
 sess := NewSession(ctx, tx, schema)
Once a session has been created, it is possible to create simple row insert/update statements with
minimal effort.
 var row User
 // ... populate row with data here and then ...

 // generates the correct SQL to insert a row into the users table
 rowsAffected, err := sess.Exec(row, "insert into users({}) values({})")

 // ... and then later on ...

 // generates the correct SQL to update a the matching row in the users table
 rowsAffected, err := sess.Exec(row, "update users set {} where {}")
The Exec method parses the SQL query and replaces occurrences of "{}" with the column names
or placeholders that make sense for the SQL clause in which they occur. In the example above,
the insert and update statements would look like:
 insert into users(`id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,
 `locality`,`postcode`,`country`,`phone`,`mobile`,`fax`) values(?,?,?,?,
 ?,?,?,?,?,?,?,?)

 update users set `given_name`=?,`family_name`=?,`dob`=?,`ssn`=?,`street`=?,
 `locality`=?,`postcode`=?,`country`=?,`phone`=?,`mobile`=?,`fax`=? where `id`=?
If the schema is created with a different dialect then the generated SQL will be different.
For example if the Postgres dialect was used the insert and update queries would look more like:
 insert into users("id","given_name","family_name","dob","ssn","street","locality",
 "postcode","country","phone","mobile","fax") values($1,$2,$3,$4,$5,$6,$7,$8,$9,
 $10,$11,$12)

 update users set "given_name"=$1,"family_name"=$2,"dob"=$3,"ssn"=$4,"street"=$5,
 "locality"=$6,"postcode"=$7,"country"=$8,"phone"=$9,"mobile"=$10,"fax"=$11
 where "id"=$12
Inserting and updating a single row are common enough operations that the session has methods
that make it very simple:
 sess.InsertRow(row)
 sess.UpdateRow(row)
Select queries are handled in a similar fashion:
 var rows []*User

 // will populate rows slice with the results of the query
 rowCount, err := sess.Select(&rows, "select {} from users where postcode = ?", postcode)

 var row User

 // will populate row with the first row returned by the query
 rowCount, err = sess.Select(&row, "select {} from users where {}", userID)

 // more complex query involving joins and aliases
 rowCount, err = sess.Select(&rows, `
     select {alias u}
     from users u
     inner join user_search_terms ust on ust.user_id = u.id
     where ust.search_term like ?
     order by {alias u}`, searchTermText + "%")
The SQL queries prepared in the above example would look like the following:
 select `id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,`locality`,
 `postcode`,`country`,`phone`,`mobile`,`fax` from users where postcode=?

 select `id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,`locality`,
 `postcode`,`country`,`phone`,`mobile`,`fax` from users where id=?

 select u.`id`,u.`given_name`,u.`family_name`,u.`dob`,u.`ssn`,u.`street`,
 u.`locality`,u.`postcode`,u.`country`,u.`phone`,u.`mobile`,u.`fax`
 from users u inner join user_search_terms ust on ust.user_id = u.id where
 ust.search_term_like ? order by u.`id`
The examples are using a MySQL dialect. If the schema had been setup for, say, a Postgres
dialect, a generated query would look more like:
 select "id","given_name","family_name","dob","ssn","street","locality",
 "postcode","country","phone","mobile","fax" from users where postcode=$1
It is an important point to note that this feature is not about writing the SQL for the programmer.
Rather it is about "filling in the blanks": allowing the programmer to specify as much of the
SQL query as they want without having to write the tiresome bits.

Autoincrement Column Values

When inserting rows, if a column is defined as an autoincrement column, then the generated
value will be retrieved from the database server, and the corresponding field in the row
structure will be updated.
 type Row {
   ID   int    `sql:"primary key autoincrement"`
   Name string
 }

 row := &Row{Name: "some name"}
 _, err := sess.InsertRow(row)
 if err != nil {
   log.Fatal(err)
 }

 // row.ID will contain the auto-generated value
 fmt.Println(row.ID)
Autoincrement column values work for all supported databases (PostgreSQL, MySQL,
Microsoft SQL Server and SQLite).

Null Columns

Most SQL database tables have columns that are nullable, and it can be tiresome to always
map to pointer types or special nullable types such as sql.NullString. In many cases it is
acceptable to map a database NULL value to the empty value for the corresponding Go struct
field.

Where it is acceptable to map a NULL value to an empty value and vice-versa, the Go struct
field can be marked with the "null" keyword in the field's struct tag.
 type Employee struct {
     ID        int     `sql:"primary key"`
     Name      string
     ManagerID int     `sql:"null"`
     Phone     string  `sql:"null"`
 }
In the above example the `manager_id` column can be null, but if all valid IDs are non-zero,
it is unambiguous to map a database NULL to the zero value. Similarly, if the `phone` column
is null it will be mapped to an empty string. An empty string in the Go struct field will
be mapped to NULL in the database.

Care should be taken, because there are cases where an empty value and a database NULL do not
represent the same thing. There are many cases, however, where this feature can be applied,
and the result is simpler code that is easier to read.

JSON Columns

It is not uncommon to serialize complex objects as JSON text for storage in an SQL database.
Native support for JSON is available in some database servers: in partcular Postgres has
excellent support for JSON.

It is straightforward to use this package to serialize a structure field to JSON:
 type SomethingComplex struct {
     Name       string
     Values     []int
     MoreValues map[string]float64
     // ... and more fields here ...
 }

 type Row struct {
     ID    int                `sql:"primary key"`
     Name  string
     Cmplx *SomethingComplex  `sql:"json"`
 }
In the example above the `Cmplx` field will be marshaled as JSON text when
writing to the database, and unmarshaled into the struct when reading from
the database.

WHERE IN Clauses with Multiple Values

While most SQL queries accept a fixed number of parameters, if the SQL query
contains a `WHERE IN` clause, it requires additional string manipulation to match
the number of placeholders in the query with args.

This package simplifies queries with a variable number of arguments. When processing
an SQL query, it detects if any of the arguments are slices:
 // GetWidgets returns all the widgets associated with the supplied IDs.
 func GetWidgets(sess *sqlr.Session, ids ...int) ([]*Widget, error) {
     var rows []*Widget
     _, err := sess.Select(&rows, `select {} from widgets where id in (?)`, ids)
     if err != nil {
       return nil, err
     }
     return widgets, nil
 }
In the above example, the number of placeholders ("?") in the query will be increased to
match the number of values in the `ids` slice. The expansion logic can handle any mix of
slice and scalar arguments.

Type-Safe Query Functions

A session can create type-safe query functions. This is a very powerful feature and makes
it very easy to create type-safe data access. See the Session.MakeQuery function for examples.

Performance and Caching

This package makes use of reflection in order to build the SQL that is sent
to the database server, and this imposes a performance penalty. In order
to reduce this overhead each schema instance caches queries generated.
The goal is for queries generated by this package to have performance
as close as possible to equivalent hand-constructed SQL queries that call
package "database/sql" directly.

Source Code

The source code for this package is available at https://github.com/jjeffery/sqlr.
*/
package sqlr
<commit_msg>Update godoc comment to match v0.6 API.<commit_after>/*
Package sqlr is designed to reduce the effort required to work with SQL databases.
It is intended for programmers who are comfortable with writing SQL, but would
like assistance with the sometimes tedious process of preparing SQL queries for
tables that have a large number of columns, or have a variable number of input parameters.

This GoDoc summary provides an overview of how to use this package. For
more detailed documentation, see https://jjeffery.github.io/sqlr.

Prepare SQL queries based on row structures

Preparing SQL queries with many placeholder arguments is tedious and error-prone. The following
insert query has a dozen placeholders, and it is difficult to match up the columns with the
placeholders. It is not uncommon to have tables with many more columns than this example, and the
level of difficulty increases with the number of columns in the table.
 insert into users(id,given_name,family_name,dob,ssn,street,locality,postcode,
 country,phone,mobile,fax) values(?,?,?,?,?,?,?,?,?,?,?,?)
This package uses reflection to simplify the construction of SQL queries. Supplementary information
about each database column is stored in the structure tag of the associated field.
 type User struct {
     ID          int       `sql:"primary key"`
     GivenName   string
     FamilyName  string
     DOB         time.Time
     SSN         string
     Street      string
     Locality    string
     Postcode    string
     Country     string
     Phone       string
     Mobile      string
     Facsimile   string    `sql:"fax"` // "fax" overrides the column name
 }
The calling program creates a schema, which describes rules for generating SQL statements. These
rules include specifying the SQL dialect (eg MySQL, Postgres, SQLite) and the naming convention
used to convert Go struct field names into column names (eg "GivenName" => "given_name"). The schema
is usually created during program initialization. Once created, a schema is immutable and can be
called concurrently from multiple goroutines.
 schema := MustCreateSchema(
   WithDialect(MySQL),
   WithNamingConvention(SnakeCase),
 )
A session is created using a context, a database connection (eg *sql.DB, *sql.Tx, *sql.Conn), and a
schema. A session is inexpensive to create, and is intended to last no longer than a single request
(which might be a HTTP request, in the case of a HTTP server). A session is bounded by the lifetime
of its context.
 session := NewSession(ctx, tx, schema)
Once a session has been created, it is possible to create simple row insert/update statements with
minimal effort.
 var row User
 // ... populate row with data here and then ...

 // generates the correct SQL to insert a row into the users table
 result, err := session.Row(row).Exec("insert into users({}) values({})")

 // ... and then later on ...

 // generates the correct SQL to update a the matching row in the users table
 result, err := session.Row(row).Exec("update users set {} where {}")
The Exec method parses the SQL query and replaces occurrences of "{}" with the column names
or placeholders that make sense for the SQL clause in which they occur. In the example above,
the insert and update statements would look like:
 insert into users(`id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,
 `locality`,`postcode`,`country`,`phone`,`mobile`,`fax`) values(?,?,?,?,
 ?,?,?,?,?,?,?,?)

 update users set `given_name`=?,`family_name`=?,`dob`=?,`ssn`=?,`street`=?,
 `locality`=?,`postcode`=?,`country`=?,`phone`=?,`mobile`=?,`fax`=? where `id`=?
If the schema is created with a different dialect then the generated SQL will be different.
For example if the Postgres dialect was used the insert and update queries would look more like:
 insert into users("id","given_name","family_name","dob","ssn","street","locality",
 "postcode","country","phone","mobile","fax") values($1,$2,$3,$4,$5,$6,$7,$8,$9,
 $10,$11,$12)

 update users set "given_name"=$1,"family_name"=$2,"dob"=$3,"ssn"=$4,"street"=$5,
 "locality"=$6,"postcode"=$7,"country"=$8,"phone"=$9,"mobile"=$10,"fax"=$11
 where "id"=$12
Inserting and updating a single row are common enough operations that the session has methods
that make it very simple:
 session.InsertRow(row)
 session.UpdateRow(row)
Select queries can be performed using the session's Select method:
 var rows []*User

 // will populate rows slice with the results of the query
 rowCount, err := session.Select(&rows, "select {} from users where postcode = ?", postcode)

 var row User

 // will populate row with the first row returned by the query
 rowCount, err = session.Select(&row, "select {} from users where {}", userID)

 // more complex query involving joins and aliases
 rowCount, err = session.Select(&rows, `
     select {alias u}
     from users u
     inner join user_search_terms ust on ust.user_id = u.id
     where ust.search_term like ?
     order by {alias u}`, searchTermText + "%")
The SQL queries prepared in the above example would look like the following:
 select `id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,`locality`,
 `postcode`,`country`,`phone`,`mobile`,`fax` from users where postcode=?

 select `id`,`given_name`,`family_name`,`dob`,`ssn`,`street`,`locality`,
 `postcode`,`country`,`phone`,`mobile`,`fax` from users where id=?

 select u.`id`,u.`given_name`,u.`family_name`,u.`dob`,u.`ssn`,u.`street`,
 u.`locality`,u.`postcode`,u.`country`,u.`phone`,u.`mobile`,u.`fax`
 from users u inner join user_search_terms ust on ust.user_id = u.id where
 ust.search_term_like ? order by u.`id`
The examples are using a MySQL dialect. If the schema had been setup for, say, a Postgres
dialect, a generated query would look more like:
 select "id","given_name","family_name","dob","ssn","street","locality",
 "postcode","country","phone","mobile","fax" from users where postcode=$1
It is an important point to note that this feature is not about writing the SQL for the programmer.
Rather it is about "filling in the blanks": allowing the programmer to specify as much of the
SQL query as they want without having to write the tiresome bits.

Autoincrement Column Values

When inserting rows, if a column is defined as an autoincrement column, then the generated
value will be retrieved from the database server, and the corresponding field in the row
structure will be updated.
 type Row {
   ID   int    `sql:"primary key autoincrement"`
   Name string
 }

 row := &Row{Name: "some name"}
 _, err := session.InsertRow(row)
 if err != nil {
   log.Fatal(err)
 }

 // row.ID will contain the auto-generated value
 fmt.Println(row.ID)
Autoincrement column values work for all supported databases (PostgreSQL, MySQL,
Microsoft SQL Server and SQLite).

Null Columns

Most SQL database tables have columns that are nullable, and it can be tiresome to always
map to pointer types or special nullable types such as sql.NullString. In many cases it is
acceptable to map the zero value for the field a database NULL in the corresponding database
column.

Where it is acceptable to map a zero value to a NULL database column, the Go struct field can
be marked with the "null" keyword in the field's struct tag.
 type Employee struct {
     ID        int     `sql:"primary key"`
     Name      string
     ManagerID int     `sql:"null"`
     Phone     string  `sql:"null"`
 }
In the above example the `manager_id` column can be null, but if all valid IDs are non-zero,
it is unambiguous to map the zero value to a database NULL. Similarly, if the `phone` column
an empty string it will be stored as a NULL in the database.

Care should be taken, because there are cases where a zero value and a database NULL do not
represent the same thing. There are many cases, however, where this feature can be applied,
and the result is simpler code that is easier to read.

JSON Columns

It is not uncommon to serialize complex objects as JSON text for storage in an SQL database.
Native support for JSON is available in some database servers: in partcular Postgres has
excellent support for JSON.

It is straightforward to use this package to serialize a structure field to JSON:
 type SomethingComplex struct {
     Name       string
     Values     []int
     MoreValues map[string]float64
     // ... and more fields here ...
 }

 type Row struct {
     ID    int                `sql:"primary key"`
     Name  string
     Cmplx *SomethingComplex  `sql:"json"`
 }
In the example above the `Cmplx` field will be marshaled as JSON text when
writing to the database, and unmarshaled into the struct when reading from
the database.

WHERE IN Clauses with Multiple Values

While most SQL queries accept a fixed number of parameters, if the SQL query
contains a `WHERE IN` clause, it requires additional string manipulation to match
the number of placeholders in the query with args.

This package simplifies queries with a variable number of arguments. When processing
an SQL query, it detects if any of the arguments are slices:
 // GetWidgets returns all the widgets associated with the supplied IDs.
 func GetWidgets(session *sqlr.Session, ids ...int) ([]*Widget, error) {
     var rows []*Widget
     _, err := session.Select(&rows, `select {} from widgets where id in (?)`, ids)
     if err != nil {
       return nil, err
     }
     return widgets, nil
 }
In the above example, the number of placeholders ("?") in the query will be increased to
match the number of values in the `ids` slice. The expansion logic can handle any mix of
slice and scalar arguments.

Type-Safe Query Functions

A session can create type-safe query functions. This is a very powerful feature and makes
it very easy to create type-safe data access. See the Session.MakeQuery function for examples.
*/
package sqlr
<|endoftext|>


<commit_before>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
    esc [-o outfile.go] [-pkg package] [-prefix prefix] [name ...]

The flags are:
    -o=""
        output filename, defaults to stdout
    -pkg="main"
        package name of output file, defaults to main
    -prefix=""
        strip given prefix from filenames

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

HTTP Example

Embedded assets can be served with HTTP using the http.FileServer. Assuming you have a directory called "static" and
have run "esc static > static.go" and main.go has the following code:

    package main

    import (
        "log"
        "net/http"
    )

    func main() {
        //FS() is created by esc and returns a http.Filesystem compatible with http.FileServer
        http.Handle("/static/", http.FileServer(FS(false)))

        //Start the server
        if err := http.ListenAndServe(":8080", nil); err != nil {
            log.Fatal("HTTP Server failed: ", err)
        }
    }

You can now execute "go run main.go static.go" and access the embedded files in a
browser via http://localhost:8080/static/

*/
package main
<commit_msg>Update doc.go<commit_after>/*

esc embeds files into go programs and provides http.FileSystem interfaces
to them.

It adds all named files or files recursively under named directories at the
path specified. The output file provides an http.FileSystem interface with
zero dependencies on packages outside the standard library.

Usage:
    esc [-o outfile.go] [-pkg package] [-prefix prefix] [name ...]

The flags are:
    -o=""
        output filename, defaults to stdout
    -pkg="main"
        package name of output file, defaults to main
    -prefix=""
        strip given prefix from filenames

Accessing Embedded Files

After producing an output file, the assets may be accessed with the FS()
function, which takes a flag to use local assets instead (for local
development).

Example

Embedded assets can be served with HTTP using the http.FileServer. Assuming you have a directory called "static" and
have run "esc -o static.go static" and main.go has the following code:

    package main

    import (
        "log"
        "net/http"
    )

    func main() {
        //FS() is created by esc and returns a http.Filesystem compatible with http.FileServer
        http.Handle("/static/", http.FileServer(FS(false)))
        log.Fatal(http.ListenAndServe(":8080", nil))
    }

You can now execute "go run main.go static.go" and access the embedded files in a
browser via http://localhost:8080/static/

*/
package main
<|endoftext|>


<commit_before>// Package slack is a client library for Slack.

// Usage:
/*
  package main

  import (
    "github.com/Bowery/slack"
  )

  var (
    client *slack.Client
  )

  func main() {
    client = slack.NewClient("API_TOKEN")
    err := client.SendMessage("#mychannel", "message", "username")
    if err != nil {
      log.Fatal(err)
    }
  }
*/

package slack
<commit_msg>fix godoc fmt<commit_after>// Package slack is a client library for Slack.
//
// Usage:
/*
  package main

  import (
    "github.com/Bowery/slack"
  )

  var (
    client *slack.Client
  )

  func main() {
    client = slack.NewClient("API_TOKEN")
    err := client.SendMessage("#mychannel", "message", "username")
    if err != nil {
      log.Fatal(err)
    }
  }
*/

package slack
<|endoftext|>


<commit_before>/*
Package exif44 encodes and decodes Exif metadata in TIFF and JPEG files. See the README in the repository for notes and limitations.
*/
package exif44
<commit_msg>expand package comment<commit_after>/*
Package exif44 encodes and decodes Exif metadata in TIFF and JPEG
files. See the README in the repository for notes and limitations.

The high-level interfaces are Read / ReadFile for read-only processing
and ReadWrite / ReadWriteFile for read-write processing. These are
procedures that take a control structure with callbacks for
user-defined processing. Structuring it this way makes it possible for
the library itself to handle the details of processing JPEG files that
contain multiple images using the Multi-Picture Format (MPF), aka
Multi-Picture Object (MPO). This is a JPEG extension used by various
cameras to store multiple images in a single file, typically for large
preview images or steroscopic images.

The high-level interfaces are implemented using lower-level interfaces,
which in turn using the tiff66 and jpegsegs libraries which are
packaged separately.
*/
package exif44
<|endoftext|>


<commit_before>package sgr

// Typical usage is to use Parseln() or MustParseln(), and use the resulting string in succeeding `fmt` or `log` calls.

// ```go
// package main

// import (
// 	"fmt"
// 	"github.com/foize/go.sgr"
// )

// func main() {
// 	exampleString := sgr.MustParseln("This is an example: [fg-red bold] important text [reset] normal text again.")
// 	fmt.Print(exampleString)

// 	secretNumberFormat := sgr.MustParseln("The secret number is [bg-17 blink]%d")
// 	fmt.Printf(secretNumberFormat, 42)

// 	fmt.Println("This text is normal again, MustParseln puts a reset at the end of the line.")
// }
// ```
<commit_msg>Updated doc.go<commit_after>/*
Typical usage is to use Parseln() or MustParseln(), and use the resulting string in succeeding `fmt` or `log` calls.

```go
package main

import (
	"fmt"
	"github.com/foize/go.sgr"
)

func main() {
	exampleString := sgr.MustParseln("This is an example: [fg-red bold] important text [reset] normal text again.")
	fmt.Print(exampleString)

	secretNumberFormat := sgr.MustParseln("The secret number is [bg-17 blink]%d")
	fmt.Printf(secretNumberFormat, 42)

	fmt.Println("This text is normal again, MustParseln puts a reset at the end of the line.")
}
```
*/
package sgr
<|endoftext|>


<commit_before>// Copyright 2014 The gocui 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 gocui allows to create console user interfaces.

Create a new GUI:

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		// handle error
	}
	defer g.Close()

	// Set layout and key bindings
	// ...

	if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
		// handle error
	}

Set the layout function:

	g.SetLayout(fcn)

On each iteration of the GUI's main loop, the "layout function" is executed.
These layout functions can be used to set-up and update the application's main
views, being possible to freely switch between them. Also, it is important to
mention that a main loop iteration is executed on each reported event
(key-press, mouse event, window resize, etc).

GUIs are composed by Views, you can think of it as buffers. Views implement the
io.ReadWriter interface, so you can just write to them if you want to modify
their content. The same is valid for reading.

Create and initialize a view with absolute coordinates:

	if v, err := g.SetView("viewname", 2, 2, 22, 7); err != nil {
		if err != gocui.ErrUnknownView {
			// handle error
		}
		fmt.Fprintln(v, "This is a new view")
		// ...
	}

Views can also being created using relative coordinates:

	maxX, maxY := g.Size()
	if v, err := g.SetView("viewname", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
		// ...
	}

IMPORTANT: Views can only be created, destroyed or updated in two ways: from a
layout funcion or via *Gui.Execute(). The reason for this is that it allows
gocui to be conccurent-safe. So, if you want to update your GUI from a
goroutine, you must use *Gui.Execute(). For example:

	g.Execute(func(g *gocui.Gui) error {
		v, err := g.View("viewname")
		if err != nil {
			// handle error
		}
		v.Clear()
		fmt.Fprintln(v, "Writing from different goroutines")
		return nil
	})

Configure keybindings:

	if err := g.SetKeybinding("viewname", gocui.KeyEnter, gocui.ModNone, fcn); err != nil {
		// handle error
	}

gocui implements full mouse support than can be enabled with:

	g.Mouse = true

Mouse events are handled like any other keybinding:

	if err := g.SetKeybinding("viewname", gocui.MouseLeft, gocui.ModNone, fcn); err != nil {
		// handle error
	}

By default, gocui provides a basic edition mode. This mode can be extended
and customized creating a new Editor and assigning it to *Gui.Editor:

	type Editor interface {
		Edit(v *View, key Key, ch rune, mod Modifier)
	}

DefaultEditor can be taken as example to create your own custom Editor:

	var DefaultEditor = EditorFunc(simpleEditor)

	func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
		switch {
		case ch != 0 && mod == 0:
			v.EditWrite(ch)
		case key == KeySpace:
			v.EditWrite(' ')
		case key == KeyBackspace || key == KeyBackspace2:
			v.EditDelete(true)
		// ...
		}
	}

For more information, see the examples in folder "_examples/".
*/
package gocui
<commit_msg>Update doc<commit_after>// Copyright 2014 The gocui 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 gocui allows to create console user interfaces.

Create a new GUI:

	g := gocui.NewGui()
	if err := g.Init(); err != nil {
		// handle error
	}
	defer g.Close()

	// Set layout and key bindings
	// ...

	if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
		// handle error
	}

Set the layout function:

	g.SetLayout(fcn)

On each iteration of the GUI's main loop, the "layout function" is executed.
These layout functions can be used to set-up and update the application's main
views, being possible to freely switch between them. Also, it is important to
mention that a main loop iteration is executed on each reported event
(key-press, mouse event, window resize, etc).

GUIs are composed by Views, you can think of it as buffers. Views implement the
io.ReadWriter interface, so you can just write to them if you want to modify
their content. The same is valid for reading.

Create and initialize a view with absolute coordinates:

	if v, err := g.SetView("viewname", 2, 2, 22, 7); err != nil {
		if err != gocui.ErrUnknownView {
			// handle error
		}
		fmt.Fprintln(v, "This is a new view")
		// ...
	}

Views can also being created using relative coordinates:

	maxX, maxY := g.Size()
	if v, err := g.SetView("viewname", maxX/2-30, maxY/2, maxX/2+30, maxY/2+2); err != nil {
		// ...
	}

IMPORTANT: Views can only be created, destroyed or updated in two ways: from a
layout funcion or via *Gui.Execute(). The reason for this is that it allows
gocui to be conccurent-safe. So, if you want to update your GUI from a
goroutine, you must use *Gui.Execute(). For example:

	g.Execute(func(g *gocui.Gui) error {
		v, err := g.View("viewname")
		if err != nil {
			// handle error
		}
		v.Clear()
		fmt.Fprintln(v, "Writing from different goroutines")
		return nil
	})

Configure keybindings:

	if err := g.SetKeybinding("viewname", gocui.KeyEnter, gocui.ModNone, fcn); err != nil {
		// handle error
	}

gocui implements full mouse support than can be enabled with:

	g.Mouse = true

Mouse events are handled like any other keybinding:

	if err := g.SetKeybinding("viewname", gocui.MouseLeft, gocui.ModNone, fcn); err != nil {
		// handle error
	}

By default, gocui provides a basic edition mode. This mode can be extended
and customized creating a new Editor and assigning it to *Gui.Editor:

	type Editor interface {
		Edit(v *View, key Key, ch rune, mod Modifier)
	}

DefaultEditor can be taken as example to create your own custom Editor:

	var DefaultEditor Editor = EditorFunc(simpleEditor)

	func simpleEditor(v *View, key Key, ch rune, mod Modifier) {
		switch {
		case ch != 0 && mod == 0:
			v.EditWrite(ch)
		case key == KeySpace:
			v.EditWrite(' ')
		case key == KeyBackspace || key == KeyBackspace2:
			v.EditDelete(true)
		// ...
		}
	}

For more information, see the examples in folder "_examples/".
*/
package gocui
<|endoftext|>


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

// commandmocker is a simple utility for tests in Go. It adds command with
// expected output to the path.
//
// For example, if you want to mock the command "ssh", you can write a test that
// looks like this:
//
//     import (
//         "github.com/timeredbull/commandmocker"
//         "testing"
//     )
//
//     func TestScreamsIfSSHFail(t *testing.T) {
// 		msg := "ssh: Could not resolve hostname myhost: nodename nor servname provided, or not known"
//         path, err := commandmocker.Add("ssh", msg)
//         if err != nil {
//             t.Error(err)
//             t.FailNow()
//         }
//         defer commandmocker.Remove(path)
//
//         // write your test and expectations
//     }
//
// Please notice that commandmocker is intended for testing only.
package commandmocker
<commit_msg>doc: fix indentation<commit_after>// Copyright 2012 commandmocker authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// commandmocker is a simple utility for tests in Go. It adds command with
// expected output to the path.
//
// For example, if you want to mock the command "ssh", you can write a test that
// looks like this:
//
//     import (
//         "github.com/timeredbull/commandmocker"
//         "testing"
//     )
//
//     func TestScreamsIfSSHFail(t *testing.T) {
//     msg := "ssh: Could not resolve hostname myhost: nodename nor servname provided, or not known"
//         path, err := commandmocker.Add("ssh", msg)
//         if err != nil {
//             t.Error(err)
//             t.FailNow()
//         }
//         defer commandmocker.Remove(path)
//
//         // write your test and expectations
//     }
//
// Please notice that commandmocker is intended for testing only.
package commandmocker
<|endoftext|>


<commit_before>/*
Package route is a helper for the Core (https://github.com/volatile/core).
It provides syntactic sugar that create a handler filtered by request's method and path.

Usage

Example:

	package main

	import (
		"fmt"

		"github.com/volatile/core"
		"github.com/volatile/route"
	)

	func main() {
		route.Get("^/$", func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Hello, World!")
		})

		// Named parameters
		route.Get("^/(?P<name>[A-Za-z]+)$", func(c *core.Context, params map[string]string) {
			fmt.Fprintf(c.ResponseWriter, "Hello, %s!", params["name"])
		})

		core.Run()
	}

Method filtering

Functions exists for the most common and standard HTTP methods.
If you need to handle custom methods, use the Use function with the methods in a strings slice as the first parameter.

Remember that HTTP methods are case-sensitive (see RFC 2616 5.1.1 (https://tools.ietf.org/html/rfc2616#section-5.1.1)).

Path filtering

A regular expression is used to match the request path.
So you keep a full control over your routing strategies.
We think the regular expressions offer the best balance between performance and power for this kind of job.

If you need to use named parameters from the URL, just use a regexp named group like (?P<id>[0-9]+) and a func(c *core.Context, map[string]string) handler type.
*/
package route
<commit_msg>Update doc<commit_after>/*
Package route is a helper for the Core (https://github.com/volatile/core).
It provides syntactic sugar that create a handler filtered by request's method and path.

Installation

In the terminal:

	$ go get github.com/volatile/route

Usage

Example:

	package main

	import (
		"fmt"

		"github.com/volatile/core"
		"github.com/volatile/route"
	)

	func main() {
		route.Get("^/$", func(c *core.Context) {
			fmt.Fprint(c.ResponseWriter, "Hello, World!")
		})

		// Named parameters
		route.Get("^/(?P<name>[A-Za-z]+)$", func(c *core.Context, params map[string]string) {
			fmt.Fprintf(c.ResponseWriter, "Hello, %s!", params["name"])
		})

		core.Run()
	}

Method filtering

Functions exists for the most common and standard HTTP methods.
If you need to handle custom methods, use the Use function with the methods in a strings slice as the first parameter.

Remember that HTTP methods are case-sensitive (see RFC 2616 5.1.1 (https://tools.ietf.org/html/rfc2616#section-5.1.1)).

Path filtering

A regular expression is used to match the request path.
So you keep a full control over your routing strategies.
We think the regular expressions offer the best balance between performance and power for this kind of job.

If you need to use named parameters from the URL, just use a regexp named group like (?P<id>[0-9]+) and a func(c *core.Context, map[string]string) handler type.
*/
package route
<|endoftext|>