SecDb.h
1 /* 2 * Copyright (c) 2012-2016 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 34 typedef struct __OpaqueSecDb *SecDbRef; 35 typedef struct __OpaqueSecDbConnection *SecDbConnectionRef; 36 typedef struct __OpaqueSecDbStatement *SecDbStatementRef; 37 struct SOSDigestVector; 38 39 // MARK: SecDbTransactionType 40 enum { 41 kSecDbNoneTransactionType = 0, 42 kSecDbImmediateTransactionType, 43 kSecDbExclusiveTransactionType, 44 kSecDbNormalTransactionType, 45 kSecDbExclusiveRemoteSOSTransactionType, 46 kSecDbExclusiveRemoteCKKSTransactionType, 47 }; 48 typedef CFOptionFlags SecDbTransactionType; 49 50 enum SecDbTransactionPhase { 51 kSecDbTransactionDidRollback = 0, // A transaction just got rolled back 52 kSecDbTransactionWillCommit, // A transaction is about to commit. 53 kSecDbTransactionDidCommit, // A transnaction successfully committed. 54 }; 55 typedef CFOptionFlags SecDbTransactionPhase; 56 57 enum SecDbTransactionSource { 58 kSecDbSOSTransaction = 0, // A remotely initated transaction (via SOS) 59 kSecDbCKKSTransaction = 3, // A transaction initiated by CKKS (either via remote notification or queue processing) 60 kSecDbAPITransaction = 1, // A user initated transaction. 61 kSecDbInvalidTransaction = 2, // An invalid transaction source (used for initialization) 62 63 }; 64 typedef CFOptionFlags SecDbTransactionSource; 65 66 // MARK: -- 67 // MARK: Error creation helpers. 68 69 // SQLITE3 errors are in this domain 70 extern CFStringRef kSecDbErrorDomain; 71 72 typedef CFTypeRef SecDbEntryRef; 73 74 bool SecDbError(int sql_code, CFErrorRef *error, CFStringRef format, ...) CF_FORMAT_FUNCTION(3, 4); 75 bool SecDbErrorWithDb(int sql_code, sqlite3 *db, CFErrorRef *error, CFStringRef format, ...) CF_FORMAT_FUNCTION(4, 5); 76 bool SecDbErrorWithStmt(int sql_code, sqlite3_stmt *stmt, CFErrorRef *error, CFStringRef format, ...) CF_FORMAT_FUNCTION(4, 5); 77 78 // MARK: mark - 79 // MARK: mark SecDbRef 80 81 void _SecDbServerSetup(void); 82 83 typedef CFTypeRef SecDbEventRef; 84 85 SecDbEventRef SecDbEventCreateWithComponents(CFTypeRef deleted, CFTypeRef inserted); 86 void SecDbEventTranslateComponents(SecDbEventRef item, CFTypeRef* deleted, CFTypeRef* inserted); 87 88 // Return deleted and inserted for a given changes entry, both are optional 89 bool SecDbEventGetComponents(SecDbEventRef event, CFTypeRef *deleted, CFTypeRef *inserted, CFErrorRef *error); 90 91 // changes is an array of SecDbEventRef 92 typedef void (^SecDBNotifyBlock)(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, CFArrayRef changes); 93 94 CFTypeID SecDbGetTypeID(void); 95 96 // Database creation 97 SecDbRef 98 SecDbCreate(CFStringRef dbName, mode_t mode, 99 bool readWrite, bool allowRepair, bool useWAL, bool useRobotVacuum, uint8_t maxIdleHandles, 100 bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)); 101 102 void SecDbAddNotifyPhaseBlock(SecDbRef db, SecDBNotifyBlock notifyPhase); 103 void SecDbSetCorruptionReset(SecDbRef db, void (^corruptionReset)(void)); 104 105 // Read only connections go to the end of the queue, writeable 106 // connections go to the start of the queue. Use SecDbPerformRead() and SecDbPerformWrite() if you 107 // can to avoid leaks. 108 SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef *error); 109 bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db, bool readOnly, SecDbConnectionRef* dbconnRef, CFErrorRef *error); 110 void SecDbConnectionRelease(SecDbConnectionRef dbconn); 111 112 // Perform a database read operation, 113 bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)); 114 bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn)); 115 116 // TODO: DEBUG only -> Private header 117 CFIndex SecDbIdleConnectionCount(SecDbRef db); 118 void SecDbReleaseAllConnections(SecDbRef db); 119 120 void SecDbForceClose(SecDbRef db); 121 122 CFStringRef SecDbGetPath(SecDbRef db); 123 124 // MARK: - 125 // MARK: SecDbConectionRef 126 127 CFTypeID SecDbConnectionGetTypeID(void); 128 129 bool SecDbPrepare(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, void(^exec)(sqlite3_stmt *stmt)); 130 131 bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, void (^row)(bool *stop)); 132 133 bool SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error); 134 135 bool SecDbCheckpoint(SecDbConnectionRef dbconn, CFErrorRef *error); 136 137 bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType ttype, CFErrorRef *error, 138 void (^transaction)(bool *commit)); 139 140 sqlite3 *SecDbHandle(SecDbConnectionRef dbconn); 141 142 bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn); 143 144 // Do not call this unless you are SecDbItem! 145 void SecDbRecordChange(SecDbConnectionRef dbconn, CFTypeRef deleted, CFTypeRef inserted); 146 147 void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn, bool barrier, dispatch_block_t perform); 148 void SecDBManagementTasks(SecDbConnectionRef dbconn); 149 150 // MARK: - 151 // MARK: Bind helpers 152 153 bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); 154 bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); 155 bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error); 156 bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error); 157 bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error); 158 bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef *error); 159 160 // MARK: - 161 // MARK: SecDbStatementRef 162 163 bool SecDbReset(sqlite3_stmt *stmt, CFErrorRef *error); 164 bool SecDbClearBindings(sqlite3_stmt *stmt, CFErrorRef *error); 165 bool SecDbFinalize(sqlite3_stmt *stmt, CFErrorRef *error); 166 sqlite3_stmt *SecDbPrepareV2(SecDbConnectionRef dbconn, const char *sql, size_t sqlLen, const char **sqlTail, CFErrorRef *error); 167 sqlite3_stmt *SecDbCopyStmt(SecDbConnectionRef dbconn, CFStringRef sql, CFStringRef *tail, CFErrorRef *error); 168 bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn, CFStringRef sql, sqlite3_stmt *stmt, CFErrorRef *error); 169 bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, bool(^perform)(sqlite3_stmt *stmt)); 170 bool SecDbForEach(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)); 171 172 // Mark the database as corrupted. 173 void SecDbCorrupt(SecDbConnectionRef dbconn, CFErrorRef error); 174 175 // Testing only. Normally this calls exit() so make it do something more test-friendly instead 176 extern void (*SecDbCorruptionExitHandler)(void); 177 void SecDbResetCorruptionExitHandler(void); 178 __END_DECLS 179 180 #endif /* !_UTILITIES_SECDB_H_ */