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