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 // |