OpenASIP  2.0
SQLiteQueryResult.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file SQLiteQueryResult.cc
26  *
27  * Implementation of SQLiteQueryResult class.
28  *
29  * @author Pekka Jääskeläinen 2004 (pekka.jaaskelainen-no.spam-tut.fi)
30  *
31  * @note rating: red
32  */
33 
34 #include <string>
35 using std::string;
36 
37 #include "Application.hh"
38 #include "SQLiteQueryResult.hh"
39 #include "DataObject.hh"
40 #include "SQLiteConnection.hh"
41 
42 #include "Conversion.hh"
43 
44 /**
45  * Constructor.
46  *
47  * @param virtualMachine Compiled SQLite virtual machine for the query.
48  */
50  sqlite3_stmt* statement,
51  SQLiteConnection* connection,
52  bool init) :
53  statement_(statement),
54  connection_(connection),
55  dataInitialized_(init) {
56 
57  // initialize columnNames_ and nextData_
58  if (init) {
59  next();
60  }
61 }
62 
63 /**
64  * Destructor.
65  *
66  * SQLite virtual machine is freed.
67  *
68  */
70  try {
72  } catch (const RelationalDBException& e) {
74  __FILE__, __LINE__, "~SQLiteQueryResult()", e.errorMessage());
75  }
76 }
77 
78 
79 /**
80  * Returns the number of columns in the result set.
81  *
82  * @return Number of columns, UNKNOWN_INDEX if unknown (if not supported by
83  * the driver).
84  */
85 int
87  return columnNames_.size();
88 }
89 
90 /**
91  * Returns the name (title) of a column in the result set.
92  *
93  * @param columnIndex Index of the column of which title interested.
94  * @return Title. Empty string if unknown (if not supported by the driver or
95  * index out of bounds).
96  */
97 std::string
98 SQLiteQueryResult::columnName(std::size_t columnIndex) const {
99  if (columnIndex >= columnNames_.size()) {
100  return "";
101  }
102 
103  return columnNames_[columnIndex];
104 }
105 
106 /**
107  * Returns the data of a column in the current row in the result set.
108  *
109  * @param columnIndex Index of the column of which data to return.
110  * @return The data. Returns NullDataObject if the index is out of bounds.
111  *
112  */
113 const DataObject&
114 SQLiteQueryResult::data(std::size_t columnIndex) const {
115 
116  if (currentData_.size() == 0 || columnIndex >= currentData_.size()) {
117  return NullDataObject::instance();
118  }
119  return currentData_.at(columnIndex);
120 }
121 
122 /**
123  * Returns the data of a column in the current row in the result set.
124  *
125  * This implementation is just to silence Intel compiler's warnings about
126  * "partial implementation" of data() (because it's overriden function).
127  *
128  * @param name Name of the column of which data to return.
129  * @return The data. Returns NullDataObject if the column cannot be found.
130  * Also returns NullDataObject in case the feature is not supported
131  * by the database implementation.
132  *
133  */
134 const DataObject&
135 SQLiteQueryResult::data(const std::string& name) const {
136  return RelationalDBQueryResult::data(name);
137 }
138 
139 
140 /**
141  * Queries if the result set contains more rows.
142  *
143  * @return True if there are more rows that can be accessed with next().
144  */
145 bool
147  if (!dataInitialized_) {
148  next();
149  }
150  return nextData_.size() > 0;
151 }
152 
153 /**
154  * Advances the row cursor to next row in the result set.
155  *
156  * In case the current row is the last row this method does nothing but
157  * returns false.
158  *
159  * @return True if there are still more rows to fetch.
160  */
161 bool
163 
164  dataInitialized_ = true;
165  if (currentData_.size() > 0 && !hasNext()) {
166  return false;
167  }
168 
169  std::vector<std::string> columnNames;
170 
171  assert(statement_ != NULL);
172 
173  int columnCount = 0;
174  int dataCount = 0;
175 
176  int result = sqlite3_step(statement_);
177  columnCount = sqlite3_column_count(statement_);
178  for (int i = 0; i < columnCount; i++) {
179  columnNames.push_back(sqlite3_column_name(statement_, i));
180  }
182  if (result == SQLITE_ROW) {
183  nextData_.clear();
184  dataCount = sqlite3_data_count(statement_);
185  for (int i = 0; i < dataCount; i++) {
186  char* columnText = (char*)sqlite3_column_text(statement_, i);
188  if (columnText == NULL) {
189  data.setNull();
190  } else {
191  data.setString(columnText);
192  }
193  nextData_.push_back(data);
194  }
195  } else if (result == SQLITE_DONE) {
196  nextData_.clear();
197  } else {
198  // error occured
199  nextData_.clear();
200  return false;
201  }
202 
203  // check if it's the initialization call when one should save column
204  // names and column count
205  if (columnNames_.size() == 0 && columnNames.size() != 0) {
206  columnNames_ = columnNames;
207  }
208  return nextData_.size() > 0;
209 }
210 
211 /**
212  * Binds int to sqlite statement at given position (1->)
213  */
214 void
215 SQLiteQueryResult::bindInt(unsigned int position, int value) {
216  connection_->throwIfSQLiteError(sqlite3_bind_int(statement_, position, value));
217 }
218 
219 /**
220  * Binds string to sqlite statement at given position (1->)
221  */
222 void
223 SQLiteQueryResult::bindString(unsigned int position, const std::string& value) {
224  connection_->throwIfSQLiteError(sqlite3_bind_text(statement_, position, value.c_str(),
225  -1, NULL));
226 }
227 
228 /**
229  * Resets compiled sqlite statement for new bindings and execution.
230  */
231 void
233  connection_->throwIfSQLiteError(sqlite3_reset(statement_));
234  // reset doesn't clear bindings
235  //connection_->throwIfSQLiteError(sqlite3_clear_bindings(statement_));
236  columnNames_.clear();
237  currentData_.clear();
238  nextData_.clear();
239  dataInitialized_ = false;
240 }
241 
SQLiteQueryResult::hasNext
virtual bool hasNext()
Definition: SQLiteQueryResult.cc:146
SQLiteQueryResult::bindString
virtual void bindString(unsigned int position, const std::string &value)
Definition: SQLiteQueryResult.cc:223
RelationalDBException
Definition: Exception.hh:692
DataObject
Definition: DataObject.hh:50
RelationalDBQueryResult::data
virtual const DataObject & data(std::size_t column) const =0
Definition: RelationalDBQueryResult.cc:96
Application::writeToErrorLog
static void writeToErrorLog(const std::string fileName, const int lineNumber, const std::string functionName, const std::string message, const int neededVerbosity=0)
Definition: Application.cc:224
SQLiteConnection.hh
SQLiteQueryResult::currentData_
std::vector< DataObject > currentData_
data of the current row
Definition: SQLiteQueryResult.hh:76
SQLiteQueryResult::next
virtual bool next()
Definition: SQLiteQueryResult.cc:162
SQLiteQueryResult::columnNames_
std::vector< std::string > columnNames_
column names
Definition: SQLiteQueryResult.hh:74
SQLiteQueryResult::data
virtual const DataObject & data(std::size_t columnIndex) const
Definition: SQLiteQueryResult.cc:114
assert
#define assert(condition)
Definition: Application.hh:86
SQLiteQueryResult::connection_
SQLiteConnection * connection_
sqlite connection handle
Definition: SQLiteQueryResult.hh:72
SQLiteConnection::throwIfSQLiteError
void throwIfSQLiteError(int result)
Definition: SQLiteConnection.cc:253
Conversion.hh
Application.hh
SQLiteQueryResult::statement_
sqlite3_stmt * statement_
the compiled SQLite statement handle
Definition: SQLiteQueryResult.hh:70
SQLiteConnection::finalizeQuery
void finalizeQuery(sqlite3_stmt *statement)
Definition: SQLiteConnection.cc:291
DataObject.hh
Exception::errorMessage
std::string errorMessage() const
Definition: Exception.cc:123
DataObject::setNull
virtual void setNull()
Definition: DataObject.cc:184
SQLiteQueryResult::~SQLiteQueryResult
virtual ~SQLiteQueryResult()
Definition: SQLiteQueryResult.cc:69
SQLiteQueryResult::bindInt
virtual void bindInt(unsigned int position, int value)
Definition: SQLiteQueryResult.cc:215
SQLiteQueryResult.hh
DataObject::setString
virtual void setString(std::string value)
Definition: DataObject.cc:130
SQLiteQueryResult::nextData_
std::vector< DataObject > nextData_
data of the next row
Definition: SQLiteQueryResult.hh:78
SQLiteQueryResult::reset
virtual void reset()
Definition: SQLiteQueryResult.cc:232
SQLiteQueryResult::columnName
virtual std::string columnName(std::size_t columnIndex) const
Definition: SQLiteQueryResult.cc:98
NullDataObject::instance
static NullDataObject & instance()
Definition: DataObject.cc:542
SQLiteQueryResult::SQLiteQueryResult
SQLiteQueryResult(sqlite3_stmt *statement, SQLiteConnection *connection, bool init=true)
Definition: SQLiteQueryResult.cc:49
SQLiteQueryResult::columns
virtual int columns() const
Definition: SQLiteQueryResult.cc:86
SQLiteConnection
Definition: SQLiteConnection.hh:47
SQLiteQueryResult::dataInitialized_
bool dataInitialized_
has next() been called for this query
Definition: SQLiteQueryResult.hh:80