diff --git a/bulkcopy.go b/bulkcopy.go index 1d5eacb3..1792d275 100644 --- a/bulkcopy.go +++ b/bulkcopy.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/denisenkom/go-mssqldb/internal/decimal" + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" ) type Bulk struct { @@ -490,24 +490,24 @@ func (b *Bulk) makeParam(val DataValue, col columnStruct) (res param, err error) case typeDecimal, typeDecimalN, typeNumeric, typeNumericN: prec := col.ti.Prec scale := col.ti.Scale - var dec decimal.Decimal + var dec mssqltypes.Decimal switch v := val.(type) { case int: - dec = decimal.Int64ToDecimalScale(int64(v), 0) + dec = mssqltypes.Int64ToDecimalScale(int64(v), 0) case int8: - dec = decimal.Int64ToDecimalScale(int64(v), 0) + dec = mssqltypes.Int64ToDecimalScale(int64(v), 0) case int16: - dec = decimal.Int64ToDecimalScale(int64(v), 0) + dec = mssqltypes.Int64ToDecimalScale(int64(v), 0) case int32: - dec = decimal.Int64ToDecimalScale(int64(v), 0) + dec = mssqltypes.Int64ToDecimalScale(int64(v), 0) case int64: - dec = decimal.Int64ToDecimalScale(int64(v), 0) + dec = mssqltypes.Int64ToDecimalScale(int64(v), 0) case float32: - dec, err = decimal.Float64ToDecimalScale(float64(v), scale) + dec, err = mssqltypes.Float64ToDecimalScale(float64(v), scale) case float64: - dec, err = decimal.Float64ToDecimalScale(float64(v), scale) + dec, err = mssqltypes.Float64ToDecimalScale(float64(v), scale) case string: - dec, err = decimal.StringToDecimalScale(v, scale) + dec, err = mssqltypes.StringToDecimalScale(v, scale) default: return res, fmt.Errorf("unknown value for decimal: %T %#v", v, v) } diff --git a/datetimeoffset_example_test.go b/datetimeoffset_example_test.go index 186f8196..95a0de03 100644 --- a/datetimeoffset_example_test.go +++ b/datetimeoffset_example_test.go @@ -9,8 +9,8 @@ import ( "log" "time" + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" "github.com/golang-sql/civil" - "github.com/denisenkom/go-mssqldb" ) // This example shows how to insert and retrieve date and time types data @@ -56,9 +56,9 @@ func insertDateTime(db *sql.DB) { var timeCol civil.Time = civil.TimeOf(tin) var dateCol civil.Date = civil.DateOf(tin) var smalldatetimeCol string = "2006-01-02 22:04:00" - var datetimeCol mssql.DateTime1 = mssql.DateTime1(tin) + var datetimeCol mssqltypes.DateTime1 = mssqltypes.DateTime1(tin) var datetime2Col civil.DateTime = civil.DateTimeOf(tin) - var datetimeoffsetCol mssql.DateTimeOffset = mssql.DateTimeOffset(tin) + var datetimeoffsetCol mssqltypes.DateTimeOffset = mssqltypes.DateTimeOffset(tin) _, err = stmt.Exec(timeCol, dateCol, smalldatetimeCol, datetimeCol, datetime2Col, datetimeoffsetCol) if err != nil { log.Fatal(err) @@ -103,8 +103,8 @@ func retrieveDateTimeOutParam(db *sql.DB) { log.Fatal(err) } var ( - timeOutParam, datetime2OutParam, datetimeoffsetOutParam mssql.DateTimeOffset - dateOutParam, datetimeOutParam mssql.DateTime1 + timeOutParam, datetime2OutParam, datetimeoffsetOutParam mssqltypes.DateTimeOffset + dateOutParam, datetimeOutParam mssqltypes.DateTime1 smalldatetimeOutParam string ) _, err = db.Exec("OutDatetimeProc", diff --git a/error.go b/error.go index 2e5bacee..6a0175c0 100644 --- a/error.go +++ b/error.go @@ -19,6 +19,7 @@ type Error struct { LineNo int32 } +// Error returns the SQL Server error message. func (e Error) Error() string { return "mssql: " + e.Message } @@ -28,34 +29,42 @@ func (e Error) SQLErrorNumber() int32 { return e.Number } +// SQLErrorState returns the SQL Server error state. func (e Error) SQLErrorState() uint8 { return e.State } +// SQLErrorClass returns the SQL Server error class. func (e Error) SQLErrorClass() uint8 { return e.Class } +// SQLErrorMessage returns the SQL Server error message. func (e Error) SQLErrorMessage() string { return e.Message } +// SQLErrorServerName returns the SQL Server name. func (e Error) SQLErrorServerName() string { return e.ServerName } +// SQLErrorProcName returns the procedure name. func (e Error) SQLErrorProcName() string { return e.ProcName } +// SQLErrorLineNo returns the error line number. func (e Error) SQLErrorLineNo() int32 { return e.LineNo } +// StreamError represents TDS stream error. type StreamError struct { Message string } +// Error returns the TDS stream error message. func (e StreamError) Error() string { return e.Message } diff --git a/internal/decimal/decimal.go b/internal/mssqltypes/decimal.go similarity index 99% rename from internal/decimal/decimal.go rename to internal/mssqltypes/decimal.go index 7da0375d..6f4e7b2a 100644 --- a/internal/decimal/decimal.go +++ b/internal/mssqltypes/decimal.go @@ -1,4 +1,4 @@ -package decimal +package mssqltypes import ( "encoding/binary" diff --git a/internal/decimal/decimal_test.go b/internal/mssqltypes/decimal_test.go similarity index 99% rename from internal/decimal/decimal_test.go rename to internal/mssqltypes/decimal_test.go index 4086a964..f75cf79e 100644 --- a/internal/decimal/decimal_test.go +++ b/internal/mssqltypes/decimal_test.go @@ -1,4 +1,4 @@ -package decimal +package mssqltypes import ( "math" diff --git a/internal/mssqltypes/mssqltypes.go b/internal/mssqltypes/mssqltypes.go new file mode 100644 index 00000000..92b04b3c --- /dev/null +++ b/internal/mssqltypes/mssqltypes.go @@ -0,0 +1,20 @@ +// +build go1.9 + +package mssqltypes + +import "time" + +// VarChar parameter types. +type VarChar string + +// NVarCharMax encodes parameters to NVarChar(max) SQL type. +type NVarCharMax string + +// VarCharMax encodes parameter to VarChar(max) SQL type. +type VarCharMax string + +// DateTime1 encodes parameters to original DateTime SQL types. +type DateTime1 time.Time + +// DateTimeOffset encodes parameters to DateTimeOffset, preserving the UTC offset. +type DateTimeOffset time.Time diff --git a/uniqueidentifier.go b/internal/mssqltypes/uniqueidentifier.go similarity index 88% rename from uniqueidentifier.go rename to internal/mssqltypes/uniqueidentifier.go index 3ad6f863..b147fad6 100644 --- a/uniqueidentifier.go +++ b/internal/mssqltypes/uniqueidentifier.go @@ -1,4 +1,4 @@ -package mssql +package mssqltypes import ( "database/sql/driver" @@ -7,8 +7,10 @@ import ( "fmt" ) +// UniqueIdentifier encodes parameters to Uniqueidentifier SQL type. type UniqueIdentifier [16]byte +// Scan converts v to UniqueIdentifier func (u *UniqueIdentifier) Scan(v interface{}) error { reverse := func(b []byte) { for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 { @@ -52,6 +54,7 @@ func (u *UniqueIdentifier) Scan(v interface{}) error { } } +// Value converts UniqueIdentifier to bytes func (u UniqueIdentifier) Value() (driver.Value, error) { reverse := func(b []byte) { for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 { @@ -69,6 +72,7 @@ func (u UniqueIdentifier) Value() (driver.Value, error) { return raw, nil } +// String converts UniqueIdentifier to string func (u UniqueIdentifier) String() string { return fmt.Sprintf("%X-%X-%X-%X-%X", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) } diff --git a/uniqueidentifier_test.go b/internal/mssqltypes/uniqueidentifier_test.go similarity index 99% rename from uniqueidentifier_test.go rename to internal/mssqltypes/uniqueidentifier_test.go index 47a3d883..ff553bd5 100644 --- a/uniqueidentifier_test.go +++ b/internal/mssqltypes/uniqueidentifier_test.go @@ -1,4 +1,4 @@ -package mssql +package mssqltypes import ( "bytes" diff --git a/mssql_go19.go b/mssql_go19.go index a2bd1167..170a2a0d 100644 --- a/mssql_go19.go +++ b/mssql_go19.go @@ -11,6 +11,7 @@ import ( "time" // "github.com/cockroachdb/apd" + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" "github.com/golang-sql/civil" ) @@ -26,29 +27,17 @@ type MssqlStmt = Stmt // Deprecated: users should transition to th var _ driver.NamedValueChecker = &Conn{} -// VarChar parameter types. -type VarChar string - -type NVarCharMax string -type VarCharMax string - -// DateTime1 encodes parameters to original DateTime SQL types. -type DateTime1 time.Time - -// DateTimeOffset encodes parameters to DateTimeOffset, preserving the UTC offset. -type DateTimeOffset time.Time - func convertInputParameter(val interface{}) (interface{}, error) { switch v := val.(type) { - case VarChar: + case mssqltypes.VarChar: return val, nil - case NVarCharMax: + case mssqltypes.NVarCharMax: return val, nil - case VarCharMax: + case mssqltypes.VarCharMax: return val, nil - case DateTime1: + case mssqltypes.DateTime1: return val, nil - case DateTimeOffset: + case mssqltypes.DateTimeOffset: return val, nil case civil.Date: return val, nil @@ -123,24 +112,24 @@ func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error { func (s *Stmt) makeParamExtra(val driver.Value) (res param, err error) { switch val := val.(type) { - case VarChar: + case mssqltypes.VarChar: res.ti.TypeId = typeBigVarChar res.buffer = []byte(val) res.ti.Size = len(res.buffer) - case VarCharMax: + case mssqltypes.VarCharMax: res.ti.TypeId = typeBigVarChar res.buffer = []byte(val) res.ti.Size = 0 // currently zero forces varchar(max) - case NVarCharMax: + case mssqltypes.NVarCharMax: res.ti.TypeId = typeNVarChar res.buffer = str2ucs2(string(val)) res.ti.Size = 0 // currently zero forces nvarchar(max) - case DateTime1: + case mssqltypes.DateTime1: t := time.Time(val) res.ti.TypeId = typeDateTimeN res.buffer = encodeDateTime(t) res.ti.Size = len(res.buffer) - case DateTimeOffset: + case mssqltypes.DateTimeOffset: res.ti.TypeId = typeDateTimeOffsetN res.ti.Scale = 7 res.buffer = encodeDateTimeOffset(time.Time(val), int(res.ti.Scale)) diff --git a/queries_go110_test.go b/queries_go110_test.go index debb636f..f7e7b16e 100644 --- a/queries_go110_test.go +++ b/queries_go110_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" "github.com/golang-sql/civil" ) @@ -80,14 +81,14 @@ select ; `, sql.Named("nv", "base type nvarchar"), - sql.Named("v", VarChar("base type varchar")), - sql.Named("nvcm", NVarCharMax(strings.Repeat("x", 5000))), - sql.Named("vcm", VarCharMax(strings.Repeat("x", 5000))), - sql.Named("dt1", DateTime1(tin)), + sql.Named("v", mssqltypes.VarChar("base type varchar")), + sql.Named("nvcm", mssqltypes.NVarCharMax(strings.Repeat("x", 5000))), + sql.Named("vcm", mssqltypes.VarCharMax(strings.Repeat("x", 5000))), + sql.Named("dt1", mssqltypes.DateTime1(tin)), sql.Named("dt2", civil.DateTimeOf(tin)), sql.Named("d", civil.DateOf(tin)), sql.Named("tm", civil.TimeOf(tin)), - sql.Named("dto", DateTimeOffset(tin)), + sql.Named("dto", mssqltypes.DateTimeOffset(tin)), ) err = row.Scan(&nv, &v, &nvcm, &vcm, &dt1, &dt2, &d, &tm, &dto) if err != nil { @@ -153,11 +154,11 @@ select sql.Named("nv", sin), sql.Named("v", sin), sql.Named("tgo", tin), - sql.Named("dt1", DateTime1(tin)), + sql.Named("dt1", mssqltypes.DateTime1(tin)), sql.Named("dt2", civil.DateTimeOf(tin)), sql.Named("d", civil.DateOf(tin)), sql.Named("tm", civil.TimeOf(tin)), - sql.Named("dto", DateTimeOffset(tin)), + sql.Named("dto", mssqltypes.DateTimeOffset(tin)), ).Scan(&nv, &v, &tgo, &dt1, &dt2, &d, &tm, &dto) if err != nil { t.Fatal(err) diff --git a/queries_go19_test.go b/queries_go19_test.go index e3addd03..222a034d 100644 --- a/queries_go19_test.go +++ b/queries_go19_test.go @@ -10,6 +10,8 @@ import ( "regexp" "testing" "time" + + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" ) func TestOutputParam(t *testing.T) { @@ -174,8 +176,8 @@ END; if err != nil { t.Fatal(err) } - var datetime_param DateTime1 - datetime_param = DateTime1(tin) + var datetime_param mssqltypes.DateTime1 + datetime_param = mssqltypes.DateTime1(tin) _, err = db.ExecContext(ctx, sqltextrun, sql.Named("datetime", sql.Out{Dest: &datetime_param}), ) @@ -346,7 +348,7 @@ END; t.Run("original test", func(t *testing.T) { var bout int64 = 3 var cout string - var vout VarChar + var vout mssqltypes.VarChar _, err = db.ExecContext(ctx, sqltextrun, sql.Named("aid", 5), sql.Named("bid", sql.Out{Dest: &bout}), @@ -964,12 +966,12 @@ func TestDateTimeParam19(t *testing.T) { var emptydate time.Time mindate1 := time.Date(1753, 1, 1, 0, 0, 0, 0, time.UTC) maxdate1 := time.Date(9999, 12, 31, 23, 59, 59, 997000000, time.UTC) - testdates1 := []DateTime1{ - DateTime1(mindate1), - DateTime1(maxdate1), - DateTime1(time.Date(1752, 12, 31, 23, 59, 59, 997000000, time.UTC)), // just a little below minimum date - DateTime1(time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC)), // just a little over maximum date - DateTime1(emptydate), + testdates1 := []mssqltypes.DateTime1{ + mssqltypes.DateTime1(mindate1), + mssqltypes.DateTime1(maxdate1), + mssqltypes.DateTime1(time.Date(1752, 12, 31, 23, 59, 59, 997000000, time.UTC)), // just a little below minimum date + mssqltypes.DateTime1(time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC)), // just a little over maximum date + mssqltypes.DateTime1(emptydate), } for _, test := range testdates1 { diff --git a/queries_test.go b/queries_test.go index 3625788b..d141b312 100644 --- a/queries_test.go +++ b/queries_test.go @@ -14,6 +14,8 @@ import ( "sync" "testing" "time" + + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" ) func driverWithProcess(t *testing.T) *Driver { @@ -836,7 +838,7 @@ func TestUniqueIdentifierParam(t *testing.T) { uuid interface{} } - expected := UniqueIdentifier{0x01, 0x23, 0x45, 0x67, + expected := mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, @@ -856,7 +858,7 @@ func TestUniqueIdentifierParam(t *testing.T) { for _, test := range values { t.Run(test.name, func(t *testing.T) { - var uuid2 UniqueIdentifier + var uuid2 mssqltypes.UniqueIdentifier err := conn.QueryRow("select @p1", test.uuid).Scan(&uuid2) if err != nil { t.Fatal("select / scan failed", err.Error()) diff --git a/tvp_go19_db_test.go b/tvp_go19_db_test.go index 6cf42641..d5f33db0 100644 --- a/tvp_go19_db_test.go +++ b/tvp_go19_db_test.go @@ -9,6 +9,8 @@ import ( "reflect" "testing" "time" + + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" ) const ( @@ -40,87 +42,87 @@ const ( ) type TvptableRow struct { - PBinary []byte `db:"p_binary"` - PVarchar string `db:"p_varchar"` - PVarcharNull *string `db:"p_varcharNull"` - PNvarchar string `db:"p_nvarchar"` - PNvarcharNull *string `db:"p_nvarcharNull"` - PID UniqueIdentifier `db:"p_id"` - PIDNull *UniqueIdentifier `db:"p_idNull"` - PVarbinary []byte `db:"p_varbinary"` - PTinyint int8 `db:"p_tinyint"` - PTinyintNull *int8 `db:"p_tinyintNull"` - PSmallint int16 `db:"p_smallint"` - PSmallintNull *int16 `db:"p_smallintNull"` - PInt int32 `db:"p_int"` - PIntNull *int32 `db:"p_intNull"` - PBigint int64 `db:"p_bigint"` - PBigintNull *int64 `db:"p_bigintNull"` - PBit bool `db:"p_bit"` - PBitNull *bool `db:"p_bitNull"` - PFloat32 float32 `db:"p_float32"` - PFloatNull32 *float32 `db:"p_floatNull32"` - PFloat64 float64 `db:"p_float64"` - PFloatNull64 *float64 `db:"p_floatNull64"` - DTime time.Time `db:"p_timeNull"` - DTimeNull *time.Time `db:"p_time"` - Pint int `db:"pInt"` - PintNull *int `db:"pIntNull"` + PBinary []byte `db:"p_binary"` + PVarchar string `db:"p_varchar"` + PVarcharNull *string `db:"p_varcharNull"` + PNvarchar string `db:"p_nvarchar"` + PNvarcharNull *string `db:"p_nvarcharNull"` + PID mssqltypes.UniqueIdentifier `db:"p_id"` + PIDNull *mssqltypes.UniqueIdentifier `db:"p_idNull"` + PVarbinary []byte `db:"p_varbinary"` + PTinyint int8 `db:"p_tinyint"` + PTinyintNull *int8 `db:"p_tinyintNull"` + PSmallint int16 `db:"p_smallint"` + PSmallintNull *int16 `db:"p_smallintNull"` + PInt int32 `db:"p_int"` + PIntNull *int32 `db:"p_intNull"` + PBigint int64 `db:"p_bigint"` + PBigintNull *int64 `db:"p_bigintNull"` + PBit bool `db:"p_bit"` + PBitNull *bool `db:"p_bitNull"` + PFloat32 float32 `db:"p_float32"` + PFloatNull32 *float32 `db:"p_floatNull32"` + PFloat64 float64 `db:"p_float64"` + PFloatNull64 *float64 `db:"p_floatNull64"` + DTime time.Time `db:"p_timeNull"` + DTimeNull *time.Time `db:"p_time"` + Pint int `db:"pInt"` + PintNull *int `db:"pIntNull"` } type TvptableRowWithSkipTag struct { - PBinary []byte `db:"p_binary"` - SkipPBinary []byte `json:"-"` - PVarchar string `db:"p_varchar"` - SkipPVarchar string `tvp:"-"` - PVarcharNull *string `db:"p_varcharNull"` - SkipPVarcharNull *string `json:"-" tvp:"-"` - PNvarchar string `db:"p_nvarchar"` - SkipPNvarchar string `json:"-"` - PNvarcharNull *string `db:"p_nvarcharNull"` - SkipPNvarcharNull *string `json:"-"` - PID UniqueIdentifier `db:"p_id"` - SkipPID UniqueIdentifier `json:"-"` - PIDNull *UniqueIdentifier `db:"p_idNull"` - SkipPIDNull *UniqueIdentifier `tvp:"-"` - PVarbinary []byte `db:"p_varbinary"` - SkipPVarbinary []byte `json:"-" tvp:"-"` - PTinyint int8 `db:"p_tinyint"` - SkipPTinyint int8 `tvp:"-"` - PTinyintNull *int8 `db:"p_tinyintNull"` - SkipPTinyintNull *int8 `tvp:"-" json:"any"` - PSmallint int16 `db:"p_smallint"` - SkipPSmallint int16 `json:"-"` - PSmallintNull *int16 `db:"p_smallintNull"` - SkipPSmallintNull *int16 `tvp:"-"` - PInt int32 `db:"p_int"` - SkipPInt int32 `json:"-"` - PIntNull *int32 `db:"p_intNull"` - SkipPIntNull *int32 `tvp:"-"` - PBigint int64 `db:"p_bigint"` - SkipPBigint int64 `tvp:"-"` - PBigintNull *int64 `db:"p_bigintNull"` - SkipPBigintNull *int64 `json:"any" tvp:"-"` - PBit bool `db:"p_bit"` - SkipPBit bool `json:"-"` - PBitNull *bool `db:"p_bitNull"` - SkipPBitNull *bool `json:"-"` - PFloat32 float32 `db:"p_float32"` - SkipPFloat32 float32 `tvp:"-"` - PFloatNull32 *float32 `db:"p_floatNull32"` - SkipPFloatNull32 *float32 `tvp:"-"` - PFloat64 float64 `db:"p_float64"` - SkipPFloat64 float64 `tvp:"-"` - PFloatNull64 *float64 `db:"p_floatNull64"` - SkipPFloatNull64 *float64 `tvp:"-"` - DTime time.Time `db:"p_timeNull"` - SkipDTime time.Time `tvp:"-"` - DTimeNull *time.Time `db:"p_time"` - SkipDTimeNull *time.Time `tvp:"-"` - Pint int `db:"p_int_null"` - SkipPint int `tvp:"-"` - PintNull *int `db:"p_int_"` - SkipPintNull *int `tvp:"-"` + PBinary []byte `db:"p_binary"` + SkipPBinary []byte `json:"-"` + PVarchar string `db:"p_varchar"` + SkipPVarchar string `tvp:"-"` + PVarcharNull *string `db:"p_varcharNull"` + SkipPVarcharNull *string `json:"-" tvp:"-"` + PNvarchar string `db:"p_nvarchar"` + SkipPNvarchar string `json:"-"` + PNvarcharNull *string `db:"p_nvarcharNull"` + SkipPNvarcharNull *string `json:"-"` + PID mssqltypes.UniqueIdentifier `db:"p_id"` + SkipPID mssqltypes.UniqueIdentifier `json:"-"` + PIDNull *mssqltypes.UniqueIdentifier `db:"p_idNull"` + SkipPIDNull *mssqltypes.UniqueIdentifier `tvp:"-"` + PVarbinary []byte `db:"p_varbinary"` + SkipPVarbinary []byte `json:"-" tvp:"-"` + PTinyint int8 `db:"p_tinyint"` + SkipPTinyint int8 `tvp:"-"` + PTinyintNull *int8 `db:"p_tinyintNull"` + SkipPTinyintNull *int8 `tvp:"-" json:"any"` + PSmallint int16 `db:"p_smallint"` + SkipPSmallint int16 `json:"-"` + PSmallintNull *int16 `db:"p_smallintNull"` + SkipPSmallintNull *int16 `tvp:"-"` + PInt int32 `db:"p_int"` + SkipPInt int32 `json:"-"` + PIntNull *int32 `db:"p_intNull"` + SkipPIntNull *int32 `tvp:"-"` + PBigint int64 `db:"p_bigint"` + SkipPBigint int64 `tvp:"-"` + PBigintNull *int64 `db:"p_bigintNull"` + SkipPBigintNull *int64 `json:"any" tvp:"-"` + PBit bool `db:"p_bit"` + SkipPBit bool `json:"-"` + PBitNull *bool `db:"p_bitNull"` + SkipPBitNull *bool `json:"-"` + PFloat32 float32 `db:"p_float32"` + SkipPFloat32 float32 `tvp:"-"` + PFloatNull32 *float32 `db:"p_floatNull32"` + SkipPFloatNull32 *float32 `tvp:"-"` + PFloat64 float64 `db:"p_float64"` + SkipPFloat64 float64 `tvp:"-"` + PFloatNull64 *float64 `db:"p_floatNull64"` + SkipPFloatNull64 *float64 `tvp:"-"` + DTime time.Time `db:"p_timeNull"` + SkipDTime time.Time `tvp:"-"` + DTimeNull *time.Time `db:"p_time"` + SkipDTimeNull *time.Time `tvp:"-"` + Pint int `db:"p_int_null"` + SkipPint int `tvp:"-"` + PintNull *int `db:"p_int_"` + SkipPintNull *int `tvp:"-"` } func TestTVP(t *testing.T) { @@ -215,7 +217,7 @@ func TestTVP(t *testing.T) { PBinary: []byte("ccc"), PVarchar: varcharNull, PNvarchar: nvarchar, - PID: UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PID: mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PVarbinary: bytesMock, PTinyint: i8, PSmallint: i16, @@ -231,7 +233,7 @@ func TestTVP(t *testing.T) { PBinary: []byte("www"), PVarchar: "eee", PNvarchar: "lll", - PID: UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PID: mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PVarbinary: []byte("zzz"), PTinyint: 5, PSmallint: 16000, @@ -247,7 +249,7 @@ func TestTVP(t *testing.T) { PBinary: nil, PVarcharNull: &varcharNull, PNvarcharNull: &nvarchar, - PIDNull: &UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PIDNull: &mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PTinyintNull: &i8, PSmallintNull: &i16, PIntNull: &i32, @@ -263,7 +265,7 @@ func TestTVP(t *testing.T) { PBinary: []byte("www"), PVarchar: "eee", PNvarchar: "lll", - PIDNull: &UniqueIdentifier{}, + PIDNull: &mssqltypes.UniqueIdentifier{}, PVarbinary: []byte("zzz"), PTinyint: 5, PSmallint: 16000, @@ -468,7 +470,7 @@ func TestTVP_WithTag(t *testing.T) { PBinary: []byte("ccc"), PVarchar: varcharNull, PNvarchar: nvarchar, - PID: UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PID: mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PVarbinary: bytesMock, PTinyint: i8, PSmallint: i16, @@ -485,7 +487,7 @@ func TestTVP_WithTag(t *testing.T) { PBinary: []byte("www"), PVarchar: "eee", PNvarchar: "lll", - PID: UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PID: mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PVarbinary: []byte("zzz"), PTinyint: 5, PSmallint: 16000, @@ -502,7 +504,7 @@ func TestTVP_WithTag(t *testing.T) { PBinary: nil, PVarcharNull: &varcharNull, PNvarcharNull: &nvarchar, - PIDNull: &UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + PIDNull: &mssqltypes.UniqueIdentifier{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, PTinyintNull: &i8, PSmallintNull: &i16, PIntNull: &i32, @@ -518,7 +520,7 @@ func TestTVP_WithTag(t *testing.T) { PBinary: []byte("www"), PVarchar: "eee", PNvarchar: "lll", - PIDNull: &UniqueIdentifier{}, + PIDNull: &mssqltypes.UniqueIdentifier{}, PVarbinary: []byte("zzz"), PTinyint: 5, PSmallint: 16000, diff --git a/types.go b/types.go index b6e7fb2b..497d3abf 100644 --- a/types.go +++ b/types.go @@ -11,7 +11,7 @@ import ( "time" "github.com/denisenkom/go-mssqldb/internal/cp" - "github.com/denisenkom/go-mssqldb/internal/decimal" + "github.com/denisenkom/go-mssqldb/internal/mssqltypes" ) // fixed-length data types @@ -819,12 +819,12 @@ func decodeMoney(buf []byte) []byte { uint64(buf[1])<<40 | uint64(buf[2])<<48 | uint64(buf[3])<<56) - return decimal.ScaleBytes(strconv.FormatInt(money, 10), 4) + return mssqltypes.ScaleBytes(strconv.FormatInt(money, 10), 4) } func decodeMoney4(buf []byte) []byte { money := int32(binary.LittleEndian.Uint32(buf[0:4])) - return decimal.ScaleBytes(strconv.FormatInt(int64(money), 10), 4) + return mssqltypes.ScaleBytes(strconv.FormatInt(int64(money), 10), 4) } func decodeGuid(buf []byte) []byte { @@ -836,7 +836,7 @@ func decodeGuid(buf []byte) []byte { func decodeDecimal(prec uint8, scale uint8, buf []byte) []byte { var sign uint8 sign = buf[0] - var dec decimal.Decimal + var dec mssqltypes.Decimal dec.SetPositive(sign != 0) dec.SetPrec(prec) dec.SetScale(scale)