1//
2//  SecDb.h
3//  utilities
4//
5//  Created by Michael Brouwer on 11/12/12.
6//  Copyright (c) 2012 Apple Inc. All rights reserved.
7//
8
9#ifndef _UTILITIES_SECDB_H_
10#define _UTILITIES_SECDB_H_
11
12#include <CoreFoundation/CoreFoundation.h>
13#include <sqlite3.h>
14
15__BEGIN_DECLS
16
17// MARK: SecDbRef and SecDbConnectionRef forward declarations
18typedef struct __OpaqueSecDb *SecDbRef;
19typedef struct __OpaqueSecDbConnection *SecDbConnectionRef;
20typedef struct __OpaqueSecDbStatement *SecDbStatementRef;
21
22// MARK: Configuration values, not used by clients directly.
23// TODO: Move this section to a private header
24enum {
25    kSecDbMaxReaders = 4,
26    kSecDbMaxWriters = 1,
27    kSecDbMaxIdleHandles = 3,
28};
29
30// MARK: SecDbTransactionType
31enum {
32    kSecDbNoneTransactionType = 0,
33    kSecDbImmediateTransactionType,
34    kSecDbExclusiveTransactionType,
35    kSecDbNormalTransactionType
36};
37typedef uint32_t SecDbTransactionType;
38
39// MARK: --
40// MARK: Error creation helpers.
41
42// SQLITE3 errors are in this domain
43extern CFStringRef kSecDbErrorDomain;
44
45bool SecDbError(int sql_code, CFErrorRef *error, CFStringRef format, ...);
46bool SecDbErrorWithDb(int sql_code, sqlite3 *db, CFErrorRef *error, CFStringRef format, ...);
47bool SecDbErrorWithStmt(int sql_code, sqlite3_stmt *stmt, CFErrorRef *error, CFStringRef format, ...);
48
49// MARK: mark -
50// MARK: mark SecDbRef
51
52CFTypeID SecDbGetTypeID(void);
53
54SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbConnectionRef dbconn, bool did_create, CFErrorRef *error));
55
56// Read only connections go to the end of the queue, writeable
57// connections go to the start of the queue.  Use SecDbPerformRead() and SecDbPerformWrite() if you
58// can to avoid leaks.
59SecDbConnectionRef SecDbConnectionAquire(SecDbRef db, bool readOnly, CFErrorRef *error);
60void SecDbConnectionRelease(SecDbConnectionRef dbconn);
61
62// Perform a database read operation,
63bool SecDbPerformRead(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn));
64bool SecDbPerformWrite(SecDbRef db, CFErrorRef *error, void (^perform)(SecDbConnectionRef dbconn));
65
66// TODO: DEBUG only -> Private header
67CFIndex SecDbIdleConnectionCount(SecDbRef db);
68
69// MARK: -
70// MARK: SecDbConectionRef
71
72CFTypeID SecDbConnectionGetTypeID(void);
73
74bool SecDbPrepare(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, void(^exec)(sqlite3_stmt *stmt));
75
76bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, void (^row)(bool *stop));
77
78bool SecDbExec(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error);
79
80bool SecDbCheckpoint(SecDbConnectionRef dbconn, CFErrorRef *error);
81
82bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType ttype, CFErrorRef *error,
83                      void (^transaction)(bool *commit));
84
85sqlite3 *SecDbHandle(SecDbConnectionRef dbconn);
86
87// MARK: -
88// MARK: Bind helpers
89
90#if 0
91bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error);
92#endif
93bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error);
94bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error);
95bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error);
96bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error);
97bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error);
98bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef *error);
99
100// MARK: -
101// MARK: SecDbStatementRef
102
103bool SecDbReset(sqlite3_stmt *stmt, CFErrorRef *error);
104bool SecDbClearBindings(sqlite3_stmt *stmt, CFErrorRef *error);
105bool SecDbFinalize(sqlite3_stmt *stmt, CFErrorRef *error);
106sqlite3_stmt *SecDbPrepareV2(SecDbConnectionRef dbconn, const char *sql, size_t sqlLen, const char **sqlTail, CFErrorRef *error);
107sqlite3_stmt *SecDbCopyStmt(SecDbConnectionRef dbconn, CFStringRef sql, CFStringRef *tail, CFErrorRef *error);
108bool SecDbReleaseCachedStmt(SecDbConnectionRef dbconn, CFStringRef sql, sqlite3_stmt *stmt, CFErrorRef *error);
109bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, bool(^perform)(sqlite3_stmt *stmt));
110bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index));
111
112// Mark the database as corrupted.
113void SecDbCorrupt(SecDbConnectionRef dbconn);
114
115__END_DECLS
116
117#endif /* !_UTILITIES_SECDB_H_ */
118