1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/* sqlite.h -- Generic functions to simplify SQLite3 queries - data structures defined here
*
* GPLv2 only - Copyright (C) 2008 - 2010
* David Sommerseth <dazo@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/**
* @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_
#include <stdarg.h>
#ifdef HAVE_LIBXML2
# include <libxml/tree.h>
#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; /**< Numeric field ID, starts at 1 and increases */
char *name; /**< Name of the field/column */
// char *type;
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; /**< 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 {
// 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 */
// "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;
/**
* 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 *, ...);
dbresult *sqlite_query_mapped(eurephiaCTX *ctx, SQLqueryType type, const char *sqlstub,
eDBfieldMap *valMap, eDBfieldMap *whereMap, const char *sortkeys);
char *sqlite_get_value(dbresult *res, int, int);
#ifdef HAVE_LIBXML2
xmlNodePtr sqlite_xml_value(xmlNodePtr node, xmlFieldType xmltyp, char *name, dbresult *res, int row, int col);
#endif
void sqlite_dump_result(FILE *, dbresult *);
/**
* Retrieve number of tuples in a given dbresult structure
*
* @param dbres Pointer to a dbresult
*
* @return Returns number of rows/number of tuples in the result.
*/
#define sqlite_get_numtuples(dbres) (dbres != NULL ? dbres->num_tuples : 0)
/**
* 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 dbres Pointer to a dbresult
*
* @return Returns number of rows/tuples affected by the SQL query
*/
#define sqlite_get_affected_rows(dbres) (dbres != NULL ? dbres->affected_rows : 0)
#endif /* !SQLITE_H_ */
|