diff options
| author | Brad Fitzpatrick <bradfitz@golang.org> | 2012-01-19 16:04:26 -0800 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2012-01-19 16:04:26 -0800 |
| commit | 7fc4c07172b7b6feb2da345511ad439fedaf876b (patch) | |
| tree | 88637df85d0f813cbb80045811a2c341edb4a242 /src/pkg/exp/sql/driver | |
| parent | 369454d7b2f3b03ee5bdfde1eae6092bace14951 (diff) | |
| download | go-7fc4c07172b7b6feb2da345511ad439fedaf876b.tar.xz | |
database/sql: move from exp/sql
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5536076
Diffstat (limited to 'src/pkg/exp/sql/driver')
| -rw-r--r-- | src/pkg/exp/sql/driver/Makefile | 12 | ||||
| -rw-r--r-- | src/pkg/exp/sql/driver/driver.go | 207 | ||||
| -rw-r--r-- | src/pkg/exp/sql/driver/types.go | 265 | ||||
| -rw-r--r-- | src/pkg/exp/sql/driver/types_test.go | 61 |
4 files changed, 0 insertions, 545 deletions
diff --git a/src/pkg/exp/sql/driver/Makefile b/src/pkg/exp/sql/driver/Makefile deleted file mode 100644 index fce3f2c27c..0000000000 --- a/src/pkg/exp/sql/driver/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2011 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -include ../../../../Make.inc - -TARG=exp/sql/driver -GOFILES=\ - driver.go\ - types.go\ - -include ../../../../Make.pkg diff --git a/src/pkg/exp/sql/driver/driver.go b/src/pkg/exp/sql/driver/driver.go deleted file mode 100644 index 0cd2562d68..0000000000 --- a/src/pkg/exp/sql/driver/driver.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package driver defines interfaces to be implemented by database -// drivers as used by package sql. -// -// Code simply using databases should use package sql. -// -// Drivers only need to be aware of a subset of Go's types. The sql package -// will convert all types into one of the following: -// -// int64 -// float64 -// bool -// nil -// []byte -// string [*] everywhere except from Rows.Next. -// time.Time -// -package driver - -import "errors" - -// Driver is the interface that must be implemented by a database -// driver. -type Driver interface { - // Open returns a new connection to the database. - // The name is a string in a driver-specific format. - // - // Open may return a cached connection (one previously - // closed), but doing so is unnecessary; the sql package - // maintains a pool of idle connections for efficient re-use. - // - // The returned connection is only used by one goroutine at a - // time. - Open(name string) (Conn, error) -} - -// ErrSkip may be returned by some optional interfaces' methods to -// indicate at runtime that the fast path is unavailable and the sql -// package should continue as if the optional interface was not -// implemented. ErrSkip is only supported where explicitly -// documented. -var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented") - -// Execer is an optional interface that may be implemented by a Conn. -// -// If a Conn does not implement Execer, the db package's DB.Exec will -// first prepare a query, execute the statement, and then close the -// statement. -// -// All arguments are of a subset type as defined in the package docs. -// -// Exec may return ErrSkip. -type Execer interface { - Exec(query string, args []interface{}) (Result, error) -} - -// Conn is a connection to a database. It is not used concurrently -// by multiple goroutines. -// -// Conn is assumed to be stateful. -type Conn interface { - // Prepare returns a prepared statement, bound to this connection. - Prepare(query string) (Stmt, error) - - // Close invalidates and potentially stops any current - // prepared statements and transactions, marking this - // connection as no longer in use. - // - // Because the sql package maintains a free pool of - // connections and only calls Close when there's a surplus of - // idle connections, it shouldn't be necessary for drivers to - // do their own connection caching. - Close() error - - // Begin starts and returns a new transaction. - Begin() (Tx, error) -} - -// Result is the result of a query execution. -type Result interface { - // LastInsertId returns the database's auto-generated ID - // after, for example, an INSERT into a table with primary - // key. - LastInsertId() (int64, error) - - // RowsAffected returns the number of rows affected by the - // query. - RowsAffected() (int64, error) -} - -// Stmt is a prepared statement. It is bound to a Conn and not -// used by multiple goroutines concurrently. -type Stmt interface { - // Close closes the statement. - // - // Closing a statement should not interrupt any outstanding - // query created from that statement. That is, the following - // order of operations is valid: - // - // * create a driver statement - // * call Query on statement, returning Rows - // * close the statement - // * read from Rows - // - // If closing a statement invalidates currently-running - // queries, the final step above will incorrectly fail. - // - // TODO(bradfitz): possibly remove the restriction above, if - // enough driver authors object and find it complicates their - // code too much. The sql package could be smarter about - // refcounting the statement and closing it at the appropriate - // time. - Close() error - - // NumInput returns the number of placeholder parameters. - // - // If NumInput returns >= 0, the sql package will sanity check - // argument counts from callers and return errors to the caller - // before the statement's Exec or Query methods are called. - // - // NumInput may also return -1, if the driver doesn't know - // its number of placeholders. In that case, the sql package - // will not sanity check Exec or Query argument counts. - NumInput() int - - // Exec executes a query that doesn't return rows, such - // as an INSERT or UPDATE. The args are all of a subset - // type as defined above. - Exec(args []interface{}) (Result, error) - - // Exec executes a query that may return rows, such as a - // SELECT. The args of all of a subset type as defined above. - Query(args []interface{}) (Rows, error) -} - -// ColumnConverter may be optionally implemented by Stmt if the -// the statement is aware of its own columns' types and can -// convert from any type to a driver subset type. -type ColumnConverter interface { - // ColumnConverter returns a ValueConverter for the provided - // column index. If the type of a specific column isn't known - // or shouldn't be handled specially, DefaultValueConverter - // can be returned. - ColumnConverter(idx int) ValueConverter -} - -// Rows is an iterator over an executed query's results. -type Rows interface { - // Columns returns the names of the columns. The number of - // columns of the result is inferred from the length of the - // slice. If a particular column name isn't known, an empty - // string should be returned for that entry. - Columns() []string - - // Close closes the rows iterator. - Close() error - - // Next is called to populate the next row of data into - // the provided slice. The provided slice will be the same - // size as the Columns() are wide. - // - // The dest slice may be populated with only with values - // of subset types defined above, but excluding string. - // All string values must be converted to []byte. - // - // Next should return io.EOF when there are no more rows. - Next(dest []interface{}) error -} - -// Tx is a transaction. -type Tx interface { - Commit() error - Rollback() error -} - -// RowsAffected implements Result for an INSERT or UPDATE operation -// which mutates a number of rows. -type RowsAffected int64 - -var _ Result = RowsAffected(0) - -func (RowsAffected) LastInsertId() (int64, error) { - return 0, errors.New("no LastInsertId available") -} - -func (v RowsAffected) RowsAffected() (int64, error) { - return int64(v), nil -} - -// DDLSuccess is a pre-defined Result for drivers to return when a DDL -// command succeeds. -var DDLSuccess ddlSuccess - -type ddlSuccess struct{} - -var _ Result = ddlSuccess{} - -func (ddlSuccess) LastInsertId() (int64, error) { - return 0, errors.New("no LastInsertId available after DDL statement") -} - -func (ddlSuccess) RowsAffected() (int64, error) { - return 0, errors.New("no RowsAffected available after DDL statement") -} diff --git a/src/pkg/exp/sql/driver/types.go b/src/pkg/exp/sql/driver/types.go deleted file mode 100644 index f383885231..0000000000 --- a/src/pkg/exp/sql/driver/types.go +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package driver - -import ( - "fmt" - "reflect" - "strconv" - "time" -) - -// ValueConverter is the interface providing the ConvertValue method. -// -// Various implementations of ValueConverter are provided by the -// driver package to provide consistent implementations of conversions -// between drivers. The ValueConverters have several uses: -// -// * converting from the subset types as provided by the sql package -// into a database table's specific column type and making sure it -// fits, such as making sure a particular int64 fits in a -// table's uint16 column. -// -// * converting a value as given from the database into one of the -// subset types. -// -// * by the sql package, for converting from a driver's subset type -// to a user's type in a scan. -type ValueConverter interface { - // ConvertValue converts a value to a restricted subset type. - ConvertValue(v interface{}) (interface{}, error) -} - -// SubsetValuer is the interface providing the SubsetValue method. -// -// Types implementing SubsetValuer interface are able to convert -// themselves to one of the driver's allowed subset values. -type SubsetValuer interface { - // SubsetValue returns a driver parameter subset value. - SubsetValue() (interface{}, error) -} - -// Bool is a ValueConverter that converts input values to bools. -// -// The conversion rules are: -// - booleans are returned unchanged -// - for integer types, -// 1 is true -// 0 is false, -// other integers are an error -// - for strings and []byte, same rules as strconv.ParseBool -// - all other types are an error -var Bool boolType - -type boolType struct{} - -var _ ValueConverter = boolType{} - -func (boolType) String() string { return "Bool" } - -func (boolType) ConvertValue(src interface{}) (interface{}, error) { - switch s := src.(type) { - case bool: - return s, nil - case string: - b, err := strconv.ParseBool(s) - if err != nil { - return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) - } - return b, nil - case []byte: - b, err := strconv.ParseBool(string(s)) - if err != nil { - return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) - } - return b, nil - } - - sv := reflect.ValueOf(src) - switch sv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - iv := sv.Int() - if iv == 1 || iv == 0 { - return iv == 1, nil - } - return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", iv) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - uv := sv.Uint() - if uv == 1 || uv == 0 { - return uv == 1, nil - } - return nil, fmt.Errorf("sql/driver: couldn't convert %d into type bool", uv) - } - - return nil, fmt.Errorf("sql/driver: couldn't convert %v (%T) into type bool", src, src) -} - -// Int32 is a ValueConverter that converts input values to int64, -// respecting the limits of an int32 value. -var Int32 int32Type - -type int32Type struct{} - -var _ ValueConverter = int32Type{} - -func (int32Type) ConvertValue(v interface{}) (interface{}, error) { - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - i64 := rv.Int() - if i64 > (1<<31)-1 || i64 < -(1<<31) { - return nil, fmt.Errorf("sql/driver: value %d overflows int32", v) - } - return i64, nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - u64 := rv.Uint() - if u64 > (1<<31)-1 { - return nil, fmt.Errorf("sql/driver: value %d overflows int32", v) - } - return int64(u64), nil - case reflect.String: - i, err := strconv.Atoi(rv.String()) - if err != nil { - return nil, fmt.Errorf("sql/driver: value %q can't be converted to int32", v) - } - return int64(i), nil - } - return nil, fmt.Errorf("sql/driver: unsupported value %v (type %T) converting to int32", v, v) -} - -// String is a ValueConverter that converts its input to a string. -// If the value is already a string or []byte, it's unchanged. -// If the value is of another type, conversion to string is done -// with fmt.Sprintf("%v", v). -var String stringType - -type stringType struct{} - -func (stringType) ConvertValue(v interface{}) (interface{}, error) { - switch v.(type) { - case string, []byte: - return v, nil - } - return fmt.Sprintf("%v", v), nil -} - -// Null is a type that implements ValueConverter by allowing nil -// values but otherwise delegating to another ValueConverter. -type Null struct { - Converter ValueConverter -} - -func (n Null) ConvertValue(v interface{}) (interface{}, error) { - if v == nil { - return nil, nil - } - return n.Converter.ConvertValue(v) -} - -// NotNull is a type that implements ValueConverter by disallowing nil -// values but otherwise delegating to another ValueConverter. -type NotNull struct { - Converter ValueConverter -} - -func (n NotNull) ConvertValue(v interface{}) (interface{}, error) { - if v == nil { - return nil, fmt.Errorf("nil value not allowed") - } - return n.Converter.ConvertValue(v) -} - -// IsParameterSubsetType reports whether v is of a valid type for a -// parameter. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// string -// -// This is the same list as IsScanSubsetType, with the addition of -// string. -func IsParameterSubsetType(v interface{}) bool { - if IsScanSubsetType(v) { - return true - } - if _, ok := v.(string); ok { - return true - } - return false -} - -// IsScanSubsetType reports whether v is of a valid type for a -// value populated by Rows.Next. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// -// This is the same list as IsParameterSubsetType, without string. -func IsScanSubsetType(v interface{}) bool { - if v == nil { - return true - } - switch v.(type) { - case int64, float64, []byte, bool, time.Time: - return true - } - return false -} - -// DefaultParameterConverter is the default implementation of -// ValueConverter that's used when a Stmt doesn't implement -// ColumnConverter. -// -// DefaultParameterConverter returns the given value directly if -// IsSubsetType(value). Otherwise integer type are converted to -// int64, floats to float64, and strings to []byte. Other types are -// an error. -var DefaultParameterConverter defaultConverter - -type defaultConverter struct{} - -var _ ValueConverter = defaultConverter{} - -func (defaultConverter) ConvertValue(v interface{}) (interface{}, error) { - if IsParameterSubsetType(v) { - return v, nil - } - - if svi, ok := v.(SubsetValuer); ok { - sv, err := svi.SubsetValue() - if err != nil { - return nil, err - } - if !IsParameterSubsetType(sv) { - return nil, fmt.Errorf("non-subset type %T returned from SubsetValue", sv) - } - return sv, nil - } - - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return rv.Int(), nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: - return int64(rv.Uint()), nil - case reflect.Uint64: - u64 := rv.Uint() - if u64 >= 1<<63 { - return nil, fmt.Errorf("uint64 values with high bit set are not supported") - } - return int64(u64), nil - case reflect.Float32, reflect.Float64: - return rv.Float(), nil - } - return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) -} diff --git a/src/pkg/exp/sql/driver/types_test.go b/src/pkg/exp/sql/driver/types_test.go deleted file mode 100644 index 966bc6b458..0000000000 --- a/src/pkg/exp/sql/driver/types_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package driver - -import ( - "reflect" - "testing" - "time" -) - -type valueConverterTest struct { - c ValueConverter - in interface{} - out interface{} - err string -} - -var now = time.Now() - -var valueConverterTests = []valueConverterTest{ - {Bool, "true", true, ""}, - {Bool, "True", true, ""}, - {Bool, []byte("t"), true, ""}, - {Bool, true, true, ""}, - {Bool, "1", true, ""}, - {Bool, 1, true, ""}, - {Bool, int64(1), true, ""}, - {Bool, uint16(1), true, ""}, - {Bool, "false", false, ""}, - {Bool, false, false, ""}, - {Bool, "0", false, ""}, - {Bool, 0, false, ""}, - {Bool, int64(0), false, ""}, - {Bool, uint16(0), false, ""}, - {c: Bool, in: "foo", err: "sql/driver: couldn't convert \"foo\" into type bool"}, - {c: Bool, in: 2, err: "sql/driver: couldn't convert 2 into type bool"}, - {DefaultParameterConverter, now, now, ""}, -} - -func TestValueConverters(t *testing.T) { - for i, tt := range valueConverterTests { - out, err := tt.c.ConvertValue(tt.in) - goterr := "" - if err != nil { - goterr = err.Error() - } - if goterr != tt.err { - t.Errorf("test %d: %s(%T(%v)) error = %q; want error = %q", - i, tt.c, tt.in, tt.in, goterr, tt.err) - } - if tt.err != "" { - continue - } - if !reflect.DeepEqual(out, tt.out) { - t.Errorf("test %d: %s(%T(%v)) = %v (%T); want %v (%T)", - i, tt.c, tt.in, tt.in, out, out, tt.out, tt.out) - } - } -} |
