sources/cqlrt.h (223 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <math.h>
#include <sqlite3.h>
#ifndef __clang__
#ifndef _Nonnull
/* Hide Clang-only nullability specifiers if not Clang */
#define _Nonnull
#define _Nullable
#endif
#endif
#define cql_contract assert
#define cql_invariant assert
#define cql_tripwire assert
#define cql_log_database_error(...)
#define cql_error_trace()
// value types
typedef unsigned char cql_bool;
#define cql_true (cql_bool)1
#define cql_false (cql_bool)0
// metatypes for the straight C implementation
#define CQL_C_TYPE_STRING 0
#define CQL_C_TYPE_BLOB 1
#define CQL_C_TYPE_RESULTS 2
#define CQL_C_TYPE_BOXED_STMT 3
#define CQL_C_TYPE_OBJECT 4
typedef unsigned long cql_hash_code;
typedef int32_t cql_int32;
typedef uint32_t cql_uint32;
typedef uint16_t cql_uint16;
typedef sqlite3_int64 cql_int64;
typedef double cql_double;
typedef int cql_code;
// base ref counting struct
typedef struct cql_type *cql_type_ref;
typedef struct cql_type {
int type;
int ref_count;
void (*_Nullable finalize)(cql_type_ref _Nonnull ref);
} cql_type;
void cql_retain(cql_type_ref _Nullable ref);
void cql_release(cql_type_ref _Nullable ref);
cql_hash_code cql_ref_hash(cql_type_ref _Nonnull typeref);
cql_bool cql_ref_equal(cql_type_ref _Nullable typeref1, cql_type_ref _Nullable typeref2);
// builtin object
typedef struct cql_object *cql_object_ref;
typedef struct cql_object {
cql_type base;
const void *_Nonnull ptr;
} cql_object;
#define cql_object_retain(object) cql_retain((cql_type_ref)object);
#define cql_object_release(object) cql_release((cql_type_ref)object);
// builtin statement box
typedef struct cql_boxed_stmt *cql_boxed_stmt_ref;
typedef struct cql_boxed_stmt {
cql_type base;
sqlite3_stmt *_Nullable stmt;
} cql_boxed_stmt;
// builtin blob
typedef struct cql_blob *cql_blob_ref;
typedef struct cql_blob {
cql_type base;
const void *_Nonnull ptr;
cql_uint32 size;
} cql_blob;
#define cql_blob_retain(object) cql_retain((cql_type_ref)object);
#define cql_blob_release(object) cql_release((cql_type_ref)object);
cql_blob_ref _Nonnull cql_blob_ref_new(const void *_Nonnull data, cql_uint32 size);
#define cql_get_blob_bytes(data) (data->ptr)
#define cql_get_blob_size(data) (data->size)
cql_hash_code cql_blob_hash(cql_blob_ref _Nullable str);
cql_bool cql_blob_equal(cql_blob_ref _Nullable blob1, cql_blob_ref _Nullable blob2);
// builtin string
typedef struct cql_string *cql_string_ref;
typedef struct cql_string {
cql_type base;
const char *_Nullable ptr;
} cql_string;
cql_string_ref _Nonnull cql_string_ref_new(const char *_Nonnull cstr);
#define cql_string_retain(string) cql_retain((cql_type_ref)string);
#define cql_string_release(string) cql_release((cql_type_ref)string);
#define cql_string_literal(name, text) \
static cql_string name##_ = { \
.base = { \
.type = CQL_C_TYPE_STRING, \
.ref_count = 1, \
.finalize = NULL, \
}, \
.ptr = text, \
}; \
static cql_string_ref name = &name##_
#define cql_string_proc_name(name, proc_name) \
cql_string name##_ = { \
.base = { \
.type = CQL_C_TYPE_STRING, \
.ref_count = 1, \
.finalize = NULL, \
}, \
.ptr = proc_name, \
}; \
cql_string_ref name = &name##_
int cql_string_compare(cql_string_ref _Nonnull s1, cql_string_ref _Nonnull s2);
cql_hash_code cql_string_hash(cql_string_ref _Nullable str);
cql_bool cql_string_equal(cql_string_ref _Nullable s1, cql_string_ref _Nullable s2);
int cql_string_like(cql_string_ref _Nonnull s1, cql_string_ref _Nonnull s2);
#define cql_alloc_cstr(cstr, str) const char *_Nonnull cstr = (str)->ptr
#define cql_free_cstr(cstr, str) 0
// builtin result set
typedef struct cql_result_set *cql_result_set_ref;
typedef struct cql_result_set_meta {
// release the internal memory for the rowset
void (*_Nonnull teardown)(cql_result_set_ref _Nonnull result_set);
// copy a slice of a result set starting at from of length count
void (*_Nullable copy)(
cql_result_set_ref _Nonnull result_set,
cql_result_set_ref _Nullable *_Nonnull to_result_set,
cql_int32 from,
cql_int32 count);
// hash a row in a row set using the metadata
cql_hash_code (*_Nullable rowHash)(
cql_result_set_ref _Nonnull result_set,
cql_int32 row);
// compare two rows for equality
cql_bool (*_Nullable rowsEqual)(
cql_result_set_ref _Nonnull rs1,
cql_int32 row1,
cql_result_set_ref _Nonnull rs2,
cql_int32 row2);
// compare two rows for the same identity column value(s)
cql_bool (*_Nullable rowsSame)(
cql_result_set_ref _Nonnull rs1,
cql_int32 row1,
cql_result_set_ref _Nonnull rs2,
cql_int32 row2);
// check whether the column value is encoded
cql_bool(*_Nullable getIsEncoded)(
cql_result_set_ref _Nonnull result_set,
cql_int32 col);
// count of references and offset to the first
uint16_t refsCount;
uint16_t refsOffset;
// offsets to all the columns
uint16_t *_Nullable columnOffsets;
// size of the row
size_t rowsize;
// number of columns
cql_int32 columnCount;
// count and column indexes of all the columns in the identity
uint16_t *_Nullable identityColumns;
// all datatypes of the columns
uint8_t *_Nullable dataTypes;
// index of the encode context column
int16_t encodeContextIndex;
} cql_result_set_meta;
typedef struct cql_result_set {
cql_type base;
cql_result_set_meta meta;
cql_int32 count;
void *_Nonnull data;
} cql_result_set;
#define cql_result_set_type_decl(result_set_type, result_set_ref) \
typedef struct _##result_set_type *result_set_ref;
cql_result_set_ref _Nonnull cql_result_set_create(
void *_Nonnull data,
cql_int32 count,
cql_result_set_meta meta);
#define cql_result_set_retain(result_set) cql_retain((cql_type_ref)result_set);
#define cql_result_set_release(result_set) cql_release((cql_type_ref)result_set);
#define cql_result_set_note_ownership_transferred(result_set)
#define cql_result_set_get_meta(result_set) (&((cql_result_set_ref)result_set)->meta)
#define cql_result_set_get_data(result_set) ((cql_result_set_ref)result_set)->data
#define cql_result_set_get_count(result_set) ((cql_result_set_ref)result_set)->count
#ifdef CQL_RUN_TEST
#define sqlite3_step mockable_sqlite3_step
SQLITE_API cql_code mockable_sqlite3_step(sqlite3_stmt *_Nonnull);
#endif
// No-op implementation of profiling
// * Note: we emit the crc as an expression just to be sure that there are no compiler
// errors caused by names being incorrect. This improves the quality of the CQL
// code gen tests significantly. If these were empty macros (as they once were)
// you could emit any junk in the call and it would still compile.
#define cql_profile_start(crc, index) (void)crc; (void)index;
#define cql_profile_stop(crc, index) (void)crc; (void)index;
// the basic version doesn't use column getters
#define CQL_NO_GETTERS 1
// implementation of encoding values. All sensitive values read from sqlite db will
// be encoded at the source. CQL never decode encoded sensitive string unless the
// user call explicitly decode function from code.
cql_object_ref _Nullable cql_copy_encoder(sqlite3 *_Nonnull db);
cql_bool cql_encode_bool(
cql_object_ref _Nullable encoder,
cql_bool value,
cql_int32 context_type,
void *_Nullable context);
cql_int32 cql_encode_int32(
cql_object_ref _Nullable encoder,
cql_int32 value,
cql_int32 context_type,
void *_Nullable context);
cql_int64 cql_encode_int64(
cql_object_ref _Nullable encoder,
cql_int64 value,
cql_int32 context_type,
void *_Nullable context);
cql_double cql_encode_double(
cql_object_ref _Nullable encoder,
cql_double value,
cql_int32 context_type,
void *_Nullable context);
cql_string_ref _Nonnull cql_encode_string_ref_new(
cql_object_ref _Nullable encoder,
cql_string_ref _Nonnull value,
cql_int32 context_type,
void *_Nullable context);
cql_blob_ref _Nonnull cql_encode_blob_ref_new(
cql_object_ref _Nullable encoder,
cql_blob_ref _Nonnull value,
cql_int32 context_type,
void *_Nullable context);
cql_bool cql_decode_bool(
cql_object_ref _Nullable encoder,
cql_bool value,
cql_int32 context_type,
void *_Nullable context);
cql_int32 cql_decode_int32(
cql_object_ref _Nullable encoder,
cql_int32 value,
cql_int32 context_type,
void *_Nullable context);
cql_int64 cql_decode_int64(
cql_object_ref _Nullable encoder,
cql_int64 value,
cql_int32 context_type,
void *_Nullable context);
cql_double cql_decode_double(
cql_object_ref _Nullable encoder,
cql_double value,
cql_int32 context_type,
void *_Nullable context);
cql_string_ref _Nonnull cql_decode_string_ref_new(
cql_object_ref _Nullable encoder,
cql_string_ref _Nonnull value,
cql_int32 context_type,
void *_Nullable context);
cql_blob_ref _Nonnull cql_decode_blob_ref_new(
cql_object_ref _Nullable encoder,
cql_blob_ref _Nonnull value,
cql_int32 context_type,
void *_Nullable context);
cql_object_ref _Nonnull cql_box_stmt(sqlite3_stmt *_Nullable stmt);
sqlite3_stmt *_Nullable cql_unbox_stmt(cql_object_ref _Nonnull ref);
// NOTE: This must be included *after* all of the above symbols/macros.
#include "cqlrt_common.h"