-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: combine exec and query database tools
- Combine the `Run Database Query` and `Exec Database Statement` tools into a single `Run Database Command` tool that allows for executing both statements and queries. The new tool returns the raw SQL output instead of JSON - Shell out to the sqlite3 binary instead of using a dependency-free go module - Add the `list_database_tables` and `list_database_table_rows` tools to retain database support in the user UI. Signed-off-by: Nick Hale <[email protected]>
- Loading branch information
Showing
10 changed files
with
192 additions
and
177 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/google/shlex" | ||
) | ||
|
||
// RunDatabaseCommand runs a sqlite3 command against the database and returns the output from the sqlite3 cli. | ||
func RunDatabaseCommand(ctx context.Context, dbFile *os.File, sqlite3Args string) (string, error) { | ||
// Remove the "sqlite3" prefix and trim whitespace | ||
sqlite3Args = strings.TrimPrefix(strings.TrimSpace(sqlite3Args), "sqlite3") | ||
|
||
// Split the arguments | ||
args, err := shlex.Split(sqlite3Args) | ||
if err != nil { | ||
return "", fmt.Errorf("error parsing sqlite3 args: %w", err) | ||
} | ||
|
||
// Build the sqlite3 command | ||
cmd := exec.CommandContext(ctx, "sqlite3", append([]string{dbFile.Name()}, args...)...) | ||
|
||
// Redirect the command output | ||
var stdout, stderr bytes.Buffer | ||
cmd.Stdout = &stdout | ||
cmd.Stderr = &stderr | ||
|
||
// Run the command | ||
if err := cmd.Run(); err != nil { | ||
return "", fmt.Errorf("error executing sqlite3: %w, stderr: %s", err, stderr.String()) | ||
} | ||
|
||
return stdout.String(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"os" | ||
"strings" | ||
) | ||
|
||
type Output struct { | ||
Columns []string `json:"columns"` | ||
Rows []map[string]any `json:"rows"` | ||
} | ||
|
||
// ListDatabaseTableRows lists all rows from the specified table using RunDatabaseCommand and returns a JSON object containing the results. | ||
func ListDatabaseTableRows(ctx context.Context, dbFile *os.File, table string) (string, error) { | ||
if table == "" { | ||
return "", fmt.Errorf("table name cannot be empty") | ||
} | ||
|
||
// Build the query to fetch all rows from the table | ||
query := fmt.Sprintf("SELECT * FROM %q;", table) | ||
|
||
// Execute the query using RunDatabaseCommand | ||
rawOutput, err := RunDatabaseCommand(ctx, dbFile, fmt.Sprintf("%q", query)) | ||
if err != nil { | ||
return "", fmt.Errorf("error executing query for table %q: %w", table, err) | ||
} | ||
|
||
// Split raw output into rows | ||
lines := strings.Split(strings.TrimSpace(rawOutput), "\n") | ||
if len(lines) == 0 { | ||
return "", fmt.Errorf("no output from query for table %q", table) | ||
} | ||
|
||
// The first line contains column names | ||
columns := strings.Split(lines[0], "|") | ||
output := Output{ | ||
Columns: columns, | ||
Rows: []map[string]any{}, | ||
} | ||
|
||
// Process the remaining lines as rows | ||
for _, line := range lines[1:] { | ||
values := strings.Split(line, "|") | ||
rowData := map[string]any{} | ||
for i, col := range columns { | ||
if i < len(values) { | ||
rowData[col] = values[i] | ||
} else { | ||
rowData[col] = nil | ||
} | ||
} | ||
output.Rows = append(output.Rows, rowData) | ||
} | ||
|
||
// Marshal the result to JSON | ||
content, err := json.Marshal(output) | ||
if err != nil { | ||
return "", fmt.Errorf("error marshalling output to JSON: %w", err) | ||
} | ||
|
||
return string(content), nil | ||
} |
Oops, something went wrong.