On this page
Your first query
Build a small task application with SQLite. You will create its table, name two queries and call the generated Go code.
Step 1: Prepare the practice workspace
Start with Go 1.27 and a Seagull checkout. From the repository root, prepare a new directory outside the checkout:
go run ./tests/tutorials/cmd/prepare /tmp/seagull-practice
cd /tmp/seagull-practice/01_first_query
Choose a different directory if that one already exists. The helper builds sgl and supplies the module, imports and connection setup. The first six lessons use this same application directory. Keep using ../sgl so the generator matches the checkout.
Open main.go. Its run function is empty. The supplied setup opens a fresh SQLite file, applies the migrations you will write and closes the connection afterwards. Each application run starts with an empty database.
Step 2: Describe the project
Create sgl.yaml:
version: 1
databases:
- name: tasks
dialect: sqlite
migrations: db/migrations
queries: db/queries
seeds: db/seeds
go:
package: store
out: internal/store
This tells Seagull where to read SQL and where to write the store package. The dialect describes the SQL; the generated code will use database/sql.
Step 3: Create the table
Create db/migrations/0001_tasks.up.sql:
CREATE TABLE tasks (id INTEGER PRIMARY KEY, title TEXT NOT NULL, completed INTEGER NOT NULL DEFAULT 0);
The table has an ID, a title and a completion value that starts at zero. Generation reads this migration to learn the schema. It does not create a database yet.
Step 4: Name the queries
Create db/queries/tasks.sql:
-- sgl.query(CreateTask, one)
INSERT INTO tasks (title) VALUES (?) RETURNING id, title, completed;
-- sgl.query(ListTasks, many)
SELECT id, title, completed FROM tasks ORDER BY id;
CreateTask inserts a title and returns one row. ListTasks returns all the tasks in ID order. The question mark is a parameter supplied by the Go caller.
Generate the package:
../sgl generate
Open internal/store/tasks.sql.go and find CreateTask. It accepts a title and returns a row with the three selected columns.
Step 5: Call the generated method
In main.go, put this code inside run, before its final return nil:
queries := store.New(db)
task, err := queries.CreateTask(ctx, "Feed the seagulls")
if err != nil {
return err
}
fmt.Fprintln(out, task.ID, task.Title)
store.New(db) uses the connection supplied by the setup. Run the application:
go run .
1 Feed the seagulls
The migration created the table before the call. SQLite assigned the first ID, and the generated method read the returned title.
Continue with a useful data layer. The complete checkpoint is available if you want to compare your work.