SQLBOX_OPEN(3)

NAME
sqlbox_open, sqlbox_open_async - open a database

LIBRARY
sqlbox

SYNOPSIS
#include <stdint.h>
#include <sqlbox.h>
size_t
sqlbox_open(struct sqlbox *box, size_t index);
int
sqlbox_open_async(struct sqlbox *box, size_t index);

DESCRIPTION
Open the database passed in the struct sqlbox_src array of sqlbox_alloc(3) at index. This structure has the following fields:

fname
    The database filename, ":memory:", for an in-memory database, or the empty string for a private on-disc database. May not be NULL. The latter are only available until the database is closed. Remote databases are not supported.

mode
    One of SQLBOX_SRC_RO for a readonly database, SQLBOX_SRC_RW for readable and writable, and SQLBOX_SRC_RWC to also be created. In-memory databases need not provide the creation bit.

The synchronous sqlbox_open() returns the identifier while sqlbox_open_async() only returns whether box was accessed. It is used for implicit identifiers (i.e., an identifier of zero) in subsequent operations on the database.

Both functions always enable foreign key support on the database.

If the database is not closed with sqlbox_close(3), it is automatically closed on 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.

It's perfectly alright to open multiple databases of the same index, although it's probably not what you want.

  SQLite3 Implementation
Opens the database with sqlite3_open_v2(3). Has a random back-off on return of SQLITE_BUSY, SQLITE_LOCKED, or SQLITE_PROTOCOL. Otherwise, if not SQLITE_OK, considers it a failed open.

The foreign keys are enabled with a call to sqlite3_exec(3) using a similar back-off algorithm.

RETURN VALUES
sqlbox_open() returns an identifier >0 if communication with box works, zero otherwise (opening the database files, etc.). sqlbox_open_async() returns zero if communication with box failed, non-zero otherwise.

If sqlbox_open() or sqlbox_open_async() fail, box is no longer accessible beyond sqlbox_ping(3) and sqlbox_free(3).

EXAMPLES
This opens an in-memory database then immediately exits.

    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");
    sqlbox_free(p);

The following opens (and creates, if not found) the database db.db. The database is explicitly closed.

    struct sqlbox *p;
    struct sqlbox_src srcs[] = {
      { .fname = (char *)"db.db",
        .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);

Performing the same with implicit identifiers:

    struct sqlbox *p;
    struct sqlbox_src srcs[] = {
      { .fname = (char *)"db.db",
        .mode = SQLBOX_SRC_RWC },
    };
    struct sqlbox_cfg cfg;
    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 (!sqlbox_open_async(p, 0))
      errx(EXIT_FAILURE, "sqlbox_open_async");
    /* Perform work... */
    if (!sqlbox_close(p, 0))
      errx(EXIT_FAILURE, "sqlbox_close");
    sqlbox_free(p);

SEE ALSO
sqlbox_close(3), sqlbox_free(3)