]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/sqlite++.h
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / sqlite++.h
1 /*
2 * Copyright (c) 2008,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 //
24 // sqlite++ - C++ interface to SQLite3
25 //
26 #ifndef _H_SQLITEPP
27 #define _H_SQLITEPP
28
29 #include <sqlite3.h>
30 #include <security_utilities/errors.h>
31 #include <security_utilities/threading.h>
32 #include <CoreFoundation/CFData.h>
33
34
35 namespace Security {
36 namespace SQLite3 {
37
38 class Database;
39 class Statement;
40
41 typedef sqlite3_int64 int64;
42 typedef sqlite3_uint64 uint64;
43
44
45 //
46 // An sqlite3 error
47 //
48 class Error : public CommonError {
49 public:
50 Error(Database &db);
51 Error(int err) : error(err) { }
52 Error(int err, const char *msg) : error(err), message(msg) { }
53 ~Error() throw () { }
54 const int error;
55 const std::string message;
56
57 const char *what() const throw () { return message.c_str(); }
58 OSStatus osStatus() const;
59 int unixError() const;
60
61 static void check(int err);
62 static void throwMe(int err) __attribute__((noreturn));
63 };
64
65
66 //
67 // An sqlite3 database "connection"
68 //
69 class Database {
70 friend class Statement;
71 public:
72 Database(const char *path, int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, bool lenient = false);
73 virtual ~Database();
74
75 bool isOpen() const { return mDb != NULL; }
76 void close();
77
78 // open flags
79 int openFlags() const { return mOpenFlags; }
80
81 // last error condition encountered
82 int errcode();
83 const char *errmsg();
84
85 bool inTransaction();
86 int64 lastInsert();
87 int changes();
88
89 void interrupt();
90
91 int execute(const char *text, bool strict = true);
92 int execute(const std::string &text, bool strict = true)
93 { return execute(text.c_str(), strict); }
94
95 bool empty();
96
97 template <class RType> RType value(const char *text, RType defaultResult = RType());
98 template <class RType> RType value(const std::string &text, RType defaultResult = RType())
99 { return value(text.c_str(), defaultResult); }
100
101 double julianNow()
102 { return this->value<double>("SELECT JULIANDAY('now');"); }
103
104 void busyDelay(int ms);
105
106 void check(int err);
107
108 sqlite3 *sql() const { return mDb; }
109
110 private:
111 sqlite3 *mDb;
112 Mutex mMutex;
113 int mOpenFlags;
114 };
115
116
117 //
118 // An sqlite column value.
119 // These are definitely not first-class API objects; in particular,
120 // there doesn't seem to be API to actually *make* one - you can only
121 // get them out of sqlite.
122 //
123 class Value {
124 public:
125 Value(sqlite3_value *v) : mValue(v) { }
126
127 operator int () const { return ::sqlite3_value_int(mValue); }
128 operator sqlite3_int64 () const { return ::sqlite3_value_int64(mValue); }
129 operator const char * () const { return (const char *)::sqlite3_value_text(mValue); }
130 operator double () const { return ::sqlite3_value_double(mValue); }
131
132 int type() const { return ::sqlite3_value_type(mValue); }
133 int numericType() const { return ::sqlite3_value_numeric_type(mValue); }
134
135 operator bool () const { return type() != SQLITE_NULL; }
136 bool operator ! () const { return type() == SQLITE_NULL; }
137
138 sqlite3_value *sql() const { return mValue; }
139
140 private:
141 sqlite3_value *mValue;
142 };
143
144
145 //
146 // A Transaction proxy.
147 //
148 class Transaction {
149 public:
150 enum Type {
151 deferred,
152 immediate,
153 exclusive
154 };
155
156 public:
157 Transaction(Database &db, Type type = deferred, const char *name = NULL);
158 virtual ~Transaction();
159
160 void commit();
161 void abort();
162 void rollback() { this->abort(); }
163
164 Database &database;
165
166 protected:
167 void xactCommand(const std::string &s);
168
169 private:
170 std::string mName;
171 };
172
173
174 //
175 // A (prepared) statement.
176 //
177 class Statement : private StLock<Mutex> {
178 class Binding;
179
180 public:
181 Statement(Database &db, const char *text); // ready to serve
182 Statement(Database &db); // quiescent; call query(text) to activate it
183 virtual ~Statement();
184
185 Database &database;
186
187 operator bool () const { return mStmt != NULL; } // active
188
189 void query(const char *text); // activate statement with query text
190 void query(const std::string &text)
191 { query(text.c_str()); }
192 void close(); // close up active statement
193
194 Binding bind(int ix) const { return Binding(*this, ix); }
195 Binding bind(const char *name) const;
196 unsigned int bindings() const { return ::sqlite3_bind_parameter_count(mStmt); }
197 void unbind();
198
199 int step();
200 void execute();
201 bool nextRow();
202 bool operator () () { return nextRow(); }
203
204 void reset();
205
206 class Result;
207 Result operator [] (int ix) { return Result(*this, ix); }
208 unsigned int count() const { return ::sqlite3_column_count(mStmt); }
209
210 void check(int err) const { database.check(err); }
211 sqlite3_stmt *sql() const { return mStmt; }
212
213 private:
214 class Column {
215 public:
216 Column(const Statement &st, int ix) : statement(st), index(ix) { }
217
218 const Statement &statement;
219 const int index;
220 };
221
222 class Binding : public Column {
223 public:
224 Binding(const Statement &st, int ix) : Column(st, ix) { }
225
226 const char *name() const;
227
228 void null();
229 void operator = (int value);
230 void operator = (sqlite3_int64 value);
231 void operator = (double value);
232 void operator = (const char *value);
233 void operator = (const std::string &value);
234 void operator = (const Value &value);
235 void integer(sqlite3_int64 value);
236 void blob(const void *data, size_t length, bool shared = false);
237 void operator = (CFDataRef data);
238 void operator = (CFStringRef value);
239 };
240
241 public:
242 class Result : public Column {
243 public:
244 Result(const Statement &st, int ix) : Column(st, ix) { }
245
246 const char *name() const;
247
248 operator int () const { return ::sqlite3_column_int(statement.sql(), index); }
249 operator sqlite3_int64 () const { return ::sqlite3_column_int64(statement.sql(), index); }
250 operator double () const { return ::sqlite3_column_double(statement.sql(), index); }
251 const char *string() const { return (const char *)::sqlite3_column_text(statement.sql(), index); }
252 operator const char *() const { return this->string(); }
253 const void *blob() const { return ::sqlite3_column_blob(statement.sql(), index); }
254 int length() const { return ::sqlite3_column_bytes(statement.sql(), index); }
255 CFDataRef data() const;
256
257 int type() const { return ::sqlite3_column_type(statement.sql(), index); }
258 const char *declType() const { return ::sqlite3_column_decltype(statement.sql(), index); }
259
260 operator bool () const { return type() != SQLITE_NULL; }
261 bool operator ! () const { return type() == SQLITE_NULL; }
262 };
263
264 private:
265 sqlite3_stmt *mStmt;
266 };
267
268
269 template <class RType>
270 RType Database::value(const char *text, RType defaultResult)
271 {
272 Statement stmt(*this, text);
273 if (stmt())
274 return RType(stmt[0]);
275 else
276 return defaultResult;
277 }
278
279
280
281 } // SQLite3
282 } // Security
283
284 #endif //_H_SQLITEPP