Thinking I might want to write another Go webapp with some database in the background I wanted to play around with DBs first.
I decided to use pop for this.
Let’s create the project:
mkdir -p ~/.go/src/github.com/jubalh/soda-pop-example
cd ~/.go/src/github.com/jubalh/soda-pop-example
And define a SQLite test database:
$ vi database.yml
development:
dialect: "sqlite3"
database: "./db.sqlite"
Our example program looks like this for now:
package main
import (
"fmt"
"log"
"github.com/gobuffalo/pop"
)
func main() {
fmt.Println("This is a Go database test program")
}
It’s time to install pop and it’s cli frontend soda:
go get github.com/gobuffalo/pop/...
go install github.com/gobuffalo/pop/soda
Tell soda do create the database:
$ soda create development
v4.0.2
created database ./db.sqlite
Now we can add the code to our Go file to connect to the database:
db, err := pop.Connect("development")
if err != nil {
log.Panic(err)
}
A model is something we fill with values and put into our database. In the code we can use it as a struct and pop takes care of its representation in the DB via the model we specified.
soda generate model user firstname:text lastname:text
v4.0.2
create models/user.go
create models/user_test.go
run goimports -w main.go models/user.go models/user_test.go
> migrations/20180228135043_create_users.up.fizz
> migrations/20180228135043_create_users.down.fizz
Look at the generated files to learn about them.
Apply to database:
soda migrate up
v4.0.2
> create_users
0.0741 seconds
dumped schema for ./db.sqlite
We can add users inside our program like this:
user := models.User{Firstname: "Vincent", Lastname: "Vega"}
_, err = db.ValidateAndSave(&user)
if err != nil {
log.Panic(err)
}
fmt.Printf("Added %s to database\n", user.Firstname)
user = models.User{Firstname: "Jules", Lastname: "Winnfield"}
_, err = db.ValidateAndSave(&user)
if err != nil {
log.Panic(err)
}
fmt.Printf("Added %s to database\n", user.Firstname)
Running it we get:
$ go run main.go
This is a Go database test program
Added Vincent to database
Added Jules to database
Through looking at the models/user.go
file we understood what the struct looked like that soda
created for us. Now let’s take a look at the SQLite table:
sqlite3 ./db.sqlite
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> SELECT * FROM users;
fd38017c-5426-42bb-90b3-40a76ee3316f|Vincent|Vega|2018-02-28 14:59:22.864084017+01:00|2018-02-28 14:59:22.864084669+01:00
a57aa8a3-ba52-453c-a337-1453570c72a6|Jules|Winnfield|2018-02-28 14:59:22.897798215+01:00|2018-02-28 14:59:22.897801007+01:00
sqlite> .exit
Only thing we forgot is that those folks have an age too. (No, no birthdate, they don’t age)
$ soda generate fizz add_age
v4.0.2
> migrations/20180228141319_add_age.up.fizz
> migrations/20180228141319_add_age.down.fizz
$ vi migrations/20180228141319_add_age.up.fizz
add_column("users", "age", "integer", {"default": "23"})
$ vi migrations/20180228141319_add_age.down.fizz
drop_column("users", "age")
Also append the line Age int
json:“age” db:“age”`` to the User struct in models/user.go
.
Now we update or migrate the database to the new scheme:
$ soda migrate
v4.0.2
> add_age
0.0350 secondsj
dumped schema for ./db.sqlite
By using sqlite3
you can check how the database changed.
The files can be found in my GitHub repo soda-pop-example.