/ OSX / utilities / SecDb.h
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_ */