summaryrefslogtreecommitdiff
path: root/libsqlitepp/sqlite-connection.cpp
blob: 5eead630022a3e5029fc7c18cf764814e0c263f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "sqlite-connection.h"
#include "sqlite-error.h"
#include "sqlite-selectcommand.h"
#include "sqlite-modifycommand.h"

SQLite::Connection::Connection(const std::string & str) :
	txDepth(0),
	rolledback(false)
{
	if (sqlite3_open(str.c_str(), &db) != SQLITE_OK) {
		if (db) {
			std::string err(sqlite3_errmsg(db));
			sqlite3_close(db);
			throw Error(err.c_str());
		}
		throw Error("Unknown error opening database");
	}
}

SQLite::Connection::~Connection()
{
	sqlite3_close(db);
}

void
SQLite::Connection::finish() const
{
	if (txDepth != 0) {
		rollbackTx();
		throw Error("Transaction still open");
	}
}

int
SQLite::Connection::beginTx() const
{
	if (txDepth == 0) {
		if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
			throw Error(sqlite3_errmsg(db));
		}
		rolledback = false;
	}
	return ++txDepth;
}

int
SQLite::Connection::commitTx() const
{
	if (rolledback) {
		return rollbackTx();
	}
	if (--txDepth == 0) {
		if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
			throw Error(sqlite3_errmsg(db));
		}
	}
	return txDepth;
}

int
SQLite::Connection::rollbackTx() const
{
	if (--txDepth == 0) {
		if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
			throw Error(sqlite3_errmsg(db));
		}
	}
	else {
		rolledback = true;
	}
	return txDepth;
}

bool
SQLite::Connection::inTx() const
{
	return txDepth;
}

DB::BulkDeleteStyle
SQLite::Connection::bulkDeleteStyle() const
{
	return DB::BulkDeleteUsingUsingAlias;
}

DB::BulkUpdateStyle
SQLite::Connection::bulkUpdateStyle() const
{
	return DB::BulkUpdateUsingJoin;
}

void
SQLite::Connection::ping() const
{
	// Can this fail?
}


DB::SelectCommand *
SQLite::Connection::newSelectCommand(const std::string & sql) const
{
	return new SelectCommand(this, sql);
}

DB::ModifyCommand *
SQLite::Connection::newModifyCommand(const std::string & sql) const
{
	return new ModifyCommand(this, sql);
}

void
SQLite::Connection::beginBulkUpload(const char *, const char *) const
{
	throw Error("Not implemented");
}

void
SQLite::Connection::endBulkUpload(const char *) const
{
	throw Error("Not implemented");
}

size_t
SQLite::Connection::bulkUploadData(const char *, size_t) const
{
	throw Error("Not implemented");
}

int64_t
SQLite::Connection::insertId() const
{
	return sqlite3_last_insert_rowid(db);
}