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