src.dualinventive.com/mtinfo/secureserver/legacy/lib/include/di-util/database.h

224 lines
7.6 KiB
C

/*
************************************************************************
**
** Copyright (c) 2009..2010 by
** Core|Vision B.V.
** Cereslaan 10b
** 5384 VT Heesch
** The Netherlands
**
** All Rights Reserved
**
************************************************************************
*/
/*
************************************************************************
**
** Project name: Dual Inventive: Utility Library
** Filename: database.h
** Author: Jack Weeland
** Date: October 27, 2009
** File version: 1.00 of October 27, 2009
**
************************************************************************
*/
/*
************************************************************************
**
** Database functions - definitions
**
** When you use the database functions defined in this file, you must
** link your executable with '-lmysql'.
**
************************************************************************
*/
#ifndef __DATABASE_H
#define __DATABASE_H
#include <stddef.h>
/*
** Data structures
*/
// handle for the database connection (as returned by 'db_init()')
typedef struct DATABASE *db_t;
// to determine the type of a field in the result set
typedef enum DATABASE_FIELD_TYPE
{
result_type_uint, // unsigned int
result_type_uint64, // unsigned long long _or_ my_ulonglong
result_type_int, // int
result_type_float, // float
result_type_string, // char*
result_type_binary, // unsigned char*
result_type_datetime // char*
} db_fieldtype_t;
// structure to store the results of a query
typedef struct DATABASE_RESULT {
// result data from the database
struct DATABASE_RESULT_DATA *data;
// linked list
struct DATABASE_RESULT *next;
} *db_result_t;
/*
** Initialisation
*/
// initialise a 'db_t' structure, set the database name (direct,
// using a string of the format "database:user:password@host:port"
// or "database:user:password@socket", or using a configu-
// ration file) and connect to it
// the database name can be set later, with 'db_set_database()',
// _but_ then 'db_connect()' must be called too; if such scenario,
// the argument for 'db_name' must be NULL
db_t db_init(const char *db_name);
void db_deinit(db_t db);
// set database name (direct or from a file) - only to be used when
// 'db' was initialized, but 'db_init()', with a NULL database
int db_set_database(db_t db, const char *db_name);
// connect to the database - see above
int db_connect(db_t db);
/*
** Run a query and process its results
**
** General operation:
**
** db_result_t results;
**
** db_query(db_handle, "SELECT string FROM whatever", &results);
** do
** {
** int i;
**
** for( i = 0; i < db_num_rows(results); i++) {
** printf("%d: %s\n", i, db_get_str(results, i, 0));
** }
** } while( db_next_result(&results) != NULL );
**
** or
**
** db_result_t results;
** int i;
**
** db_query(db_handle, "SELECT string FROM whatever", &results);
**
** for( i = 0; i < db_num_rows(results); i++) {
** printf("%d: %s\n", i, db_get_str(results, i, 0));
** }
** db_destroy_result(&results);
**
** and for simple queries that return one row
**
** db_result_t results;
**
** db_query(db_handle, "SELECT string FROM whatever WHERE id=1234", &results);
**
** printf("%s\n", db_get_str(results, 0, 0));
**
** db_destroy_result(&results);
**
*/
// run a query or a number of queries, separated by semicolons, and consume
// the result data from the database server; returns the number of items
// (should be equal to the number of actual queries) in the result set, or
// '-1' if an error was detected - the result set may still be valid!
// the result set must deleted with 'db_destroy_result()' or by calling
// 'db_next_result()' repeatedly until it returns NULL
int db_query(db_t, const char *query, db_result_t *resultset);
// value of the last insert item with an auto incremented identifier
unsigned long long db_last_id(db_t);
/*
** Operations on a result set of a query
*/
// get the next result from the result set; the current node is destroyed
// the next result set is returned _and_ the pointer 'resultset' is
// modified as well;
// returns NULL when there are no more results
db_result_t db_next_result(db_result_t *resultset);
// for simple queries, the result set can be destroyed with this function
int db_destroy_result(db_result_t *resultset);
// number of data rows in the result set
int db_num_rows(db_result_t resultset);
// number of fields per row
int db_num_fields(db_result_t resultset);
// get the index of a field by name
int db_get_field(db_result_t resultset, const char *field_name);
// get the name, type, length (size) and precision of a field
const char *db_field_name(db_result_t resultset, int field);
db_fieldtype_t db_field_type(db_result_t resultset, int field);
int db_field_length(db_result_t resultset, int field);
int db_field_precision(db_result_t resultset, int field);
// does a field have a NULL value?
int db_is_null(db_result_t resultset, int row, int field);
// get a field; the buffer must be large enough and it can be a pointer
// to an integer ('bufsz' = sizeof(int)), string (char* or unsigned char*,
// 'bufsz' is the length of the buffer, floating point or 64-bit integer
// (unsigned long long or my_ulonglong); the type of the field in the
// database determines the type of 'buffer'
// generic function, returns the number of bytes returned in 'buffer'
// to enquire the buffer size needed, specify 'buffer' as NULL and 'bufsz'
// as '0' and the funtion returns the number of bytes needed to store
// the result.
int db_get_data(db_result_t resultset, int row, int field, void *buffer, size_t bufsz);
// functions to get an (unsigned) integer and a string; the returned
// string is no longer valid after a call to 'db_next_result()'
int db_get_int(db_result_t resultset, int row, int field);
unsigned int db_get_uint(db_result_t resultset, int row, int field);
unsigned long long db_get_uint64(db_result_t resultset, int row, int field);
double db_get_float(db_result_t resultset, int row, int field);
const char *db_get_str(db_result_t resultset, int row, int field);
// get a date/time (time_t) from the result set
time_t db_get_date(db_result_t resultset, int row, int field);
// compare 'str' with the value in the database, minding the type of the field
// returns a negative number if the database field is less than 'str',
// zero if they are equal and a positive number otherwise, like strcmp()
// resp. strncmp() and memcmp()
// returns -1, 0 or +1 when the database data is an unsigned integer or a
// floating point number to avoid overflow issues
// returns -1 on error
int db_cmp(db_result_t resultset, int row, int field, const char *str);
int db_ncmp(db_result_t resultset, int row, int field, const char *str, size_t len);
/*
** Miscellaneous functions
*/
// errors from the database
int db_errno(db_t db);
const char *db_error(db_t db);
int db_error_str(db_t db, char *buffer, size_t bufsz);
// escape quotes (and other characters) in a string or a block of binary data
// - the variant with a user supplied buffer returns the length of 'escaped'
// - when using the variant with a static, please note that this buffer is 4096
// bytes in size (i.e. the length of 'str' must be less than 2048); supply
// a user buffer when this is not large enough
// the output buffer 'escaped' should be "2 * strlen(str) + 1"
// returns the number of characters in 'escaped' or '-1' on error (buffer too
// small or invalid parameters)
// NOTE: the output buffer _must_ be large enough, or these functions will fail!
const char *db_escape(db_t db, const char *str);
int db_escape_str(db_t db, const char *str, char *escaped, size_t escaped_sz);
int db_escape_bin(db_t db, const void *data, size_t data_sz, char *escaped, size_t escaped_sz);
#endif /* __DATABASE_H */