Skip to content

Commit

Permalink
Replace sqlite3dump with directly using sqlite3 from $PATH
Browse files Browse the repository at this point in the history
sqlite3dump requires turso-cli to be built with CGO. Even though it
works when you you build the CLI locally (if you have CGO enabled),
it won't work for our official release builds. Compiling multiplatform
binaries with CGO isn't trivial and it is not worth it. sqlite3 should
be available on most systems and it is reasonable to depend on it for
features such as --from-file.
  • Loading branch information
athoscouto committed Oct 14, 2023
1 parent fe804bf commit 872e867
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 9 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/schollz/sqlite3dump v1.3.1
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.15.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
Expand Down
3 changes: 0 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
Expand Down Expand Up @@ -314,8 +313,6 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/schollz/sqlite3dump v1.3.1 h1:QXizJ7XEJ7hggjqjZ3YRtF3+javm8zKtzNByYtEkPRA=
github.com/schollz/sqlite3dump v1.3.1/go.mod h1:mzSTjZpJH4zAb1FN3iNlhWPbbdyeBpOaTW0hukyMHyI=
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
Expand Down
75 changes: 70 additions & 5 deletions internal/cmd/group_flag.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cmd

import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"time"

"github.com/schollz/sqlite3dump"
"github.com/spf13/cobra"
"github.com/tursodatabase/turso-cli/internal/prompt"
"github.com/tursodatabase/turso-cli/internal/turso"
Expand Down Expand Up @@ -135,13 +137,76 @@ func countFlags(flags ...string) (count int) {
}

func handleDBFile(client *turso.Client, file string) (*turso.DBSeed, error) {
f, err := os.CreateTemp("", "")
if err := checkFileExists(file); err != nil {
return nil, err
}
if err := checkSQLiteAvailable(); err != nil {
return nil, err
}

if err := checkSQLiteFile(file); err != nil {
return nil, err
}

tmp, err := createTempFile()
if err != nil {
return nil, err
}

if err := dumpSQLiteDatabase(file, tmp); err != nil {
return nil, err
}

return handleDumpFile(client, tmp.Name())
}

func checkFileExists(file string) error {
_, err := os.Stat(file)
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("could not find file %s", file)
}
return err
}

func checkSQLiteAvailable() error {
_, err := exec.LookPath("sqlite3")
if errors.Is(err, exec.ErrNotFound) {
return fmt.Errorf("could not find sqlite3 on your system. Please install it to use the --from-file flag or use --from-dump instead")
}
return err
}

func checkSQLiteFile(file string) error {
output, err := exec.Command("sqlite3", file, "pragma quick_check;").CombinedOutput()

execErr := &exec.ExitError{}
if errors.As(err, &execErr) && execErr.ExitCode() == 26 {
return fmt.Errorf("file %s is not a valid SQLite database file", file)
}

if err != nil {
return fmt.Errorf("could not check database file: %w: %s", err, output)
}
return nil
}

func createTempFile() (*os.File, error) {
tmp, err := os.CreateTemp("", "")
if err != nil {
return nil, fmt.Errorf("could not create temporary file to dump database file: %w", err)
}
if err := sqlite3dump.Dump(file, f); err != nil {
return nil, fmt.Errorf("could not dump database file: %w", err)
return tmp, nil
}

func dumpSQLiteDatabase(database string, dump *os.File) error {
stdErr := &bytes.Buffer{}
cmd := exec.Command("sqlite3", database, ".dump")
cmd.Stdout = dump
cmd.Stderr = stdErr

if err := cmd.Run(); err != nil {
return fmt.Errorf("could not dump database file: %w: %x", err, stdErr.Bytes())
}

return handleDumpFile(client, f.Name())
return nil
}

0 comments on commit 872e867

Please sign in to comment.