11package driver
22
33import (
4+ "bytes"
45 "context"
56 "database/sql"
67 sqlDriver "database/sql/driver"
7- _ "embed"
8+ "embed"
89 "errors"
910 "flag"
1011 "fmt"
1112 "io/fs"
1213 "os"
1314 "regexp"
15+ "strconv"
16+ "strings"
1417 "testing"
1518
1619 "github.com/stephenafamo/bob/gen"
@@ -21,7 +24,7 @@ import (
2124 "modernc.org/sqlite"
2225)
2326
24- func cleanup (t * testing.T , config Config ) {
27+ func cleanupSQLite (t * testing.T , config Config ) {
2528 t .Helper ()
2629
2730 fmt .Printf ("cleaning..." )
@@ -40,42 +43,131 @@ func cleanup(t *testing.T, config Config) {
4043 fmt .Printf (" DONE\n " )
4144}
4245
46+ func cleanupLibSQL (t * testing.T , db * sql.DB ) {
47+ t .Helper ()
48+
49+ fmt .Printf ("cleaning..." )
50+
51+ // Find all tables
52+ rows , err := db .Query ("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';" )
53+ if err != nil {
54+ t .Fatal (err )
55+ }
56+ defer rows .Close ()
57+
58+ // Drop each table
59+ for rows .Next () {
60+ var tableName string
61+ if err = rows .Scan (& tableName ); err != nil {
62+ t .Fatalf ("could not delete existing db: %v" , err )
63+ }
64+ _ , err = db .Exec (fmt .Sprintf ("DROP TABLE IF EXISTS %q;" , tableName ))
65+ if err != nil {
66+ t .Fatalf ("could not delete %q table: %v" , tableName , err )
67+ }
68+ }
69+
70+ fmt .Printf (" DONE\n " )
71+ }
72+
4373var flagOverwriteGolden = flag .Bool ("overwrite-golden" , false , "Overwrite the golden file with the current execution results" )
4474
45- func TestAssemble (t * testing.T ) {
75+ func TestAssembleSQLite (t * testing.T ) {
4676 ctx := context .Background ()
4777
4878 config := Config {
4979 DSN : "./test.db" ,
5080 Attach : map [string ]string {"one" : "./test1.db" },
5181 }
5282
53- cleanup (t , config )
54- t .Cleanup (func () { cleanup (t , config ) })
83+ cleanupSQLite (t , config )
84+ t .Cleanup (func () { cleanupSQLite (t , config ) })
5585
56- db , err := sql .Open ("sqlite" , config .DSN )
57- if err != nil {
58- t .Fatalf ("failed to connect to database: %v" , err )
59- }
86+ db := connect (t , "sqlite" , config .DSN )
6087 defer db .Close ()
6188
62- if err = registerRegexpFunction (); err != nil {
89+ if err := registerRegexpFunction (); err != nil {
90+ t .Fatal (err )
91+ }
92+
93+ attach (t , ctx , db , config )
94+
95+ fmt .Printf ("migrating..." )
96+ migrate (t , db , testfiles .SQLiteSchema )
97+ fmt .Printf (" DONE\n " )
98+
99+ assemble (t , config )
100+ }
101+
102+ func TestAssembleLibSQL (t * testing.T ) {
103+ ctx := context .Background ()
104+
105+ err := adjustGoldenFiles ()
106+ if err != nil {
63107 t .Fatal (err )
64108 }
65109
110+ config := Config {
111+ DSN : "ws://localhost:8080" ,
112+ Attach : map [string ]string {"one" : "one" },
113+ }
114+
115+ db := connect (t , "libsql" , config .DSN )
116+
117+ attach (t , ctx , db , config )
118+
119+ fmt .Printf ("migrating..." )
120+ dbHttpDefault := connect (t , "libsql" , "http://localhost:8080" )
121+ migrate (t , dbHttpDefault , testfiles .LibSQLDefaultSchema )
122+ dbHttpOne := connect (t , "libsql" , "http://one.localhost:8080" )
123+ migrate (t , dbHttpOne , testfiles .LibSQLOneSchema )
124+ fmt .Printf (" DONE\n " )
125+
126+ t .Cleanup (func () {
127+ cleanupLibSQL (t , dbHttpDefault )
128+ cleanupLibSQL (t , dbHttpOne )
129+ dbHttpDefault .Close ()
130+ dbHttpOne .Close ()
131+ err = restoreGoldenFiles ()
132+ if err != nil {
133+ t .Fatal (err )
134+ }
135+ })
136+
137+ assemble (t , config )
138+ }
139+
140+ func connect (t * testing.T , driverName , dsn string ) * sql.DB {
141+ t .Helper ()
142+ db , err := sql .Open (driverName , dsn )
143+ if err != nil {
144+ t .Fatalf ("failed to connect to database: %v" , err )
145+ }
146+ return db
147+ }
148+
149+ func attach (t * testing.T , ctx context.Context , db * sql.DB , config Config ) {
150+ t .Helper ()
66151 for schema , conn := range config .Attach {
67- _ , err = db .ExecContext (ctx , fmt .Sprintf ("attach database '%s' as %q" , conn , schema ))
152+ if strings .HasPrefix (conn , "./" ) {
153+ conn = strconv .Quote (conn )
154+ }
155+ _ , err := db .ExecContext (ctx , fmt .Sprintf ("attach database %s as %s" , conn , schema ))
68156 if err != nil {
69157 t .Fatalf ("could not attach %q: %v" , conn , err )
70158 }
71159 }
160+ }
72161
73- fmt .Printf ("migrating..." )
74- if err := helpers .Migrate (context .Background (), db , testfiles .SQLiteSchema ); err != nil {
162+ func migrate (t * testing.T , db * sql.DB , schema embed.FS ) {
163+ t .Helper ()
164+ if err := helpers .Migrate (context .Background (), db , schema ); err != nil {
75165 t .Fatal (err )
76166 }
77- fmt . Printf ( " DONE \n " )
167+ }
78168
169+ func assemble (t * testing.T , config Config ) {
170+ t .Helper ()
79171 tests := []struct {
80172 name string
81173 config Config
@@ -243,3 +335,53 @@ func registerRegexpFunction() error {
243335 return match , nil
244336 })
245337}
338+
339+ var goldenFiles = []string {
340+ "exclude-tables.golden.json" ,
341+ "include-exclude-tables.golden.json" ,
342+ "include-exclude-tables-mixed.golden.json" ,
343+ "include-exclude-tables-regex.golden.json" ,
344+ "include-tables.golden.json" ,
345+ "sqlite.golden.json" ,
346+ }
347+
348+ func adjustGoldenFiles () error {
349+ for _ , f := range goldenFiles {
350+ err := replaceStringInFile (f , "modernc.org/sqlite" , "github.com/tursodatabase/libsql-client-go/libsql" )
351+ if err != nil {
352+ return err
353+ }
354+ }
355+ return nil
356+ }
357+
358+ func restoreGoldenFiles () error {
359+ for _ , f := range goldenFiles {
360+ err := replaceStringInFile (f , "github.com/tursodatabase/libsql-client-go/libsql" , "modernc.org/sqlite" )
361+ if err != nil {
362+ return err
363+ }
364+ }
365+ return nil
366+ }
367+
368+ func replaceStringInFile (filename , oldStr , newStr string ) error {
369+ fileInfo , err := os .Stat (filename )
370+ if err != nil {
371+ return err
372+ }
373+ perm := fileInfo .Mode ().Perm ()
374+
375+ input , err := os .ReadFile (filename )
376+ if err != nil {
377+ return err
378+ }
379+ output := bytes .ReplaceAll (input , []byte (oldStr ), []byte (newStr ))
380+
381+ err = os .WriteFile (filename , output , perm )
382+ if err != nil {
383+ return err
384+ }
385+
386+ return nil
387+ }
0 commit comments