]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/sqlite++.h
2 * Copyright (c) 2008,2011-2012,2014 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@
24 // sqlite++ - C++ interface to SQLite3
30 #include <security_utilities/errors.h>
31 #include <security_utilities/threading.h>
32 #include <CoreFoundation/CFData.h>
41 typedef sqlite3_int64 int64
;
42 typedef sqlite3_uint64 uint64
;
48 class Error
: public CommonError
{
51 Error(int err
) : error(err
) { }
52 Error(int err
, const char *msg
) : error(err
), message(msg
) { }
55 const std::string message
;
57 const char *what() const throw () { return message
.c_str(); }
58 OSStatus
osStatus() const;
59 int unixError() const;
61 static void check(int err
);
62 static void throwMe(int err
) __attribute__((noreturn
));
67 // An sqlite3 database "connection"
70 friend class Statement
;
72 Database(const char *path
, int flags
= SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE
, bool lenient
= false);
75 bool isOpen() const { return mDb
!= NULL
; }
79 int openFlags() const { return mOpenFlags
; }
81 // last error condition encountered
91 int execute(const char *text
, bool strict
= true);
92 int execute(const std::string
&text
, bool strict
= true)
93 { return execute(text
.c_str(), strict
); }
97 template <class RType
> RType
value(const char *text
, RType defaultResult
= RType());
98 template <class RType
> RType
value(const std::string
&text
, RType defaultResult
= RType())
99 { return value(text
.c_str(), defaultResult
); }
102 { return this->value
<double>("SELECT JULIANDAY('now');"); }
104 void busyDelay(int ms
);
108 sqlite3
*sql() const { return mDb
; }
118 // An sqlite column value.
119 // These are definitely not first-class API objects; in particular,
120 // there doesn't seem to be API to actually *make* one - you can only
121 // get them out of sqlite.
125 Value(sqlite3_value
*v
) : mValue(v
) { }
127 operator int () const { return ::sqlite3_value_int(mValue
); }
128 operator sqlite3_int64 () const { return ::sqlite3_value_int64(mValue
); }
129 operator const char * () const { return (const char *)::sqlite3_value_text(mValue
); }
130 operator double () const { return ::sqlite3_value_double(mValue
); }
132 int type() const { return ::sqlite3_value_type(mValue
); }
133 int numericType() const { return ::sqlite3_value_numeric_type(mValue
); }
135 operator bool () const { return type() != SQLITE_NULL
; }
136 bool operator ! () const { return type() == SQLITE_NULL
; }
138 sqlite3_value
*sql() const { return mValue
; }
141 sqlite3_value
*mValue
;
146 // A Transaction proxy.
157 Transaction(Database
&db
, Type type
= deferred
, const char *name
= NULL
);
158 virtual ~Transaction();
162 void rollback() { this->abort(); }
167 void xactCommand(const std::string
&s
);
175 // A (prepared) statement.
177 class Statement
: private StLock
<Mutex
> {
181 Statement(Database
&db
, const char *text
); // ready to serve
182 Statement(Database
&db
); // quiescent; call query(text) to activate it
183 virtual ~Statement();
187 operator bool () const { return mStmt
!= NULL
; } // active
189 void query(const char *text
); // activate statement with query text
190 void query(const std::string
&text
)
191 { query(text
.c_str()); }
192 void close(); // close up active statement
194 Binding
bind(int ix
) const { return Binding(*this, ix
); }
195 Binding
bind(const char *name
) const;
196 unsigned int bindings() const { return ::sqlite3_bind_parameter_count(mStmt
); }
202 bool operator () () { return nextRow(); }
207 Result
operator [] (int ix
) { return Result(*this, ix
); }
208 unsigned int count() const { return ::sqlite3_column_count(mStmt
); }
210 void check(int err
) const { database
.check(err
); }
211 sqlite3_stmt
*sql() const { return mStmt
; }
216 Column(const Statement
&st
, int ix
) : statement(st
), index(ix
) { }
218 const Statement
&statement
;
222 class Binding
: public Column
{
224 Binding(const Statement
&st
, int ix
) : Column(st
, ix
) { }
226 const char *name() const;
229 void operator = (int value
);
230 void operator = (sqlite3_int64 value
);
231 void operator = (double value
);
232 void operator = (const char *value
);
233 void operator = (const std::string
&value
);
234 void operator = (const Value
&value
);
235 void integer(sqlite3_int64 value
);
236 void blob(const void *data
, size_t length
, bool shared
= false);
237 void operator = (CFDataRef data
);
238 void operator = (CFStringRef value
);
242 class Result
: public Column
{
244 Result(const Statement
&st
, int ix
) : Column(st
, ix
) { }
246 const char *name() const;
248 operator int () const { return ::sqlite3_column_int(statement
.sql(), index
); }
249 operator sqlite3_int64 () const { return ::sqlite3_column_int64(statement
.sql(), index
); }
250 operator double () const { return ::sqlite3_column_double(statement
.sql(), index
); }
251 const char *string() const { return (const char *)::sqlite3_column_text(statement
.sql(), index
); }
252 operator const char *() const { return this->string(); }
253 const void *blob() const { return ::sqlite3_column_blob(statement
.sql(), index
); }
254 int length() const { return ::sqlite3_column_bytes(statement
.sql(), index
); }
255 CFDataRef
data() const;
257 int type() const { return ::sqlite3_column_type(statement
.sql(), index
); }
258 const char *declType() const { return ::sqlite3_column_decltype(statement
.sql(), index
); }
260 operator bool () const { return type() != SQLITE_NULL
; }
261 bool operator ! () const { return type() == SQLITE_NULL
; }
269 template <class RType
>
270 RType
Database::value(const char *text
, RType defaultResult
)
272 Statement
stmt(*this, text
);
274 return RType(stmt
[0]);
276 return defaultResult
;