summaryrefslogtreecommitdiffstats
path: root/database/sqlite
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2009-09-08 23:12:42 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2009-09-08 23:12:42 +0200
commitb1369101f94a107dd5d650dc4894abfa66ca6556 (patch)
tree558aaaef7dbb4c582c35790caabd869b36bf8f68 /database/sqlite
parent184ae2541ac312585c4358944385c7ed851c8d0b (diff)
downloadeurephia-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.c152
-rw-r--r--database/sqlite/sqlite.h98
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_ */