Skip to content

Commit b8949b4

Browse files
author
Roman A. Grigorovich
committed
feat: add Unqualified method to return columns without table alias/prefix
1 parent 8437224 commit b8949b4

File tree

2 files changed

+110
-101
lines changed

2 files changed

+110
-101
lines changed

CHANGELOG.md

Lines changed: 94 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Added `Unqualified()` method to generated column structures that returns columns without table alias/prefix. (thanks @atzedus)
1213
- Added `PreloadCount` and `ThenLoadCount` to generate code for preloading and then loading counts for relationships. (thanks @jacobmolby)
1314
- MySQL support for insert queries executing loaders (e.g., `InsertThenLoad`, `InsertThenLoadCount`). (thanks @jacobmolby)
1415
- Added overwritable hooks that are run before the exec or scanning test of generated queries. This allows seeding data before the test runs.
@@ -88,20 +89,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8889
### Added
8990

9091
- Made code generation modular by relying on built-in plugins that can be enabled or disabled in the configuration.
91-
- `dbinfo`: Generates code for information about each database. Schemas, tables, columns, indexes, primary keys, foreign keys, unique constraints, and check constraints.
92-
- `enums`: Generates code for enums in a separate package, if there are any present.
93-
- `models`: Generates code for models. Depends on `enums`.
94-
- `factory`: Generates code for factories. Depends on `models`.
95-
- `dberrors`: Generates code for unique constraint errors. Depends on `models`.
96-
- `where`: Generates type-safe code for `WHERE` clauses in queries. Depends on `models`.
97-
- `loaders`: Adds templates to the `models` package to generate code for loaders e.g `models.SelectThenLoad.Table.Rel()`.
98-
- `joins`: Adds templates to the `models` package to generate code for joins e.g `models.SelectJoin.Table.LeftJoin.Rel`.
99-
- `queries`: Generates code for queries.
92+
- `dbinfo`: Generates code for information about each database. Schemas, tables, columns, indexes, primary keys, foreign keys, unique constraints, and check constraints.
93+
- `enums`: Generates code for enums in a separate package, if there are any present.
94+
- `models`: Generates code for models. Depends on `enums`.
95+
- `factory`: Generates code for factories. Depends on `models`.
96+
- `dberrors`: Generates code for unique constraint errors. Depends on `models`.
97+
- `where`: Generates type-safe code for `WHERE` clauses in queries. Depends on `models`.
98+
- `loaders`: Adds templates to the `models` package to generate code for loaders e.g `models.SelectThenLoad.Table.Rel()`.
99+
- `joins`: Adds templates to the `models` package to generate code for joins e.g `models.SelectJoin.Table.LeftJoin.Rel`.
100+
- `queries`: Generates code for queries.
100101
- Added new `types.Uint64` type that sends values to the database as strings. This is necessary because using `uint64` directly can cause an overflow if the value exceeds the maximum value of an `int64`. This is a limitation imposed by `database/sql/driver.Valuer` interface.
101102
- Added support for `pgvector` types during code generation.
102-
- `pgvector.Vector`
103-
- `pgvector.HalfVector`
104-
- `pgvector.SparseVector`
103+
- `pgvector.Vector`
104+
- `pgvector.HalfVector`
105+
- `pgvector.SparseVector`
105106

106107
### Changed
107108

@@ -141,8 +142,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
141142
- Added the `type_system` configuration option to determine how to generate null and optional values in the generated code.
142143
Possible options: `github.com/aarondl/opt`, `github.com/aarondl/opt/null` or `database/sql`. The default value is `github.com/aarondl/opt`.
143144
- When generating code for queries, The `All` method of the generated query will return a struct with nested fields instead of a flat struct.
144-
- columns with dots (`.`) are assumed to be a `to-many` nested field.
145-
- columns with double underscores (`__`) are assumed to be a `to-one` nested field.
145+
- columns with dots (`.`) are assumed to be a `to-many` nested field.
146+
- columns with double underscores (`__`) are assumed to be a `to-one` nested field.
146147
- Implement `--prefix` annotation in queries for `bobgen-psql`.
147148
- Add FromExisting**Rel** method to factories to create a template from an existing model. (thanks @dutow)
148149
- Add WithExisting**Rel** to factory mods to attach an existing model as a relationship. (thanks @dutow)
@@ -216,8 +217,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
216217
- Removed the `StdInterface` interface as it is unnecessary.
217218
- Remove redundant `orm.Model` interface.
218219
- Remove dependence on `github.com/aarondl/opt` in generated code.
219-
- Nullable values are now wrapped `database/sql.Null` with instead of `github.com/aarondl/opt/null.Val`.
220-
- Optional values are now represented as pointers instead of `github.com/aarondl/opt/omit.Val[T]`.
220+
- Nullable values are now wrapped `database/sql.Null` with instead of `github.com/aarondl/opt/null.Val`.
221+
- Optional values are now represented as pointers instead of `github.com/aarondl/opt/omit.Val[T]`.
221222
- Removed `in_generated_package` type configuration option. This was limited and could only indicate that the type is in the models package.
222223
Instead the full import path can now be used in the `imports` configuration option, and if it is in the same package as the generated code, the prefix will be automatically removed.
223224

@@ -239,15 +240,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
239240

240241
- Loaders are now generated as singular instead of plural. This feels more natural when using them in code.
241242

242-
```go
243-
// Before
244-
models.Preload.Users.Pilots()
245-
models.SelectThenLoad.Users.Pilots()
243+
```go
244+
// Before
245+
models.Preload.Users.Pilots()
246+
models.SelectThenLoad.Users.Pilots()
246247

247-
// After
248-
models.Preload.User.Pilots()
249-
models.SelectThenLoad.User.Pilot()
250-
```
248+
// After
249+
models.Preload.User.Pilots()
250+
models.SelectThenLoad.User.Pilot()
251+
```
251252

252253
## [v0.35.1] - 2025-05-27
253254

@@ -288,13 +289,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
288289
- Generated tests that required a database connection no longer create a new connection for each test. Instead it depends on a `testDB` connection that the user has to provide.
289290
- In the generated models, relationships for `ModelSlice` are now loaded using arrays to reduce the number of parameter in the query.
290291

291-
```sql
292-
-- Before
293-
SELECT * FROM pilots WHERE jet_id IN ($1, $2, $3, ...); -- Parameters increase with the number of pilots
292+
```sql
293+
-- Before
294+
SELECT * FROM pilots WHERE jet_id IN ($1, $2, $3, ...); -- Parameters increase with the number of pilots
294295
295-
-- After
296-
SELECT * FROM pilots WHERE jet_id IN (SELECT unnest(CAST($1 AS integer[])); -- Parameters are always 1
297-
```
296+
-- After
297+
SELECT * FROM pilots WHERE jet_id IN (SELECT unnest(CAST($1 AS integer[])); -- Parameters are always 1
298+
```
298299

299300
- In the generated model code, `Preload` is now a struct instead of multiple standaalone functions.
300301
It is now used like `Preload.User.Pilots()`, instead of `PreloadUserPilots()`.
@@ -465,9 +466,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
465466
- `UNION`, `INTERSECT` and `EXCEPT` mods now append to the query instead of replacing it.
466467
- Generated files now end with `.bob.go` instead of `.go` and are always cleaned up before generating new files. Singleton templates are now required to have a `.bob.go.tpl` extension.
467468
- The expected structure for templates have been changed:
468-
- Previously, singleton templates should be kept in a `singleton` folder. Now, any template not inside a folder is considered a singleton template.
469-
- Previoulsy, templates in the root folder are merged and run for each table. Now, this will happen to templates in the `table/` folder.
470-
- Previoulsy, the entire file tree and every subdirectory is walked to find templates. Now only templates in the root folder and the `table/` folder are considered.
469+
- Previously, singleton templates should be kept in a `singleton` folder. Now, any template not inside a folder is considered a singleton template.
470+
- Previoulsy, templates in the root folder are merged and run for each table. Now, this will happen to templates in the `table/` folder.
471+
- Previoulsy, the entire file tree and every subdirectory is walked to find templates. Now only templates in the root folder and the `table/` folder are considered.
471472
- Change `From` in `clause.Window` to `BasedOn` to avoid confusion with `FromPreceding` and `FromFollowing`. Also change `SetFrom` to `SetBasedOn`.
472473
- Embed `clause.OrderBy` in `clause.Window` to make it possible to reuse `OrderBy` mods in window definitions.
473474
- Change the `Definition` field in `clause.NamedWindow` from `any` to `clause.Window` for extra type safety.
@@ -522,32 +523,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
522523

523524
- `context.Context` is now passed to `Query.WriteQuery()` and `Expression.WriteSQL()` methods. This allows for more control over how the query is built and executed.
524525
This change made is possible to delete some hacks and simplify the codebase.
525-
- The `Name()` and `NameAs()` methods of Views/Tables no longer need the context argument since the context will be passed when writing the expression. The API then becomes cleaner.
526-
- Preloading mods no longer need to store a context internally. `SetLoadContext()` and `GetLoadContext()` have removed.
527-
- The `ToExpr` field in `orm.RelSide` which was used for preloading is no longer needed and has been removed.
526+
- The `Name()` and `NameAs()` methods of Views/Tables no longer need the context argument since the context will be passed when writing the expression. The API then becomes cleaner.
527+
- Preloading mods no longer need to store a context internally. `SetLoadContext()` and `GetLoadContext()` have removed.
528+
- The `ToExpr` field in `orm.RelSide` which was used for preloading is no longer needed and has been removed.
528529
- Moved `orm.Hooks` to `bob.Hooks` since it should not be limited to only ORM queries.
529530
- Moved `mods.QueryModFunc` to `bob.ModFunc` since it should be available to all packages.
530531
- The mod capability for `orm.Setter` is now reversed. It should now be a mod for Insert and have a method that returns a mod for Update.
531532
This makes more sense since one would at most use one setter during updates, but can use multiple setters in a bulk insert.
532533
- `table.InsertQ` has been renamed to `table.Insert`. The old implementation of `Insert` has been removed.
533534
The same functionality can be achieved in the following way:
534535

535-
```go
536-
//----------------------------------------------
537-
// OLD WAY
538-
//----------------------------------------------
539-
user, err := models.Users.Insert(ctx, db, setter) // insert one
540-
users, err := models.Users.InsertMany(ctx, db, setters...) // insert many
541-
542-
//----------------------------------------------
543-
// NEW WAY
544-
//----------------------------------------------
545-
user, err := models.Users.Insert(setter).One(ctx, db) // insert one
546-
users, err := models.Users.Insert(setters[0], setters[1]).All(ctx, db) // insert many
547-
548-
// For cases where you already have a slice of setters and you want to pass them all, you can use `bob.ToMods`
549-
users, err := models.Users.Insert(bob.ToMods(setters)).All(ctx, db) // insert many
550-
```
536+
```go
537+
//----------------------------------------------
538+
// OLD WAY
539+
//----------------------------------------------
540+
user, err := models.Users.Insert(ctx, db, setter) // insert one
541+
users, err := models.Users.InsertMany(ctx, db, setters...) // insert many
542+
543+
//----------------------------------------------
544+
// NEW WAY
545+
//----------------------------------------------
546+
user, err := models.Users.Insert(setter).One(ctx, db) // insert one
547+
users, err := models.Users.Insert(setters[0], setters[1]).All(ctx, db) // insert many
548+
549+
// For cases where you already have a slice of setters and you want to pass them all, you can use `bob.ToMods`
550+
users, err := models.Users.Insert(bob.ToMods(setters)).All(ctx, db) // insert many
551+
```
551552

552553
- `table.UpdateQ` has been renamed to `table.Update`. The old implementation of `Update` has been removed.
553554
The same functionality can be achieved by using `model.Update()` or `modelSlice.UpdateAll()`.
@@ -557,12 +558,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
557558
This is because it is not possible to know before executing the queries exactly how many setters are being used since additional rows can be inserted by applying another setter as a mod.
558559
- `bob.Cache()` now requires an `Executor`. This is used to run any query hooks.
559560
- `bob.Prepare()` now requires a type parameter to be used to bind named arguments. The type can either be:
560-
- A struct with fields that match the named arguments in the query
561-
- A map with string keys. When supplied, the values in the map will be used to bind the named arguments in the query.
562-
- When there is only a single named argument, one of the following can be used:
563-
- A primitive type (int, bool, string, etc)
564-
- `time.Time`
565-
- Any type that implements `driver.Valuer`.
561+
- A struct with fields that match the named arguments in the query
562+
- A map with string keys. When supplied, the values in the map will be used to bind the named arguments in the query.
563+
- When there is only a single named argument, one of the following can be used:
564+
- A primitive type (int, bool, string, etc)
565+
- `time.Time`
566+
- Any type that implements `driver.Valuer`.
566567
- `Index` columns are no longer just strings, but are a struct to include more information such as the sort order.
567568

568569
### Removed
@@ -641,58 +642,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
641642
- Add PreloadAs PreloadOption to override the join alias when preloading a relationship with a left join. (thanks @daddz)
642643
- Add `AliasedAs()` method to `tableColumns` and `tableWhere` types to use a custom alias.
643644
- Add `AliasedAs()` method to generated relationship join mods. This is avaible in two places:
644-
- one to change the alias of the table being queried
645+
- one to change the alias of the table being queried
645646

646-
```go
647-
models.SelectJoins.Jets.AliasedAs("j").InnerJoin.Pilots(ctx)
648-
```
647+
```go
648+
models.SelectJoins.Jets.AliasedAs("j").InnerJoin.Pilots(ctx)
649+
```
649650

650-
- and the other to change the alias of the relationship.
651+
- and the other to change the alias of the relationship.
651652

652-
```go
653-
models.SelectJoins.Jets.InnerJoin.Pilots(ctx).AliasedAs("p")
654-
```
653+
```go
654+
models.SelectJoins.Jets.InnerJoin.Pilots(ctx).AliasedAs("p")
655+
```
655656

656657
- Add `fm` mods to all supported dialects (psql, mysql and sqlite). These are mods for functions and are used to modify the function call. For example:
657658

658-
```go
659-
// import "github.com/stephenafamo/bob/dialect/psql/fm"
660-
psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done"))))
661-
```
659+
```go
660+
// import "github.com/stephenafamo/bob/dialect/psql/fm"
661+
psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done"))))
662+
```
662663

663664
- Add `MustCreate`, `MustCreateMany`, `CreateOrFail` and `CreateManyOrFail` methods to generated factory Templates
664665

665666
### Changed
666667

667668
- Change the function call point for generated relationship join mods. This reduces the amount of allocations and only does the work for the relationship being used.
668669

669-
```go
670-
// Before
671-
models.SelectJoins(ctx).Jets.InnerJoin.Pilots
672-
// After
673-
models.SelectJoins.Jets.InnerJoin.Pilots(ctx)
674-
```
670+
```go
671+
// Before
672+
models.SelectJoins(ctx).Jets.InnerJoin.Pilots
673+
// After
674+
models.SelectJoins.Jets.InnerJoin.Pilots(ctx)
675+
```
675676

676677
- Changed the `Count()` function on `Views` to clone the query instead of changing the existing one. This makes queries reusable and the `Count()` function to behave as one would expect.
677678

678-
```go
679-
// This now works as expected
680-
query := models.Jets.Query(ctx, db, /** list of various mods **/)
681-
count, err := query.Count()
682-
items, err := query.All()
683-
```
679+
```go
680+
// This now works as expected
681+
query := models.Jets.Query(ctx, db, /** list of various mods **/)
682+
count, err := query.Count()
683+
items, err := query.All()
684+
```
684685

685686
- Changed how functions are modified. Instead of chained methods, the `F()` starter now returns a function which can be called with mods:
686687

687-
```go
688-
// Before
689-
psql.F( "count", "*",).FilterWhere(psql.Quote("status").EQ(psql.S("done"))),
690-
// After
691-
// import "github.com/stephenafamo/bob/dialect/psql/fm"
692-
psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done")))),
693-
```
688+
```go
689+
// Before
690+
psql.F( "count", "*",).FilterWhere(psql.Quote("status").EQ(psql.S("done"))),
691+
// After
692+
// import "github.com/stephenafamo/bob/dialect/psql/fm"
693+
psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done")))),
694+
```
694695

695-
This makes it possible to support more queries.
696+
This makes it possible to support more queries.
696697

697698
- Use `netip.Addr` instead of `netip.Prefix` for Postgres `cidr` type.
698699
- Use `decimal.Decimal` instead of `string` for Postgres `money` type.
@@ -912,9 +913,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
912913

913914
- Make `View.Name()` return a dialect-specific expression
914915
- Improve `Debug` helpers.
915-
- `Debug` writes query output to stdout
916-
- `DebugToWriter` writes the query output to any `io.Writer` with a fallback to stdout.
917-
- `DebugToPrinter` prints the query with a given `bob.DebugPrinter`. Also falls back to stdout.
916+
- `Debug` writes query output to stdout
917+
- `DebugToWriter` writes the query output to any `io.Writer` with a fallback to stdout.
918+
- `DebugToPrinter` prints the query with a given `bob.DebugPrinter`. Also falls back to stdout.
918919
- Rename `OnlyColumns` to `PreloadOnly` and `ExceptColumns` to `PreloadExcept` to be more consistent with the newly added `PreloadWhere`.
919920
- `JoinChain.On` now takes Expressions instead of `any`.
920921
- `JoinChain.Using` now takes strings instead of `any`.

gen/templates/models/table/001_types.go.tpl

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,19 @@ type {{$tAlias.DownSingular}}R struct {
6161

6262
{{$.Importer.Import "github.com/stephenafamo/bob/expr"}}
6363
{{$.Importer.Import (printf "github.com/stephenafamo/bob/dialect/%s" $.Dialect)}}
64-
func build{{$tAlias.UpSingular}}Columns(alias string) {{$tAlias.DownSingular}}Columns {
64+
func build{{$tAlias.UpSingular}}Columns(tableName string) {{$tAlias.DownSingular}}Columns {
65+
columnsExpr := expr.NewColumnsExpr(
66+
{{range $column := $table.Columns -}}{{quote $column.Name}},{{end}}
67+
)
68+
if tableName != "" {
69+
columnsExpr = columnsExpr.WithParent(tableName)
70+
}
6571
return {{$tAlias.DownSingular}}Columns{
66-
ColumnsExpr: expr.NewColumnsExpr(
67-
{{range $column := $table.Columns -}}{{quote $column.Name}},{{end}}
68-
).WithParent({{quote $table.Key}}),
69-
tableAlias: alias,
72+
ColumnsExpr: columnsExpr,
73+
tableAlias: tableName,
7074
{{range $column := $table.Columns -}}
7175
{{- $colAlias := $tAlias.Column $column.Name -}}
72-
{{$colAlias}}: {{$.Dialect}}.Quote(alias, {{quote $column.Name}}),
76+
{{$colAlias}}: {{$.Dialect}}.Quote(tableName, {{quote $column.Name}}),
7377
{{end -}}
7478
}
7579
}
@@ -87,6 +91,10 @@ func (c {{$tAlias.DownSingular}}Columns) Alias() string {
8791
return c.tableAlias
8892
}
8993

90-
func ({{$tAlias.DownSingular}}Columns) AliasedAs(alias string) {{$tAlias.DownSingular}}Columns {
91-
return build{{$tAlias.UpSingular}}Columns(alias)
94+
func ({{$tAlias.DownSingular}}Columns) AliasedAs(tableName string) {{$tAlias.DownSingular}}Columns {
95+
return build{{$tAlias.UpSingular}}Columns(tableName)
96+
}
97+
98+
func (c {{$tAlias.DownSingular}}Columns) Unqualified() {{$tAlias.DownSingular}}Columns {
99+
return build{{$tAlias.UpSingular}}Columns("")
92100
}

0 commit comments

Comments
 (0)