Releases: VinGarcia/ksql
Add adapter kpostgres
This is a minor release that adds a new adapter kpostgres
, this adapter is only meant to be used if you are using a framework that forces you to connect to Postgres over a database/sql.DB
instance.
More specifically this addition was made with help from @devalexandre for integrating KSQL with the encore
framework.
In any case, if you have the choice you should always use kpgx
over kpostgres
since the former is much more efficient.
Fix issue with qualified table names
As suggested by one user of the KSQL library I should start doing official releases like this one explaining all the changes and updates every time I release a new version.
Since I have not been doing actual releases for a long time (I was only creating tags but with no description of the changes) this release will describe all new features and updates ever since the last version that was officially released, namely: v1.6.0
- Remove direct import to
github.com/lib/pq
from thekpgx
adapter. This still doesn´t completely remove it from the indirect dependencies because this library is an indirect dependency used on pgx for testing (if I remember correctly). - Add
kpgx5
adapter. This adapter is just like thekpgx
adapter but works using pgx v5 instead of pgx 4. - Add
modernc-ksqlite
adapter. This adapter is just like theksqlite
adapter but it uses the https://pkg.go.dev/modernc.org/sqlite implementation, which, although not being as widely used and battle-tested as the former, does not depend on CGO which is a big advantage in many situations. - Remove the deprecated
Update()
function: use thePatch()
function instead (which has the exact same implementation). This function was renamed fromUpdate
toPatch
because it contains the "patching" feature of automatically ignoring null pointers instead of trying to set the attribute to NULL. This behavior would be counter-intuitive if someone tried to guess its behavior from the nameUpdate
. Also having the nameUpdate
used for this prevented me from in the future adding an actualUpdate
function on v2, which is something I intend to do, and deprecating/removing this now will probably prevent users from not noticing this subtle difference when updating to v2, so I considered that this breaking change was would probably make the update safer in the future. - Move the
ksql.Dialect
interface to subpackagesqldialect
and rename it tosqldialect.Provider
. - Add
ksql.InjectLogger()
function for helping debug query errors. - When using the
Patch()
method without providing all required IDs KSQL will now return aksql.ErrRecordMissingIDs
with a more appropriate error message. - Fixes an issue that prevented the
Insert
,Patch
andDelete
helper functions from working with qualified table names, e.g.public.users
.
And that is pretty much all of it, I hope you guys like it
Add Nullable Modifier
Before this modifier the Patch function would always ignore null pointers.
Which was no convenient because there was no good way of setting fields to NULL on the database when desired forcing users to use:
db.Exec("UPDATE <table> SET <field_name> = NULL")
manually
Now it is possible to just add the nullable modifier to the attribute, e.g.:
type User struct{
ID int `ksql:"id"`
Name *string `ksql:"name,nullable"`
}
// Set name to NULL:
err := db.Insert(ctx, usersTable, &User{
ID: userID,
Name: nil,
})
Add the concept of attribute modifiers
This release adds the concept of a modifier.
What is a KSQL Modifier?
A KSQL modifier is a special tag you can add to any of the attributes of your struct to alter the behavior of KSQL when reading or writing that attribute into the database. To use it, it is necessary to add the name of the modifier on the ksql
tag after a comma, e.g.:
`ksql:"column_name,json"`
Before this release, the json
modifier was the only one available in KSQL, and it would help the user by converting the attribute to JSON before writing to the database and back from JSON when reading from the database.
Adding Custom Modifiers
This release improves on this idea of modifiers by making it possible for users to add their own user-created modifiers. This release also adds 4 new built-in modifiers so users can use out of the box, namely:
timeNowUTC
: It only works if on attributes of typetime.Time
and it sets this attribute totime.Now().UTC()
every time before insertions and updates. This modifier was created to be used onUpdatedAt
timestamp fields.timeNowUTC/skipUpdates
: Does the same as the above but only on insertions. This is useful forCreatedAt
fields where you only want them to be set once onInsert()
.skipUpdates
: Will ignore fields on updates.skipInserts
: Will ignore fields on inserts.
Here is an example of how a User
struct might look like using some of these modifiers:
type user struct {
ID uint `ksql:"id"`
Name string `ksql:"name"`
Age int `ksql:"age"`
Address Address `ksql:"address,json"`
UpdatedAt time.Time `ksql:"updated_at,timeNowUTC"`
CreatedAt time.Time `ksql:"created_at,timeNowUTC/skipUpdates"`
}
We also have plans on releasing some modifiers for saving time.Time
instances as UNIX timestamps on the database in the future.
Registering new Modifiers
Registering new modifiers is done by instantiating a struct like the below:
func init() {
ksqlmodifiers.RegisterAttrModifier("my_modifier_name", ksqlmodifiers.AttrModifier{
SkipInserts: false, // set it to true if you want this modifier to cause the field to be ignored on inserts.
SkipUpdates: false, // set it to true if you want this modifier to cause the field to be ignored on updates.
Scan: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, attrPtr interface{}, dbValue interface{}) error {
// Read the dbValue, modify it and then save it into the attrPtr argument using reflection.
},
Value: func(ctx context.Context, opInfo ksqlmodifiers.OpInfo, inputValue interface{}) (outputValue interface{}, _ error) {
// Read the inputValue, modify it and then return it so the database can save it.
},
})
}
This registration should be performed inside your code before making any calls to the KSQL library. I recommend doing it inside a init()
function since then it will run before main()
starts.
Fix a race condition problem and improves the docs
v1.4.7 Remove dependency on ditointernet/go-assert
Update ksql.DB & adapters to implement io.Closer()
v1.4.6 Try to fix CI again
Add more flexible constructor for `kpgx`
Add the new kpgx.NewFromPgxPool(pool *pgxpool.Pool) (ksql.DB, error)
constructor for allowing users to setup more complicated configurations for pgxpool
.
Add support for TLS on ksql.Config
v1.4.4 Add tls.Config to ksql.Config
Fix bug that caused go get to fail
This Release fixes a bug that was causing go get github.com/vingarcia/ksql/adapters/kpgx
to fail.
This bug also affected the other adapters and was caused by the fact we are using the replace
directive on go.mod
for making sure we were testing the correct version of ksql everytime.
This Release fixes this go get
issue, but I will need to find a way to make sure the tests are working as expected in the future.
Refactor dependencies as submodules
This release makes a very big refactor that allowed all the dependencies of each different adapter to be moved to different submodules.
This means two things:
Now if you want to use kpgx
you would need to:
go get github.com/vingarcia/ksql
- and
go get github.com/vingarcia/ksql/adapters/kpgx
This is more work for the dev, but this also has one advantage (the second thing):
Now when importing ksql
you only depend on what you use. This means that we can add support to several more databases without worrying that we would bloat the go.sum
of our users with several dependencies they are not even using.