src/PreparedStatement.cpp
branchv_0
changeset 30 629565ff82d3
parent 29 b0ef1e1dc9c8
child 33 86ceb97db7de
equal deleted inserted replaced
29:b0ef1e1dc9c8 30:629565ff82d3
    23 
    23 
    24 namespace relpipe {
    24 namespace relpipe {
    25 namespace tr {
    25 namespace tr {
    26 namespace sql {
    26 namespace sql {
    27 
    27 
    28 PreparedStatement::PreparedStatement(sqlite3_stmt* stmt) : stmt(stmt) {
    28 PreparedStatement::PreparedStatement(void* stmt) : stmt(stmt) {
    29 }
    29 }
    30 
    30 
    31 PreparedStatement::~PreparedStatement() {
    31 PreparedStatement::~PreparedStatement() {
    32 	sqlite3_finalize(stmt);
    32 	sqlite3_finalize((sqlite3_stmt*) stmt);
    33 }
    33 }
    34 
    34 
    35 void PreparedStatement::setBoolean(int parameterIndex, relpipe::reader::boolean_t value) {
    35 void PreparedStatement::setBoolean(int parameterIndex, relpipe::reader::boolean_t value) {
    36 	int result = sqlite3_bind_int(stmt, parameterIndex, value);
    36 	int result = sqlite3_bind_int((sqlite3_stmt*) stmt, parameterIndex, value);
    37 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    37 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    38 }
    38 }
    39 
    39 
    40 void PreparedStatement::setInteger(int parameterIndex, relpipe::reader::integer_t value) {
    40 void PreparedStatement::setInteger(int parameterIndex, relpipe::reader::integer_t value) {
    41 	int result = sqlite3_bind_int64(stmt, parameterIndex, value);
    41 	int result = sqlite3_bind_int64((sqlite3_stmt*) stmt, parameterIndex, value);
    42 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    42 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    43 }
    43 }
    44 
    44 
    45 void PreparedStatement::setString(int parameterIndex, std::string value) {
    45 void PreparedStatement::setString(int parameterIndex, std::string value) {
    46 	int result = sqlite3_bind_text(stmt, parameterIndex, value.c_str(), -1, SQLITE_TRANSIENT);
    46 	int result = sqlite3_bind_text((sqlite3_stmt*) stmt, parameterIndex, value.c_str(), -1, SQLITE_TRANSIENT);
    47 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    47 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    48 }
    48 }
    49 
    49 
    50 void PreparedStatement::setNull(int parameterIndex) {
    50 void PreparedStatement::setNull(int parameterIndex) {
    51 	int result = sqlite3_bind_null(stmt, parameterIndex);
    51 	int result = sqlite3_bind_null((sqlite3_stmt*) stmt, parameterIndex);
    52 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    52 	if (result != SQLITE_OK) throw SqlException(L"Unable to set SQLite parameter.");
    53 }
    53 }
    54 
    54 
    55 bool PreparedStatement::next() {
    55 bool PreparedStatement::next() {
    56 	int result = sqlite3_step(stmt);
    56 	int result = sqlite3_step((sqlite3_stmt*) stmt);
    57 	if (result == SQLITE_ROW) return true;
    57 	if (result == SQLITE_ROW) return true;
    58 	else if (result == SQLITE_DONE) return false;
    58 	else if (result == SQLITE_DONE) return false;
    59 	else throw SqlException(L"Error while iterating over SQLite result.");
    59 	else throw SqlException(L"Error while iterating over SQLite result.");
    60 }
    60 }
    61 
    61 
    62 void PreparedStatement::reset() {
    62 void PreparedStatement::reset() {
    63 	int result = sqlite3_reset(stmt);
    63 	int result = sqlite3_reset((sqlite3_stmt*) stmt);
    64 	if (result != SQLITE_OK) throw SqlException(L"Unable to reset SQLite prepared statement.");
    64 	if (result != SQLITE_OK) throw SqlException(L"Unable to reset SQLite prepared statement.");
    65 }
    65 }
    66 
    66 
    67 int PreparedStatement::getColumnCount() {
    67 int PreparedStatement::getColumnCount() {
    68 	return sqlite3_column_count(stmt);
    68 	return sqlite3_column_count((sqlite3_stmt*) stmt);
    69 }
    69 }
    70 
    70 
    71 std::string PreparedStatement::getColumName(int columnIndex) {
    71 std::string PreparedStatement::getColumName(int columnIndex) {
    72 	const char* name = sqlite3_column_name(stmt, columnIndex);
    72 	const char* name = sqlite3_column_name((sqlite3_stmt*) stmt, columnIndex);
    73 	if (name) return name;
    73 	if (name) return name;
    74 	else throw SqlException(L"Unable to get SQLite column name.");
    74 	else throw SqlException(L"Unable to get SQLite column name.");
    75 }
    75 }
    76 
    76 
    77 relpipe::writer::TypeId PreparedStatement::getColumType(int columnIndex, relpipe::writer::TypeId defaultType) {
    77 relpipe::writer::TypeId PreparedStatement::getColumType(int columnIndex, relpipe::writer::TypeId defaultType) {
    78 	const char* type = sqlite3_column_decltype(stmt, columnIndex);
    78 	const char* type = sqlite3_column_decltype((sqlite3_stmt*) stmt, columnIndex);
    79 
    79 
    80 	// TODO: sqlite3_column_decltype returns value only for columns of existing tables, not for dynamic expressions – SQLite uses dynamic types
    80 	// TODO: sqlite3_column_decltype returns value only for columns of existing tables, not for dynamic expressions – SQLite uses dynamic types
    81 	// maybe we could write a function/module that returns result set metadata for given query (before executing it)
    81 	// maybe we could write a function/module that returns result set metadata for given query (before executing it)
    82 	// or use at least explicit casts in SQL and modify sqlite3_column_decltype() function or add some new one to return such casted type
    82 	// or use at least explicit casts in SQL and modify sqlite3_column_decltype() function or add some new one to return such casted type
    83 	// 
    83 	// 
    95 	else return defaultType;
    95 	else return defaultType;
    96 	// TODO: support also other data types
    96 	// TODO: support also other data types
    97 }
    97 }
    98 
    98 
    99 std::string PreparedStatement::getString(int columnIndex) {
    99 std::string PreparedStatement::getString(int columnIndex) {
   100 	const char* value = (const char*) sqlite3_column_text(stmt, columnIndex);
   100 	const char* value = (const char*) sqlite3_column_text((sqlite3_stmt*) stmt, columnIndex);
   101 	return value ? value : ""; // TODO: support NULL values (when supported in relpipe format)
   101 	return value ? value : ""; // TODO: support NULL values (when supported in relpipe format)
   102 }
   102 }
   103 
   103 
   104 bool PreparedStatement::isComplete(const char* sql) {
   104 bool PreparedStatement::isComplete(const char* sql) {
   105 	return sqlite3_complete(sql);
   105 	return sqlite3_complete(sql);