2020-08-06 20:58:47 +03:00
|
|
|
package sqlserver_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/kind"
|
2020-08-23 22:00:13 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/sqlmodel"
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/stringz"
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/neilotoole/sq/testh"
|
|
|
|
"github.com/neilotoole/sq/testh/fixt"
|
|
|
|
"github.com/neilotoole/sq/testh/sakila"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestSmoke(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2020-08-09 17:40:46 +03:00
|
|
|
for _, handle := range sakila.MSAll() {
|
2020-08-06 20:58:47 +03:00
|
|
|
handle := handle
|
|
|
|
|
|
|
|
t.Run(handle, func(t *testing.T) {
|
2022-12-18 02:11:33 +03:00
|
|
|
t.Parallel()
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2023-07-08 18:21:27 +03:00
|
|
|
th, src, _, _, _ := testh.NewWith(t, handle)
|
2020-08-06 20:58:47 +03:00
|
|
|
sink, err := th.QuerySQL(src, "SELECT * FROM actor")
|
|
|
|
require.NoError(t, err)
|
2020-08-10 18:16:44 +03:00
|
|
|
require.Equal(t, len(sakila.TblActorCols()), len(sink.RecMeta))
|
2020-08-06 20:58:47 +03:00
|
|
|
require.Equal(t, sakila.TblActorCount, len(sink.Recs))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDriverBehavior(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
// This test exists to help understand the behavior of the driver impl.
|
|
|
|
// It can be deleted eventually.
|
|
|
|
|
|
|
|
th := testh.New(t)
|
|
|
|
src := th.Source(sakila.MS)
|
2023-07-08 18:21:27 +03:00
|
|
|
db := th.OpenDB(src)
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
const query = "SELECT * FROM payment ORDER BY (SELECT 0) OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY"
|
|
|
|
|
|
|
|
rows, err := db.QueryContext(th.Context, query)
|
|
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() { assert.NoError(t, rows.Close()) })
|
|
|
|
|
|
|
|
colTypes, err := rows.ColumnTypes()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
for i, colType := range colTypes {
|
|
|
|
nullable, ok := colType.Nullable()
|
2022-12-18 10:18:35 +03:00
|
|
|
t.Logf("%d: %s %s %s nullable,ok={%v,%v}", i, colType.Name(), colType.DatabaseTypeName(),
|
|
|
|
colType.ScanType().Name(), nullable, ok)
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
if !nullable {
|
|
|
|
scanType := colType.ScanType()
|
|
|
|
z := reflect.Zero(scanType)
|
|
|
|
t.Logf("zero: %T %v", z, z)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDriver_CreateTable_NotNullDefault(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2023-04-16 01:28:51 +03:00
|
|
|
testCases := []string{sakila.MS}
|
2020-08-06 20:58:47 +03:00
|
|
|
for _, handle := range testCases {
|
|
|
|
handle := handle
|
|
|
|
|
|
|
|
t.Run(handle, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2023-07-08 18:21:27 +03:00
|
|
|
th, src, drvr, _, db := testh.NewWith(t, handle)
|
2020-08-06 20:58:47 +03:00
|
|
|
|
|
|
|
tblName := stringz.UniqTableName(t.Name())
|
|
|
|
colNames, colKinds := fixt.ColNamePerKind(drvr.Dialect().IntBool, false, false)
|
|
|
|
|
|
|
|
tblDef := sqlmodel.NewTableDef(tblName, colNames, colKinds)
|
|
|
|
for _, colDef := range tblDef.Cols {
|
|
|
|
colDef.NotNull = true
|
|
|
|
colDef.HasDefault = true
|
|
|
|
}
|
|
|
|
|
2023-07-08 18:21:27 +03:00
|
|
|
err := drvr.CreateTable(th.Context, db, tblDef)
|
2020-08-06 20:58:47 +03:00
|
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() { th.DropTable(src, tblName) })
|
|
|
|
|
|
|
|
th.InsertDefaultRow(src, tblName)
|
|
|
|
|
|
|
|
sink, err := th.QuerySQL(src, "SELECT * FROM "+tblName)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 1, len(sink.Recs))
|
|
|
|
require.Equal(t, len(colNames), len(sink.RecMeta))
|
|
|
|
for i := range colNames {
|
|
|
|
require.NotNil(t, sink.Recs[0][i])
|
|
|
|
nullable, ok := sink.RecMeta[i].Nullable()
|
|
|
|
require.True(t, ok)
|
|
|
|
require.False(t, nullable)
|
|
|
|
}
|
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
// Check kind.Bytes is handled correctly
|
2020-08-06 20:58:47 +03:00
|
|
|
const iBytes = 8 // the index of col_bytes
|
2020-08-23 13:42:15 +03:00
|
|
|
require.Equal(t, kind.Bytes, colKinds[iBytes])
|
2023-05-27 16:57:07 +03:00
|
|
|
b, ok := sink.Recs[0][iBytes].([]byte)
|
2020-08-06 20:58:47 +03:00
|
|
|
require.True(t, ok)
|
|
|
|
require.NotNil(t, b)
|
2023-05-27 16:57:07 +03:00
|
|
|
require.Equal(t, 0, len(b), "b should be non-nil but zero length")
|
2020-08-06 20:58:47 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|