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 successfully 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);
106 SecDbCreate(CFStringRef dbName
, mode_t mode
,
107 bool readWrite
, bool allowRepair
, bool useWAL
, bool useRobotVacuum
, uint8_t maxIdleHandles
,
108 bool (^opened
)(SecDbRef db
, SecDbConnectionRef dbconn
, bool didCreate
, bool *callMeAgainForNextConnection
, CFErrorRef
*error
));
110 void SecDbAddNotifyPhaseBlock(SecDbRef db
, SecDBNotifyBlock notifyPhase
);
111 void SecDbSetCorruptionReset(SecDbRef db
, void (^corruptionReset
)(void));
113 // Read only connections go to the end of the queue, writeable
114 // connections go to the start of the queue. Use SecDbPerformRead() and SecDbPerformWrite() if you
115 // can to avoid leaks.
116 SecDbConnectionRef
SecDbConnectionAcquire(SecDbRef db
, bool readOnly
, CFErrorRef
*error
);
117 bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db
, bool readOnly
, SecDbConnectionRef
* dbconnRef
, CFErrorRef
*error
);
118 void SecDbConnectionRelease(SecDbConnectionRef dbconn
);
120 // Perform a database read operation,
121 bool SecDbPerformRead(SecDbRef db
, CFErrorRef
*error
, void (^perform
)(SecDbConnectionRef dbconn
));
122 bool SecDbPerformWrite(SecDbRef db
, CFErrorRef
*error
, void (^perform
)(SecDbConnectionRef dbconn
));
124 // TODO: DEBUG only -> Private header
125 CFIndex
SecDbIdleConnectionCount(SecDbRef db
);
126 void SecDbReleaseAllConnections(SecDbRef db
);
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 bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn
);
150 // Do not call this unless you are SecDbItem!
151 void SecDbRecordChange(SecDbConnectionRef dbconn
, CFTypeRef deleted
, CFTypeRef inserted
);
153 void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn
, bool barrier
, dispatch_block_t perform
);
154 void SecDBManagementTasks(SecDbConnectionRef dbconn
);
157 // MARK: Bind helpers
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
);
181 // Testing only. Normally this calls exit() so make it do something more test-friendly instead
182 extern void (*SecDbCorruptionExitHandler
)(void);
183 void SecDbResetCorruptionExitHandler(void);
186 #endif /* !_UTILITIES_SECDB_H_ */