1/*
2 * Copyright (c) 2008 Apple Computer, 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// sqlite++ - C++ interface to SQLite3
25//
26#include "sqlite++.h"
27#include <stdexcept>
28#include <security_utilities/cfutilities.h>
29
30
31//@@@
32// From cssmapple.h - layering break
33// Where should this go?
34//@@@
35#define errSecErrnoBase 100000
36#define errSecErrnoLimit 100255
37
38
39namespace Security {
40namespace SQLite3 {
41
42
43//
44// Our exception object
45//
46void Error::check(int err)
47{
48	if (err != SQLITE_OK)
49		throw Error(err);
50}
51
52Error::Error(Database &db)
53	: error(db.errcode()), message(db.errmsg())
54{
55	SECURITY_EXCEPTION_THROW_SQLITE(this, error, (char*)message.c_str());
56}
57
58void Error::throwMe(int err)
59{
60	throw Error(err);
61}
62
63OSStatus Error::osStatus() const
64{
65	return unixError() + errSecErrnoBase;
66}
67
68int Error::unixError() const
69{
70	switch (error) {
71	case SQLITE_PERM:
72	case SQLITE_READONLY:
73	case SQLITE_AUTH:
74		return EACCES;
75	case SQLITE_BUSY:
76		return EAGAIN;
77	case SQLITE_NOMEM:
78		return ENOMEM;
79	case SQLITE_IOERR:
80		return EIO;
81	case SQLITE_FULL:
82		return ENOSPC;
83	case SQLITE_TOOBIG:
84		return EFBIG;
85	case SQLITE_MISMATCH:
86	case SQLITE_MISUSE:
87		return EINVAL;
88	case SQLITE_NOLFS:
89		return ENOTSUP;
90	case SQLITE_RANGE:
91		return EDOM;
92	default:
93		return -1;
94	}
95}
96
97
98//
99// Database objects
100//
101Database::Database(const char *path, int flags, bool lenient /* = false */)
102	: mMutex(Mutex::recursive)
103{
104	try {
105		int rc = ::sqlite3_open_v2(path, &mDb, flags, NULL);
106		if (rc != SQLITE_OK && lenient) {	// silent open failure
107			sqlite3_close(mDb); // ditch useless Db object
108			mDb = NULL;			// indicate failure
109			return;
110		}
111		check(rc);
112		check(::sqlite3_extended_result_codes(mDb, true));
113		mOpenFlags = flags;
114	} catch (...) {
115		sqlite3_close(mDb);		// allocated even if open fails(!)
116		throw;
117	}
118}
119
120Database::~Database()
121{
122	this->close();
123}
124
125void Database::close()
126{
127	if (mDb)
128		check(::sqlite3_close(mDb));
129}
130
131
132int Database::execute(const char *text, bool strict /* = true */)
133{
134	StLock<Mutex> _(mMutex);
135
136	int rc = ::sqlite3_exec(mDb, text, NULL, NULL, NULL);
137	if (strict)
138		check(rc);
139	return rc;
140}
141
142
143void Database::busyDelay(int ms)
144{
145	StLock<Mutex> _(mMutex);
146
147	check(::sqlite3_busy_timeout(mDb, ms));
148}
149
150
151void Database::check(int err)
152{
153	if (err)
154		throw Error(*this);
155}
156
157
158bool Database::empty()
159{
160	return value("select count(*) from sqlite_master;", 0) == 0;
161}
162
163
164int Database::errcode()
165{
166	StLock<Mutex> _(mMutex);
167
168	return sqlite3_errcode(mDb);
169}
170
171
172
173const char *Database::errmsg()
174{
175	StLock<Mutex> _(mMutex);
176
177	return sqlite3_errmsg(mDb);
178}
179
180
181
182bool Database::inTransaction()
183{
184	StLock<Mutex> _(mMutex);
185
186	return !::sqlite3_get_autocommit(mDb);
187}
188
189
190
191int64 Database::lastInsert()
192{
193	StLock<Mutex> _(mMutex);
194
195	return ::sqlite3_last_insert_rowid(mDb);
196}
197
198int Database::changes()
199{
200	StLock<Mutex> _(mMutex);
201
202	return ::sqlite3_changes(mDb);
203}
204
205void Database::interrupt()
206{
207	StLock<Mutex> _(mMutex);
208
209	::sqlite3_interrupt(mDb);
210}
211
212//
213// Transaction managers
214//
215Transaction::Transaction(Database &db, Type type, const char *name)
216	: database(db), mName(name ? name : "")
217{
218	switch (type) {
219	case deferred:	xactCommand("BEGIN DEFERRED"); break;
220	case immediate:	xactCommand("BEGIN IMMEDIATE"); break;
221	case exclusive:	xactCommand("BEGIN EXCLUSIVE"); break;
222	}
223}
224
225Transaction::~Transaction()
226{
227	if (database.inTransaction())
228		abort();
229}
230
231void Transaction::commit()
232{
233	xactCommand("COMMIT");
234}
235
236void Transaction::abort()
237{
238	xactCommand("ROLLBACK");
239}
240
241void Transaction::xactCommand(const string &cmd)
242{
243	database.execute(cmd + " TRANSACTION " + mName + ";");
244}
245
246
247//
248// Statement objects
249//
250Statement::Statement(Database &db, const char *text)
251	: StLock<Mutex>(db.mMutex), database(db), mStmt(NULL)
252{
253	this->query(text);
254}
255
256Statement::Statement(Database &db)
257	: StLock<Mutex>(db.mMutex), database(db), mStmt(NULL)
258{ }
259
260void Statement::query(const char *text)
261{
262	this->close();
263	const char *tail;
264	check(::sqlite3_prepare_v2(database.sql(), text, -1, &mStmt, &tail));
265	if (*tail)
266		throw std::logic_error("multiple statements");
267}
268
269void Statement::close()
270{
271	// Sqlite3_finalize will return an error if the Statement (executed and) failed.
272	// So we eat any error code here, since we can't tell "genuine" errors apart from
273	// errors inherited from the Statement execution.
274	if (mStmt)
275		::sqlite3_finalize(mStmt);
276	mStmt = NULL;
277}
278
279Statement::~Statement()
280{
281	this->close();
282}
283
284
285void Statement::unbind()
286{
287	check(::sqlite3_clear_bindings(mStmt));
288}
289
290void Statement::reset()
291{
292	check(::sqlite3_reset(mStmt));
293}
294
295
296int Statement::step()
297{
298	return ::sqlite3_step(mStmt);
299}
300
301void Statement::execute()
302{
303	switch (int rc = this->step()) {
304	case SQLITE_DONE:
305	case SQLITE_OK:
306		break;
307	default:
308		check(rc);
309	}
310}
311
312bool Statement::nextRow()
313{
314	switch (int rc = this->step()) {
315	case SQLITE_ROW:
316		return true;
317	case SQLITE_DONE:
318		return false;
319	default:
320		check(rc);
321		return false;
322	}
323}
324
325
326//
327// Binding gluons.
328//
329Statement::Binding Statement::bind(const char *name) const
330{
331	if (int ix = ::sqlite3_bind_parameter_index(mStmt, name))
332		return Binding(*this, ix);
333	else
334		throw std::logic_error("unknown parameter name");
335}
336
337void Statement::Binding::null()
338{
339	statement.check(::sqlite3_bind_null(statement.sql(), index));
340}
341
342void Statement::Binding::operator = (const Value &value)
343{
344	statement.check(::sqlite3_bind_value(statement.sql(), index, value.sql()));
345}
346
347void Statement::Binding::operator = (int value)
348{
349	statement.check(::sqlite3_bind_int(statement.sql(), index, value));
350}
351
352void Statement::Binding::operator = (sqlite3_int64 value)
353{
354	statement.check(::sqlite3_bind_int64(statement.sql(), index, value));
355}
356
357void Statement::Binding::integer(sqlite3_int64 value)
358{
359	statement.check(::sqlite3_bind_int64(statement.sql(), index, value));
360}
361
362void Statement::Binding::operator = (double value)
363{
364	statement.check(::sqlite3_bind_double(statement.sql(), index, value));
365}
366
367void Statement::Binding::operator = (const char *value)
368{
369	if (value == NULL)
370		this->null();
371	else
372		statement.check(::sqlite3_bind_text(statement.sql(), index,
373			::strdup(value), -1, ::free));
374}
375
376void Statement::Binding::operator = (const std::string &value)
377{
378	statement.check(::sqlite3_bind_text(statement.sql(), index,
379		::strdup(value.c_str()), -1, ::free));
380}
381
382void Statement::Binding::blob(const void *data, size_t length, bool shared /* = false */)
383{
384	if (data == NULL)
385		this->null();
386	else if (shared) {
387		statement.check(::sqlite3_bind_blob(statement.sql(), index, data, (int)length, NULL));
388	} else if (void *copy = ::malloc(length)) {
389		::memcpy(copy, data, length);
390		statement.check(::sqlite3_bind_blob(statement.sql(), index,
391		copy, (int)length, ::free));
392	} else
393		throw std::bad_alloc();
394}
395
396void Statement::Binding::operator = (CFDataRef data)
397{
398	if (data)
399		this->blob(CFDataGetBytePtr(data), CFDataGetLength(data));
400	else
401		this->null();
402}
403
404void Statement::Binding::operator = (CFStringRef value)
405{
406	if (value)
407		*this = cfString(value).c_str();
408	else
409		this->null();
410}
411
412const char *Statement::Binding::name() const
413{
414	return sqlite3_bind_parameter_name(statement.sql(), index);
415}
416
417
418//
419// Row/column results
420//
421const char *Statement::Result::name() const
422{
423	return sqlite3_column_name(statement.sql(), index);
424}
425
426CFDataRef Statement::Result::data() const
427{
428	switch (this->type()) {
429	case SQLITE_NULL:
430		return NULL;
431	case SQLITE_BLOB:
432		return makeCFData(this->blob(), this->length());
433	default:
434		throw Error(SQLITE_MISMATCH, "Retrieving data() of non-Blob");
435	}
436}
437
438
439}	// SQLite3
440}	// Security
441