Skip to content

Releases: VinGarcia/ksql

Add adapter kpostgres

22 Jan 13:49
6356f35
Compare
Choose a tag to compare

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

17 Jan 03:29
Compare
Choose a tag to compare

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 the kpgx 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 the kpgx adapter but works using pgx v5 instead of pgx 4.
  • Add modernc-ksqlite adapter. This adapter is just like the ksqlite 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 the Patch() function instead (which has the exact same implementation). This function was renamed from Update to Patch 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 name Update. Also having the name Update used for this prevented me from in the future adding an actual Update 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 subpackage sqldialect and rename it to sqldialect.Provider.
  • Add ksql.InjectLogger() function for helping debug query errors.
  • When using the Patch() method without providing all required IDs KSQL will now return a ksql.ErrRecordMissingIDs with a more appropriate error message.
  • Fixes an issue that prevented the Insert, Patch and Delete 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

17 Dec 18:16
6ff6720
Compare
Choose a tag to compare

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

13 Nov 17:38
Compare
Choose a tag to compare

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 type time.Time and it sets this attribute to time.Now().UTC() every time before insertions and updates. This modifier was created to be used on UpdatedAt timestamp fields.
  • timeNowUTC/skipUpdates: Does the same as the above but only on insertions. This is useful for CreatedAt fields where you only want them to be set once on Insert().
  • 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

19 Jul 17:11
Compare
Choose a tag to compare
v1.4.7

Remove dependency on ditointernet/go-assert

Update ksql.DB & adapters to implement io.Closer()

20 Apr 23:51
Compare
Choose a tag to compare

Add more flexible constructor for `kpgx`

11 Apr 23:06
Compare
Choose a tag to compare

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

04 Apr 00:30
Compare
Choose a tag to compare
v1.4.4

Add tls.Config to ksql.Config

Fix bug that caused go get to fail

27 Mar 01:07
9ff5f70
Compare
Choose a tag to compare

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

16 Mar 00:39
fe4530f
Compare
Choose a tag to compare

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.