// Debby is a command line tool that links your dolt database to visidata package main import ( "fmt" "os" "os/exec" "strings" "sync" ) var once = sync.Once{} func main() { // Menu loop. 1. Read tale names 2. Run query 3. Run and save query 4. Execute Dolt command 5. Exit for { // Print menu fmt.Println("1. Read table names") fmt.Println("2. Run query") fmt.Println("3. Edit table") fmt.Println("4. Execute Dolt command") fmt.Println("5. Exit") fmt.Print("Enter your choice: ") // Read user input var choice int fmt.Scanln(&choice) // Execute choice switch choice { case 1: // Read table names ReadTableNames() case 2: // Request query fmt.Print("Enter your query: ") var query string fmt.Scanln(&query) // Table name will be empty. Run query RunSQL(query, "") case 3: // Request table name fmt.Print("Enter your table name: ") var table string fmt.Scanln(&table) // Run query RunSQL("select * from " + table + ";", table) case 4: // Request command fmt.Print("dolt ") var args string fmt.Scanln(&args) // Execute command ExecuteDoltCommand(args) case 5: // Exit return default: // Invalid choice fmt.Println("Invalid choice") } } } func ExecuteDoltCommand(args ...string) { cmd := exec.Command("dolt", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin cmd.Run() } func SaveToTable(table, file string) error { // Run dolt table import -r table file cmd := exec.Command("dolt", "table", "import", "-r", table, file) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin return cmd.Run() } func ReadTableNames() { // Run dolt ls cmd := exec.Command("dolt", "ls") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin cmd.Run() } func RunSQL(query, table string) error { // Create a temporary file to open in visidata f, err := os.CreateTemp("", "debby-*.sql") if err != nil { return err } defer os.Remove(f.Name()) // Run the query and write the output to the file cmd := exec.Command("dolt", "sql", "-q", query, "-r", "csv") cmd.Stdout = f err = cmd.Run() if err != nil { return err } // Open the file in visidata OpenVisidata(f.Name(), "-f", "csv") // If table is not empty, save the file to the table if table != "" { err = SaveToTable(table, f.Name()) if err != nil { return err } } // Read the file back into memory return nil } func OpenVisidata(args ...string) { vdcmd := os.Getenv("EDITOR") once.Do(func() { // run with --version and check if it returns saul.pw/VisiData, if not try the same with visidata instead for _, cmd := range []string{"vd", "visidata"} { out, err := exec.Command(cmd, "--version").Output() if err != nil { continue } if strings.Contains(string(out), "saul.pw/VisiData") { vdcmd = cmd break } } }) cmd := exec.Command(vdcmd, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin cmd.Run() }