105 lines
2.0 KiB
Go
105 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"slices"
|
|
"strings"
|
|
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
func main() {
|
|
db, err := sql.Open("sqlite", os.Args[1])
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
tables, err := Tables(db)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if len(os.Args) > 2 {
|
|
tables = slices.DeleteFunc(tables, func(s string) bool { return !slices.Contains(os.Args[2:], s) })
|
|
}
|
|
|
|
for i, table := range tables {
|
|
if err := func() error {
|
|
rows, err := db.Query(fmt.Sprintf(`SELECT * FROM %q`, table))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer rows.Close()
|
|
|
|
columns, err := rows.Columns()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if i > 0 {
|
|
fmt.Println("")
|
|
}
|
|
fmt.Println("---", table)
|
|
fmt.Println(strings.Join(func() []string {
|
|
quoted := []string{}
|
|
for _, col := range columns {
|
|
quoted = append(quoted, fmt.Sprintf("%q", col))
|
|
}
|
|
return quoted
|
|
}(), ","))
|
|
|
|
row := make([]any, len(columns))
|
|
for rows.Next() {
|
|
for i := range row {
|
|
var a any
|
|
row[i] = &a
|
|
}
|
|
if err := rows.Scan(row...); err != nil {
|
|
return err
|
|
}
|
|
jsons := []string{}
|
|
for i := range row {
|
|
row[i] = *(row[i].(*any))
|
|
if b, ok := row[i].([]byte); ok {
|
|
row[i] = string(b)
|
|
}
|
|
b, _ := json.Marshal(row[i])
|
|
jsons = append(jsons, string(b))
|
|
}
|
|
fmt.Println(strings.Join(jsons, ","))
|
|
}
|
|
|
|
return rows.Err()
|
|
}(); err != nil {
|
|
log.Fatalf("%s: %v", table, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Tables(db *sql.DB) ([]string, error) {
|
|
return Select[string](db, `SELECT name FROM sqlite_schema WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`)
|
|
}
|
|
|
|
func Select[T any](db *sql.DB, q string, args ...any) ([]T, error) {
|
|
rows, err := db.Query(q, args...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
results := []T{}
|
|
for rows.Next() {
|
|
var some T
|
|
if err := rows.Scan(&some); err != nil {
|
|
return nil, err
|
|
}
|
|
results = append(results, some)
|
|
}
|
|
|
|
return results, rows.Err()
|
|
}
|