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

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

Usage:

	% tsuru <command> [args]

The currently available commands are (grouped by subject):

	target            changes or retrive the current tsuru server
	version           displays current tsuru version

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

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

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

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

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

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

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

Change/retrieve remote tsuru server

Usage:

	% tsuru target [target]

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

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

Check current version

Usage:

	% tsuru version

This command returns the current version of tsuru command.

Create a user

Usage:

	% tsuru user-create <email>

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

Authenticate within remote tsuru server

Usage:

	% tsuru login <email>

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

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

Logout from remote tsuru server

Usage:

	% tsuru logout

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

Add SSH public key to tsuru's git server

Usage:

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

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

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

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

Remove SSH public key from tsuru's git server

Usage:

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

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

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

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

Create a new team for the user

Usage:

	% tsuru team-create <teamname>

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

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

List teams that the user is member of

Usage:

	% tsuru team-list

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

Add a user to a team

Usage:

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

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

Remove a user from a team

Usage:

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

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

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

Create an app

Usage:

	% tsuru app-create <appname> <platform>

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

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

Remove an app

Usage:

	% tsuru app-remove <appname>

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

List apps that the user has access to

Usage:

	% tsuru app-list

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

Allow a team to access an app

Usage:

	% tsuru app-grant <appname> <teamname>

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

Revoke from a team access to an app

Usage:

	% tsuru app-revoke <appname> <teamname>

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

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

See app's logs

Usage:

	% tsuru log <appname>

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

Run an arbitrary command in the app machine

Usage:

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

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

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

Restart the app's application server

Usage:

	% tsuru restart <appname>

Restart will call the restart hook from the app platform (the "restart" hook
from the Juju charm).
*/
package documentation
<commit_msg>cmd/tsuru: fix typo and minor improvement in text<commit_after>/*
tsuru is a command line tool for application developers.

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

Usage:

	% tsuru <command> [args]

The currently available commands are (grouped by subject):

	target            changes or retrive the current tsuru server
	version           displays current tsuru version

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

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

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

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

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

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

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

Change/retrieve remote tsuru server

Usage:

	% tsuru target [target]

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

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

Check current version

Usage:

	% tsuru version

This command returns the current version of tsuru command.

Create a user

Usage:

	% tsuru user-create <email>

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

Authenticate within remote tsuru server

Usage:

	% tsuru login <email>

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

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

Logout from remote tsuru server

Usage:

	% tsuru logout

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

Add SSH public key to tsuru's git server

Usage:

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

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

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

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

Remove SSH public key from tsuru's git server

Usage:

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

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

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

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

Create a new team for the user

Usage:

	% tsuru team-create <teamname>

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

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

List teams that the user is member of

Usage:

	% tsuru team-list

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

Add a user to a team

Usage:

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

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

Remove a user from a team

Usage:

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

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

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

Create an app

Usage:

	% tsuru app-create <appname> <platform>

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

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

Remove an app

Usage:

	% tsuru app-remove <appname>

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

List apps that the user has access to

Usage:

	% tsuru app-list

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

Allow a team to access an app

Usage:

	% tsuru app-grant <appname> <teamname>

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

Revoke from a team access to an app

Usage:

	% tsuru app-revoke <appname> <teamname>

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

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

See app's logs

Usage:

	% tsuru log <appname>

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

Run an arbitrary command in the app machine

Usage:

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

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

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

Restart the app's application server

Usage:

	% tsuru restart <appname>

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


<commit_before>/*
 * doc.go
 *
 * Copyright 2013-2015 Krzysztof Wilczynski
 *
 * 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 magic implements
 See: http://www.darwinsys.com/file/
*/
package magic
<commit_msg>[ci skip] More updates as per the golint tool.<commit_after>/*
 * doc.go
 *
 * Copyright 2013-2015 Krzysztof Wilczynski
 *
 * 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 magic implements simple interface to libmagic for Go Programming Language.
*/
package magic
<|endoftext|>


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

/*
Package maps provides a client library for the Google Maps Web Service APIs.
Please see https://developers.google.com/maps/documentation/webservices/ for
an overview of the Maps Web Service API suite.
*/
package maps
<commit_msg>Giving this package a canonical path<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
Package maps provides a client library for the Google Maps Web Service APIs.
Please see https://developers.google.com/maps/documentation/webservices/ for
an overview of the Maps Web Service API suite.
*/
package maps // import "developers.google.com/maps"
<|endoftext|>


<commit_before>/*
Package gstrings provides common sense
string manipulation methods from ruby.
     package main
     import "github.com/wallclockbuilder/gstrings"
     func main() {
       gstrings.Capitalize("abcde")          #=> "ABCDE"
       gstrings.Reverse("stressed")          #=> "desserts"
       gstrings.Swapcase("Hello")            #=> "hELLO"
     }
*/
package gstrings
<commit_msg>Update<commit_after>/*
Package gstrings provides common sense
string manipulation methods from ruby.
     package main
     import "github.com/wallclockbuilder/gstrings"

     func main() {
       gstrings.Capitalize("abcde")          #=> "ABCDE"
       gstrings.Reverse("stressed")          #=> "desserts"
       gstrings.Swapcase("Hello")            #=> "hELLO"
     }
*/
package gstrings
<|endoftext|>


<commit_before>/*
Pacakge kms (Killing Me Softly) is a library that aids in graceful shutdown of a process/application.

Example:
	package main

	import (
		"net/http"
		"time"

		"github.com/go-playground/kms"
		"github.com/go-playground/kms/kmsnet/kmshttp"
	)

	func main() {

		// listen for shutdown signal(s) with timeout, non-blocking
		kms.ListenTimeout(false, time.Minute*3)

		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("Home"))
		})

		kmshttp.ListenAndServe(":3007", nil)
	}
*/
package kms
<commit_msg>correct typo<commit_after>/*
Package kms (Killing Me Softly) is a library that aids in graceful shutdown of a process/application.

Example:
	package main

	import (
		"net/http"
		"time"

		"github.com/go-playground/kms"
		"github.com/go-playground/kms/kmsnet/kmshttp"
	)

	func main() {

		// listen for shutdown signal(s) with timeout, non-blocking
		kms.ListenTimeout(false, time.Minute*3)

		http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			w.Write([]byte("Home"))
		})

		kmshttp.ListenAndServe(":3007", nil)
	}
*/
package kms
<|endoftext|>


<commit_before>// Package yiigo 简单易用的 Golang 辅助库
//
// 使用 MySQL：
//
//    // default db
//    yiigo.RegisterDB("default", yiigo.MySQL, "root:root@tcp(localhost:3306)/test")
//
//    yiigo.DB.Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
//
//    // other db
//    yiigo.RegisterDB("foo", yiigo.MySQL, "root:root@tcp(localhost:3306)/test")
//
//    yiigo.UseDB("foo").Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
//
// 使用 MongoDB：
//
//    // default mongodb
//    yiigo.RegisterMongoDB("default", "mongodb://username:password@localhost:27017")
//
//    ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
//    yiigo.Mongo.Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
//
//    // other mongodb
//    yiigo.RegisterMongoDB("foo", "mongodb://username:password@localhost:27017")
//
//    ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
//    yiigo.UseMongo("foo").Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
//
// 使用 Redis：
//
//    // default redis
//    yiigo.RegisterRedis("default", "localhost:6379")
//
//    conn, err := yiigo.Redis.Get()
//
//    if err != nil {
// 	      log.Fatal(err)
//    }
//
//    defer yiigo.Redis.Put(conn)
//
//    conn.Do("SET", "test_key", "hello world")
//
//    // other redis
//    yiigo.RegisterRedis("foo", "localhost:6379")
//
//    foo := yiigo.UseRedis("foo")
//    conn, err := foo.Get()
//
//    if err != nil {
// 	      log.Fatal(err)
//    }
//
//    defer foo.Put(conn)
//
//    conn.Do("SET", "test_key", "hello world")
//
// 使用配置文件：
//
//    // env.toml
//    //
//    // [app]
//    // env = "dev"
//    // debug = true
//    // port = 50001
//
//    yiigo.UseEnv("env.toml")
//
//    yiigo.Env.GetBool("app.debug", true)
//    yiigo.Env.GetInt("app.port", 12345)
//    yiigo.Env.GetString("app.env", "dev")
//
// 使用日志：
//
//    // default logger
//    yiigo.RegisterLogger("default", "app.log")
//    yiigo.Logger.Info("hello world")
//
//    // other logger
//    yiigo.RegisterLogger("foo", "foo.log")
//    yiigo.UseLogger("foo").Info("hello world")
//
// For more details, see the documentation for the types and methods.
//
package yiigo
<commit_msg>update<commit_after>// Package yiigo 简单易用的 Golang 辅助库
//
// 基本使用如下：
//
// MySQL:
//
//    // default db
//    yiigo.RegisterDB("default", yiigo.MySQL, "root:root@tcp(localhost:3306)/test")
//
//    yiigo.DB.Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
//
//    // other db
//    yiigo.RegisterDB("foo", yiigo.MySQL, "root:root@tcp(localhost:3306)/test")
//
//    yiigo.UseDB("foo").Get(&User{}, "SELECT * FROM `user` WHERE `id` = ?", 1)
//
// MongoDB:
//
//    // default mongodb
//    yiigo.RegisterMongoDB("default", "mongodb://username:password@localhost:27017")
//
//    ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
//    yiigo.Mongo.Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
//
//    // other mongodb
//    yiigo.RegisterMongoDB("foo", "mongodb://username:password@localhost:27017")
//
//    ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
//    yiigo.UseMongo("foo").Database("test").Collection("numbers").InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
//
// Redis:
//
//    // default redis
//    yiigo.RegisterRedis("default", "localhost:6379")
//
//    conn, err := yiigo.Redis.Get()
//
//    if err != nil {
// 	      log.Fatal(err)
//    }
//
//    defer yiigo.Redis.Put(conn)
//
//    conn.Do("SET", "test_key", "hello world")
//
//    // other redis
//    yiigo.RegisterRedis("foo", "localhost:6379")
//
//    foo := yiigo.UseRedis("foo")
//    conn, err := foo.Get()
//
//    if err != nil {
// 	      log.Fatal(err)
//    }
//
//    defer foo.Put(conn)
//
//    conn.Do("SET", "test_key", "hello world")
//
// Config:
//
//    // env.toml
//    //
//    // [app]
//    // env = "dev"
//    // debug = true
//    // port = 50001
//
//    yiigo.UseEnv("env.toml")
//
//    yiigo.Env.GetBool("app.debug", true)
//    yiigo.Env.GetInt("app.port", 12345)
//    yiigo.Env.GetString("app.env", "dev")
//
// Logger:
//
//    // default logger
//    yiigo.RegisterLogger("default", "app.log")
//    yiigo.Logger.Info("hello world")
//
//    // other logger
//    yiigo.RegisterLogger("foo", "foo.log")
//    yiigo.UseLogger("foo").Info("hello world")
//
// For more details, see the documentation for the types and methods.
//
package yiigo
<|endoftext|>


<commit_before>/*
Package sqlstmt aims to make it easy to construct and execute SQL
statements for common scenarios. Supported scenarios include:

 * Insert a single row based on a Go struct
 * Update a single row based on a Go struct
 * Delete a single row based on a Go struct
 * Select a single row into a Go struct
 * Select zero, one or more rows int a a slice of Go structs

This package is intended for programmers who are comfortable with
writing SQL, but would like assistance with the sometimes tedious
process of preparing SELECT, INSERT, UPDATE and DELETE statements
for tables that have a large number of columns.

This package is designed to work seamlessly with the standard library
"database/sql" package. It does not provide any layer on top of *sql.DB
or *sql.Tx. If the calling program has a need to execute queries independently
of this package, it can use "database/sql" directly, or make use of any other
third party package that uses "database/sql".

More information about this package is found at https://github.com/jjeffery/sqlstmt.
*/
package sqlstmt
<commit_msg>Update doc.go<commit_after>/*
Package sqlstmt aims to make it easy to construct and execute SQL
statements for common scenarios. Supported scenarios include:

 * Insert a single row based on a Go struct
 * Update a single row based on a Go struct
 * Delete a single row based on a Go struct
 * Select a single row into a Go struct
 * Select zero, one or more rows int a a slice of Go structs

This package is intended for programmers who are comfortable with
writing SQL, but would like assistance with the sometimes tedious
process of preparing SELECT, INSERT, UPDATE and DELETE statements
for tables that have a large number of columns.

This package is designed to work seamlessly with the standard library
"database/sql" package. It does not provide any layer on top of *sql.DB
or *sql.Tx. If the calling program has a need to execute queries independently
of this package, it can use "database/sql" directly, or make use of any other
third party package that uses "database/sql".

More information about this package can be found at https://github.com/jjeffery/sqlstmt.
*/
package sqlstmt
<|endoftext|>


<commit_before>/*
Package sqlrow makes it easy to construct and execute SQL
queries for common, row-based scenarios. Supported scenarios include:

 (a) Insert, update or delete a single row based on the contents of a Go struct;
 (b) Select a single row into a Go struct; and
 (c) Select zero, one or more rows into a slice of Go structs.

This package is intended for programmers who are comfortable with
writing SQL, but would like assistance with the sometimes tedious
process of preparing SELECT, INSERT, UPDATE and DELETE statements
for tables that have a large number of columns.

This package is designed to work seamlessly with the standard library
"database/sql" package. It does not provide any layer on top of *sql.DB
or *sql.Tx. If the calling program has a need to execute queries independently
of this package, it can use "database/sql" directly, or make use of any other
third party package that uses "database/sql".

SQL INSERT

Package sqlrow uses reflection on the supplied row to provide assistance
with creating SQL. This assistance is particularly useful for tables with
many columns, but the following examples use this simple structure:

 type UserRow struct {
	ID         int64 `sql:"primary key autoincrement"`
	GivenName  string
	FamilyName string
 }

For a row of type UserRow the following INSERT query:

 sqlrow.Insert(db, row, `insert into users({}) values({})`)

will be translated into the following, depending on the SQL dialect:
 insert into users(`given_name`,`family_name`) values(?,?)   -- MySQL, SQLite
 insert into users("given_name","family_name") values($1,$2) -- PostgreSQL
 insert into users([given_name],[family_name]) values(?,?)   -- MSSQL

In the above example note that the "id" column is not inserted. This is
because it is defined as an auto-increment column. If it were not an
auto-increment column it would be included in the column list.

This pattern is so common for inserting individual rows that,
for convenience, providing just the table name has the same result:

 sqlrow.Insert(db, row, `users`)

SQL UPDATE

The following UPDATE query:

 sqlrow.Update(db, row, `update users set {} where {}`)

will be translated into the following:
 update users set `given_name`=?,`family_name`=? where `id`=?    -- MySQL, SQLite
 update users set "given_name"=$1,"family_name"=$2 where "id"=$3 -- PostgreSQL
 update users set [given_name]=?,[family_name]=? where [id]=?    -- MSSQL

This pattern is so common for inserting individual rows that,
for convenience, providing just the table name has the same result:

 sqlrow.Update(db, row, `users`)

It is possible to construct more complex UPDATE statements. The following
example can be useful for rows that make use of optimistic locking:
 sqlrow.Update(db, row, `update users set {} where {} and version = ?', oldVersion)

SQL DELETE

DELETE queries are similar to UPDATE queries:

 sqlrow.Delete(db, row, `delete from users where {}`)
and
 sqlrow.Delete(db, row, `users`)

are both translated as (for MySQL, SQLite):
 delete from users where `id`=?

SQL SELECT

SQL SELECT queries can be constructed easily

 var rows []UserRow
 sql.Select(db, &rows, `select {} from users where given_name=?`, "Smith")

is translated as (for MySQL, SQLite):
 select `id`,`given_name`,`family_name` from users where given_name=?

More complex queries involving joins and table aliases are possible:

 sql.Select(db, &rows, `
   select {alias u}
   from users u
   inner join user_search_terms t on t.user_id = u.id
   where t.search_term like ?`, "Jon%")

is translated as (for MySQL, SQLite):
 select u.`id`,u.`given_name`,u.`family_name`
 from users u inner join user_search_terms t
 on t.user_id = u.id
 where t.search_term like ?

Performance and Caching

Package sqlrow 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 the package caches queries generated. The end result
is that the performance of this package is close to the performance of
code that uses hand-constructed SQL queries to call package "database/sql"
directly.

Source Code

More information about this package can be found at https://github.com/jjeffery/sqlrow.
*/
package sqlrow
<commit_msg>wip: updating package documentation<commit_after>/*
OLD DESCRIPTION

Package sqlrow makes it easy to construct and execute SQL
queries for common, row-based scenarios. Supported scenarios include:

 (a) Insert, update or delete a single row based on the contents of a Go struct;
 (b) Select a single row into a Go struct; and
 (c) Select zero, one or more rows into a slice of Go structs.

This package is intended for programmers who are comfortable with
writing SQL, but would like assistance with the sometimes tedious
process of preparing SELECT, INSERT, UPDATE and DELETE statements
for tables that have a large number of columns.

This package is designed to work seamlessly with the standard library
"database/sql" package. It does not provide any layer on top of *sql.DB
or *sql.Tx. If the calling program has a need to execute queries independently
of this package, it can use "database/sql" directly, or make use of any other
third party package that uses "database/sql".

SQL INSERT

Package sqlrow uses reflection on the supplied row to provide assistance
with creating SQL. This assistance is particularly useful for tables with
many columns, but the following examples use this simple structure:

 type UserRow struct {
	ID         int64 `sql:"primary key autoincrement"`
	GivenName  string
	FamilyName string
 }

For a row of type UserRow the following INSERT query:

 sqlrow.Insert(db, row, `insert into users({}) values({})`)

will be translated into the following, depending on the SQL dialect:
 insert into users(`given_name`,`family_name`) values(?,?)   -- MySQL, SQLite
 insert into users("given_name","family_name") values($1,$2) -- PostgreSQL
 insert into users([given_name],[family_name]) values(?,?)   -- MSSQL

In the above example note that the "id" column is not inserted. This is
because it is defined as an auto-increment column. If it were not an
auto-increment column it would be included in the column list.

This pattern is so common for inserting individual rows that,
for convenience, providing just the table name has the same result:

 sqlrow.Insert(db, row, `users`)

SQL UPDATE

The following UPDATE query:

 sqlrow.Update(db, row, `update users set {} where {}`)

will be translated into the following:
 update users set `given_name`=?,`family_name`=? where `id`=?    -- MySQL, SQLite
 update users set "given_name"=$1,"family_name"=$2 where "id"=$3 -- PostgreSQL
 update users set [given_name]=?,[family_name]=? where [id]=?    -- MSSQL

This pattern is so common for inserting individual rows that,
for convenience, providing just the table name has the same result:

 sqlrow.Update(db, row, `users`)

It is possible to construct more complex UPDATE statements. The following
example can be useful for rows that make use of optimistic locking:
 sqlrow.Update(db, row, `update users set {} where {} and version = ?', oldVersion)

SQL DELETE

DELETE queries are similar to UPDATE queries:

 sqlrow.Delete(db, row, `delete from users where {}`)
and
 sqlrow.Delete(db, row, `users`)

are both translated as (for MySQL, SQLite):
 delete from users where `id`=?

SQL SELECT

SQL SELECT queries can be constructed easily

 var rows []UserRow
 sql.Select(db, &rows, `select {} from users where given_name=?`, "Smith")

is translated as (for MySQL, SQLite):
 select `id`,`given_name`,`family_name` from users where given_name=?

More complex queries involving joins and table aliases are possible:

 sql.Select(db, &rows, `
   select {alias u}
   from users u
   inner join user_search_terms t on t.user_id = u.id
   where t.search_term like ?`, "Jon%")

is translated as (for MySQL, SQLite):
 select u.`id`,u.`given_name`,u.`family_name`
 from users u inner join user_search_terms t
 on t.user_id = u.id
 where t.search_term like ?

Performance and Caching

Package sqlrow 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 the package caches queries generated. The end result
is that the performance of this package is close to the performance of
code that uses hand-constructed SQL queries to call package "database/sql"
directly.

Source Code

More information about this package can be found at https://github.com/jjeffery/sqlrow.
*/

/*
Package sqlrow is designed to reduce the effort required to implement
common operations against 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.

Prepare SQL from 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 enough to match the columns with the
placeholder. Many tables have multiple dozens of columns, some have more.
 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 statements for insert, update, delete
and select queries. Supplementary information about each database column is stored as a structure tag
in the associated field.
 type User struct {
     ID          int       `sql:"primary key"`
     GivenName   string
     FamilyName  string
     DOB         time.Time `sql:"null"`
     SSN         string
     Street      string
     Locality    string
     Postcode    string
     Country     string
     Phone       string    `sql:"null"`
     Mobile      string    `sql:"null"`
     Facsimile   string    `sql:"fax null"`
 }
The calling program creates a schema, which describes rules for generating SQL statements. These
rules include specifying the SQL dialect (eg MySQL, Posgres, 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.
 schema := NewSchema(
   WithDialect(MySQL),
   WithNamingConvention(SnakeCase),
 )
Once the schema has been defined and a database handle is available (eg *sql.DB, *sql.Tx), it is possible
to create simple row insert/update/delete 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 := schema.Exec(db, 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 := schema.Exec(db, row, "update users set {} where {}")
The Exec method parses the SQL query and replaces occurrances 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
Select queries are handled in a similar fashion:
 var rows []*User

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

 var row User

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

 // more complex query involving joins and aliases
 rowCount, err = schema.Select(db, &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

Autoincrement Primary Keys

When inserting rows, if a column is defined as an autoincrement column, then the generated
value will be retrieved 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 := schema.Exec(db, row, "insert into table_name({}) values({})")
 if err != nil {
   log.Fatal(err)
 }

 // row.ID will contain the auto-generated value
 fmt.Println(row.ID)
*/
package sqlrow
<|endoftext|>


<commit_before>// Copyright (c) 2019 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Package dig provides an opinionated way of resolving object dependencies.
//
// # Status
//
// STABLE. No breaking changes will be made in this major version.
//
// # Container
//
// Dig exposes type Container as an object capable of resolving a directed
// acyclic dependency graph. Use the New function to create one.
//
//	c := dig.New()
//
// # Provide
//
// Constructors for different types are added to the container by using the
// Provide method. A constructor can declare a dependency on another type by
// simply adding it as a function parameter. Dependencies for a type can be
// added to the graph both, before and after the type was added.
//
//	err := c.Provide(func(conn *sql.DB) (*UserGateway, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	if err := c.Provide(newDBConnection); err != nil {
//	  // ...
//	}
//
// Multiple constructors can rely on the same type. The container creates a
// singleton for each retained type, instantiating it at most once when
// requested directly or as a dependency of another type.
//
//	err := c.Provide(func(conn *sql.DB) *CommentGateway {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Constructors can declare any number of dependencies as parameters and
// optionally, return errors.
//
//	err := c.Provide(func(u *UserGateway, c *CommentGateway) (*RequestHandler, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	if err := c.Provide(newHTTPServer); err != nil {
//	  // ...
//	}
//
// Constructors can also return multiple results to add multiple types to the
// container.
//
//	err := c.Provide(func(conn *sql.DB) (*UserGateway, *CommentGateway, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Constructors that accept a variadic number of arguments are treated as if
// they don't have those arguments. That is,
//
//	func NewVoteGateway(db *sql.DB, options ...Option) *VoteGateway
//
// Is treated the same as,
//
//	func NewVoteGateway(db *sql.DB) *VoteGateway
//
// The constructor will be called with all other dependencies and no variadic
// arguments.
//
// # Invoke
//
// Types added to to the container may be consumed by using the Invoke method.
// Invoke accepts any function that accepts one or more parameters and
// optionally, returns an error. Dig calls the function with the requested
// type, instantiating only those types that were requested by the function.
// The call fails if any type or its dependencies (both direct and transitive)
// were not available in the container.
//
//	err := c.Invoke(func(l *log.Logger) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	err := c.Invoke(func(server *http.Server) error {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Any error returned by the invoked function is propagated back to the
// caller.
//
// # Parameter Objects
//
// Constructors declare their dependencies as function parameters. This can
// very quickly become unreadable if the constructor has a lot of
// dependencies.
//
//	func NewHandler(users *UserGateway, comments *CommentGateway, posts *PostGateway, votes *VoteGateway, authz *AuthZGateway) *Handler {
//	  // ...
//	}
//
// A pattern employed to improve readability in a situation like this is to
// create a struct that lists all the parameters of the function as fields and
// changing the function to accept that struct instead. This is referred to as
// a parameter object.
//
// Dig has first class support for parameter objects: any struct embedding
// dig.In gets treated as a parameter object. The following is equivalent to
// the constructor above.
//
//	type HandlerParams struct {
//	  dig.In
//
//	  Users    *UserGateway
//	  Comments *CommentGateway
//	  Posts    *PostGateway
//	  Votes    *VoteGateway
//	  AuthZ    *AuthZGateway
//	}
//
//	func NewHandler(p HandlerParams) *Handler {
//	  // ...
//	}
//
// Handlers can receive any combination of parameter objects and parameters.
//
//	func NewHandler(p HandlerParams, l *log.Logger) *Handler {
//	  // ...
//	}
//
// # Result Objects
//
// Result objects are the flip side of parameter objects. These are structs
// that represent multiple outputs from a single function as fields in the
// struct. Structs embedding dig.Out get treated as result objects.
//
//	func SetupGateways(conn *sql.DB) (*UserGateway, *CommentGateway, *PostGateway, error) {
//	  // ...
//	}
//
// The above is equivalent to,
//
//	type Gateways struct {
//	  dig.Out
//
//	  Users    *UserGateway
//	  Comments *CommentGateway
//	  Posts    *PostGateway
//	}
//
//	func SetupGateways(conn *sql.DB) (Gateways, error) {
//	  // ...
//	}
//
// # Optional Dependencies
//
// Constructors often don't have a hard dependency on some types and
// are able to operate in a degraded state when that dependency is missing.
// Dig supports declaring dependencies as optional by adding an
// `optional:"true"` tag to fields of a dig.In struct.
//
// Fields in a dig.In structs that have the `optional:"true"` tag are treated
// as optional by Dig.
//
//	type UserGatewayParams struct {
//	  dig.In
//
//	  Conn  *sql.DB
//	  Cache *redis.Client `optional:"true"`
//	}
//
// If an optional field is not available in the container, the constructor
// will receive a zero value for the field.
//
//	func NewUserGateway(p UserGatewayParams, log *log.Logger) (*UserGateway, error) {
//	  if p.Cache == nil {
//	    log.Print("Logging disabled")
//	  }
//	  // ...
//	}
//
// Constructors that declare dependencies as optional MUST handle the case of
// those dependencies being absent.
//
// The optional tag also allows adding new dependencies without breaking
// existing consumers of the constructor.
//
// # Named Values
//
// Some use cases call for multiple values of the same type. Dig allows adding
// multiple values of the same type to the container with the use of Named
// Values.
//
// Named Values can be produced by passing the dig.Name option when a
// constructor is provided. All values produced by that constructor will have
// the given name.
//
// Given the following constructors,
//
//	func NewReadOnlyConnection(...) (*sql.DB, error)
//	func NewReadWriteConnection(...) (*sql.DB, error)
//
// You can provide *sql.DB into a Container under different names by passing
// the dig.Name option.
//
//	c.Provide(NewReadOnlyConnection, dig.Name("ro"))
//	c.Provide(NewReadWriteConnection, dig.Name("rw"))
//
// Alternatively, you can produce a dig.Out struct and tag its fields with
// `name:".."` to have the corresponding value added to the graph under the
// specified name.
//
//	type ConnectionResult struct {
//	  dig.Out
//
//	  ReadWrite *sql.DB `name:"rw"`
//	  ReadOnly  *sql.DB `name:"ro"`
//	}
//
//	func ConnectToDatabase(...) (ConnectionResult, error) {
//	  // ...
//	  return ConnectionResult{ReadWrite: rw, ReadOnly:  ro}, nil
//	}
//
// Regardless of how a Named Value was produced, it can be consumed by another
// constructor by accepting a dig.In struct which has exported fields with the
// same name AND type that you provided.
//
//	type GatewayParams struct {
//	  dig.In
//
//	  WriteToConn  *sql.DB `name:"rw"`
//	  ReadFromConn *sql.DB `name:"ro"`
//	}
//
// The name tag may be combined with the optional tag to declare the
// dependency optional.
//
//	type GatewayParams struct {
//	  dig.In
//
//	  WriteToConn  *sql.DB `name:"rw"`
//	  ReadFromConn *sql.DB `name:"ro" optional:"true"`
//	}
//
//	func NewCommentGateway(p GatewayParams, log *log.Logger) (*CommentGateway, error) {
//	  if p.ReadFromConn == nil {
//	    log.Print("Warning: Using RW connection for reads")
//	    p.ReadFromConn = p.WriteToConn
//	  }
//	  // ...
//	}
//
// # Value Groups
//
// Added in Dig 1.2.
//
// Dig provides value groups to allow producing and consuming many values of
// the same type. Value groups allow constructors to send values to a named,
// unordered collection in the container. Other constructors can request all
// values in this collection as a slice.
//
// Constructors can send values into value groups by returning a dig.Out
// struct tagged with `group:".."`.
//
//	type HandlerResult struct {
//	  dig.Out
//
//	  Handler Handler `group:"server"`
//	}
//
//	func NewHelloHandler() HandlerResult {
//	  ..
//	}
//
//	func NewEchoHandler() HandlerResult {
//	  ..
//	}
//
// Any number of constructors may provide values to this named collection.
// Other constructors can request all values for this collection by requesting
// a slice tagged with `group:".."`. This will execute all constructors that
// provide a value to that group in an unspecified order.
//
//	type ServerParams struct {
//	  dig.In
//
//	  Handlers []Handler `group:"server"`
//	}
//
//	func NewServer(p ServerParams) *Server {
//	  server := newServer()
//	  for _, h := range p.Handlers {
//	    server.Register(h)
//	  }
//	  return server
//	}
//
// Note that values in a value group are unordered. Dig makes no guarantees
// about the order in which these values will be produced.
//
// Value groups can be used to provide multiple values for a group from a
// dig.Out using slices, however considering groups are retrieved by requesting
// a slice this implies that the values must be retrieved using a slice of
// slices. As of dig v1.9.0, if you want to provide individual elements to the
// group instead of the slice itself, you can add the `flatten` modifier to the
// group from a dig.Out.
//
//	type IntResult struct {
//	  dig.Out
//
//	  Handler []int `group:"server"`         // [][]int from dig.In
//	  Handler []int `group:"server,flatten"` // []int from dig.In
//	}
package dig // import "go.uber.org/dig"
<commit_msg>fix doc typo (#359)<commit_after>// Copyright (c) 2019 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Package dig provides an opinionated way of resolving object dependencies.
//
// # Status
//
// STABLE. No breaking changes will be made in this major version.
//
// # Container
//
// Dig exposes type Container as an object capable of resolving a directed
// acyclic dependency graph. Use the New function to create one.
//
//	c := dig.New()
//
// # Provide
//
// Constructors for different types are added to the container by using the
// Provide method. A constructor can declare a dependency on another type by
// simply adding it as a function parameter. Dependencies for a type can be
// added to the graph both, before and after the type was added.
//
//	err := c.Provide(func(conn *sql.DB) (*UserGateway, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	if err := c.Provide(newDBConnection); err != nil {
//	  // ...
//	}
//
// Multiple constructors can rely on the same type. The container creates a
// singleton for each retained type, instantiating it at most once when
// requested directly or as a dependency of another type.
//
//	err := c.Provide(func(conn *sql.DB) *CommentGateway {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Constructors can declare any number of dependencies as parameters and
// optionally, return errors.
//
//	err := c.Provide(func(u *UserGateway, c *CommentGateway) (*RequestHandler, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	if err := c.Provide(newHTTPServer); err != nil {
//	  // ...
//	}
//
// Constructors can also return multiple results to add multiple types to the
// container.
//
//	err := c.Provide(func(conn *sql.DB) (*UserGateway, *CommentGateway, error) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Constructors that accept a variadic number of arguments are treated as if
// they don't have those arguments. That is,
//
//	func NewVoteGateway(db *sql.DB, options ...Option) *VoteGateway
//
// Is treated the same as,
//
//	func NewVoteGateway(db *sql.DB) *VoteGateway
//
// The constructor will be called with all other dependencies and no variadic
// arguments.
//
// # Invoke
//
// Types added to the container may be consumed by using the Invoke method.
// Invoke accepts any function that accepts one or more parameters and
// optionally, returns an error. Dig calls the function with the requested
// type, instantiating only those types that were requested by the function.
// The call fails if any type or its dependencies (both direct and transitive)
// were not available in the container.
//
//	err := c.Invoke(func(l *log.Logger) {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
//	err := c.Invoke(func(server *http.Server) error {
//	  // ...
//	})
//	if err != nil {
//	  // ...
//	}
//
// Any error returned by the invoked function is propagated back to the
// caller.
//
// # Parameter Objects
//
// Constructors declare their dependencies as function parameters. This can
// very quickly become unreadable if the constructor has a lot of
// dependencies.
//
//	func NewHandler(users *UserGateway, comments *CommentGateway, posts *PostGateway, votes *VoteGateway, authz *AuthZGateway) *Handler {
//	  // ...
//	}
//
// A pattern employed to improve readability in a situation like this is to
// create a struct that lists all the parameters of the function as fields and
// changing the function to accept that struct instead. This is referred to as
// a parameter object.
//
// Dig has first class support for parameter objects: any struct embedding
// dig.In gets treated as a parameter object. The following is equivalent to
// the constructor above.
//
//	type HandlerParams struct {
//	  dig.In
//
//	  Users    *UserGateway
//	  Comments *CommentGateway
//	  Posts    *PostGateway
//	  Votes    *VoteGateway
//	  AuthZ    *AuthZGateway
//	}
//
//	func NewHandler(p HandlerParams) *Handler {
//	  // ...
//	}
//
// Handlers can receive any combination of parameter objects and parameters.
//
//	func NewHandler(p HandlerParams, l *log.Logger) *Handler {
//	  // ...
//	}
//
// # Result Objects
//
// Result objects are the flip side of parameter objects. These are structs
// that represent multiple outputs from a single function as fields in the
// struct. Structs embedding dig.Out get treated as result objects.
//
//	func SetupGateways(conn *sql.DB) (*UserGateway, *CommentGateway, *PostGateway, error) {
//	  // ...
//	}
//
// The above is equivalent to,
//
//	type Gateways struct {
//	  dig.Out
//
//	  Users    *UserGateway
//	  Comments *CommentGateway
//	  Posts    *PostGateway
//	}
//
//	func SetupGateways(conn *sql.DB) (Gateways, error) {
//	  // ...
//	}
//
// # Optional Dependencies
//
// Constructors often don't have a hard dependency on some types and
// are able to operate in a degraded state when that dependency is missing.
// Dig supports declaring dependencies as optional by adding an
// `optional:"true"` tag to fields of a dig.In struct.
//
// Fields in a dig.In structs that have the `optional:"true"` tag are treated
// as optional by Dig.
//
//	type UserGatewayParams struct {
//	  dig.In
//
//	  Conn  *sql.DB
//	  Cache *redis.Client `optional:"true"`
//	}
//
// If an optional field is not available in the container, the constructor
// will receive a zero value for the field.
//
//	func NewUserGateway(p UserGatewayParams, log *log.Logger) (*UserGateway, error) {
//	  if p.Cache == nil {
//	    log.Print("Logging disabled")
//	  }
//	  // ...
//	}
//
// Constructors that declare dependencies as optional MUST handle the case of
// those dependencies being absent.
//
// The optional tag also allows adding new dependencies without breaking
// existing consumers of the constructor.
//
// # Named Values
//
// Some use cases call for multiple values of the same type. Dig allows adding
// multiple values of the same type to the container with the use of Named
// Values.
//
// Named Values can be produced by passing the dig.Name option when a
// constructor is provided. All values produced by that constructor will have
// the given name.
//
// Given the following constructors,
//
//	func NewReadOnlyConnection(...) (*sql.DB, error)
//	func NewReadWriteConnection(...) (*sql.DB, error)
//
// You can provide *sql.DB into a Container under different names by passing
// the dig.Name option.
//
//	c.Provide(NewReadOnlyConnection, dig.Name("ro"))
//	c.Provide(NewReadWriteConnection, dig.Name("rw"))
//
// Alternatively, you can produce a dig.Out struct and tag its fields with
// `name:".."` to have the corresponding value added to the graph under the
// specified name.
//
//	type ConnectionResult struct {
//	  dig.Out
//
//	  ReadWrite *sql.DB `name:"rw"`
//	  ReadOnly  *sql.DB `name:"ro"`
//	}
//
//	func ConnectToDatabase(...) (ConnectionResult, error) {
//	  // ...
//	  return ConnectionResult{ReadWrite: rw, ReadOnly:  ro}, nil
//	}
//
// Regardless of how a Named Value was produced, it can be consumed by another
// constructor by accepting a dig.In struct which has exported fields with the
// same name AND type that you provided.
//
//	type GatewayParams struct {
//	  dig.In
//
//	  WriteToConn  *sql.DB `name:"rw"`
//	  ReadFromConn *sql.DB `name:"ro"`
//	}
//
// The name tag may be combined with the optional tag to declare the
// dependency optional.
//
//	type GatewayParams struct {
//	  dig.In
//
//	  WriteToConn  *sql.DB `name:"rw"`
//	  ReadFromConn *sql.DB `name:"ro" optional:"true"`
//	}
//
//	func NewCommentGateway(p GatewayParams, log *log.Logger) (*CommentGateway, error) {
//	  if p.ReadFromConn == nil {
//	    log.Print("Warning: Using RW connection for reads")
//	    p.ReadFromConn = p.WriteToConn
//	  }
//	  // ...
//	}
//
// # Value Groups
//
// Added in Dig 1.2.
//
// Dig provides value groups to allow producing and consuming many values of
// the same type. Value groups allow constructors to send values to a named,
// unordered collection in the container. Other constructors can request all
// values in this collection as a slice.
//
// Constructors can send values into value groups by returning a dig.Out
// struct tagged with `group:".."`.
//
//	type HandlerResult struct {
//	  dig.Out
//
//	  Handler Handler `group:"server"`
//	}
//
//	func NewHelloHandler() HandlerResult {
//	  ..
//	}
//
//	func NewEchoHandler() HandlerResult {
//	  ..
//	}
//
// Any number of constructors may provide values to this named collection.
// Other constructors can request all values for this collection by requesting
// a slice tagged with `group:".."`. This will execute all constructors that
// provide a value to that group in an unspecified order.
//
//	type ServerParams struct {
//	  dig.In
//
//	  Handlers []Handler `group:"server"`
//	}
//
//	func NewServer(p ServerParams) *Server {
//	  server := newServer()
//	  for _, h := range p.Handlers {
//	    server.Register(h)
//	  }
//	  return server
//	}
//
// Note that values in a value group are unordered. Dig makes no guarantees
// about the order in which these values will be produced.
//
// Value groups can be used to provide multiple values for a group from a
// dig.Out using slices, however considering groups are retrieved by requesting
// a slice this implies that the values must be retrieved using a slice of
// slices. As of dig v1.9.0, if you want to provide individual elements to the
// group instead of the slice itself, you can add the `flatten` modifier to the
// group from a dig.Out.
//
//	type IntResult struct {
//	  dig.Out
//
//	  Handler []int `group:"server"`         // [][]int from dig.In
//	  Handler []int `group:"server,flatten"` // []int from dig.In
//	}
package dig // import "go.uber.org/dig"
<|endoftext|>


<commit_before>/*
Package signals generates and manipulates signals:- https://en.wikipedia.org/wiki/Signal_processing.

Overview

signals are entirely procedural, all values are calculated as needed, currently no cache.

this package supports only 1-Dimensionsal variation, and for simplicity the terminolology used represents analogue variation in time.

this package is intended to be general, and so a base package for import, and then used with specific real-world quantities.

signals can be encode/decoded as go code binary (gob), and encoded as PCM wave files.

Fundamental Types

level :- can have a value from -MaxLevel to +MaxLevel

interval :- 'usually' can be used as if infinite (+ve and -ve), with UnitTime somewhere near the center of its precision range.

Interfaces

Signal :- has method Level() which returns a Level value from an Interval value parameter.

Periodical :- a Signal with an additional method  Period(), that returns the signals assumed repeat period Interval.

Notes

PCM Signals are an evenly spaced array of levels, stored at a particular precision, and can be saved/loaded. could be used as a cache.

*/
package signals
<commit_msg>save PCM<commit_after>/*
Package signals generates and manipulates signals:- https://en.wikipedia.org/wiki/Signal_processing.

Overview

Signals are procedural, levels are calculated as needed, meaning changes in parameters, or arrangment, are immediately effective.

PCMSignals are stored, at a particular precision, and can be used to cache an expensive precedural Signal.

only 1-Dimensionsal variation, and for simplicity the terminolology used represents analogue variation in time.

intended to be general, and a base package for import, then used with specific real-world quantities.

Signals can be encode/decoded as go code binary (gob), (probably best not used for PCMSignals, where saving as wav files is available.)

Fundamental Types

level :- can have a value from -MaxLevel to +MaxLevel

interval :- 'usually' can be used as if infinite (+ve and -ve), with UnitTime somewhere near the center of its precision range.

Interfaces

Signal :- has method Level() which returns a Level value from an Interval value parameter.

Periodical :- a Signal with an additional method  Period(), that returns the signals assumed repeat period Interval.

Notes

PCMSignals are an evenly spaced array of levels, with different types that store at a particular precisions.

*/
package signals
<|endoftext|>


<commit_before>/*
Multitemplate is a library to allow you to write html templates in
multiple languages, then allowing those templates to work with each
other using either a Rails-like yield/content_for paradigm or a
Django style block/extends paradigm.

Multitemplate at the moment has 3 languages, the standard Go template
syntax, a simplified haml-like language called bham, and a simple
mustache implementation. Multitemplate has an open interface for
creating new syntaxes, so external languages can be easily used.

Terminology

Yield's are executing saved templates or blocks. You can add a fallback
template to yields, but not fallback content. Yielding with a name will return the
first template set for that name, or the content of the first block that
had that name.

ContentFor will set a template to be executed on a name. This is similar
to the template command built in to the go template library, but with
a layer of indirection.

Blocks are template content that is executed, then saved for a later time.
Blocks share names with ContentFor and yields, so a yield might outtput
the content from a block, or a template set with ContentFor.

Inherited templates are templates that use the inherits function to
define that after it is executed, then another template should be
executed as well. These templates should only be made up of non-writing
functions and blocks.

Context's are the way to use the more advanced features of the multitemplate
library. With Context's, you can set two templates to be executed, a Main
template (executed first), and a Layout template (executed after Main). You
can also set Templates for Yields and Block content. Since you can't pass
RenderArgs in the ExecuteContext, you should put your RenderArgs in the Dot
variable.

Layouts are templates executed after a Main template. Context's are the way
to define Layouts to be executed. The Main template should set up content
that can then be yielded using the Main template. Yielding without a name
will cause the main template's content to be output.

Integrations

While multitemplate is available to use as a library in all
Go applications, it also includes integrations libraries that
will integrate multitemplate into external frameworks without
requiring the user to learn how to integrate this library.

The Revel integration is (as far as I know) a drop-in
replacement for the Revel template library. Instructions on
how to integrate are available in the godoc for the
github.com/acsellers/multitemplate/revel subdirectory, while
the integration code is in
github.com/acsellers/multitemplate/revel/app/controllers due
to how revel deals with modules.

Yield functionality

The following code demonstrates the common types of yield statements.
The first yield will render the template assigned to the stylesheets
key, or render the template "include/javascripts.html" if there is
not a set argument. The second yield will render the template set on
"stylesheets" with the .Stylesheets as the data. The third will render
the template set for "sidebar" with the data originally put into
ExecuteTemplate. The fourth yield will render the main template. This will
be the template set for the Main attribute on the Context struct in this
case.

app_controller.go
  ctx := multitemplate.NewContext(renderArgs)
  ctx.Yields["sidebar"] = "sidebars/admin.html"
  ctx.Main = "app/main.html"
  ctx.Layout = "layouts/main.html"
  templates.ExecuteContext(writer, ctx)

layouts/main.html

      {{ yield "javascript" (fallback "include/javascripts.html") }}
      {{ yield "stylesheets" .Stylesheets}}

          {{ yield "sidebar" }}

          {{ yield }}

Block functionality

The following code describes two templates that use the inherits
function to utilize template inheritence. It works similarly to
the yield example. Note that the inherits call should be the first
call of the view, any code before the inherits call may be sent to
the writer added to the Execute call.

app_controller.go
  templates.ExecuteTemplate(writer, "app/index.html", renderArgs)

layouts/main.html

      {{ block "javascript" }}


<commit_before>/*
Package stick is a go-language port of the Twig templating engine.

Twig is a powerful templating language that promotes separation of logic
from the view.

Stick executes Twig templates using an instance of Env. An Env contains all
the configured Functions, Filters, and Tests as well as a Loader to load
named templates from any source.

Obligatory "Hello, World!" example:

	env := stick.NewEnv(nil); // A nil loader means stick will simply execute
					  // the string passed into env.Execute.
	err := env.Execute("Hello, {{ name }}!", os.Stdout, map[string]stick.Value{"name": "World"})
	if err != nil { panic(err) }

In the previous example, notice that we passed in os.Stdout. Any io.Writer can be used.

Another example, using a FilesystemLoader and responding to an HTTP request:

	import "net/http"

	// ...

	fsRoot := os.Getwd() // Templates are loaded relative to this directory.
	env := stick.NewEnv(stick.NewFilesystemLoader(fsRoot))
	http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
		env.Execute("bar.html.twig", w, nil) // Loads "bar.html.twig" relative to fsRoot.
	})
	http.ListenAndServe(":80", nil)

Types and values

Stick makes no restriction on what is stored in a stick.Value, but some built-in
operators will try to coerce a value into a boolean, string, or number depending
on the operation.

BUG(tyler-sommer): Missing documentation on operators, tests, functions, filters, and much more.

For additional information on Twig, check http://twig.sensiolabs.org/
*/
package stick

<commit_msg>Simplified bug username in docs.<commit_after>/*
Package stick is a go-language port of the Twig templating engine.

Twig is a powerful templating language that promotes separation of logic
from the view.

Stick executes Twig templates using an instance of Env. An Env contains all
the configured Functions, Filters, and Tests as well as a Loader to load
named templates from any source.

Obligatory "Hello, World!" example:

	env := stick.NewEnv(nil); // A nil loader means stick will simply execute
					  // the string passed into env.Execute.
	err := env.Execute("Hello, {{ name }}!", os.Stdout, map[string]stick.Value{"name": "World"})
	if err != nil { panic(err) }

In the previous example, notice that we passed in os.Stdout. Any io.Writer can be used.

Another example, using a FilesystemLoader and responding to an HTTP request:

	import "net/http"

	// ...

	fsRoot := os.Getwd() // Templates are loaded relative to this directory.
	env := stick.NewEnv(stick.NewFilesystemLoader(fsRoot))
	http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
		env.Execute("bar.html.twig", w, nil) // Loads "bar.html.twig" relative to fsRoot.
	})
	http.ListenAndServe(":80", nil)

Types and values

Stick makes no restriction on what is stored in a stick.Value, but some built-in
operators will try to coerce a value into a boolean, string, or number depending
on the operation.

BUG(ts): Missing documentation on operators, tests, functions, filters, and much more.

For additional information on Twig, check http://twig.sensiolabs.org/
*/
package stick

<|endoftext|>


<commit_before>package dsunit

import (
	"github.com/pkg/errors"
	"github.com/viant/dsc"
	"github.com/viant/toolbox"
	"strings"
	"time"
)

type datasetDmlProvider struct {
	*dsc.DmlBuilder
}

func (p *datasetDmlProvider) record(instance interface{}) *map[string]interface{} {
	switch result := instance.(type) {
	case map[string]interface{}:
		return &result
	case *map[string]interface{}:
		return result
	}
	return nil
}

func (p *datasetDmlProvider) Key(instance interface{}) []interface{} {
	record := instance.(map[string]interface{})
	var result = make([]interface{}, 0)
	for _, column := range p.TableDescriptor.PkColumns {
		var value = record[column]
		if toolbox.IsFloat(value) {
			value = toolbox.AsInt(value)
		}
		result = append(result, value)
	}
	return result
}

func (p *datasetDmlProvider) SetKey(instance interface{}, seq int64) {
	record := p.record(instance)
	key := p.TableDescriptor.PkColumns[0]
	(*record)[key] = seq
}

func (p *datasetDmlProvider) Get(sqlType int, instance interface{}) *dsc.ParametrizedSQL {
	record := p.record(instance)
	return p.GetParametrizedSQL(sqlType, func(column string) interface{} {
		return (*record)[column]
	})
}

func newDatasetDmlProvider(dmlBuilder *dsc.DmlBuilder) *datasetDmlProvider {
	return &datasetDmlProvider{dmlBuilder}
}

type datasetRowMapper struct {
	dsc.Scanner
	valueProviders   []func(slice []interface{}, index int)
	columns          []string
	columnToIndexMap map[string]int
}

func (m *datasetRowMapper) Map(scanner dsc.Scanner) (interface{}, error) {
	m.Scanner = scanner
	columnValues, columns, err := dsc.ScanRow(m)
	if err != nil {
		return nil, err
	}
	var values = make(map[string]interface{})
	for i, item := range columnValues {
		values[columns[i]] = item
	}
	return &values, nil
}

func (m *datasetRowMapper) buildProviders(types map[string]dsc.Column) []func(slice []interface{}, index int) {
	valueProvider := []func(slice []interface{}, index int){}

	if len(types) == 0 || len(m.columns) == 0 {
		return valueProvider
	}

	for _, column := range m.columns {
		if info, ok := types[column]; ok {
			dbTypeName := info.DatabaseTypeName()
			switch strings.ToUpper(dbTypeName) {
			case "VARCHAR", "VARCHAR2", "CHAR", "STRING", "TEXT":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *string
					slice[index] = &value
				})
			case "DATE", "DATETIME", "TIMESTAMP":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *time.Time
					slice[index] = &value
				})
			case "INT", "BIGINT", "TINYINT", "INT64":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *int
					slice[index] = &value
				})
			case "FLOAT", "FLOAT64", "DECIMAL", "NUMERIC":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *float64
					slice[index] = &value
				})
			default:
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value interface{}
					slice[index] = &value
				})
			}
		}
	}
	return valueProvider
}

func (m *datasetRowMapper) ColumnValues() ([]interface{}, error) {
	if len(m.valueProviders) == 0 {
		return nil, errors.New("not supported")
	}
	var result = make([]interface{}, len(m.columns))
	for i, provider := range m.valueProviders {
		provider(result, i)
	}
	return result, nil
}

func newDatasetRowMapper(columns []string, types []dsc.Column) dsc.RecordMapper {
	var columnToIndexMap = make(map[string]int)
	for index, column := range columns {
		columnToIndexMap[column] = index
	}
	var result = &datasetRowMapper{
		columns:          columns,
		columnToIndexMap: columnToIndexMap,
	}
	if len(types) > 0 {
		indexTypes := make(map[string]dsc.Column)
		for _, column := range types {
			indexTypes[column.Name()] = column
		}
		result.valueProviders = result.buildProviders(indexTypes)
	}
	return result
}
<commit_msg>patched record mapping<commit_after>package dsunit

import (
	"github.com/pkg/errors"
	"github.com/viant/dsc"
	"github.com/viant/toolbox"
	"strings"
	"time"
)

type datasetDmlProvider struct {
	*dsc.DmlBuilder
}

func (p *datasetDmlProvider) record(instance interface{}) *map[string]interface{} {
	switch result := instance.(type) {
	case map[string]interface{}:
		return &result
	case *map[string]interface{}:
		return result
	}
	return nil
}

func (p *datasetDmlProvider) Key(instance interface{}) []interface{} {
	record := instance.(map[string]interface{})
	var result = make([]interface{}, 0)
	for _, column := range p.TableDescriptor.PkColumns {
		var value = record[column]
		if toolbox.IsFloat(value) {
			value = toolbox.AsInt(value)
		}
		result = append(result, value)
	}
	return result
}

func (p *datasetDmlProvider) SetKey(instance interface{}, seq int64) {
	record := p.record(instance)
	key := p.TableDescriptor.PkColumns[0]
	(*record)[key] = seq
}

func (p *datasetDmlProvider) Get(sqlType int, instance interface{}) *dsc.ParametrizedSQL {
	record := p.record(instance)
	return p.GetParametrizedSQL(sqlType, func(column string) interface{} {
		return (*record)[column]
	})
}

func newDatasetDmlProvider(dmlBuilder *dsc.DmlBuilder) *datasetDmlProvider {
	return &datasetDmlProvider{dmlBuilder}
}

type datasetRowMapper struct {
	dsc.Scanner
	valueProviders   []func(slice []interface{}, index int)
	columns          []string
	columnToIndexMap map[string]int
}

func (m *datasetRowMapper) Map(scanner dsc.Scanner) (interface{}, error) {
	m.Scanner = scanner
	columnValues, columns, err := dsc.ScanRow(m)
	if err != nil {
		return nil, err
	}
	var values = make(map[string]interface{})
	for i, item := range columnValues {
		values[columns[i]] = item
	}
	return &values, nil
}

func (m *datasetRowMapper) buildProviders(types map[string]dsc.Column) []func(slice []interface{}, index int) {
	valueProvider := []func(slice []interface{}, index int){}

	if len(types) == 0 || len(m.columns) == 0 {
		return valueProvider
	}

	for _, column := range m.columns {
		if info, ok := types[column]; ok {
			dbTypeName := info.DatabaseTypeName()
			switch strings.ToUpper(dbTypeName) {
			case "VARCHAR", "VARCHAR2", "CHAR", "STRING", "TEXT":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *string
					slice[index] = &value
				})
			case "DATE", "DATETIME", "TIMESTAMP":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *time.Time
					slice[index] = &value
				})
			case "INT", "INTEGER", "BIGINT", "TINYINT", "INT64":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *int
					slice[index] = &value
				})
			case "FLOAT", "FLOAT64", "DECIMAL", "NUMERIC":
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value *float64
					slice[index] = &value
				})
			default:
				valueProvider = append(valueProvider, func(slice []interface{}, index int) {
					var value interface{}
					slice[index] = &value
				})
			}
		}
	}
	return valueProvider
}

func (m *datasetRowMapper) ColumnValues() ([]interface{}, error) {
	if len(m.valueProviders) == 0 {
		return nil, errors.New("not supported")
	}
	var result = make([]interface{}, len(m.columns))
	for i, provider := range m.valueProviders {
		provider(result, i)
	}
	return result, nil
}

func newDatasetRowMapper(columns []string, types []dsc.Column) dsc.RecordMapper {
	var columnToIndexMap = make(map[string]int)
	for index, column := range columns {
		columnToIndexMap[column] = index
	}
	var result = &datasetRowMapper{
		columns:          columns,
		columnToIndexMap: columnToIndexMap,
	}
	if len(types) > 0 {
		indexTypes := make(map[string]dsc.Column)
		for _, column := range types {
			indexTypes[column.Name()] = column
		}
		result.valueProviders = result.buildProviders(indexTypes)
	}
	return result
}
<|endoftext|>


<commit_before>// Package dxf is a DXF(Drawing Exchange Format) library for golang.
// ACAD2000(AC1015), ASCII format is only supported.
// http://www.autodesk.com/techpubs/autocad/acad2000/dxf/index.htm
package dxf

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/yofu/dxf/color"
	"github.com/yofu/dxf/drawing"
	"github.com/yofu/dxf/table"
)

// Default values.
var (
	DefaultColor    = color.White
	DefaultLineType = table.LT_CONTINUOUS
)

// NewDrawing creates a drawing.
func NewDrawing() *drawing.Drawing {
	return drawing.New()
}

// Create drawing from file
func FromFile(fn string) (*drawing.Drawing, error) {
	var err error
	f, err := os.Open(fn)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return FromReader(f)
}

// Create drawing from string
func FromStringData(d string) (*drawing.Drawing, error) {
	sr := strings.NewReader(d)
	return FromReader(sr)
}

// Main logic to create a drawing
func FromReader(r io.Reader) (*drawing.Drawing, error) {
	var err error
	scanner := bufio.NewScanner(r)
	d := NewDrawing()
	var code, value string
	parsers := []func(*drawing.Drawing, int, [][2]string) error{
		ParseHeader,
		ParseClasses,
		ParseTables,
		ParseBlocks,
		ParseEntities,
		ParseObjects,
	}
	data := make([][2]string, 0)
	setparser := false
	var parser func(*drawing.Drawing, int, [][2]string) error
	line := 0
	startline := 0
	for scanner.Scan() {
		line++
		if line%2 == 1 {
			code = strings.TrimSpace(scanner.Text())
			if err != nil {
				return d, err
			}
		} else {
			value = scanner.Text()
			if setparser {
				if code != "2" {
					return d, fmt.Errorf("line %d: invalid group code: %s", line, code)
				}
				ind := drawing.SectionTypeValue(strings.ToUpper(value))
				if ind < 0 {
					return d, fmt.Errorf("line %d: unknown section name: %s", line, value)
				}
				parser = parsers[ind]
				startline = line + 1
				setparser = false
			} else {
				if code == "0" {
					switch strings.ToUpper(value) {
					case "EOF":
						return d, nil
					case "SECTION":
						setparser = true
					case "ENDSEC":
						err := parser(d, startline, data)
						if err != nil {
							return d, err
						}
						data = make([][2]string, 0)
						startline = line + 1
					default:
						data = append(data, [2]string{code, scanner.Text()})
					}
				} else {
					data = append(data, [2]string{code, scanner.Text()})
				}
			}
		}
	}
	if err := scanner.Err(); err != nil {
		return d, err
	}
	if len(data) > 0 {
		err := parser(d, startline, data)
		if err != nil {
			return d, err
		}
	}
	return d, nil
}

// Deprecated in favor of FromFile
func Open(filename string) (*drawing.Drawing, error) {
	var err error
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return FromReader(f)
}

// ColorIndex converts RGB value to corresponding color number.
func ColorIndex(cl []int) color.ColorNumber {
	minind := 0
	minval := 1000000
	for i, c := range color.ColorRGB {
		tmpval := 0
		for j := 0; j < 3; j++ {
			tmpval += (cl[j] - int(c[j])) * (cl[j] - int(c[j]))
		}
		if tmpval < minval {
			minind = i
			minval = tmpval
			if minval == 0 {
				break
			}
		}
	}
	return color.ColorNumber(minind)
}

// IndexColor converts color number to RGB value.
func IndexColor(index uint8) []uint8 {
	return color.ColorRGB[index]
}
<commit_msg>Open is an Alias to FromFile.<commit_after>// Package dxf is a DXF(Drawing Exchange Format) library for golang.
// ACAD2000(AC1015), ASCII format is only supported.
// http://www.autodesk.com/techpubs/autocad/acad2000/dxf/index.htm
package dxf

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/yofu/dxf/color"
	"github.com/yofu/dxf/drawing"
	"github.com/yofu/dxf/table"
)

// Default values.
var (
	DefaultColor    = color.White
	DefaultLineType = table.LT_CONTINUOUS
)

// NewDrawing creates a drawing.
func NewDrawing() *drawing.Drawing {
	return drawing.New()
}

// Create drawing from file
func FromFile(fn string) (*drawing.Drawing, error) {
	var err error
	f, err := os.Open(fn)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	return FromReader(f)
}

// Create drawing from string
func FromStringData(d string) (*drawing.Drawing, error) {
	sr := strings.NewReader(d)
	return FromReader(sr)
}

// Main logic to create a drawing
func FromReader(r io.Reader) (*drawing.Drawing, error) {
	var err error
	scanner := bufio.NewScanner(r)
	d := NewDrawing()
	var code, value string
	parsers := []func(*drawing.Drawing, int, [][2]string) error{
		ParseHeader,
		ParseClasses,
		ParseTables,
		ParseBlocks,
		ParseEntities,
		ParseObjects,
	}
	data := make([][2]string, 0)
	setparser := false
	var parser func(*drawing.Drawing, int, [][2]string) error
	line := 0
	startline := 0
	for scanner.Scan() {
		line++
		if line%2 == 1 {
			code = strings.TrimSpace(scanner.Text())
			if err != nil {
				return d, err
			}
		} else {
			value = scanner.Text()
			if setparser {
				if code != "2" {
					return d, fmt.Errorf("line %d: invalid group code: %s", line, code)
				}
				ind := drawing.SectionTypeValue(strings.ToUpper(value))
				if ind < 0 {
					return d, fmt.Errorf("line %d: unknown section name: %s", line, value)
				}
				parser = parsers[ind]
				startline = line + 1
				setparser = false
			} else {
				if code == "0" {
					switch strings.ToUpper(value) {
					case "EOF":
						return d, nil
					case "SECTION":
						setparser = true
					case "ENDSEC":
						err := parser(d, startline, data)
						if err != nil {
							return d, err
						}
						data = make([][2]string, 0)
						startline = line + 1
					default:
						data = append(data, [2]string{code, scanner.Text()})
					}
				} else {
					data = append(data, [2]string{code, scanner.Text()})
				}
			}
		}
	}
	if err := scanner.Err(); err != nil {
		return d, err
	}
	if len(data) > 0 {
		err := parser(d, startline, data)
		if err != nil {
			return d, err
		}
	}
	return d, nil
}

// Open is deprecated, please use FromFile
func Open(filename string) (*drawing.Drawing, error) {
	return FromFile(filename)
}

// ColorIndex converts RGB value to corresponding color number.
func ColorIndex(cl []int) color.ColorNumber {
	minind := 0
	minval := 1000000
	for i, c := range color.ColorRGB {
		tmpval := 0
		for j := 0; j < 3; j++ {
			tmpval += (cl[j] - int(c[j])) * (cl[j] - int(c[j]))
		}
		if tmpval < minval {
			minind = i
			minval = tmpval
			if minval == 0 {
				break
			}
		}
	}
	return color.ColorNumber(minind)
}

// IndexColor converts color number to RGB value.
func IndexColor(index uint8) []uint8 {
	return color.ColorRGB[index]
}
<|endoftext|>


<commit_before>package yiigo

import (
	"errors"
	"path/filepath"
	"strconv"
	"sync"
	"time"

	toml "github.com/pelletier/go-toml"
)

type env struct {
	tree  *toml.Tree
	mutex sync.RWMutex
}

// Env enviroment
var Env *env

// ErrEnvNil returned when config not found.
var ErrEnvNil = errors.New("yiigo: env config not found")

// loadEnv load env file.
func loadEnv() {
	abs, _ := filepath.Abs("env.toml")
	tomlTree, err := toml.LoadFile(abs)

	if err != nil {
		panic(err)
	}

	Env = &env{tree: tomlTree}
}

// String returns a value of string.
func (e *env) String(key string, defaultValue ...string) string {
	dv := ""

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case string:
		return t
	case int64:
		return strconv.FormatInt(t, 10)
	case uint64:
		return strconv.FormatInt(int64(t), 10)
	case float64:
		return strconv.FormatFloat(t, 'f', -1, 64)
	case bool:
		return strconv.FormatBool(t)
	default:
		return dv
	}
}

// Int returns a value of int.
func (e *env) Int(key string, defaultValue ...int) int {
	dv := 0

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case int64:
		return int(t)
	case uint64:
		return int(t)
	case float64:
		return int(t)
	case string:
		if v, err := strconv.ParseInt(t, 0, 0); err == nil {
			return int(v)
		}

		return dv
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return dv
	}
}

// Int64 returns a value of int64.
func (e *env) Int64(key string, defaultValue ...int64) int64 {
	var dv int64

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case int64:
		return t
	case uint64:
		return int64(t)
	case float64:
		return int64(t)
	case string:
		if v, err := strconv.ParseInt(t, 0, 0); err == nil {
			return v
		}

		return dv
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return dv
	}
}

// Float64 returns a value of float64.
func (e *env) Float64(key string, defaultValue ...float64) float64 {
	var dv float64

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case float64:
		return t
	case int64:
		return float64(t)
	case uint64:
		return float64(t)
	case string:
		if v, err := strconv.ParseFloat(t, 64); err == nil {
			return v
		}

		return dv
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return dv
	}
}

// Bool returns a value of bool.
func (e *env) Bool(key string, defaultValue ...bool) bool {
	var dv bool

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case bool:
		return t
	case int64:
		if t != 0 {
			return true
		}

		return false
	case uint64:
		if t != 0 {
			return true
		}

		return false
	case string:
		if v, err := strconv.ParseBool(t); err == nil {
			return v
		}

		return dv
	default:
		return dv
	}
}

// Time returns a value of time.Time.
func (e *env) Time(key string, defaultValue ...time.Time) time.Time {
	var dv time.Time

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	i := e.Get(key)

	switch t := i.(type) {
	case time.Time:
		return t
	case string:
		if v, err := time.Parse("2006-01-02 15:04:05", t); err == nil {
			return v
		}

		return dv
	case int64:
		return time.Unix(t, 0)
	case uint64:
		return time.Unix(int64(t), 0)
	default:
		return dv
	}
}

// Map returns a value of map[string]interface{}.
func (e *env) Map(key string) map[string]interface{} {
	i := e.Get(key)

	m := make(map[string]interface{})

	if v, ok := i.(*toml.Tree); ok {
		m = v.ToMap()
	}

	return m
}

// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by dest.
func (e *env) Unmarshal(key string, dest interface{}) error {
	i := e.Get(key)

	if i == nil {
		return ErrEnvNil
	}

	if v, ok := i.(*toml.Tree); ok {
		err := v.Unmarshal(dest)

		return err
	}

	return errors.New("yiigo: env config is not a tree of toml")
}

// Get returns a value of interface{}.
func (e *env) Get(key string) interface{} {
	e.mutex.RLock()
	defer e.mutex.RUnlock()

	return e.tree.Get(key)
}
<commit_msg>Improve env<commit_after>package yiigo

import (
	"errors"
	"path/filepath"
	"reflect"
	"strconv"
	"sync"
	"time"

	toml "github.com/pelletier/go-toml"
)

type env struct {
	tree  *toml.Tree
	mutex sync.RWMutex
}

// Env enviroment
var Env *env

// ErrEnvNil returned when config not found.
var ErrEnvNil = errors.New("yiigo: env config not found")

// loadEnv load env file.
func loadEnv() {
	abs, err := filepath.Abs("env.toml")

	if err != nil {
		panic(err)
	}

	tomlTree, err := toml.LoadFile(abs)

	if err != nil {
		panic(err)
	}

	Env = &env{tree: tomlTree}
}

// String returns a value of string.
func (e *env) String(key string, defaultValue ...string) string {
	dv := ""

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case string:
		return t
	case int64:
		return strconv.FormatInt(t, 10)
	case uint64:
		return strconv.FormatInt(int64(t), 10)
	case float64:
		return strconv.FormatFloat(t, 'f', -1, 64)
	case bool:
		return strconv.FormatBool(t)
	default:
		return ""
	}
}

// Strings returns a value of []string.
func (e *env) Strings(key string, defaultValue ...string) []string {
	ev := e.Get(key)

	if ev == nil {
		return defaultValue
	}

	v := reflect.Indirect(reflect.ValueOf(ev))

	if v.Kind() != reflect.Slice {
		return []string{}
	}

	l := v.Len()

	result := make([]string, 0, l)

	if l == 0 {
		return result
	}

	for i := 0; i < l; i++ {
		switch t := v.Index(i).Interface().(type) {
		case string:
			result = append(result, t)
		case int64:
			result = append(result, strconv.FormatInt(t, 10))
		case uint64:
			result = append(result, strconv.FormatInt(int64(t), 10))
		case float64:
			result = append(result, strconv.FormatFloat(t, 'f', -1, 64))
		case bool:
			result = append(result, strconv.FormatBool(t))
		default:
			result = append(result, "")
		}
	}

	return result
}

// Int returns a value of int.
func (e *env) Int(key string, defaultValue ...int) int {
	dv := 0

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case int64:
		return int(t)
	case uint64:
		return int(t)
	case float64:
		return int(t)
	case string:
		v, _ := strconv.Atoi(t)

		return v
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return 0
	}
}

// Ints returns a value of []int.
func (e *env) Ints(key string, defaultValue ...int) []int {
	ev := e.Get(key)

	if ev == nil {
		return []int{}
	}

	v := reflect.Indirect(reflect.ValueOf(ev))

	if v.Kind() != reflect.Slice {
		return defaultValue
	}

	l := v.Len()

	result := make([]int, 0, l)

	if l == 0 {
		return result
	}

	for i := 0; i < l; i++ {
		switch t := v.Index(i).Interface().(type) {
		case int64:
			result = append(result, int(t))
		case uint64:
			result = append(result, int(t))
		case float64:
			result = append(result, int(t))
		case string:
			n, _ := strconv.Atoi(t)
			result = append(result, n)
		case bool:
			if t {
				result = append(result, 1)
			} else {
				result = append(result, 0)
			}
		default:
			result = append(result, 0)
		}
	}

	return result
}

// Int64 returns a value of int64.
func (e *env) Int64(key string, defaultValue ...int64) int64 {
	var dv int64

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case int64:
		return t
	case uint64:
		return int64(t)
	case float64:
		return int64(t)
	case string:
		v, _ := strconv.ParseInt(t, 0, 0)

		return v
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return 0
	}
}

// Int64s returns a value of []int64.
func (e *env) Int64s(key string, defaultValue ...int64) []int64 {
	ev := e.Get(key)

	if ev == nil {
		return defaultValue
	}

	v := reflect.Indirect(reflect.ValueOf(ev))

	if v.Kind() != reflect.Slice {
		return []int64{}
	}

	l := v.Len()

	result := make([]int64, 0, l)

	if l == 0 {
		return result
	}

	for i := 0; i < l; i++ {
		switch t := v.Index(i).Interface().(type) {
		case int64:
			result = append(result, t)
		case uint64:
			result = append(result, int64(t))
		case float64:
			result = append(result, int64(t))
		case string:
			n, _ := strconv.ParseInt(t, 10, 64)

			result = append(result, n)
		case bool:
			if t {
				result = append(result, 1)
			} else {
				result = append(result, 0)
			}
		default:
			result = append(result, 0)
		}
	}

	return result
}

// Float64 returns a value of float64.
func (e *env) Float64(key string, defaultValue ...float64) float64 {
	var dv float64

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case float64:
		return t
	case int64:
		return float64(t)
	case uint64:
		return float64(t)
	case string:
		v, _ := strconv.ParseFloat(t, 64)

		return v
	case bool:
		if t {
			return 1
		}

		return 0
	default:
		return 0
	}
}

// Float64s returns a value of []float64.
func (e *env) Float64s(key string, defaultValue ...float64) []float64 {
	ev := e.Get(key)

	if ev == nil {
		return defaultValue
	}

	v := reflect.Indirect(reflect.ValueOf(ev))

	if v.Kind() != reflect.Slice {
		return []float64{}
	}

	l := v.Len()

	result := make([]float64, 0, l)

	if l == 0 {
		return result
	}

	for i := 0; i < l; i++ {
		switch t := v.Index(i).Interface().(type) {
		case float64:
			result = append(result, t)
		case int64:
			result = append(result, float64(t))
		case uint64:
			result = append(result, float64(t))
		case string:
			n, _ := strconv.ParseFloat(t, 64)

			result = append(result, n)
		case bool:
			if t {
				result = append(result, 1)
			} else {
				result = append(result, 0)
			}
		default:
			result = append(result, 0)
		}
	}

	return result
}

// Bool returns a value of bool.
func (e *env) Bool(key string, defaultValue ...bool) bool {
	var dv bool

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case bool:
		return t
	case int64:
		if t != 0 {
			return true
		}

		return false
	case uint64:
		if t != 0 {
			return true
		}

		return false
	case string:
		v, _ := strconv.ParseBool(t)

		return v
	default:
		return false
	}
}

// Time returns a value of time.Time.
// Layout is required when the env value is a string.
func (e *env) Time(key string, layout string, defaultValue ...time.Time) time.Time {
	var dv time.Time

	if len(defaultValue) > 0 {
		dv = defaultValue[0]
	}

	ev := e.Get(key)

	if ev == nil {
		return dv
	}

	switch t := ev.(type) {
	case time.Time:
		return t
	case string:
		v, _ := time.Parse(layout, t)

		return v
	case int64:
		return time.Unix(t, 0)
	case uint64:
		return time.Unix(int64(t), 0)
	default:
		return time.Time{}
	}
}

// Map returns a value of map[string]interface{}.
func (e *env) Map(key string) map[string]interface{} {
	m := make(map[string]interface{})

	if v, ok := e.Get(key).(*toml.Tree); ok {
		m = v.ToMap()
	}

	return m
}

// Unmarshal attempts to unmarshal the Tree into a Go struct pointed by dest.
func (e *env) Unmarshal(key string, dest interface{}) error {
	i := e.Get(key)

	if i == nil {
		return ErrEnvNil
	}

	if v, ok := i.(*toml.Tree); ok {
		err := v.Unmarshal(dest)

		return err
	}

	return errors.New("yiigo: env config is not a tree of toml")
}

// Get returns the value at key in the env Tree.
func (e *env) Get(key string) interface{} {
	e.mutex.RLock()
	defer e.mutex.RUnlock()

	return e.tree.Get(key)
}
<|endoftext|>