Releases: mjoerussell/zdb
zdb 0.2
Welcome to zdb v0.2! The main goal of this release is to learn from the API mistakes of 0.1 and make the core features of zdb easier to use for simple and complex use-cases.
What's Changed?
In many ways, just about everything has changed since the last release. I can't cover all of the details here so I'm just going to cover the most impactful changes.
Overall API changes
Connection
(formerlyDBConnection
),Cursor
, andResultSet
have been updated to be file-level structs rather than (mostly) single-struct files. This should make using these files a little easier.- Updated the APIs to prefer the "unmanaged" approach to allocations, meaning that instead of Cursor, for example, having an allocator field now all of it's functions that allocate have an allocator parameter. I thought that this would be better because it's not always clear when an allocation could happen and when it won't.
ResultSet
In 0.1.X, there were two types of result sets: RowBindingResultSet and ColumnBindingResultSet. Which one you got depended on what type you specified in Cursor when executing a statement. The rules were as follows:
- The type always had to be a struct
- If the struct had a
fromRow
member function, then you would get aColumnBindingResultSet
which used that function to generate instances of that struct. - Otherwise, you would get a
RowBindingResultSet
which would automatically bind the fields of the struct to columns in the table.
This approach had a few downsides:
- You could only get results as structs
- You had to collect the results in some data type
- There was an implicit decision being made, based on the presence of
fromRow
, which got in the way of helping people understand what was happening.
And the biggest issue with this API: you had to know the type of your data at compile time. This is possible in some use cases, but completely rules out other common cases such as generating SQL queries at runtime.
The new approach works like this:
- When you execute a statement you no longer provide a result type
- There is only one type of result set -
ResultSet
. - To get results from the result set, you can create one of two iterators:
RowIterator
orItemIterator
RowIterator
returns aRow
struct on each call toiter.next()
. This row struct has many functions for getting specific columns. If you don't know the type of the column you can useprint
to write the value as a string to a customWriter
.ItemIterator
accepts a type parameter and works similarly to theRowBindingResultSet
from 0.1 - on each call toiter.next()
you get an instance of whatever struct type you provided, with the fields automatically bound to the result set.
This approach is much more flexible, while also being more explicit and without losing some of the best convenience qualities of the original verison.
Changes to inserting data
In 0.1 using Cursor.insert
required knowing the insert statement at comptime, and required that the data being inserted were structs. Now statements can be known at runtime, and likewise are validated at runtime. Insert params can also be of almost any type, including structs, and insert()
will intelligently bind the data to the insert statement that the user provided.
Code Examples
A new /examples
directory has been created with some simple usage examples. These examples assume that you have Postgres installed on your machine, but could be modified to work with any ODBC driver that you have installed.
At the time of this release there are 4 examples available. More will be added as zdb grows.
Implementation Details
Some efficiency improvements have been made which don't directly affect the outward API. The most notable of this is in ParameterBucket
. ParameterBucket
has been rewritten from the ground up to dynamically increase in size when needed so that Cursor
doesn't have to deinit/reinit a new instance every time a query is executed with parameters. Instead the already-allocated param buffer can be reused indefinitely.
0.1.5
This release is intended to be the latest "0.1" release before 0.2.0, which will introduce major breaking API changes.
This release has a few important updates since the original 0.1.0 release:
- Updated code to work with Zig 0.9.1
- Allow pulling multiple rows at a time when using ColumnBindingResultSet.
- Removing
Allocator
fields on most structs. This should make the APIs more clear about which functions will (or may) allocate and which won't, rather than storing an allocator and then hiding that possibility. - Adds
build_pkg.zig
, which other projects can use in their build scripts to easily build zdb as a dependency
Release 0.1.0
This release marks an initial stage of maturity for zdb. There's a long way to go, but using zdb for general DB operations has become very practical.
Features in this Release
Here's a list of the major features included in this release:
- Connecting to a database using a connection string or DSN + username and password (tested so far with Postgres and Snowflake)
- Catalog functions
SQLTables
,SQLColumns
, andSQLTablePrivileges
- Automatically inserting data with structs/
cursor.insert
- Parameter binding on SQL statements
- Preparing and executing statements with
cursor.prepare -> cursor.execute
- Directly executing statements with
cursor.executeDirect
- Fast, typesafe row-wise binding
- More customizable column-wise binding with user defined
fromRow
functions
Features not included
Here is an incomplete list of some features that will be coming in future releases:
- Improved logging and error handling
- Scrollable cursors
- Connection pooling
- Async/await support
- Support for more catalog functions
- Transaction management features (manual commit mode, etc.)
The main thing that makes this release non-production ready (besides the missing features listed above) is that there may still be bugs in the zig-odbc
binding which probably won't be fixed until they're encountered in zdb
development. In addition to general bugs, each driver works slightly different and so there will definitely be tweaks needed as more databases are tested. The features listed above have been tested extensively with Postgres and Snowflake databases and so (even though there may still be issues) I'm confident that they'll work for most users in most use cases.
Call to Action
If anybody has already used zdb, thanks! For new users, here are some things you could do if you want to help out with zdb development
- Test with different DBMS's
- Test on Linux
- Report any bugs
- Report feature requests
- Pick up PR's, if you want! Even if I've already assigned it to myself feel free to comment if you want to work on any particular issue.
Thanks for your support!