diff options
| author | David Sommerseth <dazo@users.sourceforge.net> | 2009-09-08 23:12:42 +0200 |
|---|---|---|
| committer | David Sommerseth <dazo@users.sourceforge.net> | 2009-09-08 23:12:42 +0200 |
| commit | b1369101f94a107dd5d650dc4894abfa66ca6556 (patch) | |
| tree | 558aaaef7dbb4c582c35790caabd869b36bf8f68 /database/sqlite | |
| parent | 184ae2541ac312585c4358944385c7ed851c8d0b (diff) | |
| download | eurephia-b1369101f94a107dd5d650dc4894abfa66ca6556.tar.gz eurephia-b1369101f94a107dd5d650dc4894abfa66ca6556.tar.xz eurephia-b1369101f94a107dd5d650dc4894abfa66ca6556.zip | |
Added comments to sqlite.[ch]
Diffstat (limited to 'database/sqlite')
| -rw-r--r-- | database/sqlite/sqlite.c | 152 | ||||
| -rw-r--r-- | database/sqlite/sqlite.h | 98 |
2 files changed, 210 insertions, 40 deletions
diff --git a/database/sqlite/sqlite.c b/database/sqlite/sqlite.c index 8646ea6..70ae682 100644 --- a/database/sqlite/sqlite.c +++ b/database/sqlite/sqlite.c @@ -19,6 +19,15 @@ * */ +/** + * @file sqlite.c + * @author David Sommerseth <dazo@users.sourceforge.net> + * @date 2008-08-06 + * + * @brief Generic functions to simplify the SQLite3 integration. + * + */ + #include <string.h> #include <stdlib.h> #include <assert.h> @@ -33,20 +42,30 @@ #include <eurephia_directions.h> #include <eurephiadb_mapping.h> -#define SQLITE_C #include "./sqlite.h" #ifdef MEMWATCH #include <memwatch.h> #endif +/** + * @{ + */ #define btWHERE 0x001 #define btINSERT 0x002 #define btUPDATE 0x004 +/** + * @} + */ -dbresult *glob_results = NULL; +dbresult *glob_results = NULL; /**< A local pointer needed for the SQLite3 callback function */ -// Free up a dbresult structure +/** + * Internal function. Free up a dbresult structure. This function is available via the + * the public macro sqlite_free_results() which is defined in sqlite.h + * + * @param inres Pointer to the dbresult structure to be freed + */ void _sqlite_free_results(dbresult *inres) { _sqlite_tuples *tup = NULL, *fld = NULL; @@ -91,9 +110,17 @@ void _sqlite_free_results(dbresult *inres) free_nullsafe(NULL, inres); } - -// Callback function used by sqlite3_exec - populates a global variable glob_results. -// The glob_results structure is allocated with a new address on each sqlite_query call +/** + * Callback function used by sqlite3_exec - populates a global variable glob_results. + * The glob_results structure is allocated with a new address on each sqlite_query call + * + * @param NotUsed N/A + * @param argc Number of fields in the result + * @param argv Array pointer to the values of the fields + * @param colName Array pointer to the field names (column names) + * + * @return SQLite3 defines 0 for no errors, and 1 for errors. + */ static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName) { // This callback function is called for each row returned by the query @@ -198,9 +225,15 @@ static int _cb_parse_result(void *NotUsed, int argc, char **argv, char **colName } -// A simpler way to fetch data from SQLite than to use sqlite3_exec with callback -// each time you want to do a query -dbresult *sqlite_query(eurephiaCTX *ctx, char *fmt, ... ) { +/** + * Main function for query a SQLite3 database. + * + * @param ctx eurephiaCTX + * @param fmt The SQL query. It supports stdarg to build up dynamic queries directly. + * + * @return Returns a pointer to a dbresult struct on success, otherwise NULL. + */ +dbresult *sqlite_query(eurephiaCTX *ctx, const char *fmt, ... ) { int rc; va_list ap; char *errMsg = NULL, *sql = NULL; @@ -251,6 +284,14 @@ dbresult *sqlite_query(eurephiaCTX *ctx, char *fmt, ... ) { return glob_results; } +/** + * Internal function. Checks if the input string contains reserved words + * + * @param reserved_words Array containing the reserver words + * @param val Value to check against the reserved words + * + * @return Returns 1 if a reserverd word is found, otherwise 0 + */ inline int SQLreservedWord(char **reserved_words, const char *val) { int i; @@ -264,6 +305,14 @@ inline int SQLreservedWord(char **reserved_words, const char *val) { } +/** + * Internal function. Creates a string with the value from a particular field in a eDBfieldMap and + * formats it properly according to its field type. + * + * @param ptr Pointer to the field in the eDBfieldMap + * + * @return Returns a string to be used within an SQL query. + */ char *_build_value_string(eDBfieldMap *ptr) { char *reserved_datetime[] = {"CURRENT_TIMESTAMP", "CURRENT_TIME", "CURRENT_DATE", NULL}; char *val = NULL; @@ -297,7 +346,28 @@ char *_build_value_string(eDBfieldMap *ptr) { return val; } + +/** + * Wrapper macro, which appends a string to a destination string without exceeding the size + * of the destination buffer. + * + * @param dest Pointer to the destination buffer + * @param src Pointer to the value being concatenated to the destination string. + * @param size Size of the destination buffer + */ #define append_str(dest, src, size) strncat(dest, src, (size - strlen_nullsafe(dest))) + + +/** + * Internal function. Builds up a part of an SQL query, depending on the buildType. The values + * are taken from a pointer to an eDBfieldMap keeping the values + * + * @param btyp Must be btWHERE, btINSERT or btUPDATE + * @param map Pointer to a eDBfieldMap chain containing the values + * + * @return Returns a string with parts of the SQL query containing the dynamic variables on success, + * otherwise NULL is returned. + */ char *_build_sqlpart(int btyp, eDBfieldMap *map) { eDBfieldMap *ptr = NULL; char *ret = NULL; @@ -408,6 +478,18 @@ char *_build_sqlpart(int btyp, eDBfieldMap *map) { } +/** + * Queries an SQLite3 database by using an SQL stub plus values from a eDBfieldMap pointer chain + * + * @param ctx eurephiaCTX + * @param qType Query type, must be SQL_SELECT, SQL_INSERT, SQL_UPDATE or SQL_DELETE + * @param sqlstub The generic part of the SQL query + * @param valMap Values to be used in INSERT or UPDATE queries. May be NULL if not SQL_INSERT or SQL_UPDATE + * @param whereMap Values to be used in the WHERE section of the SQL query + * @param sortkeys Only for SQL_SELECT, list of field names to sort the result by. + * + * @return Returns a pointer to a dbresult struct on success, otherwise NULL. + */ dbresult *sqlite_query_mapped(eurephiaCTX *ctx, SQLqueryType qType, const char *sqlstub, eDBfieldMap *valMap, eDBfieldMap *whereMap, const char *sortkeys) { @@ -456,7 +538,12 @@ dbresult *sqlite_query_mapped(eurephiaCTX *ctx, SQLqueryType qType, const char * return res; } -// Simple line-by-line result dumper +/** + * Very simple dbresult dumper. Will list out all records to the given FILE destination. + * + * @param dmp pointer to a FILE stream + * @param res pointe to the dbresults to be dumped + */ void sqlite_dump_result(FILE *dmp, dbresult *res) { _sqlite_tuples *row = NULL, *field = NULL; @@ -487,7 +574,17 @@ void sqlite_dump_result(FILE *dmp, dbresult *res) { // free(hdr); } -// Retrieve a specific value from a dbresult structure +/** + * Retrieves a particular value out of a dbresult + * + * @param res Pointer to dbresult + * @param row Row number (record number) to extract + * @param col Column number (field number) to extract + * + * @return Returns a pointer to the value if found, otherwise NULL is returned. + * @remark This function returns a pointer to the value insisde the dbresult struct. If you want to use + * this value after freeing the dbresult, you must make sure you copy this value yourself. + */ char *sqlite_get_value(dbresult *res, int row, int col) { _sqlite_tuples *ptr = res->srch_tuples; @@ -513,6 +610,20 @@ char *sqlite_get_value(dbresult *res, int row, int col) { #ifdef HAVE_LIBXML2 +/** + * Retrieves a particular value out of a dbresult and places it inside an xmlNode pointer. + * + * @param node Pointer to the xmlNode + * @param xmltyp Must be XML_ATTR or XML_NODE. If XML_ATTR it will be added as an attribute/properties + * to the given xmlNode. If XML_NODE, it will be added as a child to the given xmlNode. + * @param inname String containing the name of the attribute or XML tag. (Depending on xmltyp) + * @param res Pointer to dbresult + * @param row Row number (record number) to extract + * @param col Column number (field number) to extract + * + * @return Returns a pointer to the xmlNode which got updated. If xmltyp == XML_NODE it will point at + * the newly added node. On failure NULL will be returned. + */ xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *inname, dbresult *res, int row, int col) { xmlChar *name = NULL, *data = NULL; xmlNodePtr retnode = NULL; @@ -542,12 +653,27 @@ xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *inname, } #endif -// Retrieve number of tuples in current dbresult structure + +/** + * Retrieve number of tuples in a given dbresult structure + * + * @param res Pointer to a dbresult + * + * @return Returns number of rows/number of tuples in the result. + */ int sqlite_get_numtuples(dbresult *res) { return (res != NULL ? res->num_tuples : 0); } -// Retrieve number of tuples in current dbresult structure + +/** + * Retrieve number of affected tuples in current dbresult structure. This is only useful + * when called on a result from INSERT, UPDATE or DELETE queries. + * + * @param res Pointer to a dbresult + * + * @return Returns number of rows/tuples affected by the SQL query + */ int sqlite_get_affected_rows(dbresult *res) { return (res != NULL ? res->affected_rows : 0); } diff --git a/database/sqlite/sqlite.h b/database/sqlite/sqlite.h index 67b231d..ce482e4 100644 --- a/database/sqlite/sqlite.h +++ b/database/sqlite/sqlite.h @@ -19,6 +19,15 @@ * */ +/** + * @file sqlite.h + * @author David Sommerseth <dazo@users.sourceforge.net> + * @date 2008-08-06 + * + * @brief Generic functions to simplify the SQLite3 integration. + * + */ + #ifndef SQLITE_H_ # define SQLITE_H_ @@ -28,49 +37,85 @@ #endif #include <eurephiadb_mapping.h> +/** + * Defines XML field types, used when extracting SQLite3 results directly into an xmlNode + */ typedef enum _xmlFieldType { XML_ATTR, XML_NODE } xmlFieldType; +/** + * Contains information about all fields/columns in an SQLite3 result. + * It also keeps track over the length of the longest record/field value in the given field. + * + * This struct is built up as a dual-way chain pointer ring. So you need to keep an eye + * on the fieldid value to know if you have gone one round or not. + */ typedef struct __sqlite_header { - unsigned int fieldid; - char *name; + unsigned int fieldid; /**< Numeric field ID, starts at 1 and increases */ + char *name; /**< Name of the field/column */ // char *type; - size_t namelength; - size_t maxvaluelength; - struct __sqlite_header *next; - struct __sqlite_header *prev; + size_t namelength; /**< Length of the field name */ + size_t maxvaluelength; /**< Length of the longest record in this column */ + struct __sqlite_header *next; /**< Pointer to the next field */ + struct __sqlite_header *prev; /**< Pointer to the previous field */ } _sqlite_header; +/** + * Contains information about a particular data cell. That means one specific record + * in one specific column. + * + * This struct is built up as a dual-way chain pointer ring. So you need to keep an eye + * on the fieldid and/or tupleid value to know if you have gone one round or not. + */ typedef struct __sqlite_tuples { - unsigned int tupleid; - unsigned int fieldid; - char *value; - size_t length; - _sqlite_header *header; - struct __sqlite_tuples *nextfield; - struct __sqlite_tuples *prevfield; - struct __sqlite_tuples *nexttuple; - struct __sqlite_tuples *prevtuple; + unsigned int tupleid; /**< Defines the "record number" */ + unsigned int fieldid; /**< Defines the field ID this record belongs to */ + char *value; /**< Pointer to the value of this field */ + size_t length; /**< Length of the value of this field */ + _sqlite_header *header; /**< A pointer to the header record with more info about this field/column */ + struct __sqlite_tuples *nextfield; /**< Pointer to the same record, but the next field in it */ + struct __sqlite_tuples *prevfield; /**< Pointer to the same record, but the previous field in it */ + struct __sqlite_tuples *nexttuple; /**< Pointer to the same field, but the next record */ + struct __sqlite_tuples *prevtuple; /**< Pointer to the same field, but the previous record */ } _sqlite_tuples; +/** + * The main definition of the dbresult strucutre. This structure keeps the + * complete information about both fields and values of all records from a query. + * + * This structure keeps to "search" pointers. This is used when the sqlite_get_value() or + * sqlite_xml_value() functions are called. These pointers will point at the last record being looked + * up, so that if you do sequencial look ups, it will not loop through the whole chain from the start. + * Even if you go a little bit back an forth, it will find the quickest way to avoid as many iterations + * as possible. + */ typedef struct __sqlite_dbresult { - // start of the chains - _sqlite_tuples *tuples; - _sqlite_header *headerrec; - size_t num_tuples; - size_t num_fields; - sqlite_int64 last_insert_id; - int affected_rows; + // Query results + _sqlite_tuples *tuples; /**< Pointer to the chains which contains field values */ + _sqlite_header *headerrec; /**< Pointer to the chains with info about the field/columns */ + size_t num_tuples; /**< Number of records received in the SELECT query */ + size_t num_fields; /**< Number of fields for each record */ + sqlite_int64 last_insert_id; /**< Reference to the last record from a INSERT INTO statement */ + int affected_rows; /**< How many records where INSERTed, UPDATEd or DELETEd */ - // Used for search functions - _sqlite_tuples *srch_tuples; - _sqlite_header *srch_headerrec; + // "Search" pointers + _sqlite_tuples *srch_tuples; /**< "Cache" of the last record being looked up */ + _sqlite_header *srch_headerrec; /**< "Cache" of the last header record being looked up */ } dbresult; + +/** + * Enumeration of suported SQL queries via the sqlite_query_mapped() API + */ typedef enum _SQLqueryType { SQL_SELECT, SQL_INSERT, SQL_UPDATE, SQL_DELETE } SQLqueryType; -#ifndef SQLITE_C +/** + * Free up a dbresult structure. This is the public interface for the + * internal function _sqlite_free_results() + * + * @param r Pointer to the dbresult to be freed + */ #define sqlite_free_results(r) { _sqlite_free_results(r); r = NULL; } void _sqlite_free_results(dbresult *); dbresult *sqlite_query(eurephiaCTX *ctx, const char *, ...); @@ -83,6 +128,5 @@ xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *name, db void sqlite_dump_result(FILE *, dbresult *); int sqlite_get_numtuples(dbresult *); int sqlite_get_affected_rows(dbresult *); -#endif #endif /* !SQLITE_H_ */ |
