Added
- Added error constants for matching against both specific and generic unique constraint errors raised by the underlying database driver. (thanks @mbezhanov)
- Added support for regular expressions in the
only
andexcept
table filters. (thanks @mbezhanov) - Added
ContextualMods
which are similar to regular mods but take a context argument. They are applied whenever the query is built.
This makes it cleaner to do certain things, like populating the select columns of a model if none was explicitly added.
The previous way this was done was unreliable since usingq.MustBuild()
would not add the columns whilebob.MustBuild(q)
will add them correctly. modelSlice.UpdateMod()
andmodelSlice.DeleteMod()
are new methods that returns a mod for update and delete queries on a slice of models.
It addsWHERE pk IN (pk1, pk2, pk3, ...)
to the query, and also schedule running the hooks.- Added
bob.ToMods
which a slice of structs that implementbob.Mod[T]
to a Mod. This is useful since Go does not allow using a slice of structs as a slice of an interface the struct implements. - Added
bob.HookableQuery
interface. If a query implements this interface, the methodRunHooks(ctx, exec)
will be called before the query is executed. - Added
bob.HookableType
interface. If a type implements this interface, the methodAfterQueryHook(ctx, exec, bob.QueryType)
will be called after the query is executed.
This is howAfterSeleect/Insert/Update/DeleteHooks
hooks are now implemented. - Added
Type() QueryType
method tobob.Query
to get the type of query it is. Available constants areUnknown, Select, Insert, Update, Delete
. - Postgres and SQLite Update/Delete queries now refresh the models after the query is executed. This is enabled by the
RETURNING
clause, so it is not available in MySQL. - Added the
Case()
starter to all dialects to buildCASE
expressions. (thanks @k4n4ry) - Added
bob.Named()
which is used to add named arguments to the query and bind them later. - Added
bob.BindNamed
which takes an argument (struct, map, or a single value type) to be used to bind named arguments in a query. See changes tobob.Prepare()
for details of which type can be used. - Indexes now include more information such as the type, unique and comment fields.
- Constraints now include a comment field.
- Added
Checks
field to DBConstraints so that drivers can also load check constraints. (not yet supported by the SQLite driver). - Added comments field to Table definitions.
Changed
-
context.Context
is now passed toQuery.WriteQuery()
andExpression.WriteSQL()
methods. This allows for more control over how the query is built and executed.
This change made is possible to delete some hacks and simplify the codebase.- The
Name()
andNameAs()
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. - Preloading mods no longer need to store a context internally.
SetLoadContext()
andGetLoadContext()
have removed. - The
ToExpr
field inorm.RelSide
which was used for preloading is no longer needed and has been removed.
- The
-
Moved
orm.Hooks
tobob.Hooks
since it should not be limited to only ORM queries. -
Moved
mods.QueryModFunc
tobob.ModFunc
since it should be available to all packages. -
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.
This makes more sense since one would at most use one setter during updates, but can use multiple setters in a bulk insert. -
table.InsertQ
has been renamed totable.Insert
. The old implementation ofInsert
has been removed.
The same functionality can be achieved in the following way://---------------------------------------------- // OLD WAY //---------------------------------------------- user, err := models.Users.Insert(ctx, db, setter) // insert one users, err := models.Users.InsertMany(ctx, db, setters...) // insert many //---------------------------------------------- // NEW WAY //---------------------------------------------- user, err := models.Users.Insert(setter).One(ctx, db) // insert one users, err := models.Users.Insert(setters[0], setters[1]).All(ctx, db) // insert many // For cases where you already have a slice of setters and you want to pass them all, you can use `bob.ToMods` users, err := models.Users.Insert(bob.ToMods(setters)).All(ctx, db) // insert many
-
table.UpdateQ
has been renamed totable.Update
. The old implementation ofUpdate
has been removed.
The same functionality can be achieved by usingmodel.Update()
ormodelSlice.UpdateAll()
. -
table.DeleteQ
has been renamed totable.Delete
. The old implementation ofDelete
has been removed.
The same functionality can be achieved by usingmodelSlice.DeleteAll()
or creating anDelete
query usingtable.Delete()
. -
BeforeInsertHooks
now only takes a singleModelSetter
at a time.
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. -
bob.Cache()
now requires anExecutor
. This is used to run any query hooks. -
bob.Prepare()
now requires a type parameter to be used to bind named arguments. The type can either be:- A struct with fields that match the named arguments in the query
- A map with string keys. When supplied, the values in the map will be used to bind the named arguments in the query.
- When there is only a single named argument, one of the following can be used:
- A primitive type (int, bool, string, etc)
time.Time
- Any type that implements
driver.Valuer
.
-
Index
columns are no longer just strings, but are a struct to include more information such as the sort order.
Removed
- Remove MS SQL artifacts. (thanks @mbezhanov)
- Remove redundant type parameter from
bob.Load
. - Removed
Before/AfterUpsertMods
. Upserts are really just inserts with a conflict clause and should be treated as such. - Removed
Insert/InsertMany/Upsert/UpsertMany
methods fromorm.Table
since they are not needed.
It is possible to do the same thing, with similar effor using the theInsertQ
method (which is now renamed toInsert
). - Remove
Update
andDelete
methods fromorm.Table
since they are not needed.
It is possible to do the same thing, with similar effor using the theUpdateQ
andDeleteQ
methods (which are now renamed toUpdate
andDelete
). context.Context
andbob.Executor
are no longer passed when creating a Table/ViewQuery. It is now passed at the point of execution withExec/One/All/Cursor
.- Remove
Prepare
methods from table and view qureries. Sincebob.Prepare()
now takes a type parameter, it is not possible to prepare from a method since Go does not allow additional type parameters in methods. - Removed the Prisma and Atlas code generation drivers. It is better for Bob to focus on being able to generate code from the database in the most robust and detailed way and if the user wants, they can use other tools (such as prisma and atlas) to manage migrations before the code generation.
- Removed
Expressions
from Index definitions. It is now merged with theColumns
field with anIsExpression
field to indicate if the column is an expression.
Fixed
- Removed unnecessary import of
strings
inbobfactory_random.go
. - Fixed data races in unit tests. (thanks @mbezhanov)
- Fixed invalid SQL statements generated by
sm.OrderBy().Collate()
. (thanks @mbezhanov) - Fixed a bug preventing specific columns from being excluded when generating models from SQLite. (thanks @mbezhanov)
- Fixed an issue where invalid code is generated if a configured relationship has
from_where
orto_where
. - Fixed
ModelSlice.ReloadAll()
method for models with multiple primary keys.
New Contributors
- @tjmtmmnk made their first contribution in #247
- @adel-hadadi made their first contribution in #249
- @Hasaber8 made their first contribution in #265
- @mrtztg made their first contribution in #272
- @k4n4ry made their first contribution in #294
Full Changelog: v0.28.1...v0.29.0