Skip to content

Commit 7663ac0

Browse files
committed
Refactor mode
1 parent bdafa83 commit 7663ac0

File tree

5 files changed

+114
-90
lines changed

5 files changed

+114
-90
lines changed

shell/dump.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (c CommandList) dumpCommand(ctx context.Context, s *Shell, argv []string) e
2929
return err
3030
}
3131
fmt.Fprintf(config.Stdout, "dump `%s` table to %s (mode=%s)\n",
32-
color.CyanString(argv[0]), color.HiCyanString(argv[1]), dumpMode(s.argument.Output.Mode))
32+
color.CyanString(argv[0]), color.HiCyanString(argv[1]), dumpMode(s.state.mode.PrintMode))
3333

3434
return nil
3535
}

shell/mode.go

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import (
55
"fmt"
66

77
"github.com/nao1215/sqly/config"
8-
"github.com/nao1215/sqly/domain/model"
98
)
109

1110
// modeCommand change output mode.
1211
func (c CommandList) modeCommand(_ context.Context, s *Shell, argv []string) error {
1312
if len(argv) == 0 {
1413
fmt.Fprintln(config.Stdout, "[Usage]")
15-
fmt.Fprintf(config.Stdout, " .mode OUTPUT_MODE ※ current mode=%s\n", s.argument.Output.Mode.String())
14+
fmt.Fprintf(config.Stdout, " .mode OUTPUT_MODE ※ current mode=%s\n", s.state.mode.PrintMode.String())
1615
fmt.Fprintln(config.Stdout, "[Output mode list]")
1716
fmt.Fprintln(config.Stdout, " table")
1817
fmt.Fprintln(config.Stdout, " markdown")
@@ -23,36 +22,5 @@ func (c CommandList) modeCommand(_ context.Context, s *Shell, argv []string) err
2322
fmt.Fprintln(config.Stdout, " excel ※ active only when executing .dump, otherwise same as csv mode")
2423
return nil
2524
}
26-
27-
if argv[0] == s.argument.Output.Mode.String() {
28-
fmt.Fprintf(config.Stdout, "already %s mode\n", argv[0])
29-
return nil
30-
}
31-
32-
switch argv[0] {
33-
case model.PrintModeTable.String():
34-
fmt.Fprintf(config.Stdout, "Change output mode from %s to table\n", s.argument.Output.Mode.String())
35-
s.argument.Output.Mode = model.PrintModeTable
36-
case model.PrintModeMarkdownTable.String():
37-
fmt.Fprintf(config.Stdout, "Change output mode from %s to markdown table\n", s.argument.Output.Mode.String())
38-
s.argument.Output.Mode = model.PrintModeMarkdownTable
39-
case model.PrintModeCSV.String():
40-
fmt.Fprintf(config.Stdout, "Change output mode from %s to csv\n", s.argument.Output.Mode.String())
41-
s.argument.Output.Mode = model.PrintModeCSV
42-
case model.PrintModeTSV.String():
43-
fmt.Fprintf(config.Stdout, "Change output mode from %s to tsv\n", s.argument.Output.Mode.String())
44-
s.argument.Output.Mode = model.PrintModeTSV
45-
case model.PrintModeLTSV.String():
46-
fmt.Fprintf(config.Stdout, "Change output mode from %s to ltsv\n", s.argument.Output.Mode.String())
47-
s.argument.Output.Mode = model.PrintModeLTSV
48-
case model.PrintModeJSON.String():
49-
fmt.Fprintf(config.Stdout, "Change output mode from %s to json\n", s.argument.Output.Mode.String())
50-
s.argument.Output.Mode = model.PrintModeJSON
51-
case model.PrintModeExcel.String():
52-
fmt.Fprintf(config.Stdout, "Change output mode from %s to excel (active only when executing .dump, otherwise same as csv mode)\n", s.argument.Output.Mode.String())
53-
s.argument.Output.Mode = model.PrintModeExcel
54-
default:
55-
fmt.Fprintln(config.Stdout, "invalid output mode: "+argv[0])
56-
}
57-
return nil
25+
return s.state.mode.changeOutputModeIfNeeded(argv[0])
5826
}

shell/shell.go

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,14 @@ type Shell struct {
3737
state *state
3838
}
3939

40-
// state is shell state.
41-
type state struct {
42-
// cwd is current working directory.
43-
cwd string
44-
}
45-
46-
// newState return *state.
47-
func newState() (*state, error) {
48-
dir, err := os.Getwd()
49-
if err != nil {
50-
return nil, err
51-
}
52-
return &state{
53-
cwd: dir,
54-
}, nil
55-
}
56-
57-
// shortCWD return short current working directory.
58-
// If current working directory is home directory, return "~".
59-
func (s *state) shortCWD() string {
60-
home := os.Getenv("HOME")
61-
if s.cwd == home {
62-
return "~"
63-
}
64-
return strings.Replace(s.cwd, home, "~", 1)
65-
}
66-
6740
// NewShell return *Shell.
6841
func NewShell(
6942
arg *config.Arg,
7043
cfg *config.Config,
7144
cmds CommandList,
7245
usecases Usecases,
7346
) (*Shell, error) {
74-
state, err := newState()
47+
state, err := newState(arg)
7548
if err != nil {
7649
return nil, err
7750
}
@@ -171,7 +144,7 @@ func (s *Shell) prompt(ctx context.Context) (string, error) {
171144

172145
return prompt.Input(
173146
func() string {
174-
return fmt.Sprintf("sqly:%s(%s)$ ", s.state.shortCWD(), s.argument.Output.Mode)
147+
return fmt.Sprintf("sqly:%s(%s)$ ", s.state.shortCWD(), s.state.mode.String())
175148
}(),
176149
func(d prompt.Document) []prompt.Suggest {
177150
return s.completer(ctx, d)
@@ -283,6 +256,7 @@ func (s *Shell) exec(ctx context.Context, request string) error {
283256
return nil
284257
}
285258

259+
// execSQL execute SQL query.
286260
func (s *Shell) execSQL(ctx context.Context, req string) error {
287261
req = strings.TrimRight(req, ";")
288262
table, affectedRows, err := s.usecases.sqlite3.ExecSQL(ctx, req)
@@ -298,7 +272,7 @@ func (s *Shell) execSQL(ctx context.Context, req string) error {
298272
if s.argument.NeedsOutputToFile() {
299273
return s.outputToFile(table)
300274
}
301-
table.Print(config.Stdout, s.argument.Output.Mode)
275+
table.Print(config.Stdout, s.state.mode.PrintMode)
302276
return nil
303277
}
304278

@@ -308,7 +282,7 @@ func (s *Shell) outputToFile(table *model.Table) error {
308282
return err
309283
}
310284
fmt.Fprintf(config.Stdout, "Output sql result to %s (output mode=%s)\n",
311-
color.HiCyanString(s.argument.Output.FilePath), dumpMode(s.argument.Output.Mode))
285+
color.HiCyanString(s.argument.Output.FilePath), dumpMode(s.state.mode.PrintMode))
312286
return nil
313287
}
314288

shell/shell_test.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"os"
77
"path/filepath"
8+
"strings"
89
"testing"
910

1011
"github.com/c-bata/go-prompt"
@@ -227,8 +228,8 @@ func TestShellExec(t *testing.T) {
227228
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
228229
g.Assert(t, "mode_csv_to_table", got)
229230

230-
if shell.argument.Output.Mode != model.PrintModeTable {
231-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeTable.String())
231+
if shell.state.mode.PrintMode != model.PrintModeTable {
232+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeTable.String())
232233
}
233234
})
234235

@@ -248,8 +249,8 @@ func TestShellExec(t *testing.T) {
248249
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
249250
g.Assert(t, "mode_table_to_csv", got)
250251

251-
if shell.argument.Output.Mode != model.PrintModeCSV {
252-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeCSV.String())
252+
if shell.state.mode.PrintMode != model.PrintModeCSV {
253+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeCSV.String())
253254
}
254255
})
255256

@@ -269,8 +270,8 @@ func TestShellExec(t *testing.T) {
269270
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
270271
g.Assert(t, "mode_table_to_markdown", got)
271272

272-
if shell.argument.Output.Mode != model.PrintModeMarkdownTable {
273-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeMarkdownTable.String())
273+
if shell.state.mode.PrintMode != model.PrintModeMarkdownTable {
274+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeMarkdownTable.String())
274275
}
275276
})
276277

@@ -290,8 +291,8 @@ func TestShellExec(t *testing.T) {
290291
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
291292
g.Assert(t, "mode_table_to_tsv", got)
292293

293-
if shell.argument.Output.Mode != model.PrintModeTSV {
294-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeTSV.String())
294+
if shell.state.mode.PrintMode != model.PrintModeTSV {
295+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeTSV.String())
295296
}
296297
})
297298

@@ -311,8 +312,8 @@ func TestShellExec(t *testing.T) {
311312
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
312313
g.Assert(t, "mode_table_to_ltsv", got)
313314

314-
if shell.argument.Output.Mode != model.PrintModeLTSV {
315-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeLTSV.String())
315+
if shell.state.mode.PrintMode != model.PrintModeLTSV {
316+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeLTSV.String())
316317
}
317318
})
318319

@@ -332,8 +333,8 @@ func TestShellExec(t *testing.T) {
332333
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
333334
g.Assert(t, "mode_table_to_json", got)
334335

335-
if shell.argument.Output.Mode != model.PrintModeJSON {
336-
t.Errorf("mismatch got=%s, want=%s", shell.argument.Output.Mode.String(), model.PrintModeJSON.String())
336+
if shell.state.mode.PrintMode != model.PrintModeJSON {
337+
t.Errorf("mismatch got=%s, want=%s", shell.state.mode.String(), model.PrintModeJSON.String())
337338
}
338339
})
339340

@@ -344,14 +345,10 @@ func TestShellExec(t *testing.T) {
344345
}
345346
defer cleanup()
346347

347-
got, err := getExecStdOutput(t, shell.exec, ".mode table")
348-
if err != nil {
348+
_, err = getExecStdOutput(t, shell.exec, ".mode table")
349+
if !strings.Contains(err.Error(), "already table mode") {
349350
t.Fatal(err)
350351
}
351-
352-
g := golden.New(t,
353-
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
354-
g.Assert(t, "mode_table_to_same_mode", got)
355352
})
356353

357354
t.Run("execute .mode: table to invalid mode", func(t *testing.T) {
@@ -361,14 +358,10 @@ func TestShellExec(t *testing.T) {
361358
}
362359
defer cleanup()
363360

364-
got, err := getExecStdOutput(t, shell.exec, ".mode not_exist_mode")
365-
if err != nil {
361+
_, err = getExecStdOutput(t, shell.exec, ".mode not_exist_mode")
362+
if !strings.Contains(err.Error(), "invalid output mode: not_exist_mode") {
366363
t.Fatal(err)
367364
}
368-
369-
g := golden.New(t,
370-
golden.WithFixtureDir(filepath.Join("testdata", "golden")))
371-
g.Assert(t, "mode_table_to_not_exist_mode", got)
372365
})
373366

374367
t.Run("execute .mode: if not specify mode name", func(t *testing.T) {

shell/state.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package shell
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
"strings"
8+
9+
"github.com/nao1215/sqly/config"
10+
"github.com/nao1215/sqly/domain/model"
11+
)
12+
13+
// state is shell state.
14+
type state struct {
15+
cwd string // cwd is current working directory.
16+
mode *mode // mode is output mode.
17+
}
18+
19+
// newState return *state.
20+
func newState(arg *config.Arg) (*state, error) {
21+
dir, err := os.Getwd()
22+
if err != nil {
23+
return nil, err
24+
}
25+
return &state{
26+
cwd: dir,
27+
mode: newMode(config.Stdout, arg.Output.Mode),
28+
}, nil
29+
}
30+
31+
// shortCWD return short current working directory.
32+
// If current working directory is home directory, return "~".
33+
func (s *state) shortCWD() string {
34+
home := os.Getenv("HOME")
35+
if s.cwd == home {
36+
return "~"
37+
}
38+
return strings.Replace(s.cwd, home, "~", 1)
39+
}
40+
41+
// mode is output mode.
42+
type mode struct {
43+
w io.Writer
44+
model.PrintMode
45+
}
46+
47+
// newMode returns mode.
48+
func newMode(w io.Writer, m model.PrintMode) *mode {
49+
return &mode{
50+
w: w,
51+
PrintMode: m,
52+
}
53+
}
54+
55+
// changeOutputModeIfNeeded change output mode.
56+
// modeName is new output mode (e.g. table).
57+
func (m *mode) changeOutputModeIfNeeded(modeName string) error {
58+
if modeName == m.String() {
59+
return fmt.Errorf("already %s mode", modeName)
60+
}
61+
62+
switch modeName {
63+
case model.PrintModeTable.String():
64+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s\n", m.String(), model.PrintModeTable.String())
65+
m.PrintMode = model.PrintModeTable
66+
case model.PrintModeMarkdownTable.String():
67+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s table\n", m.String(), model.PrintModeMarkdownTable.String())
68+
m.PrintMode = model.PrintModeMarkdownTable
69+
case model.PrintModeCSV.String():
70+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s\n", m.String(), model.PrintModeCSV.String())
71+
m.PrintMode = model.PrintModeCSV
72+
case model.PrintModeTSV.String():
73+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s\n", m.String(), model.PrintModeTSV.String())
74+
m.PrintMode = model.PrintModeTSV
75+
case model.PrintModeLTSV.String():
76+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s\n", m.String(), model.PrintModeLTSV.String())
77+
m.PrintMode = model.PrintModeLTSV
78+
case model.PrintModeJSON.String():
79+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s\n", m.String(), model.PrintModeJSON.String())
80+
m.PrintMode = model.PrintModeJSON
81+
case model.PrintModeExcel.String():
82+
fmt.Fprintf(config.Stdout, "Change output mode from %s to %s (active only when executing .dump, otherwise same as csv mode)\n",
83+
m.String(), model.PrintModeExcel.String())
84+
m.PrintMode = model.PrintModeExcel
85+
default:
86+
return fmt.Errorf("invalid output mode: %s", modeName)
87+
}
88+
return nil
89+
}

0 commit comments

Comments
 (0)