|
1 | 1 | # Changelog
|
2 | 2 | All notable changes to this project will be documented in this file.
|
3 | 3 |
|
| 4 | +## 1.18.0 |
| 5 | +Released 2023-04-27 |
| 6 | + |
| 7 | +### Changes |
| 8 | + |
| 9 | +#### Remote code generation |
| 10 | + |
| 11 | +_Developed by [@andrewmbenton](https://github.com/andrewmbenton)_ |
| 12 | + |
| 13 | +At its core, sqlc is powered by SQL engines, which include parsers, formatters, |
| 14 | +analyzers and more. While our goal is to support each engine on each operating |
| 15 | +system, it's not always possible. For example, the PostgreSQL engine does not |
| 16 | +work on Windows. |
| 17 | + |
| 18 | +To bridge that gap, we're announcing remote code generation, currently in |
| 19 | +private alpha. To join the private alpha, [sign up for the waitlist](https://docs.google.com/forms/d/e/1FAIpQLScDWrGtTgZWKt3mdlF5R2XCX6tL1pMkB4yuZx5yq684tTNN1Q/viewform?usp=sf_link). |
| 20 | + |
| 21 | +To configure remote generation, configure a `cloud` block in `sqlc.json`. |
| 22 | + |
| 23 | +```json |
| 24 | +{ |
| 25 | + "version": "2", |
| 26 | + "cloud": { |
| 27 | + "organization": "<org-id>", |
| 28 | + "project": "<project-id>", |
| 29 | + }, |
| 30 | + ... |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +You'll also need to the `SQLC_AUTH_TOKEN` environment variable. |
| 35 | + |
| 36 | +```bash |
| 37 | +export SQLC_AUTH_TOKEN=<token> |
| 38 | +``` |
| 39 | + |
| 40 | +When the cloud configuration exists, `sqlc generate` will default to remote |
| 41 | +generation. If you'd like to generate code locally, pass the `--no-remote` |
| 42 | +option. |
| 43 | + |
| 44 | + |
| 45 | +```bash |
| 46 | +sqlc generate --no-remote |
| 47 | +``` |
| 48 | + |
| 49 | +Remote generation is off by default and requires an opt-in to use. |
| 50 | + |
| 51 | +#### sqlc.embed |
| 52 | + |
| 53 | +_Developed by [@nickjackson](https://github.com/nickjackson)_ |
| 54 | + |
| 55 | +Embedding allows you to reuse existing model structs in more queries, resulting |
| 56 | +in less manual serilization work. First, imagine we have the following schema |
| 57 | +with students and test scores. |
| 58 | + |
| 59 | + |
| 60 | +```sql |
| 61 | +CREATE TABLE students ( |
| 62 | + id bigserial PRIMARY KEY, |
| 63 | + name text, |
| 64 | + age integer |
| 65 | +) |
| 66 | + |
| 67 | +CREATE TABLE test_scores ( |
| 68 | + student_id bigint, |
| 69 | + score integer, |
| 70 | + grade text |
| 71 | +) |
| 72 | +``` |
| 73 | + |
| 74 | +We want to select the student record and the highest score they got on a test. |
| 75 | +Here's how we'd usually do that: |
| 76 | + |
| 77 | +```sql |
| 78 | +-- name: HighScore :many |
| 79 | +WITH high_scores AS ( |
| 80 | + SELECT student_id, max(score) as high_score |
| 81 | + FROM test_scores |
| 82 | + GROUP BY 1 |
| 83 | +) |
| 84 | +SELECT students.*, high_score::integer |
| 85 | +FROM students |
| 86 | +JOIN high_scores ON high_scores.student_id = students.id; |
| 87 | +``` |
| 88 | + |
| 89 | +When using Go, sqlc will produce a struct like this: |
| 90 | + |
| 91 | +``` |
| 92 | +type HighScoreRow struct { |
| 93 | + ID int64 |
| 94 | + Name sql.NullString |
| 95 | + Age sql.NullInt32 |
| 96 | + HighScore int32 |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +With embedding, the struct will contain a model for the table instead of a |
| 101 | +flattened list of columns. |
| 102 | + |
| 103 | +```sql |
| 104 | +-- name: HighScoreEmbed :many |
| 105 | +WITH high_scores AS ( |
| 106 | + SELECT student_id, max(score) as high_score |
| 107 | + FROM test_scores |
| 108 | + GROUP BY 1 |
| 109 | +) |
| 110 | +SELECT sqlc.embed(students), high_score::integer |
| 111 | +FROM students |
| 112 | +JOIN high_scores ON high_scores.student_id = students.id; |
| 113 | +``` |
| 114 | + |
| 115 | +``` |
| 116 | +type HighScoreRow struct { |
| 117 | + Student Student |
| 118 | + HighScore int32 |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +#### sqlc.slice |
| 123 | + |
| 124 | +_Developed by Paul Cameron and Jille Timmermans_ |
| 125 | + |
| 126 | +The MySQL Go driver does not support passing slices to the IN operator. The |
| 127 | +`sqlc.slice` function generates a dynamic query at runtime with the correct |
| 128 | +number of parameters. |
| 129 | + |
| 130 | +```sql |
| 131 | +/* name: SelectStudents :many */ |
| 132 | +SELECT * FROM students |
| 133 | +WHERE age IN (sqlc.slice("ages")) |
| 134 | +``` |
| 135 | + |
| 136 | +```go |
| 137 | +func (q *Queries) SelectStudents(ctx context.Context, arges []int32) ([]Student, error) { |
| 138 | +``` |
| 139 | +
|
| 140 | +This feature is only supported in MySQL and cannot be used with prepared |
| 141 | +queries. |
| 142 | +
|
| 143 | +#### Batch operation improvements |
| 144 | +
|
| 145 | +When using batches with pgx, the error returned when a batch is closed is |
| 146 | +exported by the generated package. This change allows for cleaner error |
| 147 | +handling using `errors.Is`. |
| 148 | +
|
| 149 | +```go |
| 150 | +errors.Is(err, generated_package.ErrBatchAlreadyClosed) |
| 151 | +``` |
| 152 | +
|
| 153 | +Previously, you would have had to check match on the error message itself. |
| 154 | +
|
| 155 | +``` |
| 156 | +err.Error() == "batch already closed" |
| 157 | +``` |
| 158 | +
|
| 159 | +The generated code for batch operations always lived in `batch.go`. This file |
| 160 | +name can now be configured via the `output_batch_file_name` configuration |
| 161 | +option. |
| 162 | +
|
| 163 | +#### Configurable query parameter limits for Go |
| 164 | +
|
| 165 | +By default, sqlc will limit Go functions to a single parameter. If a query |
| 166 | +includes more than one parameter, the generated method will use an argument |
| 167 | +struct instead of positional arguments. This behavior can now be changed via |
| 168 | +the `query_parameter_limit` configuration option. If set to `0`, every |
| 169 | +genreated method will use a argument struct. |
| 170 | +
|
4 | 171 | ## [1.17.2](https://github.com/kyleconroy/sqlc/releases/tag/1.17.2)
|
5 | 172 | Released 2023-02-22
|
6 | 173 |
|
|
0 commit comments