GithubHelp home page GithubHelp logo

20kano / zqlite.zig Goto Github PK

View Code? Open in Web Editor NEW

This project forked from karlseguin/zqlite.zig

0.0 0.0 0.0 2.44 MB

A thin SQLite wrapper for Zig

License: Mozilla Public License 2.0

C 99.67% Makefile 0.01% Zig 0.33%

zqlite.zig's Introduction

A thin SQLite wrapper for Zig

Consider using zig-sqlite for a more mature, full-featured library that better leverages Zig.

// good idea to pass EXResCode to get extended result codes (more detailed errorr codes)
const flags =  zqlite.OpenFlags.Create | zqlite.OpenFlags.EXResCode;
var conn = try zqlite.open("/tmp/test.sqlite", flags);
defer conn.close();

try conn.exec("create table test (name text)", .{});
try conn.exec("insert into test (name) values (?1), (?2)", .{"Leto", "Ghanima"});

{
    if (try conn.row("select * from test order by name limit 1", .{})) |row| {
      defer row.deinit();
      std.debug.print("name: {s}\n", .{row.text(0)});
    }
}

{
    var rows = try conn.rows("select * from test order by name", .{});
    defer rows.deinit();
    while (rows.next()) |row| {
        std.debug.print("name: {s}\n", .{row.text(0)});
    }
    if (rows.err) |err| return err;
}

Unless zqlite.OpenFlags.ReadOnly is set in the open flags, zqlite.OpenFlags.ReadWrite is assumed (in other words, the database opens in read-write by default, and the ReadOnly flag must be used to open it in readony mode.)

Conn

The Conn type returned by open has the following functions:

  • row(sql, args) !?zqlite.Row - returns an optional row
  • rows(sql, args) !zqlite.Rows - returns an iterator that yields rows
  • exec(sql, args) !void - executes the statement,
  • execNoArgs(sql) !void - micro-optimization if there are no args, sql must be a null-terminated string
  • changes() usize - the number of rows inserted/updated/deleted by the previous statement
  • lastInsertedRowId() i64 - the row id of the last inserted row
  • lastError() [*:0]const u8 - an error string describing the last error
  • transaction() !void and exclusiveTransaction() !void - begins a transaction
  • commit() !void and rollback() void - commits and rollback the current transaction
  • prepare(sql, args) !zqlite.Stmt - returns a thin wrapper around a *c.sqlite3_stmt. row and rows wrap this type.
  • close() void and tryClsoe() !void - closes the database. close() silently ignores any error, if you care about the error, use tryClose()
  • busyTimeout(ms) - Sets the busyHandler for the connection. See https://www.sqlite.org/c3ref/busy_timeout.html

Row and Rows

Both row and rows wrap an zqlite.Stmt which itself is a thin wrapper around an *c.sqlite3_stmt.

While zqlite.Row exposes a deinit and deinitErr method, it should only be called when the row was fetched directly from conn.row(...):

if (conn.row("select 1", .{})) |row| {
    defer row.deinit();  // must be called
    std.debug.print("{d}\n", .{row.int(0)});

When the row comes from iterating rows, deinit or deinitErr should not be called on the individual row:

var rows = try conn.rows("select 1 union all select 2", .{})
defer rows.deinit();  // must be called

while (rows.next()) |row| {
    // row.deinit() should not be called!
    ...
}

Note that zqlite.Rows has an err: ?anyerror field which can be checked at any point. Calls to next() when err != null will return null. Thus, err need only be checked at the end of the loop:

var rows = try conn.rows("select 1 union all select 2", .{})
defer rows.deinit();  // must be called

while (rows.next()) |row| {
    ...
}

if (rows.err) |err| {
    // something went wrong 
}

Row Getters

A row exposes the following functions to fetch data:

  • boolean(index) bool
  • nullableBoolean(index) ?bool
  • int(index) i64
  • nullableInt(index) ?i64
  • float(index) i64
  • nullableFloat(index) f64
  • text(index) []const u8
  • nullableText(index) ?[]const u8
  • blob(index) []const u8
  • nullableBlob(index) ?[]const u8

The nullableXYZ functions can safely be called on a not null column. The non-nullable versions avoid a call to sqlite3_column_type (which is needed in the nullable versions to determine if the value is null or not).

Transaction:

The transaction(), exclusiveTransaction(), commit() and rollback() functions are simply wrappers to conn.execNoArgs("begin"), conn.execNoArgs("begin exclusive"), conn.execNoArgs("commit") and conn.execNoArgs("rollback")

conn.transaction()
errdefer conn.rollback();

try conn.exec(...);
try conn.exec(...);
try conn.commit();

Blobs

When binding a []const u8, this library has no way to tell whether the value should be treated as an text or blob. It defaults to text. To have the value bound as a blob use zqlite.blob(value):

conn.insert("insert into records (image) values (?1)", .{zqlite.blob(image)})

However, this should only be necessary in specific cases where SQLite blob-specific operations are used on the data. Text and blob are practically the same, except they have a different type.

Pool

zqlite.Pool is a simple thread-safe connection pool. After being created, the acquire and release functions are used to get a connection from the pool and to release it.

var pool = zqlite.Pool.init(allocator, .{
    // The number of connection in the pool. The pool will not grow or
    // shrink beyond this count
    .size = 5,   // default 5

    // The path  of the DB connection
    .path = "/tmp/zqlite.sqlite",  // no default, required

    // The zqlite.OpenFlags to use when opening each connection in the pool
    // Defaults are as shown here:
    .flags = zqlite.OpenFlags.Create | zqlite.OpenFlags.EXResCode  

    // Callback function to execute for each connection in the pool when opened
    .on_connection = null,

    // Callback function to execute only for the first connection in the pool
    .on_first_connection = null,
})

const c1 = pool.acquire();
defer pool.release(c1);
c1.execNoArgs(...);

Callbacks

Both the on_connection and on_first_connection have the same signature. For the first connection to be opened by the pool, if both callbacks are provided then both callbacks will be executed, with on_first_connection executing first.

var pool = zqlite.Pool.init(allocator, .{
    .size = 5,
    .on_first_connection = &initializeDB,
    .on_connection = &initializeConnection,
    // other required & optional fields
});
...

// Our size is 5, but this will only be executed once, for the first
// connection in our pool
fn initializeDB(conn: Conn) !void {
    try conn.executeNoArgs("create table if not exists testing(id int)");
}

// Our size is 5, so this will be executed 5 times, once for each
// connection. `initializeDB` is guaranteed to be called before this
// function is called.
fn initializeConnection(conn: Conn) !void {
    return conn.busyTimeout(1000);
}

zqlite.zig's People

Contributors

karlseguin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.