2  * Copyright (c) 2012-2016 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25 #ifndef _UTILITIES_SECDB_H_ 
  26 #define _UTILITIES_SECDB_H_ 
  28 #include <CoreFoundation/CoreFoundation.h> 
  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
; 
  39 // MARK: Configuration values, not used by clients directly. 
  40 // TODO: Move this section to a private header 
  44     kSecDbMaxIdleHandles 
= 3, 
  47 // MARK: SecDbTransactionType 
  49     kSecDbNoneTransactionType 
= 0, 
  50     kSecDbImmediateTransactionType
, 
  51     kSecDbExclusiveTransactionType
, 
  52     kSecDbNormalTransactionType
, 
  53     kSecDbExclusiveRemoteSOSTransactionType
, 
  54     kSecDbExclusiveRemoteCKKSTransactionType
, 
  56 typedef CFOptionFlags SecDbTransactionType
; 
  58 enum SecDbTransactionPhase 
{ 
  59     kSecDbTransactionDidRollback 
= 0,       // A transaction just got rolled back 
  60     kSecDbTransactionWillCommit
,        // A transaction is about to commit. 
  61     kSecDbTransactionDidCommit
,         // A transnaction sucessfully committed. 
  63 typedef CFOptionFlags SecDbTransactionPhase
; 
  65 enum SecDbTransactionSource 
{ 
  66     kSecDbSOSTransaction 
= 0,        // A remotely initated transaction (via SOS) 
  67     kSecDbCKKSTransaction 
= 3,       // A transaction initiated by CKKS (either via remote notification or queue processing) 
  68     kSecDbAPITransaction 
= 1,        // A user initated transaction. 
  69     kSecDbInvalidTransaction 
= 2,    // An invalid transaction source (used for initialization) 
  72 typedef CFOptionFlags SecDbTransactionSource
; 
  75 // MARK: Error creation helpers. 
  77 // SQLITE3 errors are in this domain 
  78 extern CFStringRef kSecDbErrorDomain
; 
  80 typedef CFTypeRef SecDbEntryRef
; 
  82 bool SecDbError(int sql_code
, CFErrorRef 
*error
, CFStringRef format
, ...) CF_FORMAT_FUNCTION(3, 4); 
  83 bool SecDbErrorWithDb(int sql_code
, sqlite3 
*db
, CFErrorRef 
*error
, CFStringRef format
, ...) CF_FORMAT_FUNCTION(4, 5); 
  84 bool SecDbErrorWithStmt(int sql_code
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, CFStringRef format
, ...) CF_FORMAT_FUNCTION(4, 5); 
  87 // MARK: mark SecDbRef 
  89 void _SecDbServerSetup(void); 
  91 typedef CFTypeRef SecDbEventRef
; 
  93 SecDbEventRef 
SecDbEventCreateWithComponents(CFTypeRef deleted
, CFTypeRef inserted
); 
  94 void SecDbEventTranslateComponents(SecDbEventRef item
, CFTypeRef
* deleted
, CFTypeRef
* inserted
); 
  96 // Return deleted and inserted for a given changes entry, both are optional 
  97 bool SecDbEventGetComponents(SecDbEventRef event
, CFTypeRef 
*deleted
, CFTypeRef 
*inserted
, CFErrorRef 
*error
); 
  99 // changes is an array of SecDbEventRef 
 100 typedef void (^SecDBNotifyBlock
)(SecDbConnectionRef dbconn
, SecDbTransactionPhase phase
, SecDbTransactionSource source
, CFArrayRef changes
); 
 102 CFTypeID 
SecDbGetTypeID(void); 
 105 SecDbRef 
SecDbCreateWithOptions(CFStringRef dbName
, mode_t mode
, bool readWrite
, bool allowRepair
, bool useWAL
, bool (^opened
)(SecDbRef db
, SecDbConnectionRef dbconn
, bool didCreate
, bool *callMeAgainForNextConnection
, CFErrorRef 
*error
)); 
 107 SecDbRef 
SecDbCreate(CFStringRef dbName
, bool (^opened
)(SecDbRef db
, SecDbConnectionRef dbconn
, bool didCreate
, bool *callMeAgainForNextConnection
, CFErrorRef 
*error
)); 
 109 void SecDbAddNotifyPhaseBlock(SecDbRef db
, SecDBNotifyBlock notifyPhase
); 
 110 void SecDbSetCorruptionReset(SecDbRef db
, void (^corruptionReset
)(void)); 
 112 // Read only connections go to the end of the queue, writeable 
 113 // connections go to the start of the queue.  Use SecDbPerformRead() and SecDbPerformWrite() if you 
 114 // can to avoid leaks. 
 115 SecDbConnectionRef 
SecDbConnectionAcquire(SecDbRef db
, bool readOnly
, CFErrorRef 
*error
); 
 116 bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db
, bool readOnly
, SecDbConnectionRef
* dbconnRef
, CFErrorRef 
*error
); 
 117 void SecDbConnectionRelease(SecDbConnectionRef dbconn
); 
 119 // Perform a database read operation, 
 120 bool SecDbPerformRead(SecDbRef db
, CFErrorRef 
*error
, void (^perform
)(SecDbConnectionRef dbconn
)); 
 121 bool SecDbPerformWrite(SecDbRef db
, CFErrorRef 
*error
, void (^perform
)(SecDbConnectionRef dbconn
)); 
 123 // TODO: DEBUG only -> Private header 
 124 CFIndex 
SecDbIdleConnectionCount(SecDbRef db
); 
 125 void SecDbReleaseAllConnections(SecDbRef db
); 
 126 bool SecDbReplace(SecDbRef db
, CFStringRef newDbPath
, CFErrorRef 
*error
); 
 128 CFStringRef 
SecDbGetPath(SecDbRef db
); 
 131 // MARK: SecDbConectionRef 
 133 CFTypeID 
SecDbConnectionGetTypeID(void); 
 135 bool SecDbPrepare(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
, void(^exec
)(sqlite3_stmt 
*stmt
)); 
 137 bool SecDbStep(SecDbConnectionRef dbconn
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, void (^row
)(bool *stop
)); 
 139 bool SecDbExec(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
); 
 141 bool SecDbCheckpoint(SecDbConnectionRef dbconn
, CFErrorRef 
*error
); 
 143 bool SecDbTransaction(SecDbConnectionRef dbconn
, SecDbTransactionType ttype
, CFErrorRef 
*error
, 
 144                       void (^transaction
)(bool *commit
)); 
 146 sqlite3 
*SecDbHandle(SecDbConnectionRef dbconn
); 
 148 // Do not call this unless you are SecDbItem! 
 149 void SecDbRecordChange(SecDbConnectionRef dbconn
, CFTypeRef deleted
, CFTypeRef inserted
); 
 151 void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn
, bool barrier
, dispatch_block_t perform
); 
 154 // MARK: Bind helpers 
 157 bool SecDbBindNull(sqlite3_stmt 
*stmt
, int param
, CFErrorRef 
*error
); 
 159 bool SecDbBindBlob(sqlite3_stmt 
*stmt
, int param
, const void *zData
, size_t n
, void(*xDel
)(void*), CFErrorRef 
*error
); 
 160 bool SecDbBindText(sqlite3_stmt 
*stmt
, int param
, const char *zData
, size_t n
, void(*xDel
)(void*), CFErrorRef 
*error
); 
 161 bool SecDbBindDouble(sqlite3_stmt 
*stmt
, int param
, double value
, CFErrorRef 
*error
); 
 162 bool SecDbBindInt(sqlite3_stmt 
*stmt
, int param
, int value
, CFErrorRef 
*error
); 
 163 bool SecDbBindInt64(sqlite3_stmt 
*stmt
, int param
, sqlite3_int64 value
, CFErrorRef 
*error
); 
 164 bool SecDbBindObject(sqlite3_stmt 
*stmt
, int param
, CFTypeRef value
, CFErrorRef 
*error
); 
 167 // MARK: SecDbStatementRef 
 169 bool SecDbReset(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
); 
 170 bool SecDbClearBindings(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
); 
 171 bool SecDbFinalize(sqlite3_stmt 
*stmt
, CFErrorRef 
*error
); 
 172 sqlite3_stmt 
*SecDbPrepareV2(SecDbConnectionRef dbconn
, const char *sql
, size_t sqlLen
, const char **sqlTail
, CFErrorRef 
*error
); 
 173 sqlite3_stmt 
*SecDbCopyStmt(SecDbConnectionRef dbconn
, CFStringRef sql
, CFStringRef 
*tail
, CFErrorRef 
*error
); 
 174 bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn
, CFStringRef sql
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
); 
 175 bool SecDbWithSQL(SecDbConnectionRef dbconn
, CFStringRef sql
, CFErrorRef 
*error
, bool(^perform
)(sqlite3_stmt 
*stmt
)); 
 176 bool SecDbForEach(SecDbConnectionRef dbconn
, sqlite3_stmt 
*stmt
, CFErrorRef 
*error
, bool(^row
)(int row_index
)); 
 178 // Mark the database as corrupted. 
 179 void SecDbCorrupt(SecDbConnectionRef dbconn
, CFErrorRef error
); 
 183 #endif /* !_UTILITIES_SECDB_H_ */