From 13a86d8560b313728a84ad7b067a151b3b1b6c7f Mon Sep 17 00:00:00 2001 From: Stephen Afam-Osemene Date: Wed, 3 Jan 2024 01:16:22 +0000 Subject: [PATCH] Update changelog --- CHANGELOG.md | 196 +++++++++++------- website/docs/code-generation/configuration.md | 3 +- website/docs/query-builder/operators.md | 41 ++-- website/docs/query-builder/starters.md | 127 ++++++------ 4 files changed, 204 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad7cf8c..03c6efdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,222 +5,258 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v0.23.0] - 2024-01-03 + +### Added + +- Add `bob.Cache()` which saves the built SQL and args to prevent rebuilding the same query multiple times. +- Add `As()` starter to alias expressions +- Add `OP()` builder method for using custom operators +- Add `table.InsertQ(ctx, db)` now includes the insert columns from the table model. +- It is now possible to configure additional constraints for code generation. +- Add `um.SetCol()` which maintains the old behavior of `um.Set()`. +- Generate additional `Expressions()` method for Setters to make it easier to use them in `um.Set()` or `im.Set()`. + +### Changed + +- Aliases configuration for code generation no longer has a top level `table` key +- When configuring relationships, `from_unique`, `to_unique`, `key_nullable` can no longer be configured. They are now inferred from the database. +- When configuring relationships, `to_key` has been changed to `modify` and should be set to `from`, `to` or `""` to indicate which side of the relationship to modify. + If left empty, Bob will try to guess which side to modify based on the presence of primary keys and unique columns. +- `RelWhere.Value` is now `RelWhere.SQLValue` +- Change CONFLICT/DUPLICATE KEY UPDATE to use mods instead of a chainable methods. +- Change `um.Set()` to take a list of expressions. +- Rename Setter method from `Insert()` to `InsertMod()` to avoid confusion. + +### Fixed + +- Prevent generating duplicate relationships for many-to-many self-join relationships +- Correctly use table alias in generated relationship join mods +- Fix an issue where CTEs were encased in double parenthesis +- Fix invalid SQL generated when doing `JOIN USING` +- Correctly include "AS" in function query if alias is set +- Setters are also generated for tables that have relationships, even if they have no primary key +- Column aliases in CTEs are now correctly included in the final query +- Fix several issues with generating code for multi-sided relationships +- Fix an issue where loading many-to-many relationships cause no columns to be selected unless specified +- Fix an issue where many-to-many relationships would not be able to use nested loaders + ## [v0.22.0] - 2023-08-18 ### Added -* Expand expressions when used in Raw (thanks @RangelReale) -* Add `InsertQ`, `UpdateQ`, and `DeleteQ` methods to Table models to start INSERT, UPDATE and DELETE queries respectively. -* Allow column comment for replacement matching (thanks @jroenf) -* Add table query hooks to modify model queries -* Include `WhereOr` and `WhereAnd` to make it easier to combine multiple generated where clauses -* Print a warning if a replacement rule did not find a match (thanks @jacobmolby) +- Expand expressions when used in Raw (thanks @RangelReale) +- Add `InsertQ`, `UpdateQ`, and `DeleteQ` methods to Table models to start INSERT, UPDATE and DELETE queries respectively. +- Allow column comment for replacement matching (thanks @jroenf) +- Add table query hooks to modify model queries +- Include `WhereOr` and `WhereAnd` to make it easier to combine multiple generated where clauses +- Print a warning if a replacement rule did not find a match (thanks @jacobmolby) ### Changed -* Export generated factory.Factory struct -* Allow Limit and Offset to be used as Arguments in PostgreSQL (thanks @RangelReale) -* Make model hooks take slices not single objects -* Return rows affected from `Exec()` method of view queries instead of `sql.Result` -* Chain comparison methods now take an `Expression` instead of `any` -* Table models now require the types to implement `orm.Table` and `orm.Setter` interfaces. +- Export generated factory.Factory struct +- Allow Limit and Offset to be used as Arguments in PostgreSQL (thanks @RangelReale) +- Make model hooks take slices not single objects +- Return rows affected from `Exec()` method of view queries instead of `sql.Result` +- Chain comparison methods now take an `Expression` instead of `any` +- Table models now require the types to implement `orm.Table` and `orm.Setter` interfaces. ### Removed -* Remove UpdateAll and DeleteAll methods on the Table models. +- Remove UpdateAll and DeleteAll methods on the Table models. ### Fixed -* Honor Only and Except in sqlite driver -* Always surround subqueries with parenthesis when used as an expression -* Fix mysql `TablesInfo` method and make sure we don't exclude entire table when targeting columns (thanks @jacobmolby) -* Fix bug in sqlite foreign key and join table detection +- Honor Only and Except in sqlite driver +- Always surround subqueries with parenthesis when used as an expression +- Fix mysql `TablesInfo` method and make sure we don't exclude entire table when targeting columns (thanks @jacobmolby) +- Fix bug in sqlite foreign key and join table detection ## [v0.21.1] - 2023-05-22 ### Fixed -* Fix `Upsert` and `UpsertAll` methods of `mysql.Table` +- Fix `Upsert` and `UpsertAll` methods of `mysql.Table` ## [v0.21.0] - 2023-05-09 ### Changed -* Force uniqueness of relationship names in `psql` driver +- Force uniqueness of relationship names in `psql` driver ### Fixed -* Fix panic when attaching associated relationships -* Make getting a random integer for preloading thread-safe +- Fix panic when attaching associated relationships +- Make getting a random integer for preloading thread-safe ## [v0.20.6] - 2023-04-25 ### Fixed -* Check all members when loading relationships +- Check all members when loading relationships ## [v0.20.5] - 2023-04-14 ### Fixed -* Fix panic in Insert/Attach Relationship loop +- Fix panic in Insert/Attach Relationship loop ## [v0.20.4] - 2023-04-07 ### Fixed -* Replace `huandu/go-clone` with `qdm12/reprint` +- Replace `huandu/go-clone` with `qdm12/reprint` ## [v0.20.3] - 2023-04-06 ### Fixed -* Fix cloning bug by replacing `jinzhu/copier` with `huandu/go-clone` +- Fix cloning bug by replacing `jinzhu/copier` with `huandu/go-clone` ## [v0.20.2] - 2023-04-05 ### Fixed -* Account for windows when calculating models module path +- Account for windows when calculating models module path ## [v0.20.1] - 2023-04-04 ### Fixed -* Update the generated code to use `github.com/gofrs/uuid/v5` -* Fix bug where auto-increment columns were marked as generated in the SQLite driver +- Update the generated code to use `github.com/gofrs/uuid/v5` +- Fix bug where auto-increment columns were marked as generated in the SQLite driver ## [v0.20.0] - 2023-04-03 ### Added -* Add the `PreloadWhere` preload mod to filter what relation should be preloaded. -* `ViewQuery` now embeds `bob.BaseQuery` giving it additional methods like `Apply` and `Build` -* Add plugin support. Currently 3 plugin hooks are provided. `PlugState`, `PlugDBInfo` and `PlugTemplateData`. +- Add the `PreloadWhere` preload mod to filter what relation should be preloaded. +- `ViewQuery` now embeds `bob.BaseQuery` giving it additional methods like `Apply` and `Build` +- Add plugin support. Currently 3 plugin hooks are provided. `PlugState`, `PlugDBInfo` and `PlugTemplateData`. ### Changed -* Make `View.Name()` return a dialect-specific expression -* Improve `Debug` helpers. - * `Debug` writes query output to stdout - * `DebugToWriter` writes the query output to any `io.Writer` with a fallback to stdout. - * `DebugToPrinter` prints the query with a given `bob.DebugPrinter`. Also falls back to stdout. -* Rename `OnlyColumns` to `PreloadOnly` and `ExceptColumns` to `PreloadExcept` to be more consistent with the newly added `PreloadWhere`. -* `JoinChain.On` now takes Expressions instead of `any`. -* `JoinChain.Using` now takes strings instead of `any`. -* Export `gen.TemplateData` +- Make `View.Name()` return a dialect-specific expression +- Improve `Debug` helpers. + - `Debug` writes query output to stdout + - `DebugToWriter` writes the query output to any `io.Writer` with a fallback to stdout. + - `DebugToPrinter` prints the query with a given `bob.DebugPrinter`. Also falls back to stdout. +- Rename `OnlyColumns` to `PreloadOnly` and `ExceptColumns` to `PreloadExcept` to be more consistent with the newly added `PreloadWhere`. +- `JoinChain.On` now takes Expressions instead of `any`. +- `JoinChain.Using` now takes strings instead of `any`. +- Export `gen.TemplateData` ### Removed -* Remove `ILIKE` operator from MySQL since it is not supported. -* Removed `Destination()` method in driver interface. -* Removed `PackageName()` method in driver interface. +- Remove `ILIKE` operator from MySQL since it is not supported. +- Removed `Destination()` method in driver interface. +- Removed `PackageName()` method in driver interface. ### Fixed -* Account for possible clashes between column and relationship alias -* Make `Preload` mods work the same way as other query mods -* Avoid overwriting manually flipped relationships. -* Account for potentially null relationship in Load methods +- Account for possible clashes between column and relationship alias +- Make `Preload` mods work the same way as other query mods +- Avoid overwriting manually flipped relationships. +- Account for potentially null relationship in Load methods ## [v0.19.1] - 2023-03-21 ### Fixed -* Fix `On` method for JoinChain in `mysql` and `sqlite` +- Fix `On` method for JoinChain in `mysql` and `sqlite` ## [v0.19.0] - 2023-03-19 ### Added -* Add `LIKE` and `ILIKE` operators -* Print generated files -* Add `no_reverse` option for user-configured relationships +- Add `LIKE` and `ILIKE` operators +- Print generated files +- Add `no_reverse` option for user-configured relationships ### Changed -* Move common parts of loading to shared internal package +- Move common parts of loading to shared internal package ### Fixed -* Fix generated joins for multi-sided relationships +- Fix generated joins for multi-sided relationships ## [v0.18.2] - 2023-03-18 ### Fixed -* Account for relationships with tables that do not have a primary key in models and factories -* Properly extract preloaders nested in `mods.QueryMods` -* Fix bug in preloading with multiple sides -* Fix issue with multi-sided relationships that include views +- Account for relationships with tables that do not have a primary key in models and factories +- Properly extract preloaders nested in `mods.QueryMods` +- Fix bug in preloading with multiple sides +- Fix issue with multi-sided relationships that include views ## [v0.18.1] - 2023-03-16 ### Fixed -* Make self-referencing foreign keys work -* Tweak factory types to make collisions even less likely +- Make self-referencing foreign keys work +- Tweak factory types to make collisions even less likely ## [v0.18.0] - 2023-03-12 ### Changed -* Comparison methods now require an expression (`bob.Expression`) +- Comparison methods now require an expression (`bob.Expression`) ### Removed -* No more `X` builder start function -* No more `P` builder method +- No more `X` builder start function +- No more `P` builder method ## [v0.17.3] - 2023-03-11 ### Fixed -* Fix bug with args in table updates -* Fix some typos in documentation (thanks @leonardtan13) +- Fix bug with args in table updates +- Fix some typos in documentation (thanks @leonardtan13) ## [v0.17.2] - 2023-03-09 ### Fixed -* Fix a bug when multiple multi-column foreign keys exist -* Multiple internal changes to the generator to make it easier to write a custom entrypoint -* More robust testing of code generation -* json, yaml and toml struct tags are no longer autogenerated but can still be added though configuration +- Fix a bug when multiple multi-column foreign keys exist +- Multiple internal changes to the generator to make it easier to write a custom entrypoint +- More robust testing of code generation +- json, yaml and toml struct tags are no longer autogenerated but can still be added though configuration ## [v0.17.1] - 2023-03-08 ### Fixed -* Fixed a bug in sqlite `join_helper` block which causes an error during code generation +- Fixed a bug in sqlite `join_helper` block which causes an error during code generation ## [v0.17.0] - 2023-03-07 ### Added -* Now, Bob will generate join mods for model relationships such as: +- Now, Bob will generate join mods for model relationships such as: - ```go - models.SelectJoin(ctx).Users.InnerJoin.Posts - ``` + ```go + models.SelectJoin(ctx).Users.InnerJoin.Posts + ``` ### Fixed -* Fixed an issue with ON DUPLICATE KEY UPDATE (#14) +- Fixed an issue with ON DUPLICATE KEY UPDATE (#14) ## [v0.16.0] - 2023-03-06 ### Added -* Add a code generation driver for Atlas -* Add JOIN mods for MySQL update queries +- Add a code generation driver for Atlas +- Add JOIN mods for MySQL update queries ### Changed -* Change how the `um.Set` update mod works to allow more query building +- Change how the `um.Set` update mod works to allow more query building ### Fixed -* Fix upserts in all 3 dialects to ignore the update columns when generating the insert column set -* Return early in InsertMany/UpsertMany/UpdateMany/DeleteMany if 0 rows to act on -* Report error if non-default codegen config file is misssing +- Fix upserts in all 3 dialects to ignore the update columns when generating the insert column set +- Return early in InsertMany/UpsertMany/UpdateMany/DeleteMany if 0 rows to act on +- Report error if non-default codegen config file is misssing diff --git a/website/docs/code-generation/configuration.md b/website/docs/code-generation/configuration.md index 598e23ca..09afe78c 100644 --- a/website/docs/code-generation/configuration.md +++ b/website/docs/code-generation/configuration.md @@ -197,7 +197,8 @@ relationships: columns: [[id, team_id]] to_where: - column: "verified" - value: "true" + sql_value: "true" + go_value: "true" ``` ## Inflections diff --git a/website/docs/query-builder/operators.md b/website/docs/query-builder/operators.md index 8e5ddf69..09e427fa 100644 --- a/website/docs/query-builder/operators.md +++ b/website/docs/query-builder/operators.md @@ -1,35 +1,34 @@ --- - sidebar_position: 5 description: Common operators accross dialects - --- # Operators Operators are methods on the dialect's `Expression`. There are a number of common operators shared by all supported dialects: -* `IsNull()`: X IS NULL -* `IsNotNull()`: X IS NOT NULL -* `IsDistinctFrom(y any)`: X IS DISTINCT FROM Y -* `IsNotDistinctFrom(y any)`: X IS NOT DISTINCT FROM Y -* `Minus(y any)`: X - Y -* `EQ(y any)`: X = Y -* `NE(y any)`: X \<\> Y -* `LT(y any)`: X \< Y -* `LTE(y any)`: X \<= Y -* `GT(y any)`: X \> Y -* `GTE(y any)`: X >= Y -* `In(...any)`: X IN (y, z) -* `NotIn(...any)`: X NOT IN (y, z) -* `Or(y any)`: X OR Y -* `And(y any)`: X AND Y -* `Concat(y any)`: X || Y -* `Between(y, z any)`: X BETWEEN Y AND Z -* `NotBetween(y, z any)`: X NOT BETWEEN Y AND Z +- `IsNull()`: X IS NULL +- `IsNotNull()`: X IS NOT NULL +- `IsDistinctFrom(y any)`: X IS DISTINCT FROM Y +- `IsNotDistinctFrom(y any)`: X IS NOT DISTINCT FROM Y +- `Minus(y any)`: X - Y +- `OP(op string, y any)`: X op Y -- for custom operators +- `EQ(y any)`: X = Y +- `NE(y any)`: X \<\> Y +- `LT(y any)`: X \< Y +- `LTE(y any)`: X \<= Y +- `GT(y any)`: X \> Y +- `GTE(y any)`: X >= Y +- `In(...any)`: X IN (y, z) +- `NotIn(...any)`: X NOT IN (y, z) +- `Or(y any)`: X OR Y +- `And(y any)`: X AND Y +- `Concat(y any)`: X || Y +- `Between(y, z any)`: X BETWEEN Y AND Z +- `NotBetween(y, z any)`: X NOT BETWEEN Y AND Z The following expressions cannot be chained and are expected to be used at the end of a chain -* `As(alias string)`: X as "alias". Used for aliasing column names +- `As(alias string)`: X as "alias". Used for aliasing column names See dialect documentation for extra operators diff --git a/website/docs/query-builder/starters.md b/website/docs/query-builder/starters.md index bf58ff46..0b71e385 100644 --- a/website/docs/query-builder/starters.md +++ b/website/docs/query-builder/starters.md @@ -1,93 +1,98 @@ --- - sidebar_position: 4.5 description: Common starters accross dialects - --- # Starters There are a number of common starter functions shared by all supported dialects: -* `S(string)`: Create a single quoted string literal. +- `S(string)`: Create a single quoted string literal. + + ```go + // SQL: 'a string' + psql.S("a string") + ``` + +- `F(name string, args ...any)`: A function call. Takes a name and the arguments. - ```go - // SQL: 'a string' - psql.S("a string") - ``` + ```go + // SQL: generate_series(1, 3) + psql.F("generate_series", 1, 3) + ``` -* `F(name string, args ...any)`: A function call. Takes a name and the arguments. +- `Not(Expression)`: Creates a `NOT expr` expression. - ```go - // SQL: generate_series(1, 3) - psql.F("generate_series", 1, 3) - ``` + ```go + // SQL: Not a = b + psql.Not("a = b") + ``` -* `Not(Expression)`: Creates a `NOT expr` expression. +- `Or(...Expression)`: Joins multiple expressions with "OR". - ```go - // SQL: Not a = b - psql.Not("a = b") - ``` + ```go + // SQL: a OR b OR c + psql.Or("a", "b", "c") + ``` -* `OR(...Expression)`: Joins multiple expressions with "OR". +- `And(...Expression)`: Joins multiple expressions with "AND" - ```go - // SQL: a OR b OR c - psql.Or("a", "b", "c") - ``` + ```go + // SQL: a AND b AND c + psql.And("a", "b", "c") + ``` -* `AND(...Expression)`: Joins multiple expressions with "AND" +- `Arg(...any)`: One or more arguments. These are replaced with placeholders in the query and the args returned. - ```go - // SQL: a AND b AND c - psql.And("a", "b", "c") - ``` + ```go + // SQL: $1, $2, $3 + // Args: 'a', 'b', 'c' + psql.Arg("a", "b", "c") + ``` -* `Arg(...any)`: One or more arguments. These are replaced with placeholders in the query and the args returned. +- `ArgGroup(...any)`: Similar to `Arg` but wraps the given set of arguments in parentheses. - ```go - // SQL: $1, $2, $3 - // Args: 'a', 'b', 'c' - psql.Arg("a", "b", "c") - ``` + ```go + // SQL: ($1, $2), ($3, $4) + // Args: ('a', 'b', 'c', 'd') + psql.Group(psql.ArgGroup("a", "b"), psql.ArgGroup("c", "d")) + ``` -* `ArgGroup(...any)`: Similar to `Arg` but wraps the given set of arguments in parentheses. +- `Placeholders(uint)`: Inserts a `count` of placeholders without any specific value yet. Useful for compiling reusable queries. - ```go - // SQL: ($1, $2), ($3, $4) - // Args: ('a', 'b', 'c', 'd') - psql.Group(psql.ArgGroup("a", "b"), psql.ArgGroup("c", "d")) - ``` + ```go + // SQL: $1, $2, $3 + // Args: nil, nil, nil + psql.Placeholders(3) + ``` -* `Placeholders(uint)`: Inserts a `count` of placeholders without any specific value yet. Useful for compiling reusable queries. +- `Group(...Expression)`: To easily group a number of expressions. Wraps them in parentheses **AND** seperates them with commas. - ```go - // SQL: $1, $2, $3 - // Args: nil, nil, nil - psql.Placeholders(3) - ``` + ```go + // SQL: (a, b, c) + psql.Group("a", "b", "c") + ``` -* `Group(...Expression)`: To easily group a number of expressions. Wraps them in parentheses **AND** seperates them with commas. +- `Quote(...string)`: For quoting. [See details](./quotes) - ```go - // SQL: (a, b, c) - psql.Group("a", "b", "c") - ``` + ```go + // SQL: "table"."column + psql.Quote("table", "column") + ``` -* `Quote(...string)`: For quoting. [See details](./quotes) +- `Raw(clause string, args ...any)`: For inserting a raw statement somewhere. To keep it dialect agnostic, placeholders should be inserted with `?` and a literal question mark can be escaped with a backslash `\?`. - ```go - // SQL: "table"."column - psql.Quote("table", "column") - ``` + ```go + // SQL: WHERE a = $1 + // Args: 'something' + psql.Raw("WHERE a = ?", "something") + ``` -* `Raw(clause string, args ...any)`: For inserting a raw statement somewhere. To keep it dialect agnostic, placeholders should be inserted with `?` and a literal question mark can be escaped with a backslash `\?`. +- `As(e Expression, alias string)`: For aliasing expressions. - ```go - // SQL: WHERE a = $1 - // Args: 'something' - psql.Raw("WHERE a = ?", "something") - ``` + ```go + // SQL: pilots as "p" + psql.As("pilots", "p") + ``` See dialect documentation for extra starters