mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-25 01:04:55 +03:00
Filepath and colorization issues with the v0.12.1 release on Windows (#50)
- Windows filepath handling - Windows colorization handling - Minor code tidy up and refactor
This commit is contained in:
parent
58d8e301e0
commit
062e2dea88
@ -348,6 +348,8 @@ func (rc *RunContext) preRunE() error {
|
||||
}
|
||||
|
||||
rc.wrtr = newWriters(rc.Log, rc.Cmd, rc.Config.Options, rc.Out, rc.ErrOut)
|
||||
rc.Out = rc.wrtr.out
|
||||
rc.ErrOut = rc.wrtr.errOut
|
||||
|
||||
var scratchSrcFunc driver.ScratchSrcFunc
|
||||
|
||||
@ -456,6 +458,8 @@ func (rc *RunContext) databases() *driver.Databases {
|
||||
|
||||
// writers is a container for the various output writer types.
|
||||
type writers struct {
|
||||
out io.Writer
|
||||
errOut io.Writer
|
||||
fmt *output.Formatting
|
||||
recordw output.RecordWriter
|
||||
metaw output.MetadataWriter
|
||||
@ -491,6 +495,8 @@ func newWriters(log lg.Log, cmd *cobra.Command, opts config.Options, out, errOut
|
||||
// flags and set the various writer fields depending upon which
|
||||
// writers the format implements.
|
||||
w := &writers{
|
||||
out: out,
|
||||
errOut: errOut,
|
||||
fmt: fm,
|
||||
recordw: tablew.NewRecordWriter(out, fm, hasHeader),
|
||||
metaw: tablew.NewMetadataWriter(out, fm),
|
||||
|
@ -149,8 +149,8 @@ func execSrcAdd(rc *RunContext, cmd *cobra.Command, args []string) error {
|
||||
//
|
||||
// The second form is particularly nice for bash completion etc.
|
||||
if typ == sqlite3.Type {
|
||||
if !strings.HasPrefix(loc, "sqlite3:") {
|
||||
loc = "sqlite3:" + loc
|
||||
if !strings.HasPrefix(loc, sqlite3.Prefix) {
|
||||
loc = sqlite3.Prefix + loc
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,8 +181,8 @@ func newNotifyAddHipChatCmd() (*cobra.Command, runFunc) {
|
||||
}
|
||||
|
||||
func execNotifyAddHipChat(rc *RunContext, cmd *cobra.Command, args []string) error {
|
||||
fmt.Println("Add HipChat room")
|
||||
fmt.Println(strings.Join(args, " | "))
|
||||
fmt.Fprintln(rc.Out, "Add HipChat room")
|
||||
fmt.Fprintln(rc.Out, strings.Join(args, " | "))
|
||||
|
||||
var label string
|
||||
var err error
|
||||
@ -194,7 +194,7 @@ func execNotifyAddHipChat(rc *RunContext, cmd *cobra.Command, args []string) err
|
||||
}
|
||||
|
||||
if label != "" {
|
||||
fmt.Printf("Label: %s", label)
|
||||
fmt.Fprintf(rc.Out, "Label: %s", label)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -18,24 +18,15 @@ import (
|
||||
"github.com/neilotoole/sq/testh/sakila"
|
||||
)
|
||||
|
||||
func TestCmdSLQ_Insert_LONG(t *testing.T) {
|
||||
testh.SkipShort(t, true)
|
||||
testCmdSLQ_Insert(t, sakila.All, sakila.SQLAll)
|
||||
}
|
||||
|
||||
// TestCmdSLQ_Insert tests "sq slq QUERY --insert=dest.tbl".
|
||||
func TestCmdSLQ_Insert(t *testing.T) {
|
||||
testCmdSLQ_Insert(t, sakila.SQLLatest, sakila.SQLLatest)
|
||||
}
|
||||
|
||||
// testCmdSLQ_Insert tests "sq slq QUERY --insert=dest.tbl".
|
||||
func testCmdSLQ_Insert(t *testing.T, origins, dests []string) {
|
||||
for _, origin := range origins {
|
||||
for _, origin := range sakila.SQLLatest {
|
||||
origin := origin
|
||||
|
||||
t.Run("origin_"+origin, func(t *testing.T) {
|
||||
testh.SkipShort(t, origin == sakila.XLSX)
|
||||
|
||||
for _, dest := range dests {
|
||||
for _, dest := range sakila.SQLLatest {
|
||||
dest := dest
|
||||
|
||||
t.Run("dest_"+dest, func(t *testing.T) {
|
||||
|
@ -16,23 +16,15 @@ import (
|
||||
"github.com/neilotoole/sq/testh/testsrc"
|
||||
)
|
||||
|
||||
func TestCmdSQL_Insert_LONG(t *testing.T) {
|
||||
testh.SkipShort(t, true)
|
||||
testCmdSQL_Insert(t, sakila.All, sakila.All)
|
||||
}
|
||||
// TestCmdSQL_Insert tests "sq sql QUERY --insert=dest.tbl".
|
||||
func TestCmdSQL_Insert(t *testing.T) {
|
||||
testCmdSQL_Insert(t, sakila.SQLLatest, sakila.SQLLatest)
|
||||
}
|
||||
|
||||
// testCmdSQL_Insert tests "sq sql QUERY --insert=dest.tbl".
|
||||
func testCmdSQL_Insert(t *testing.T, origins, dests []string) {
|
||||
for _, origin := range origins {
|
||||
for _, origin := range sakila.SQLLatest {
|
||||
origin := origin
|
||||
|
||||
t.Run("origin_"+origin, func(t *testing.T) {
|
||||
testh.SkipShort(t, origin == sakila.XLSX)
|
||||
|
||||
for _, dest := range dests {
|
||||
for _, dest := range sakila.SQLLatest {
|
||||
dest := dest
|
||||
|
||||
t.Run("dest_"+dest, func(t *testing.T) {
|
||||
@ -125,8 +117,8 @@ func TestCmdSQL_StdinQuery(t *testing.T) {
|
||||
wantCount int
|
||||
wantErr bool
|
||||
}{
|
||||
{fpath: proj.Abs(sakila.PathCSVActor), tbl: source.MonotableName, wantCount: sakila.TblActorCount + 1}, // +1 is for the header row
|
||||
{fpath: proj.Abs(sakila.PathXLSXSubset), tbl: sakila.TblActor, wantCount: sakila.TblActorCount + 1},
|
||||
{fpath: proj.Abs(sakila.PathCSVActorNoHeader), tbl: source.MonotableName, wantCount: sakila.TblActorCount},
|
||||
{fpath: proj.Abs(sakila.PathXLSXSubset), tbl: sakila.TblActor, wantCount: sakila.TblActorCount + 1}, // +1 is for the header row in the XLSX file
|
||||
{fpath: proj.Abs("README.md"), wantErr: true},
|
||||
}
|
||||
|
||||
@ -140,9 +132,10 @@ func TestCmdSQL_StdinQuery(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
ru := newRun(t).hush()
|
||||
//ru := newRun(t)
|
||||
ru.rc.Stdin = f
|
||||
|
||||
err = ru.exec("sql", "SELECT * FROM "+tc.tbl)
|
||||
err = ru.exec("sql", "--no-header", "SELECT * FROM "+tc.tbl)
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
|
@ -23,19 +23,19 @@ func execVersion(rc *RunContext, cmd *cobra.Command, args []string) error {
|
||||
// If buildinfo.Version is not set (building without ldflags),
|
||||
// then we set a dummy version.
|
||||
if version == "" {
|
||||
version = "0.0.0.dev"
|
||||
version = "0.0.0-dev"
|
||||
}
|
||||
|
||||
rc.wrtr.fmt.Hilite.Fprintf(rc.Out, "sq %s", version)
|
||||
|
||||
if len(buildinfo.Commit) > 0 {
|
||||
fmt.Fprintf(rc.Out, " ")
|
||||
rc.wrtr.fmt.Faint.Fprintf(rc.Out, "#"+buildinfo.Commit)
|
||||
fmt.Fprint(rc.Out, " ")
|
||||
rc.wrtr.fmt.Faint.Fprint(rc.Out, "#"+buildinfo.Commit)
|
||||
}
|
||||
|
||||
if len(buildinfo.Timestamp) > 0 {
|
||||
fmt.Fprintf(rc.Out, " ")
|
||||
rc.wrtr.fmt.Faint.Fprintf(rc.Out, buildinfo.Timestamp)
|
||||
fmt.Fprint(rc.Out, " ")
|
||||
rc.wrtr.fmt.Faint.Fprint(rc.Out, buildinfo.Timestamp)
|
||||
}
|
||||
|
||||
fmt.Fprintln(rc.Out)
|
||||
|
@ -349,7 +349,7 @@ func (t *Table) printHeading() {
|
||||
pad := ConditionString(i == end && !t.borders.Left, Space, t.pColumn)
|
||||
|
||||
head := t.headerTrans(fmt.Sprintf("%s %s ", padFunc(h, Space, v), pad))
|
||||
fmt.Print(head)
|
||||
fmt.Fprint(t.out, head)
|
||||
|
||||
}
|
||||
// Next line
|
||||
|
@ -46,7 +46,7 @@ func (d *database) SourceMetadata(ctx context.Context) (*source.Metadata, error)
|
||||
|
||||
meta := &source.Metadata{Handle: d.src.Handle, SourceType: Type, DBDriverType: dbDrvr}
|
||||
|
||||
dsn, err := PathFromSourceLocation(d.src)
|
||||
dsn, err := PathFromLocation(d.src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ const (
|
||||
|
||||
// dbDrvr is the backing sqlite3 SQL driver impl name.
|
||||
dbDrvr = "sqlite3"
|
||||
|
||||
// Prefix is the scheme+separator value "sqlite3://".
|
||||
Prefix = "sqlite3://"
|
||||
)
|
||||
|
||||
// Provider is the SQLite3 implementation of driver.Provider.
|
||||
@ -63,7 +66,7 @@ func (d *Driver) DriverMetadata() driver.Metadata {
|
||||
func (d *Driver) Open(ctx context.Context, src *source.Source) (driver.Database, error) {
|
||||
d.log.Debug("Opening data source: ", src)
|
||||
|
||||
dsn, err := PathFromSourceLocation(src)
|
||||
dsn, err := PathFromLocation(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -77,7 +80,7 @@ func (d *Driver) Open(ctx context.Context, src *source.Source) (driver.Database,
|
||||
|
||||
// Truncate implements driver.Driver.
|
||||
func (d *Driver) Truncate(ctx context.Context, src *source.Source, tbl string, reset bool) (affected int64, err error) {
|
||||
dsn, err := PathFromSourceLocation(src)
|
||||
dsn, err := PathFromLocation(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -118,7 +121,7 @@ func (d *Driver) ValidateSource(src *source.Source) (*source.Source, error) {
|
||||
|
||||
// Ping implements driver.Driver.
|
||||
func (d *Driver) Ping(ctx context.Context, src *source.Source) error {
|
||||
dbase, err := d.Open(context.TODO(), src)
|
||||
dbase, err := d.Open(ctx, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -378,24 +381,24 @@ func NewScratchSource(log lg.Log, name string) (src *source.Source, clnup func()
|
||||
src = &source.Source{
|
||||
Type: Type,
|
||||
Handle: source.ScratchHandle,
|
||||
Location: dbDrvr + "://" + f.Name(),
|
||||
Location: Prefix + f.Name(),
|
||||
}
|
||||
|
||||
return src, cleanFn, nil
|
||||
}
|
||||
|
||||
// PathFromSourceLocation returns absolute file path
|
||||
// from the source location, which typically has the "sqlite3:" prefix.
|
||||
func PathFromSourceLocation(src *source.Source) (string, error) {
|
||||
// PathFromLocation returns the absolute file path
|
||||
// from the source location, which should have the "sqlite3://" prefix.
|
||||
func PathFromLocation(src *source.Source) (string, error) {
|
||||
if src.Type != Type {
|
||||
return "", errz.Errorf("driver %q does not support %q", Type, src.Type)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(src.Location, dbDrvr+":") {
|
||||
return "", errz.Errorf("sqlite3 source location must begin with %q but was: %s", Type, src.RedactedLocation())
|
||||
if !strings.HasPrefix(src.Location, Prefix) {
|
||||
return "", errz.Errorf("sqlite3 source location must begin with %q but was: %s", Prefix, src.RedactedLocation())
|
||||
}
|
||||
|
||||
loc := strings.TrimPrefix(src.Location, dbDrvr+":")
|
||||
loc := strings.TrimPrefix(src.Location, Prefix)
|
||||
if len(loc) < 2 {
|
||||
return "", errz.Errorf("sqlite3 source location is too short: %s", src.RedactedLocation())
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/neilotoole/sq/drivers/sqlite3"
|
||||
"github.com/neilotoole/sq/libsq/source"
|
||||
"github.com/neilotoole/sq/libsq/sqlmodel"
|
||||
"github.com/neilotoole/sq/libsq/sqlz"
|
||||
"github.com/neilotoole/sq/libsq/stringz"
|
||||
@ -160,3 +162,36 @@ func TestDriver_CreateTable_NotNullDefault(t *testing.T) {
|
||||
require.NotNil(t, sink.Recs[0][i])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathFromLocation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
loc string
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{loc: "sqlite3:///test.db", want: "/test.db"},
|
||||
{loc: "postgres:///test.db", wantErr: true},
|
||||
{loc: `sqlite3://C:\dir\sakila.db`, want: `C:\dir\sakila.db`},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
t.Run(tc.loc, func(t *testing.T) {
|
||||
src := &source.Source{
|
||||
Handle: "@h1",
|
||||
Type: sqlite3.Type,
|
||||
Location: tc.loc,
|
||||
}
|
||||
|
||||
got, err := sqlite3.PathFromLocation(src)
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,8 @@ func TestSQLDriver_PrepareUpdateStmt(t *testing.T) {
|
||||
|
||||
func TestDriver_Ping(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := append(sakila.All, sakila.CSVActor, sakila.CSVActorHTTP)
|
||||
testCases := sakila.All
|
||||
testCases = append(testCases, sakila.CSVActor, sakila.CSVActorHTTP)
|
||||
|
||||
for _, handle := range testCases {
|
||||
handle := handle
|
||||
@ -235,7 +236,8 @@ func TestDriver_Ping(t *testing.T) {
|
||||
|
||||
func TestDriver_Open(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := append(sakila.All, sakila.CSVActor, sakila.CSVActorHTTP)
|
||||
testCases := sakila.All
|
||||
testCases = append(testCases, sakila.CSVActor, sakila.CSVActorHTTP)
|
||||
|
||||
for _, handle := range testCases {
|
||||
handle := handle
|
||||
|
@ -455,8 +455,11 @@ func AbsLocation(loc string) string {
|
||||
return loc
|
||||
}
|
||||
|
||||
// isFpath returns true if loc is a file path.
|
||||
func isFpath(loc string) (fpath string, ok bool) {
|
||||
if strings.ContainsRune(loc, ':') {
|
||||
// This is not exactly an industrial-strength algorithm...
|
||||
if strings.Contains(loc, ":/") {
|
||||
// Excludes "http:/" etc
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package source
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/neilotoole/lg/testlg"
|
||||
@ -55,15 +56,18 @@ func TestParseLoc(t *testing.T) {
|
||||
loc string
|
||||
want parsedLoc
|
||||
wantErr bool
|
||||
windows bool
|
||||
}{
|
||||
{loc: "/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "relative/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "./relative/path/to/sakila.xlsx", want: parsedLoc{name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "https://server:8080/path/to/sakila.xlsx", want: parsedLoc{scheme: "https", hostname: "server", port: 8080, name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "http://server/path/to/sakila.xlsx?param=val¶m2=val2", want: parsedLoc{scheme: "http", hostname: "server", name: "sakila", ext: ".xlsx"}},
|
||||
{loc: "sqlite3:/path/to/sakila.db", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "/path/to/sakila.db"}},
|
||||
{loc: "sqlite3:/path/to/sakila.sqlite", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: "/path/to/sakila.sqlite"}},
|
||||
{loc: "sqlite3:/path/to/sakila", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", dsn: "/path/to/sakila"}},
|
||||
{loc: "sqlite3:/path/to/sakila.db", wantErr: true}, // the scheme is malformed (should be "sqlite3://...")
|
||||
{loc: "sqlite3:///path/to/sakila.sqlite", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: "/path/to/sakila.sqlite"}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite`, windows: true, want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: `C:\path\to\sakila.sqlite`}},
|
||||
{loc: `sqlite3://C:\path\to\sakila.sqlite?param=val`, windows: true, want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".sqlite", dsn: `C:\path\to\sakila.sqlite?param=val`}},
|
||||
{loc: "sqlite3:///path/to/sakila", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", dsn: "/path/to/sakila"}},
|
||||
{loc: "sqlite3://path/to/sakila.db", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "path/to/sakila.db"}},
|
||||
{loc: "sqlite3:///path/to/sakila.db", want: parsedLoc{typ: typeSL3, scheme: "sqlite3", name: "sakila", ext: ".db", dsn: "/path/to/sakila.db"}},
|
||||
{loc: "sqlserver://sakila:p_ssW0rd@localhost?database=sakila", want: parsedLoc{typ: typeMS, scheme: "sqlserver", user: dbuser, pass: dbpass, hostname: "localhost", name: "sakila", dsn: "Password=p_ssW0rd;Server=localhost;User ID=sakila;database=sakila"}},
|
||||
@ -77,6 +81,10 @@ func TestParseLoc(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.loc, func(t *testing.T) {
|
||||
if tc.windows && runtime.GOOS != "windows" {
|
||||
return
|
||||
}
|
||||
|
||||
tc.want.loc = tc.loc // set this here rather than verbosely in the setup
|
||||
got, gotErr := parseLoc(tc.loc)
|
||||
if tc.wantErr {
|
||||
|
@ -150,8 +150,13 @@ type parsedLoc struct {
|
||||
func parseLoc(loc string) (*parsedLoc, error) {
|
||||
ploc := &parsedLoc{loc: loc}
|
||||
|
||||
if !strings.ContainsRune(loc, ':') {
|
||||
// no scheme: it's just a file path
|
||||
if !strings.Contains(loc, "://") {
|
||||
if strings.Contains(loc, ":/") {
|
||||
// malformed location, such as "sqlite3:/path/to/file"
|
||||
return nil, errz.Errorf("parse location: invalid scheme: %q", loc)
|
||||
}
|
||||
|
||||
// no scheme: it's just a regular file path for a document such as an Excel file
|
||||
name := filepath.Base(loc)
|
||||
ploc.ext = filepath.Ext(name)
|
||||
if ploc.ext != "" {
|
||||
@ -184,20 +189,22 @@ func parseLoc(loc string) (*parsedLoc, error) {
|
||||
return ploc, nil
|
||||
}
|
||||
|
||||
u, err := dburl.Parse(loc)
|
||||
if err != nil {
|
||||
return nil, errz.Err(err)
|
||||
}
|
||||
|
||||
ploc.scheme = u.OriginalScheme
|
||||
ploc.dsn = u.DSN
|
||||
ploc.user = u.User.Username()
|
||||
ploc.pass, _ = u.User.Password()
|
||||
|
||||
// sqlite3 is a special case, handle it now
|
||||
if ploc.scheme == "sqlite3" {
|
||||
const sqlitePrefix = "sqlite3://"
|
||||
if strings.HasPrefix(loc, sqlitePrefix) {
|
||||
fpath := strings.TrimPrefix(loc, sqlitePrefix)
|
||||
|
||||
ploc.scheme = "sqlite3"
|
||||
ploc.typ = typeSL3
|
||||
name := path.Base(u.DSN)
|
||||
ploc.dsn = fpath
|
||||
|
||||
// fpath could include params, e.g. "sqlite3://C:\sakila.db?param=val"
|
||||
if i := strings.IndexRune(fpath, '?'); i >= 0 {
|
||||
// Snip off the params
|
||||
fpath = fpath[:i]
|
||||
}
|
||||
|
||||
name := filepath.Base(fpath)
|
||||
ploc.ext = filepath.Ext(name)
|
||||
if ploc.ext != "" {
|
||||
name = name[:len(name)-len(ploc.ext)]
|
||||
@ -207,6 +214,15 @@ func parseLoc(loc string) (*parsedLoc, error) {
|
||||
return ploc, nil
|
||||
}
|
||||
|
||||
u, err := dburl.Parse(loc)
|
||||
if err != nil {
|
||||
return nil, errz.Err(err)
|
||||
}
|
||||
|
||||
ploc.scheme = u.OriginalScheme
|
||||
ploc.dsn = u.DSN
|
||||
ploc.user = u.User.Username()
|
||||
ploc.pass, _ = u.User.Password()
|
||||
ploc.hostname = u.Hostname()
|
||||
if u.Port() != "" {
|
||||
ploc.port, err = strconv.Atoi(u.Port())
|
||||
|
56
testh/testdata/sources.sq.yml
vendored
56
testh/testdata/sources.sq.yml
vendored
@ -29,90 +29,90 @@ sources:
|
||||
location: sqlserver://sakila:p_ssW0rd@${SQ_TEST_SRC__SAKILA_MS17}?database=sakila
|
||||
- handle: '@sakila_xlsx'
|
||||
type: xlsx
|
||||
location: "${SQ_ROOT}/drivers/xlsx/testdata/sakila.xlsx"
|
||||
location: '${SQ_ROOT}/drivers/xlsx/testdata/sakila.xlsx'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
- handle: '@sakila_xlsx_subset'
|
||||
type: xlsx
|
||||
location: "${SQ_ROOT}/drivers/xlsx/testdata/sakila_subset.xlsx"
|
||||
location: '${SQ_ROOT}/drivers/xlsx/testdata/sakila_subset.xlsx'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
- handle: '@sakila_xlsx_noheader'
|
||||
type: xlsx
|
||||
location: "${SQ_ROOT}/drivers/xlsx/testdata/sakila_noheader.xlsx"
|
||||
location: '${SQ_ROOT}/drivers/xlsx/testdata/sakila_noheader.xlsx'
|
||||
options:
|
||||
header:
|
||||
- "false"
|
||||
- 'false'
|
||||
- handle: '@sakila_csv_actor'
|
||||
type: csv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/sakila-csv/actor.csv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/sakila-csv/actor.csv'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
- handle: '@sakila_csv_actor_http'
|
||||
type: csv
|
||||
location: "https://sq.io/testdata/actor.csv"
|
||||
location: 'https://sq.io/testdata/actor.csv'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
- handle: '@sakila_csv_actor_noheader'
|
||||
type: csv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/sakila-csv-noheader/actor.csv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/sakila-csv-noheader/actor.csv'
|
||||
options:
|
||||
header:
|
||||
- "false"
|
||||
- 'false'
|
||||
- handle: '@sakila_tsv_actor'
|
||||
type: tsv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/sakila-tsv/actor.tsv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/sakila-tsv/actor.tsv'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
- handle: '@sakila_tsv_actor_noheader'
|
||||
type: tsv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/sakila-tsv-noheader/actor.tsv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/sakila-tsv-noheader/actor.tsv'
|
||||
options:
|
||||
header:
|
||||
- "false"
|
||||
- 'false'
|
||||
|
||||
- handle: '@csv_person'
|
||||
type: csv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/person.csv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/person.csv'
|
||||
- handle: '@csv_person_big'
|
||||
options:
|
||||
header:
|
||||
- "true"
|
||||
- 'true'
|
||||
type: csv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/person_big.csv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/person_big.csv'
|
||||
- handle: '@csv_person_noheader'
|
||||
type: csv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/person_noheader.csv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/person_noheader.csv'
|
||||
- handle: '@tsv_person'
|
||||
type: tsv
|
||||
location: "${SQ_ROOT}/sq/drivers/csv/testdata/person.tsv"
|
||||
location: '${SQ_ROOT}/sq/drivers/csv/testdata/person.tsv'
|
||||
- handle: '@tsv_person_noheader'
|
||||
type: tsv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/person_noheader.tsv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/person_noheader.tsv'
|
||||
- handle: '@tsv_person_noheader_cols'
|
||||
type: tsv
|
||||
location: "${SQ_ROOT}/drivers/csv/testdata/person_noheader.tsv"
|
||||
location: '${SQ_ROOT}/drivers/csv/testdata/person_noheader.tsv'
|
||||
options:
|
||||
cols:
|
||||
- uid,username,email
|
||||
- handle: '@xl_header'
|
||||
type: xlsx
|
||||
location: "${SQ_ROOT}/drivers/xlsx/testdata/test_header.xlsx"
|
||||
location: '${SQ_ROOT}/drivers/xlsx/testdata/test_header.xlsx'
|
||||
- handle: '@xl_noheader'
|
||||
type: xlsx
|
||||
location: "${SQ_ROOT}/drivers/xlsx/testdata/test_noheader.xlsx"
|
||||
location: '${SQ_ROOT}/drivers/xlsx/testdata/test_noheader.xlsx'
|
||||
- handle: '@ud_ppl'
|
||||
type: ppl
|
||||
location: "${SQ_ROOT}/drivers/userdriver/xmlud/testdata/people.xml"
|
||||
location: '${SQ_ROOT}/drivers/userdriver/xmlud/testdata/people.xml'
|
||||
- handle: '@ud_rss_nytimes_local'
|
||||
type: rss
|
||||
location: "${SQ_ROOT}/drivers/userdriver/xmlud/testdata/nytimes_local.rss.xml"
|
||||
location: '${SQ_ROOT}/drivers/userdriver/xmlud/testdata/nytimes_local.rss.xml'
|
||||
- handle: '@miscdb'
|
||||
type: sqlite3
|
||||
location: "sqlite3://${SQ_ROOT}/drivers/sqlite3/testdata/misc.db"
|
||||
location: 'sqlite3://${SQ_ROOT}/drivers/sqlite3/testdata/misc.db'
|
||||
|
||||
|
@ -150,7 +150,7 @@ func (h *Helper) Source(handle string) *source.Source {
|
||||
switch src.Type {
|
||||
case sqlite3.Type:
|
||||
// This could be easily generalized for CSV/XLSX etc.
|
||||
fpath, err := sqlite3.PathFromSourceLocation(src)
|
||||
fpath, err := sqlite3.PathFromLocation(src)
|
||||
require.NoError(t, err)
|
||||
|
||||
srcFile, err := os.Open(fpath)
|
||||
@ -167,7 +167,7 @@ func (h *Helper) Source(handle string) *source.Source {
|
||||
_, err = io.Copy(destFile, srcFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
src.Location = "sqlite3:" + destFile.Name()
|
||||
src.Location = sqlite3.Prefix + destFile.Name()
|
||||
}
|
||||
h.srcCache[handle] = src
|
||||
return src
|
||||
|
Loading…
Reference in New Issue
Block a user