Skip to content

v0.9.0

Choose a tag to compare

@vkiryakov vkiryakov released this 20 Oct 20:12
· 15 commits to dev since this release
7ef77d3

Zefir 0.9.0 adds zefir-mongo, an async MongoDB driver for a standalone mongod.

mongo

mongo.Client talks to one standalone mongod, 7.0 or later, on std.Io. Database and Collection give the operations of the database. A document can be a struct of your own, an anonymous literal or raw BSON:

var client: mongo.Client = try .init(gpa, io, .{ .uri = config.mongo.uri, .password = password });
defer client.deinit();
try client.connect(io, ctx, &diagnostics);
defer client.close(io);

var ids: bson.ObjectId.Generator = .init(io);
const db: mongo.Database = .init(&client, "shop", &ids);
const users = db.collection("users");

// The insert makes the _id, and says which.
const ann = try users.insertOne(io, op, User{ .email = "ann@example.com", .name = "Ann", .age = 30 }, .{ .allocator = arena });

// The adults, the oldest first, batch by batch.
var adults = try users.find(io, op, .{ .age = .{ .@"$gte" = 18 } }, .{ .allocator = arena, .sort = bson.literal(.{ .age = -1 }) });
defer adults.deinit(io);
while (try adults.next(io, op)) |doc| {
    const user = try bson.decode(User, arena, doc, .{});
    // ...
}
  • The client.
    • OP_MSG with the 2026 handshake.
    • SCRAM-SHA-256 and SCRAM-SHA-1, with a cache of the keys.
    • A pool of connections: a FIFO line for calls that wait, and a clear, a pause and a probe after a failure.
    • Deadlines from core.Context, sent to the server as maxTimeMS, and cancellation.
    • Cursors, and writes in batches cut to the server's limits.
    • close lets the calls in flight finish, then cuts them, and kills the open cursors.
  • Errors say whether the command may have run.
    • mongo.outcome(err) gives .not_sent or .may_have_executed.
    • Diagnostics keeps the server's code, name and labels.
    • IncompleteWrite and WriteFailed keep what a write did in partial.
    • There are no automatic retries; the guide says which errors are worth retrying.
  • BSON. Raw documents are checked when read. There are Builder, ObjectId and the other special types, and Relaxed Extended JSON for logs. The typed codec is bson.encode, bson.decode and bson.literal, and its errors name the field's path, at compile time and when decoding.
  • Database and Collection: insertOne and insertMany; find and findOne; updateOne, updateMany and replaceOne; deleteOne and deleteMany; findOneAndUpdate, findOneAndReplace and findOneAndDelete; aggregate; countDocuments and estimatedDocumentCount; distinct; indexes; collections; and runCommand.
  • mongo.testing: Script and FakeServer, a scripted mongod on loopback, to test an application without MongoDB.

Not in this version yet, as the list at the top of the guide says:

  • replica sets and sharded clusters;
  • TLS, so it needs a trusted network;
  • authentication other than SCRAM, and SCRAM-SHA-256 with a password that is not printable ASCII;
  • sessions, transactions, change streams and compression.

The connection string is strict. On Windows under zio, close doesn't interrupt a read that is already waiting.

The end-to-end tests run against mongod 7.0.45, 8.0.34 and 9.0.4 in Docker, in CI too.

See the mongo guide: the customers of a shop, step by step, every program compiled and every run shown as it printed.

zig fetch --save git+https://github.com/vkiryakov/zefir#v0.9.0

Breaking changes

  • zefir-rpc-log is gone (#68). zefir has one logger, zefir-log. An access log of rpc calls is middleware that the application writes on it; the rpc guide shows one in its "Access logs" section.