1
1
# Getting started
2
2
3
- Okay, enough hype, let's see it in action .
3
+ This tutorial assumes that the latest version of sqlc is installed and ready to use .
4
4
5
- First you pass the following SQL to ` sqlc generate ` :
5
+ Create a new directory called ` sqlc-tutorial ` and open it up.
6
+
7
+ Initialize a new Go module named ` tutorial.sql.dev/app `
8
+
9
+ ``` shell
10
+ go mod init tutorial.sqlc.dev/app
11
+ ```
12
+
13
+ sqlc looks for either a ` sqlc.yaml ` or ` sqlc.json ` file in the current
14
+ directory. In our new directory, create a file named ` sqlc.yaml ` with the
15
+ following contents:
16
+
17
+ ``` yaml
18
+ version : 1
19
+ packages :
20
+ - path : " tutorial"
21
+ name : " tutorial"
22
+ engine : " postgresql"
23
+ schema : " schema.sql"
24
+ queries : " query.sql"
25
+ ` ` `
26
+
27
+ sqlc needs to know your database schema and queries. In the same directory,
28
+ create a file named ` schema.sql` with the fullowing contents:
6
29
7
30
` ` ` sql
8
31
CREATE TABLE authors (
9
32
id BIGSERIAL PRIMARY KEY,
10
33
name text NOT NULL,
11
34
bio text
12
35
);
36
+ ` ` `
37
+
38
+ Next, create a `query.sql` file with the following four queries :
13
39
40
+ ` ` ` sql
14
41
-- name: GetAuthor :one
15
42
SELECT * FROM authors
16
43
WHERE id = $1 LIMIT 1;
@@ -32,142 +59,83 @@ DELETE FROM authors
32
59
WHERE id = $1;
33
60
` ` `
34
61
35
- And then in your application code you'd write:
62
+ You are now ready to generate code. Run the `generate` command. You shouldn't see any errors or output.
36
63
37
- ``` go
64
+ ` ` ` shell
65
+ sqlc generate
66
+ ` ` `
38
67
39
- // list all authors
40
- authors , err := db.ListAuthors (ctx)
41
- if err != nil {
42
- return err
43
- }
44
- fmt.Println (authors)
45
-
46
- // create an author
47
- insertedAuthor , err := db.CreateAuthor (ctx, db.CreateAuthorParams {
48
- Name : " Brian Kernighan" ,
49
- Bio : sql.NullString {String: " Co-author of The C Programming Language and The Go Programming Language" , Valid: true },
50
- })
51
- if err != nil {
52
- return err
53
- }
54
- fmt.Println (insertedAuthor)
68
+ You should now have a `db` package containing three files.
55
69
56
- // get the author we just inserted
57
- fetchedAuthor , err := db.GetAuthor (ctx, insertedAuthor.ID )
58
- if err != nil {
59
- return err
60
- }
61
- // prints true
62
- fmt.Println (reflect.DeepEqual (insertedAuthor, fetchedAuthor))
70
+ ```
71
+ ├── go.mod
72
+ ├── query.sql
73
+ ├── schema.sql
74
+ ├── sqlc.yaml
75
+ └── tutorial
76
+ ├── db.go
77
+ ├── models.go
78
+ └── query.sql.go
63
79
```
64
80
65
- To make that possible, sqlc generates readable, ** idiomatic** Go code that you
66
- otherwise would have had to write yourself. Take a look:
81
+ You can use your newly generated queries in `app.go`.
67
82
68
83
```go
69
- package db
84
+ package main
70
85
71
86
import (
72
87
"context"
73
88
"database/sql"
74
- )
75
-
76
- type Author struct {
77
- ID int64
78
- Name string
79
- Bio sql.NullString
80
- }
89
+ "log"
90
+ "reflect"
81
91
82
- const createAuthor = ` -- name: CreateAuthor :one
83
- INSERT INTO authors (
84
- name, bio
85
- ) VALUES (
86
- $1, $2
92
+ "tutorial.sqlc.dev/app/tutorial"
87
93
)
88
- RETURNING id, name, bio
89
- `
90
-
91
- type CreateAuthorParams struct {
92
- Name string
93
- Bio sql.NullString
94
- }
95
94
96
- func (q *Queries ) CreateAuthor (ctx context .Context , arg CreateAuthorParams ) (Author , error ) {
97
- row := q.db .QueryRowContext (ctx, createAuthor, arg.Name , arg.Bio )
98
- var i Author
99
- err := row.Scan (&i.ID , &i.Name , &i.Bio )
100
- return i, err
101
- }
95
+ func run() error {
96
+ ctx := context.Background()
102
97
103
- const deleteAuthor = ` -- name: DeleteAuthor :exec
104
- DELETE FROM authors
105
- WHERE id = $1
106
- `
107
-
108
- func (q *Queries ) DeleteAuthor (ctx context .Context , id int64 ) error {
109
- _ , err := q.db .ExecContext (ctx, deleteAuthor, id)
110
- return err
111
- }
112
-
113
- const getAuthor = ` -- name: GetAuthor :one
114
- SELECT id, name, bio FROM authors
115
- WHERE id = $1 LIMIT 1
116
- `
117
-
118
- func (q *Queries ) GetAuthor (ctx context .Context , id int64 ) (Author , error ) {
119
- row := q.db .QueryRowContext (ctx, getAuthor, id)
120
- var i Author
121
- err := row.Scan (&i.ID , &i.Name , &i.Bio )
122
- return i, err
123
- }
98
+ db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
99
+ if err != nil {
100
+ return err
101
+ }
124
102
125
- const listAuthors = ` -- name: ListAuthors :many
126
- SELECT id, name, bio FROM authors
127
- ORDER BY name
128
- `
103
+ queries := tutorial.New(db)
129
104
130
- func (q *Queries ) ListAuthors (ctx context .Context ) ([]Author , error ) {
131
- rows , err := q.db .QueryContext (ctx, listAuthors)
132
- if err != nil {
133
- return nil , err
134
- }
135
- defer rows.Close ()
136
- var items []Author
137
- for rows.Next () {
138
- var i Author
139
- if err := rows.Scan (&i.ID , &i.Name , &i.Bio ); err != nil {
140
- return nil , err
141
- }
142
- items = append (items, i)
143
- }
144
- if err := rows.Close (); err != nil {
145
- return nil , err
105
+ // list all authors
106
+ authors, err := queries.ListAuthors(ctx)
107
+ if err != nil {
108
+ return err
146
109
}
147
- if err := rows.Err (); err != nil {
148
- return nil , err
110
+ log.Println(authors)
111
+
112
+ // create an author
113
+ insertedAuthor, err := queries.CreateAuthor(ctx, tutorial.CreateAuthorParams{
114
+ Name: "Brian Kernighan",
115
+ Bio: sql.NullString{String: "Co-author of The C Programming Language and The Go Programming Language", Valid: true},
116
+ })
117
+ if err != nil {
118
+ return err
149
119
}
150
- return items, nil
151
- }
152
-
153
- type DBTX interface {
154
- ExecContext (context.Context , string , ...interface {}) (sql.Result , error )
155
- PrepareContext (context.Context , string ) (*sql.Stmt , error )
156
- QueryContext (context.Context , string , ...interface {}) (*sql.Rows , error )
157
- QueryRowContext (context.Context , string , ...interface {}) *sql.Row
158
- }
120
+ log.Println(insertedAuthor)
159
121
160
- func New (db DBTX ) *Queries {
161
- return &Queries{db: db}
162
- }
122
+ // get the author we just inserted
123
+ fetchedAuthor, err := queries.GetAuthor(ctx, insertedAuthor.ID)
124
+ if err != nil {
125
+ return err
126
+ }
163
127
164
- type Queries struct {
165
- db DBTX
128
+ // prints true
129
+ log.Println(reflect.DeepEqual(insertedAuthor, fetchedAuthor))
130
+ return nil
166
131
}
167
132
168
- func ( q * Queries ) WithTx ( tx * sql . Tx ) * Queries {
169
- return &Queries {
170
- db: tx,
133
+ func main() {
134
+ if err := run(); err != nil {
135
+ log.Fatal(err)
171
136
}
172
137
}
173
138
```
139
+
140
+ To make that possible, sqlc generates readable, ** idiomatic** Go code that you
141
+ otherwise would have had to write yourself. Take a look in ` tutorial/query.sql.go ` .
0 commit comments