1/* 2 * Copyright (c) 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 25#ifndef _UTILITIES_SECDB_H_ 26#define _UTILITIES_SECDB_H_ 27 28#include <CoreFoundation/CoreFoundation.h> 29#include <sqlite3.h> 30 31__BEGIN_DECLS 32 33// MARK: SecDbRef and SecDbConnectionRef forward declarations 34typedef struct __OpaqueSecDb *SecDbRef; 35typedef struct __OpaqueSecDbConnection *SecDbConnectionRef; 36typedef struct __OpaqueSecDbStatement *SecDbStatementRef; 37struct SOSDigestVector; 38 39// MARK: Configuration values, not used by clients directly. 40// TODO: Move this section to a private header 41enum { 42 kSecDbMaxReaders = 4, 43 kSecDbMaxWriters = 1, 44 kSecDbMaxIdleHandles = 3, 45}; 46 47// MARK: SecDbTransactionType 48enum { 49 kSecDbNoneTransactionType = 0, 50 kSecDbImmediateTransactionType, 51 kSecDbExclusiveTransactionType, 52 kSecDbNormalTransactionType, 53 kSecDbExclusiveRemoteTransactionType, 54}; 55typedef CFOptionFlags SecDbTransactionType; 56 57enum SecDbTransactionPhase { 58 kSecDbTransactionDidRollback = 0, // A transaction just got rolled back 59 kSecDbTransactionWillCommit, // A transaction is about to commit. 60 kSecDbTransactionDidCommit, // A transnaction sucessfully committed. 61}; 62typedef CFOptionFlags SecDbTransactionPhase; 63 64enum SecDbTransactionSource { 65 kSecDbSOSTransaction, // A remotely initated transaction. 66 kSecDbAPITransaction, // A user initated transaction. 67}; 68typedef CFOptionFlags SecDbTransactionSource; 69 70// MARK: -- 71// MARK: Error creation helpers. 72 73// SQLITE3 errors are in this domain 74extern CFStringRef kSecDbErrorDomain; 75 76bool SecDbError(int sql_code, CFErrorRef *error, CFStringRef format, ...); 77bool SecDbErrorWithDb(int sql_code, sqlite3 *db, CFErrorRef *error, CFStringRef format, ...); 78bool SecDbErrorWithStmt(int sql_code, sqlite3_stmt *stmt, CFErrorRef *error, CFStringRef format, ...); 79 80// MARK: mark - 81// MARK: mark SecDbRef 82 83typedef void (^SecDBNotifyBlock)(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, struct SOSDigestVector *removals, struct SOSDigestVector *additions); 84 85CFTypeID SecDbGetTypeID(void); 86 87SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbConnectionRef dbconn, bool did_create, CFErrorRef *error)); 88 89void SecDbSetNotifyPhaseBlock(SecDbRef db, SecDBNotifyBlock notifyPhase); 90 91// Read only connections go to the end of the queue, writeable 92// connections go to the start of the queue. Use SecDbPerformRead() and SecDbPerformWrite() if you 93// can to avoid leaks. 94SecDbConnectionRef SecDbConnectionAquire(SecDbRef db, bool readOnly, CFErrorRef *error); 95void SecDbConnectionRelease(SecDbConnectionRef dbconn); 96 97// Perform a database read operation, 98bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)); 99bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)); 100 101// TODO: DEBUG only -> Private header 102CFIndex SecDbIdleConnectionCount(SecDbRef db); 103 104CFStringRef SecDbGetPath(SecDbRef db); 105 106// MARK: - 107// MARK: SecDbConectionRef 108 109CFTypeID SecDbConnectionGetTypeID(void); 110 111bool SecDbPrepare(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, void(^exec)(sqlite3_stmt *stmt)); 112 113bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, void (^row)(bool *stop)); 114 115bool SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error); 116 117bool SecDbCheckpoint(SecDbConnectionRef dbconn, CFErrorRef *error); 118 119bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType ttype, CFErrorRef *error, 120 void (^transaction)(bool *commit)); 121 122sqlite3 *SecDbHandle(SecDbConnectionRef dbconn); 123 124// Do not call this unless you are SecDbItem! 125void SecDbRecordChange(SecDbConnectionRef dbconn, CFDataRef deleted, CFDataRef inserted); 126 127// MARK: - 128// MARK: Bind helpers 129 130#if 0 131bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error); 132#endif 133bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); 134bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); 135bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error); 136bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error); 137bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error); 138bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef *error); 139 140// MARK: - 141// MARK: SecDbStatementRef 142 143bool SecDbReset(sqlite3_stmt *stmt, CFErrorRef *error); 144bool SecDbClearBindings(sqlite3_stmt *stmt, CFErrorRef *error); 145bool SecDbFinalize(sqlite3_stmt *stmt, CFErrorRef *error); 146sqlite3_stmt *SecDbPrepareV2(SecDbConnectionRef dbconn, const char *sql, size_t sqlLen, const char **sqlTail, CFErrorRef *error); 147sqlite3_stmt *SecDbCopyStmt(SecDbConnectionRef dbconn, CFStringRef sql, CFStringRef *tail, CFErrorRef *error); 148bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn, CFStringRef sql, sqlite3_stmt *stmt, CFErrorRef *error); 149bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, bool(^perform)(sqlite3_stmt *stmt)); 150bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)); 151 152// Mark the database as corrupted. 153void SecDbCorrupt(SecDbConnectionRef dbconn); 154 155__END_DECLS 156 157#endif /* !_UTILITIES_SECDB_H_ */ 158