← history for main.go
e0003df2main.go119 lines⬡ raw↓ download
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main

import (
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"github.com/chzyer/readline"
	"github.com/gocql/gocql"
)

func main() {
	configPath := flag.String("config", os.Getenv("HOME")+"/.config/cqlminus/config.json", "path to json config file")
	historyPath := flag.String("history", defaultHistoryPath(), "path to history file")
	flag.Parse()

	cfg, err := LoadConfig(*configPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}

	session, err := Connect(cfg)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
	defer session.Close()

	fmt.Printf("connected to %s:%d keyspace=%s\n", cfg.Server, cfg.Port, cfg.Keyspace)
	fmt.Println("enter CQL queries, terminate with ; then enter. type exit or quit to leave.")
	fmt.Println("use up/down arrows to browse command history.")

	runLoop(session, *historyPath)
}

func defaultHistoryPath() string {
	home, err := os.UserHomeDir()
	if err != nil {
		return ".cqltui_history"
	}
	return filepath.Join(home, ".cqltui_history")
}

func runLoop(session *gocql.Session, historyPath string) {
	rl, err := readline.NewEx(&readline.Config{
		Prompt:                 "cql> ",
		HistoryFile:            historyPath,
		HistoryLimit:           1000,
		DisableAutoSaveHistory: true,
	})
	if err != nil {
		PrintError(fmt.Errorf("initializing readline: %w", err))
		return
	}
	defer rl.Close()

	var buffer strings.Builder

	for {
		if buffer.Len() == 0 {
			rl.SetPrompt("cql> ")
		} else {
			rl.SetPrompt("...> ")
		}

		line, err := rl.Readline()
		if err == readline.ErrInterrupt {
			buffer.Reset()
			continue
		}
		if err == io.EOF {
			return
		}
		if err != nil {
			return
		}

		trimmed := strings.TrimSpace(line)

		if buffer.Len() == 0 {
			lower := strings.ToLower(trimmed)
			if lower == "exit" || lower == "quit" {
				return
			}
			if trimmed == "" {
				continue
			}
		}

		buffer.WriteString(line)
		buffer.WriteString(" ")

		if !strings.HasSuffix(trimmed, ";") {
			continue
		}

		query := strings.TrimSpace(buffer.String())
		query = strings.TrimSuffix(query, ";")
		buffer.Reset()

		if query == "" {
			continue
		}

		rl.SaveHistory(query)

		result, err := RunQuery(session, query)
		if err != nil {
			PrintError(err)
			continue
		}

		PrintTable(result)
	}
}