Subzero C Shared Library
Loading...
Searching...
No Matches
Typedefs | Functions
subzero.h File Reference
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

Go to the source code of this file.

Typedefs

typedef struct sbz_DbSchema sbz_DbSchema
 
typedef struct sbz_HTTPRequest sbz_HTTPRequest
 
typedef struct sbz_Statement sbz_Statement
 
typedef struct sbz_TwoStageStatement sbz_TwoStageStatement
 

Functions

struct sbz_HTTPRequestsbz_http_request_new_with_clone (const char *method, const char *uri, const char *body, const char *const *headers, int headers_count, const char *const *env, int env_count)
 
struct sbz_HTTPRequestsbz_http_request_new (const char *method, const char *uri, const char *body, const char *const *headers, int headers_count, const char *const *env, int env_count)
 
void sbz_http_request_free (struct sbz_HTTPRequest *request)
 
struct sbz_TwoStageStatementsbz_two_stage_statement_new (const char *schema_name, const char *path_prefix, const char *role, const struct sbz_DbSchema *db_schema, const struct sbz_HTTPRequest *request, const char *max_rows)
 
const struct sbz_Statementsbz_two_stage_statement_mutate (const struct sbz_TwoStageStatement *two_stage_statement)
 
const struct sbz_Statementsbz_two_stage_statement_select (const struct sbz_TwoStageStatement *two_stage_statement)
 
int sbz_two_stage_statement_set_ids (struct sbz_TwoStageStatement *two_stage_statement, const char *const *ids, int ids_count)
 
void sbz_two_stage_statement_free (struct sbz_TwoStageStatement *two_stage_statement)
 
struct sbz_Statementsbz_statement_main_new (const char *schema_name, const char *path_prefix, const char *role, const struct sbz_DbSchema *db_schema, const struct sbz_HTTPRequest *request, const char *max_rows)
 
struct sbz_Statementsbz_statement_env_new (const struct sbz_DbSchema *db_schema, const struct sbz_HTTPRequest *request)
 
const char * sbz_statement_sql (const struct sbz_Statement *statement)
 
const char *const * sbz_statement_params (const struct sbz_Statement *statement)
 
const char *const * sbz_statement_params_types (const struct sbz_Statement *statement)
 
int sbz_statement_params_count (const struct sbz_Statement *statement)
 
void sbz_statement_free (struct sbz_Statement *statement)
 
void sbz_db_schema_free (struct sbz_DbSchema *schema)
 
struct sbz_DbSchemasbz_db_schema_new (const char *db_type, const char *db_schema_json, const char *license_key)
 
int sbz_db_schema_is_demo (const struct sbz_DbSchema *db_schema)
 
char * sbz_introspection_query (const char *db_type, const char *path, const char *custom_relations, const char *custom_permissions)
 
void sbz_introspection_query_free (char *introspection_query)
 
int sbz_last_error_message (char *buffer, int length)
 
void sbz_clear_last_error (void)
 
int sbz_last_error_length (void)
 
int sbz_last_error_http_status (void)
 

Typedef Documentation

◆ sbz_DbSchema

typedef struct sbz_DbSchema sbz_DbSchema

A structure for holding the information about database entities and permissions (tables, views, etc).

◆ sbz_HTTPRequest

A structure representing a HTTP request. This is used to pass the information about the request to the subzero core.

◆ sbz_Statement

typedef struct sbz_Statement sbz_Statement

A structure representing a SQL statement (query and parameters).

◆ sbz_TwoStageStatement

A structure representing a two-stage statement (mutate and select). The mutate statement is used to perform the mutation (insert, update, delete) and the select statement is used to retrieve the result. This is used for databases that do not support returning the result of a mutation (sqlite/mysql).

Both statements should be executed in the same transaction. The mutate statement will return two columns: id and _subzero_check__constraint You need to collect the ids and then call two_stage_statement_set_ids to set the ids for the select statement before calling sbz_two_stage_statement_select. You also need to check the _subzero_check__constraint column to be "truethy" for all rows and rollback the transaction if it is not.

Function Documentation

◆ sbz_clear_last_error()

void sbz_clear_last_error ( void )

Clear the most recent error.

Safety

◆ sbz_db_schema_free()

void sbz_db_schema_free ( struct sbz_DbSchema * schema)

Free the memory associated with a sbz_DbSchema.

Safety

Parameters

  • schema - A pointer to the sbz_DbSchema to free.

◆ sbz_db_schema_is_demo()

int sbz_db_schema_is_demo ( const struct sbz_DbSchema * db_schema)

Check if subzero is running in demo mode.

Safety

Parameters

  • db_schema - A pointer to the sbz_DbSchema.

Returns

1 if subzero is running in demo mode, 0 if it is not, -1 if an error occurred.

◆ sbz_db_schema_new()

struct sbz_DbSchema * sbz_db_schema_new ( const char * db_type,
const char * db_schema_json,
const char * license_key )

Create a new sbz_DbSchema from a JSON string.

Safety

This function is marked unsafe because it dereferences raw pointers however we are careful to check for null pointers before dereferencing them.

Parameters

  • db_type - The type of database this schema is for. Currently supported types are "postgresql", "clickhouse", "sqlite", and "mysql".
  • db_schema_json - The JSON string representing the schema.
  • license_key - The license key for the subzero core. Pass NULL if you are running in demo mode.

Returns

A pointer to the newly created DbSchema or a null pointer if an error occurred.

Note

Constructing the JSON schema is tedious and for this reason we provide "introspection queries" for each database type that can be used to generate the schema JSON.

Example

const char* db_type = "sqlite";
const char* db_schema_json = ""
"{"
" \"schemas\": ["
" {"
" \"name\": \"public\","
" \"objects\": ["
" {"
" \"kind\": \"table\","
" \"name\": \"clients\","
" \"columns\": ["
" {"
" \"name\": \"id\","
" \"data_type\": \"INTEGER\","
" \"primary_key\": true"
" },"
" {"
" \"name\": \"name\","
" \"data_type\": \"TEXT\","
" \"primary_key\": false"
" }"
" ],"
" \"foreign_keys\": []"
" }"
" ]"
" }"
" ]"
"}"
;
sbz_DbSchema* db_schema = sbz_db_schema_new(db_type, db_schema_json, NULL);
if (db_schema == NULL) {
const int err_len = sbz_last_error_length();
char* err = (char*)malloc(err_len);
sbz_last_error_message(err, err_len);
printf("Error: %s\n", err);
free(err);
return;
}
struct sbz_DbSchema * sbz_db_schema_new(const char *db_type, const char *db_schema_json, const char *license_key)
int sbz_last_error_length(void)
struct sbz_DbSchema sbz_DbSchema
Definition subzero.h:124
int sbz_last_error_message(char *buffer, int length)

◆ sbz_http_request_free()

void sbz_http_request_free ( struct sbz_HTTPRequest * request)

Free the memory associated with a sbz_HTTPRequest.

Safety

Parameters

  • request - A pointer to the sbz_HTTPRequest to free.

◆ sbz_http_request_new()

struct sbz_HTTPRequest * sbz_http_request_new ( const char * method,
const char * uri,
const char * body,
const char *const * headers,
int headers_count,
const char *const * env,
int env_count )

Create a new sbz_HTTPRequest

Safety

Parameters

  • method - The HTTP method (GET, POST, PUT, DELETE, etc).
  • uri - The full URI of the request (including the query string, ex: http://example.com/path?query=string).
  • body - The body of the request (pass NULL if there is no body).
  • headers - An array of key-value pairs representing the headers of the request, it needs to contain an even number of elements.
  • headers_count - The number of elements in the headers array.
  • env - An array of key-value pairs representing the environment data that needs to be available to the query. It needs to contain an even number of elements.
  • env_count - The number of elements in the env array.

Returns

A pointer to the newly created sbz_HTTPRequest or a null pointer if an error occurred.

Example

const char* headers[] = {"Content-Type", "application/json", "Accept", "application/json"};
const char* env[] = {"user_id", "1"};
"POST",
"http://localhost/rest/projects?select=id,name",
"[{\"name\":\"project1\"}]",
headers, 4,
env, 2
);
struct sbz_HTTPRequest sbz_HTTPRequest
Definition subzero.h:130
struct sbz_HTTPRequest * sbz_http_request_new(const char *method, const char *uri, const char *body, const char *const *headers, int headers_count, const char *const *env, int env_count)

◆ sbz_http_request_new_with_clone()

struct sbz_HTTPRequest * sbz_http_request_new_with_clone ( const char * method,
const char * uri,
const char * body,
const char *const * headers,
int headers_count,
const char *const * env,
int env_count )

Create a new sbz_HTTPRequest and take ownership of the strings. This is usefull when the caller can not guarantee that the strings will be valid for the lifetime of the sbz_HTTPRequest.

Safety

Parameters

  • method - The HTTP method (GET, POST, PUT, DELETE, etc).
  • uri - The full URI of the request (including the query string, ex: http://example.com/path?query=string).
  • body - The body of the request (pass NULL if there is no body).
  • headers - An array of key-value pairs representing the headers of the request, it needs to contain an even number of elements.
  • headers_count - The number of elements in the headers array.
  • env - An array of key-value pairs representing the environment data that needs to be available to the query. It needs to contain an even number of elements.
  • env_count - The number of elements in the env array.

Returns

A pointer to the newly created sbz_HTTPRequest or a null pointer if an error occurred.

Example

const char* headers[] = {"Content-Type", "application/json", "Accept", "application/json"};
const char* env[] = {"user_id", "1"};
"POST",
"http://localhost/rest/projects?select=id,name",
"[{\"name\":\"project1\"}]",
headers, 4,
env, 2
);

◆ sbz_introspection_query()

char * sbz_introspection_query ( const char * db_type,
const char * path,
const char * custom_relations,
const char * custom_permissions )

Get the introspection query for a database type.

Safety

Parameters

  • db_type - The type of database to get the introspection query for.
  • path - The path to the directory where the introspection query files are located.
  • custom_relations - An optional JSON string representing custom relations to include in the introspection query.
  • custom_permissions - An optional JSON string representing custom permissions to include in the introspection query.

Returns

A pointer to the introspection query as a C string.

◆ sbz_introspection_query_free()

void sbz_introspection_query_free ( char * introspection_query)

Free the memory associated with the introspection query.

Safety

Parameters

  • introspection_query - A pointer to the introspection query to free.

◆ sbz_last_error_http_status()

int sbz_last_error_http_status ( void )

Get the HTTP status code of the last error.

Returns

The HTTP status code of the last error.

◆ sbz_last_error_length()

int sbz_last_error_length ( void )

Calculate the number of bytes in the last error's error message not including any trailing null characters.

◆ sbz_last_error_message()

int sbz_last_error_message ( char * buffer,
int length )

Write the most recent error message into a caller-provided buffer as a UTF-8 string, returning the number of bytes written.

Safety

This function is marked unsafe because it dereferences raw pointers however we are careful to check for null pointers before dereferencing them.

Note

This writes a UTF-8 string into the buffer. Windows users may need to convert it to a UTF-16 "unicode" afterwards.

Parameters

  • buffer - A pointer to a buffer to write the error message into.
  • length - The length of the buffer.

Returns

If there are no recent errors then this returns 0 (because we wrote 0 bytes). -1 is returned if there are any errors, for example when passed a null pointer or a buffer of insufficient size.

◆ sbz_statement_env_new()

struct sbz_Statement * sbz_statement_env_new ( const struct sbz_DbSchema * db_schema,
const struct sbz_HTTPRequest * request )

Create a new sbz_Statement for the env query

Safety

Parameters

  • db_schema - A pointer to the sbz_DbSchema
  • request - A pointer to the sbz_HTTPRequest

Returns

A pointer to the newly created sbz_Statement or a null pointer if an error occurred.

◆ sbz_statement_free()

void sbz_statement_free ( struct sbz_Statement * statement)

Free the memory associated with a sbz_Statement.

Safety

Parameters

  • statement - A pointer to the sbz_Statement to free.

◆ sbz_statement_main_new()

struct sbz_Statement * sbz_statement_main_new ( const char * schema_name,
const char * path_prefix,
const char * role,
const struct sbz_DbSchema * db_schema,
const struct sbz_HTTPRequest * request,
const char * max_rows )

Create a new sbz_Statement for the main query.

Safety

Parameters

  • schema_name - The name of the database schema for the current request (ex: public).
  • path_prefix - The prefix of the path for the current request (ex: /api/).
  • role - The role of the user making the request
  • db_schema - A pointer to the sbz_DbSchema
  • request - A pointer to the sbz_HTTPRequest
  • max_rows - The maximum number of rows to return (pass NULL if there is no limit, otherwise pass a string representing the number of rows).

Returns

A pointer to the newly created sbz_Statement or a null pointer if an error occurred.

Example

const char* db_type = "sqlite";
sbz_DbSchema* db_schema = sbz_db_schema_new(db_type, db_schema_json, NULL); // see db_schema_new example for db_schema_json
sbz_Tuple headers[] = {{"Content-Type", "application/json"}, {"Accept", "application/json"}};
sbz_Tuple env[] = {{"user_id", "1"}};
"GET",
"http://localhost/rest/projects?select=id,name",
NULL,
headers, 4,
env, 2
);
sbz_Statement* stmt = sbz_statement_new(
"public",
"/rest/",
"user",
db_schema,
req,
NULL
);
if (stmt == NULL) {
const int err_len = sbz_last_error_length();
char* err = (char*)malloc(err_len);
sbz_last_error_message(err, err_len);
printf("Error: %s\n", err);
free(err);
return;
}
const char* sql = sbz_statement_sql(stmt);
const char *const * params = sbz_statement_params(stmt);
const char *const * params_types = sbz_statement_params_types(stmt);
int params_count = sbz_statement_params_count(stmt);
printf("SQL: %s\n", sql);
printf("params: %s\n", params[0]);
printf("params_count: %d\n", params_count);
printf("params_types: %s\n", params_types[0]);
sbz_db_schema_free(db_schema);
void sbz_statement_free(struct sbz_Statement *statement)
struct sbz_Statement sbz_Statement
Definition subzero.h:135
const char * sbz_statement_sql(const struct sbz_Statement *statement)
const char *const * sbz_statement_params(const struct sbz_Statement *statement)
void sbz_db_schema_free(struct sbz_DbSchema *schema)
const char *const * sbz_statement_params_types(const struct sbz_Statement *statement)
int sbz_statement_params_count(const struct sbz_Statement *statement)
void sbz_http_request_free(struct sbz_HTTPRequest *request)

◆ sbz_statement_params()

const char *const * sbz_statement_params ( const struct sbz_Statement * statement)

Get the parameter values from a sbz_Statement

Safety

Parameters

  • statement - A pointer to the sbz_Statement.

Returns

A pointer to the parameter values as an array of C strings.

◆ sbz_statement_params_count()

int sbz_statement_params_count ( const struct sbz_Statement * statement)

Get the number of parameters from a sbz_Statement

Safety

Parameters

  • statement - A pointer to the sbz_Statement.

Returns

The number of parameters as an integer.

◆ sbz_statement_params_types()

const char *const * sbz_statement_params_types ( const struct sbz_Statement * statement)

Get the parameter types from a sbz_Statement

Safety

Parameters

  • statement - A pointer to the sbz_Statement.

Returns

A pointer to the parameter types as an array of C strings.

Note

The parameter types are the database types of the parameters (ex: text, integer, integer[], etc).

◆ sbz_statement_sql()

const char * sbz_statement_sql ( const struct sbz_Statement * statement)

Get the SQL query from a sbz_Statement.

Safety

Parameters

  • statement - A pointer to the sbz_Statement.

Returns

A pointer to the SQL query as a C string.

◆ sbz_two_stage_statement_free()

void sbz_two_stage_statement_free ( struct sbz_TwoStageStatement * two_stage_statement)

Free the memory associated with a sbz_TwoStageStatement.

Safety

Parameters

  • two_stage_statement - A pointer to the sbz_TwoStageStatement to free.

◆ sbz_two_stage_statement_mutate()

const struct sbz_Statement * sbz_two_stage_statement_mutate ( const struct sbz_TwoStageStatement * two_stage_statement)

Get the mutate statement from a sbz_TwoStageStatement.

Safety

Parameters

  • two_stage_statement - A pointer to the sbz_TwoStageStatement.

Returns

A pointer to the sbz_Statement representing the mutate statement.

◆ sbz_two_stage_statement_new()

struct sbz_TwoStageStatement * sbz_two_stage_statement_new ( const char * schema_name,
const char * path_prefix,
const char * role,
const struct sbz_DbSchema * db_schema,
const struct sbz_HTTPRequest * request,
const char * max_rows )

Create a new sbz_TwoStageStatement

Safety

Parameters

  • schema_name - The name of the database schema for the current request (ex: public).
  • path_prefix - The prefix of the path for the current request (ex: /api/).
  • db_schema - A pointer to the sbz_DbSchema
  • request - A pointer to the sbz_HTTPRequest
  • max_rows - The maximum number of rows to return (pass NULL if there is no limit, otherwise pass a string representing the number of rows).

Returns

A pointer to the newly created sbz_TwoStageStatement or a null pointer if an error occurred.

Example

const char* db_type = "sqlite";
sbz_DbSchema* db_schema = sbz_db_schema_new(db_type, db_schema_json, NULL); // see db_schema_new example for db_schema_json
const char* headers[] = {"Content-Type", "application/json", "Accept", "application/json"};
const char* env[] = {"user_id", "1"};
"POST",
"http://localhost/rest/projects?select=id,name",
"[{\"name\":\"project1\"}",
headers, 4,
env, 2
);
"public",
"/rest/",
db_schema,
req,
NULL
);
if (stmt == NULL) {
const int err_len = sbz_last_error_length();
char* err = (char*)malloc(err_len);
sbz_last_error_message(err, err_len);
printf("Error: %s\n", err);
free(err);
return;
}
const sbz_Statement* mutate_stmt = sbz_two_stage_statement_mutate(stmt);
const char* sql = sbz_statement_sql(mutate_stmt);
const char *const * params = sbz_statement_params(mutate_stmt);
const char *const * params_types = sbz_statement_params_types(mutate_stmt);
int params_count = sbz_statement_params_count(mutate_stmt);
printf("mutate SQL: %s\n", sql);
printf("mutate params: %s\n", params[0]);
printf("mutate params_count: %d\n", params_count);
// collect the ids from the result of the mutate statement
// and set them for the select statement
const char *ids[] = {"1", "2", "3"};
const int ids_set = sbz_two_stage_statement_set_ids(main_stmt, ids, 3);
const sbz_Statement* select_stmt = sbz_two_stage_statement_select(stmt);
const char* sql_select = sbz_statement_sql(select_stmt);
const char *const * params_select = sbz_statement_params(select_stmt);
const char *const * params_types_select = sbz_statement_params_types(select_stmt);
int params_count_select = sbz_statement_params_count(select_stmt);
printf("select SQL: %s\n", sql_select);
printf("select params: %s\n", params_select[0]);
printf("select params_count: %d\n", params_count_select);
// free the memory associated with the two_stage_statement
sbz_db_schema_free(db_schema);
const struct sbz_Statement * sbz_two_stage_statement_select(const struct sbz_TwoStageStatement *two_stage_statement)
const struct sbz_Statement * sbz_two_stage_statement_mutate(const struct sbz_TwoStageStatement *two_stage_statement)
struct sbz_TwoStageStatement sbz_TwoStageStatement
Definition subzero.h:150
struct sbz_TwoStageStatement * sbz_two_stage_statement_new(const char *schema_name, const char *path_prefix, const char *role, const struct sbz_DbSchema *db_schema, const struct sbz_HTTPRequest *request, const char *max_rows)
void sbz_two_stage_statement_free(struct sbz_TwoStageStatement *two_stage_statement)
int sbz_two_stage_statement_set_ids(struct sbz_TwoStageStatement *two_stage_statement, const char *const *ids, int ids_count)

◆ sbz_two_stage_statement_select()

const struct sbz_Statement * sbz_two_stage_statement_select ( const struct sbz_TwoStageStatement * two_stage_statement)

Get the select statement from a sbz_TwoStageStatement.

Safety

Parameters

  • two_stage_statement - A pointer to the sbz_TwoStageStatement.

Returns

A pointer to the sbz_Statement representing the select statement.

Note

The ids of the mutated rows need to be set before calling this function using sbz_two_stage_statement_set_ids.

◆ sbz_two_stage_statement_set_ids()

int sbz_two_stage_statement_set_ids ( struct sbz_TwoStageStatement * two_stage_statement,
const char *const * ids,
int ids_count )

Set the ids for a sbz_TwoStageStatement.

Safety

Parameters

  • two_stage_statement - A pointer to the sbz_TwoStageStatement.
  • ids - An array of strings representing the ids of the mutated rows.
  • ids_count - The number of ids in the ids array.

Returns

0 if successful, -1 if an error occurred.

Example

const char *ids[] = {"1", "2", "3"};
const int ids_set = sbz_two_stage_statement_set_ids(stmt, ids, 3);