Update copyright year in (most) files (those that my script finds).
[exim.git] / src / src / lookups / sqlite.c
CommitLineData
d7d7b7b9 1/* $Cambridge: exim/src/src/lookups/sqlite.c,v 1.3 2006/02/07 11:19:01 ph10 Exp $ */
13b685f9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
d7d7b7b9 7/* Copyright (c) University of Cambridge 1995 - 2006 */
13b685f9
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10#include "../exim.h"
11#include "lf_functions.h"
12#include "sqlite.h"
13
14#ifndef LOOKUP_SQLITE
15static void dummy(int x) { dummy(x-1); }
16#else
17#include <sqlite3.h>
18
19
20/*************************************************
21* Open entry point *
22*************************************************/
23
24/* See local README for interface description. */
25
26void *
27sqlite_open(uschar *filename, uschar **errmsg)
28{
29sqlite3 *db = NULL;
30int ret;
31
32ret = sqlite3_open((char *)filename, &db);
33if (ret != 0)
34 {
35 *errmsg = (void *)sqlite3_errmsg(db);
36 debug_printf("Error opening database: %s\n", *errmsg);
37 }
38
31480e42 39sqlite3_busy_timeout(db, 1000 * sqlite_lock_timeout);
13b685f9
PH
40return db;
41}
42
43
44/*************************************************
45* Find entry point *
46*************************************************/
47
48/* See local README for interface description. */
49
50struct strbuf {
51 uschar *string;
52 int size;
53 int len;
54};
55
56static int sqlite_callback(void *arg, int argc, char **argv, char **azColName)
57{
58struct strbuf *res = arg;
59int i;
60
61/* For second and subsequent results, insert \n */
62
63if (res->string != NULL)
64 res->string = string_cat(res->string, &res->size, &res->len, US"\n", 1);
65
66if (argc > 1)
67 {
68 /* For multiple fields, include the field name too */
69 for (i = 0; i < argc; i++)
70 {
71 uschar *value = US((argv[i] != NULL)? argv[i]:"<NULL>");
72 res->string = lf_quote(US azColName[i], value, Ustrlen(value), res->string,
73 &res->size, &res->len);
74 }
75 }
76
77else
78 {
79 res->string = string_append(res->string, &res->size, &res->len, 1,
80 (argv[0] != NULL)? argv[0]:"<NULL>");
81 }
82
83res->string[res->len] = 0;
84return 0;
85}
86
87
88int
89sqlite_find(void *handle, uschar *filename, uschar *query, int length,
90 uschar **result, uschar **errmsg, BOOL *do_cache)
91{
92int ret;
93struct strbuf res = { NULL, 0, 0 };
94
95ret = sqlite3_exec(handle, (char *)query, sqlite_callback, &res, (char **)errmsg);
96if (ret != SQLITE_OK)
97 {
98 debug_printf("sqlite3_exec failed: %s\n", *errmsg);
99 return FAIL;
100 }
101
102if (res.string == NULL) *do_cache = FALSE;
103
104*result = res.string;
105return OK;
106}
107
108
109
110/*************************************************
111* Close entry point *
112*************************************************/
113
114/* See local README for interface description. */
115
116void sqlite_close(void *handle)
117{
118sqlite3_close(handle);
119}
120
121
122
123/*************************************************
124* Quote entry point *
125*************************************************/
126
127/* From what I have found so far, the only character that needs to be quoted
128for sqlite is the single quote, and it is quoted by doubling.
129
130Arguments:
131 s the string to be quoted
132 opt additional option text or NULL if none
133
134Returns: the processed string or NULL for a bad option
135*/
136
137uschar *
138sqlite_quote(uschar *s, uschar *opt)
139{
140register int c;
141int count = 0;
142uschar *t = s;
143uschar *quoted;
144
145if (opt != NULL) return NULL; /* No options recognized */
146
147while ((c = *t++) != 0) if (c == '\'') count++;
148
149if (count == 0) return s;
150t = quoted = store_get(Ustrlen(s) + count + 1);
151
152while ((c = *s++) != 0)
153 {
154 if (c == '\'') *t++ = '\'';
155 *t++ = c;
156 }
157
158*t = 0;
159return quoted;
160}
161
162#endif /* LOOKUP_SQLITE */
163
164/* End of lookups/sqlite.c */