github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/driver/example_test.go (about) 1 //go:build (linux || darwin || windows || freebsd || illumos) && !sqlite3_nosys 2 3 package driver_test 4 5 // Adapted from: https://go.dev/doc/tutorial/database-access 6 7 import ( 8 "database/sql" 9 "fmt" 10 "log" 11 "os" 12 13 _ "github.com/ncruces/go-sqlite3/driver" 14 _ "github.com/ncruces/go-sqlite3/embed" 15 ) 16 17 var db *sql.DB 18 19 type Album struct { 20 ID int64 21 Title string 22 Artist string 23 Price float32 24 } 25 26 func Example() { 27 // Get a database handle. 28 var err error 29 db, err = sql.Open("sqlite3", "./recordings.db") 30 if err != nil { 31 log.Fatal(err) 32 } 33 defer os.Remove("./recordings.db") 34 defer db.Close() 35 36 // Create a table with some data in it. 37 err = albumsSetup() 38 if err != nil { 39 log.Fatal(err) 40 } 41 42 albums, err := albumsByArtist("John Coltrane") 43 if err != nil { 44 log.Fatal(err) 45 } 46 fmt.Printf("Albums found: %v\n", albums) 47 48 // Hard-code ID 2 here to test the query. 49 alb, err := albumByID(2) 50 if err != nil { 51 log.Fatal(err) 52 } 53 fmt.Printf("Album found: %v\n", alb) 54 55 albID, err := addAlbum(Album{ 56 Title: "The Modern Sound of Betty Carter", 57 Artist: "Betty Carter", 58 Price: 49.99, 59 }) 60 if err != nil { 61 log.Fatal(err) 62 } 63 fmt.Printf("ID of added album: %v\n", albID) 64 // Output: 65 // Albums found: [{1 Blue Train John Coltrane 56.99} {2 Giant Steps John Coltrane 63.99}] 66 // Album found: {2 Giant Steps John Coltrane 63.99} 67 // ID of added album: 5 68 } 69 70 func albumsSetup() error { 71 _, err := db.Exec(` 72 DROP TABLE IF EXISTS album; 73 CREATE TABLE album ( 74 id INTEGER PRIMARY KEY AUTOINCREMENT, 75 title VARCHAR(128) NOT NULL, 76 artist VARCHAR(255) NOT NULL, 77 price DECIMAL(5,2) NOT NULL 78 ); 79 `) 80 if err != nil { 81 return err 82 } 83 84 _, err = db.Exec(` 85 INSERT INTO album 86 (title, artist, price) 87 VALUES 88 ('Blue Train', 'John Coltrane', 56.99), 89 ('Giant Steps', 'John Coltrane', 63.99), 90 ('Jeru', 'Gerry Mulligan', 17.99), 91 ('Sarah Vaughan', 'Sarah Vaughan', 34.98) 92 `) 93 if err != nil { 94 return err 95 } 96 97 return nil 98 } 99 100 // albumsByArtist queries for albums that have the specified artist name. 101 func albumsByArtist(name string) ([]Album, error) { 102 // An albums slice to hold data from returned rows. 103 var albums []Album 104 105 rows, err := db.Query("SELECT * FROM album WHERE artist = ?", name) 106 if err != nil { 107 return nil, fmt.Errorf("albumsByArtist %q: %w", name, err) 108 } 109 defer rows.Close() 110 // Loop through rows, using Scan to assign column data to struct fields. 111 for rows.Next() { 112 var alb Album 113 if err := rows.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil { 114 return nil, fmt.Errorf("albumsByArtist %q: %w", name, err) 115 } 116 albums = append(albums, alb) 117 } 118 if err := rows.Err(); err != nil { 119 return nil, fmt.Errorf("albumsByArtist %q: %w", name, err) 120 } 121 return albums, nil 122 } 123 124 // albumByID queries for the album with the specified ID. 125 func albumByID(id int64) (Album, error) { 126 // An album to hold data from the returned row. 127 var alb Album 128 129 row := db.QueryRow("SELECT * FROM album WHERE id = ?", id) 130 if err := row.Scan(&alb.ID, &alb.Title, &alb.Artist, &alb.Price); err != nil { 131 if err == sql.ErrNoRows { 132 return alb, fmt.Errorf("albumsById %d: no such album", id) 133 } 134 return alb, fmt.Errorf("albumsById %d: %w", id, err) 135 } 136 return alb, nil 137 } 138 139 // addAlbum adds the specified album to the database, 140 // returning the album ID of the new entry 141 func addAlbum(alb Album) (int64, error) { 142 result, err := db.Exec("INSERT INTO album (title, artist, price) VALUES (?, ?, ?)", alb.Title, alb.Artist, alb.Price) 143 if err != nil { 144 return 0, fmt.Errorf("addAlbum: %w", err) 145 } 146 id, err := result.LastInsertId() 147 if err != nil { 148 return 0, fmt.Errorf("addAlbum: %w", err) 149 } 150 return id, nil 151 }