]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/sqlite++.cpp
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / sqlite++.cpp
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 #include "sqlite++.h"
27 #include <stdexcept>
28 #include <security_utilities/cfutilities.h>
29 #include <security_utilities/debugging_internal.h>
30
31
32 //@@@
33 // From cssmapple.h - layering break
34 // Where should this go?
35 //@@@
36 #define errSecErrnoBase 100000
37 #define errSecErrnoLimit 100255
38
39
40 namespace Security {
41 namespace SQLite3 {
42
43
44 //
45 // Our exception object
46 //
47 void Error::check(int err)
48 {
49 if (err != SQLITE_OK)
50 throw Error(err);
51 }
52
53 Error::Error(Database &db)
54 : error(db.errcode()), message(db.errmsg())
55 {
56 SECURITY_EXCEPTION_THROW_SQLITE(this, error, (char*)message.c_str());
57 secnotice("security_exception", "sqlite: %d %s",error, (char*)message.c_str());
58 }
59
60 void Error::throwMe(int err)
61 {
62 throw Error(err);
63 }
64
65 OSStatus Error::osStatus() const
66 {
67 return unixError() + errSecErrnoBase;
68 }
69
70 int Error::unixError() const
71 {
72 switch (error) {
73 case SQLITE_PERM:
74 case SQLITE_READONLY:
75 case SQLITE_AUTH:
76 return EACCES;
77 case SQLITE_BUSY:
78 return EAGAIN;
79 case SQLITE_NOMEM:
80 return ENOMEM;
81 case SQLITE_IOERR:
82 return EIO;
83 case SQLITE_FULL:
84 return ENOSPC;
85 case SQLITE_TOOBIG:
86 return EFBIG;
87 case SQLITE_MISMATCH:
88 case SQLITE_MISUSE:
89 return EINVAL;
90 case SQLITE_NOLFS:
91 return ENOTSUP;
92 case SQLITE_RANGE:
93 return EDOM;
94 default:
95 return -1;
96 }
97 }
98
99
100 //
101 // Database objects
102 //
103 Database::Database(const char *path, int flags, bool lenient /* = false */)
104 : mMutex(Mutex::recursive)
105 {
106 try {
107 int rc = ::sqlite3_open_v2(path, &mDb, flags, NULL);
108 if (rc != SQLITE_OK && lenient) { // silent open failure
109 sqlite3_close(mDb); // ditch useless Db object
110 mDb = NULL; // indicate failure
111 return;
112 }
113 check(rc);
114 check(::sqlite3_extended_result_codes(mDb, true));
115 mOpenFlags = flags;
116 } catch (...) {
117 sqlite3_close(mDb); // allocated even if open fails(!)
118 throw;
119 }
120 }
121
122 Database::~Database()
123 {
124 this->close();
125 }
126
127 void Database::close()
128 {
129 if (mDb)
130 check(::sqlite3_close(mDb));
131 }
132
133
134 int Database::execute(const char *text, bool strict /* = true */)
135 {
136 StLock<Mutex> _(mMutex);
137
138 int rc = ::sqlite3_exec(mDb, text, NULL, NULL, NULL);
139 if (strict)
140 check(rc);
141 return rc;
142 }
143
144
145 void Database::busyDelay(int ms)
146 {
147 StLock<Mutex> _(mMutex);
148
149 check(::sqlite3_busy_timeout(mDb, ms));
150 }
151
152
153 void Database::check(int err)
154 {
155 if (err)
156 throw Error(*this);
157 }
158
159
160 bool Database::empty()
161 {
162 return value("select count(*) from sqlite_master;", 0) == 0;
163 }
164
165
166 int Database::errcode()
167 {
168 StLock<Mutex> _(mMutex);
169
170 return sqlite3_errcode(mDb);
171 }
172
173
174
175 const char *Database::errmsg()
176 {
177 StLock<Mutex> _(mMutex);
178
179 return sqlite3_errmsg(mDb);
180 }
181
182
183
184 bool Database::inTransaction()
185 {
186 StLock<Mutex> _(mMutex);
187
188 return !::sqlite3_get_autocommit(mDb);
189 }
190
191
192
193 int64 Database::lastInsert()
194 {
195 StLock<Mutex> _(mMutex);
196
197 return ::sqlite3_last_insert_rowid(mDb);
198 }
199
200 int Database::changes()
201 {
202 StLock<Mutex> _(mMutex);
203
204 return ::sqlite3_changes(mDb);
205 }
206
207 void Database::interrupt()
208 {
209 StLock<Mutex> _(mMutex);
210
211 ::sqlite3_interrupt(mDb);
212 }
213
214 //
215 // Transaction managers
216 //
217 Transaction::Transaction(Database &db, Type type, const char *name)
218 : database(db), mName(name ? name : "")
219 {
220 switch (type) {
221 case deferred: xactCommand("BEGIN DEFERRED"); break;
222 case immediate: xactCommand("BEGIN IMMEDIATE"); break;
223 case exclusive: xactCommand("BEGIN EXCLUSIVE"); break;
224 }
225 }
226
227 Transaction::~Transaction()
228 {
229 if (database.inTransaction()) {
230 // request rollback but ignore any errors
231 database.execute("ROLLBACK TRANSACTION", false);
232 }
233 }
234
235 void Transaction::commit()
236 {
237 xactCommand("COMMIT");
238 }
239
240 void Transaction::abort()
241 {
242 xactCommand("ROLLBACK");
243 }
244
245 void Transaction::xactCommand(const string &cmd)
246 {
247 database.execute(cmd + " TRANSACTION " + mName + ";");
248 }
249
250
251 //
252 // Statement objects
253 //
254 Statement::Statement(Database &db, const char *text)
255 : StLock<Mutex>(db.mMutex), database(db), mStmt(NULL)
256 {
257 this->query(text);
258 }
259
260 Statement::Statement(Database &db)
261 : StLock<Mutex>(db.mMutex), database(db), mStmt(NULL)
262 { }
263
264 void Statement::query(const char *text)
265 {
266 this->close();
267 const char *tail;
268 check(::sqlite3_prepare_v2(database.sql(), text, -1, &mStmt, &tail));
269 if (*tail)
270 throw std::logic_error("multiple statements");
271 }
272
273 void Statement::close()
274 {
275 // Sqlite3_finalize will return an error if the Statement (executed and) failed.
276 // So we eat any error code here, since we can't tell "genuine" errors apart from
277 // errors inherited from the Statement execution.
278 if (mStmt)
279 ::sqlite3_finalize(mStmt);
280 mStmt = NULL;
281 }
282
283 Statement::~Statement()
284 {
285 this->close();
286 }
287
288
289 void Statement::unbind()
290 {
291 check(::sqlite3_clear_bindings(mStmt));
292 }
293
294 void Statement::reset()
295 {
296 check(::sqlite3_reset(mStmt));
297 }
298
299
300 int Statement::step()
301 {
302 return ::sqlite3_step(mStmt);
303 }
304
305 void Statement::execute()
306 {
307 switch (int rc = this->step()) {
308 case SQLITE_DONE:
309 case SQLITE_OK:
310 break;
311 default:
312 check(rc);
313 }
314 }
315
316 bool Statement::nextRow()
317 {
318 switch (int rc = this->step()) {
319 case SQLITE_ROW:
320 return true;
321 case SQLITE_DONE:
322 return false;
323 default:
324 check(rc);
325 return false;
326 }
327 }
328
329
330 //
331 // Binding gluons.
332 //
333 Statement::Binding Statement::bind(const char *name) const
334 {
335 if (int ix = ::sqlite3_bind_parameter_index(mStmt, name))
336 return Binding(*this, ix);
337 else
338 throw std::logic_error("unknown parameter name");
339 }
340
341 void Statement::Binding::null()
342 {
343 statement.check(::sqlite3_bind_null(statement.sql(), index));
344 }
345
346 void Statement::Binding::operator = (const Value &value)
347 {
348 statement.check(::sqlite3_bind_value(statement.sql(), index, value.sql()));
349 }
350
351 void Statement::Binding::operator = (int value)
352 {
353 statement.check(::sqlite3_bind_int(statement.sql(), index, value));
354 }
355
356 void Statement::Binding::operator = (sqlite3_int64 value)
357 {
358 statement.check(::sqlite3_bind_int64(statement.sql(), index, value));
359 }
360
361 void Statement::Binding::integer(sqlite3_int64 value)
362 {
363 statement.check(::sqlite3_bind_int64(statement.sql(), index, value));
364 }
365
366 void Statement::Binding::operator = (double value)
367 {
368 statement.check(::sqlite3_bind_double(statement.sql(), index, value));
369 }
370
371 void Statement::Binding::operator = (const char *value)
372 {
373 if (value == NULL)
374 this->null();
375 else
376 statement.check(::sqlite3_bind_text(statement.sql(), index,
377 ::strdup(value), -1, ::free));
378 }
379
380 void Statement::Binding::operator = (const std::string &value)
381 {
382 statement.check(::sqlite3_bind_text(statement.sql(), index,
383 ::strdup(value.c_str()), -1, ::free));
384 }
385
386 void Statement::Binding::blob(const void *data, size_t length, bool shared /* = false */)
387 {
388 if (data == NULL)
389 this->null();
390 else if (shared) {
391 statement.check(::sqlite3_bind_blob(statement.sql(), index, data, (int)length, NULL));
392 } else if (void *copy = ::malloc(length)) {
393 ::memcpy(copy, data, length);
394 statement.check(::sqlite3_bind_blob(statement.sql(), index,
395 copy, (int)length, ::free));
396 } else
397 throw std::bad_alloc();
398 }
399
400 void Statement::Binding::operator = (CFDataRef data)
401 {
402 if (data)
403 this->blob(CFDataGetBytePtr(data), CFDataGetLength(data));
404 else
405 this->null();
406 }
407
408 void Statement::Binding::operator = (CFStringRef value)
409 {
410 if (value)
411 *this = cfString(value).c_str();
412 else
413 this->null();
414 }
415
416 const char *Statement::Binding::name() const
417 {
418 return sqlite3_bind_parameter_name(statement.sql(), index);
419 }
420
421
422 //
423 // Row/column results
424 //
425 const char *Statement::Result::name() const
426 {
427 return sqlite3_column_name(statement.sql(), index);
428 }
429
430 CFDataRef Statement::Result::data() const
431 {
432 switch (this->type()) {
433 case SQLITE_NULL:
434 return NULL;
435 case SQLITE_BLOB:
436 return makeCFData(this->blob(), this->length());
437 default:
438 throw Error(SQLITE_MISMATCH, "Retrieving data() of non-Blob");
439 }
440 }
441
442
443 } // SQLite3
444 } // Security