SQLBOX_CLOSE(3)

NAME
sqlbox_close - close a database

LIBRARY
sqlbox

SYNOPSIS
#include <stdint.h>
#include <sqlbox.h>
int
sqlbox_close(struct sqlbox *box, size_t id);

DESCRIPTION
Close a database with the database id as returned from sqlbox_open(3). If id is zero, the last-opened database is used. The caller must have a role capable of opening and closing the given database source. Once closed, subsequent calls to sqlbox_close() with the same identifier will fail.

If sqlbox_close() is not explicitly called, the database will be implicitly closed at sqlbox_free(3). This is not considered an error, as a common usage pattern is a role with permission opening the database, shedding its role, then the close being relegated to the full destruction of the box.

  SQLite3 Implementation
The database is closed with sqlite3_close(3).

RETURN VALUES
sqlbox_close() returns zero if communication with box fails. Otherwise, it returns non-zero on success.

If closing the database fails (not open or does not exist, statements not finalised, a transaction still open), subsequent box access will fail. Use sqlbox_ping(3) to check explicitly.

If sqlbox_close() fails, box is no longer accessible beyond sqlbox_ping(3) and sqlbox_free(3).

EXAMPLES
To simply open and close an in-memory database:

    struct sqlbox *p;
    struct sqlbox_src srcs[] = {
      { .fname = (char *)":memory:",
        .mode = SQLBOX_SRC_RWC },
    };
    struct sqlbox_cfg cfg;
    size_t id;
    memset(&cfg, 0, sizeof(struct sqlbox_cfg));
    cfg.msg.func_short = warnx;
    cfg.srcs.srcsz = 1;
    cfg.srcs.srcs = srcs;
    if ((p = sqlbox_alloc(&cfg)) == NULL)
      errx(EXIT_FAILURE, "sqlbox_alloc");
    if (!(id = sqlbox_open(p, 0)))
      errx(EXIT_FAILURE, "sqlbox_open");
    /* Perform work... */
    if (!sqlbox_close(p, id))
      errx(EXIT_FAILURE, "sqlbox_close");
    sqlbox_free(p);

To let sqlbox_free(3) handle closing the database for role-shedding:

    struct sqlbox *p;
    struct sqlbox_src srcs[] = {
      { .fname = (char *)":memory:",
        .mode = SQLBOX_SRC_RWC },
    };
    struct sqlbox_role roles[] = {
      { .roles = (size_t[]){ 0, 1 },
        .rolesz = 2,
        .stmtsz = 0,
        .srcs = (size_t[]){ 0 },
        .srcsz = 1 },
      { .rolesz = 0,
        .stmtsz = 0,
        .srcsz = 0 }
    };
    struct sqlbox_cfg cfg;
    size_t id;
    memset(&cfg, 0, sizeof(struct sqlbox_cfg));
    cfg.msg.func_short = warnx;
    cfg.srcs.srcsz = 1;
    cfg.srcs.srcs = srcs;
    cfg.roles.roles = roles;
    cfg.roles.rolesz = 2;
    cfg.roles.defrole = 0;
    if ((p = sqlbox_alloc(&cfg)) == NULL)
      errx(EXIT_FAILURE, "sqlbox_alloc");
    if (!(id = sqlbox_open(p, 0)))
      errx(EXIT_FAILURE, "sqlbox_open");
    if (!sqlbox_role(p, 1))
      errx(EXIT_FAILURE, "sqlbox_role");
    /* Perform work... */
    sqlbox_free(p);

In the last example, the default role is able to transition into the new role, which is not able to close the database.

SEE ALSO
sqlbox_open(3), sqlbox_ping(3)