summaryrefslogtreecommitdiffstats
path: root/fbreader/src/database/sqldb/implsqlite/SQLiteDataReader.cpp
blob: 3ea40919591ebb9e220c5f5d9043627165ec38ba (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
/*
 * Copyright (C) 2009-2012 Geometer Plus <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include "SQLiteDataReader.h"

shared_ptr<DBValue> SQLiteDataReader::makeDBValue(sqlite3_stmt *statement, std::size_t column) {
	if (column >= (std::size_t) sqlite3_column_count(statement)) {
		return 0;
	}
	const int type = sqlite3_column_type(statement, column);
	switch (type) {
		case SQLITE_INTEGER: return new DBIntValue(sqlite3_column_int(statement, column));
		case SQLITE_FLOAT:   return new DBRealValue(sqlite3_column_double(statement, column));
		case SQLITE_TEXT:    return new DBTextValue((const char *) sqlite3_column_text(statement, column));
		case SQLITE_NULL:    return DBValue::create(DBValue::DBNULL);
	}
	return 0;
}

SQLiteDataReader::SQLiteDataReader(SQLiteCommand &command) : 
	myCommand(command), 
	myCurrentStatement(0),
	myLocked(true) {
}

SQLiteDataReader::~SQLiteDataReader() {
	close();
}

bool SQLiteDataReader::next() {
	const std::vector<sqlite3_stmt *> &statements = myCommand.statements();
	while (true) {
		int res = sqlite3_step(statements[myCurrentStatement]);
		switch (res) {
		case SQLITE_OK:
			break;
		case SQLITE_ROW:
			return true;
		case SQLITE_DONE:
			if (++myCurrentStatement >= statements.size()) {
				return false;
			}
			break;
		default:
			myCommand.dumpError();
			return false;
		}
	}	
}

bool SQLiteDataReader::reset() {
	return myCommand.resetStatements();
}

void SQLiteDataReader::close() {
	if (myLocked) {
		reset();
		myCommand.unlock();
		myLocked = false;
	}
}

std::size_t SQLiteDataReader::columnsNumber() const {
	sqlite3_stmt *statement = currentStatement();
	return sqlite3_column_count(statement);
}

DBValue::ValueType SQLiteDataReader::type(std::size_t column) const {
	sqlite3_stmt *statement = currentStatement();
	if (column >= (std::size_t) sqlite3_column_count(statement)) {
		return DBValue::DBNULL;
	}
	const int type = sqlite3_column_type(statement, column);
	switch (type) {
	case SQLITE_INTEGER: return DBValue::DBINT;
	case SQLITE_FLOAT:   return DBValue::DBREAL;
	case SQLITE_TEXT:    return DBValue::DBTEXT;
	case SQLITE_NULL:    return DBValue::DBNULL;
	default:
		return DBValue::DBNULL;
	}
}

shared_ptr<DBValue> SQLiteDataReader::value(std::size_t column) const {
	sqlite3_stmt *statement = currentStatement();
	return makeDBValue(statement, column);
}

int SQLiteDataReader::intValue(std::size_t column) const {
	sqlite3_stmt *statement = currentStatement();
	if (column >= (std::size_t)sqlite3_column_count(statement) ||
			sqlite3_column_type(statement, column) != SQLITE_INTEGER) {
		return 0;
	}
	return sqlite3_column_int(statement, column);
}

double SQLiteDataReader::realValue(std::size_t column) const {
	sqlite3_stmt *statement = currentStatement();
	if (column >= (std::size_t)sqlite3_column_count(statement) ||
			sqlite3_column_type(statement, column) != SQLITE_FLOAT) {
		return 0;
	}
	return sqlite3_column_double(statement, column);
}

std::string SQLiteDataReader::textValue(std::size_t column, const std::string &defaultValue) const {
	sqlite3_stmt *statement = currentStatement();
	if (column < (std::size_t)sqlite3_column_count(statement) &&
			sqlite3_column_type(statement, column) == SQLITE_TEXT) {
		const char *result = (const char*)sqlite3_column_text(statement, column);
		if (result != 0) {
			return result;
		}
	}
	return defaultValue;
}