Commit d88becea authored by Jelte Jansen's avatar Jelte Jansen
Browse files

[1183] remove searchForRecords(), getNextRecord() and resetSearch()

since they can now be done through getRecords()
parent 171088e6
......@@ -362,22 +362,20 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
result_status = CNAME;
}
}
// TODO: some of these can be removed
} catch (const DataSourceError& dse) {
logger.error(DATASRC_DATABASE_FIND_ERROR)
.arg(database_->getDBName()).arg(dse.what());
// call cleanup and rethrow
database_->resetSearch();
throw;
} catch (const isc::Exception& isce) {
logger.error(DATASRC_DATABASE_FIND_UNCAUGHT_ISC_ERROR)
.arg(database_->getDBName()).arg(isce.what());
// cleanup, change it to a DataSourceError and rethrow
database_->resetSearch();
isc_throw(DataSourceError, isce.what());
} catch (const std::exception& ex) {
logger.error(DATASRC_DATABASE_FIND_UNCAUGHT_ERROR)
.arg(database_->getDBName()).arg(ex.what());
database_->resetSearch();
throw;
}
......
......@@ -188,60 +188,6 @@ public:
"This database datasource can't be iterated");
}
/**
* \brief Starts a new search for records of the given name in the given zone
*
* The data searched by this call can be retrieved with subsequent calls to
* getNextRecord().
*
* \exception DataSourceError if there is a problem connecting to the
* backend database
*
* \param zone_id The zone to search in, as returned by getZone()
* \param name The name of the records to find
*/
virtual void searchForRecords(int zone_id, const std::string& name) = 0;
/**
* \brief Retrieves the next record from the search started with searchForRecords()
*
* Returns a boolean specifying whether or not there was more data to read.
* In the case of a database error, a DatasourceError is thrown.
*
* The columns passed is an array of std::strings consisting of
* DatabaseConnection::COLUMN_COUNT elements, the elements of which
* are defined in DatabaseConnection::RecordColumns, in their basic
* string representation.
*
* If you are implementing a derived database connection class, you
* should have this method check the column_count value, and fill the
* array with strings conforming to their description in RecordColumn.
*
* \exception DatasourceError if there was an error reading from the database
*
* \param columns The elements of this array will be filled with the data
* for one record as defined by RecordColumns
* If there was no data, the array is untouched.
* \return true if there was a next record, false if there was not
*/
virtual bool getNextRecord(std::string columns[], size_t column_count) = 0;
/**
* \brief Resets the current search initiated with searchForRecords()
*
* This method will be called when the called of searchForRecords() and
* getNextRecord() finds bad data, and aborts the current search.
* It should clean up whatever handlers searchForRecords() created, and
* any other state modified or needed by getNextRecord()
*
* Of course, the implementation of getNextRecord may also use it when
* it is done with a search. If it does, the implementation of this
* method should make sure it can handle being called multiple times.
*
* The implementation for this method should make sure it never throws.
*/
virtual void resetSearch() = 0;
/**
* Definitions of the fields as they are required to be filled in
* by getNextRecord()
......
......@@ -362,10 +362,6 @@ convertToPlainChar(const unsigned char* ucp,
}
}
// TODO: Once we want to have iterator returned from searchForRecords, this
// class can be reused. It should be modified to take the sqlite3 statement
// instead of creating it in constructor, it doesn't have to care which one
// it is, just provide data from it.
class SQLite3Database::Context : public DatabaseAccessor::IteratorContext {
public:
// Construct an iterator for all records. When constructed this
......@@ -468,62 +464,5 @@ SQLite3Database::getAllRecords(const isc::dns::Name&, int id) const {
return (IteratorContextPtr(new Context(shared_from_this(), id)));
}
void
SQLite3Database::searchForRecords(int zone_id, const std::string& name) {
resetSearch();
if (sqlite3_bind_int(dbparameters_->q_any_, 1, zone_id) != SQLITE_OK) {
isc_throw(DataSourceError,
"Error in sqlite3_bind_int() for zone_id " <<
zone_id << ": " << sqlite3_errmsg(dbparameters_->db_));
}
// use transient since name is a ref and may disappear
if (sqlite3_bind_text(dbparameters_->q_any_, 2, name.c_str(), -1,
SQLITE_TRANSIENT) != SQLITE_OK) {
isc_throw(DataSourceError,
"Error in sqlite3_bind_text() for name " <<
name << ": " << sqlite3_errmsg(dbparameters_->db_));
}
}
bool
SQLite3Database::getNextRecord(std::string columns[], size_t column_count) {
if (column_count != COLUMN_COUNT) {
isc_throw(DataSourceError,
"Datasource backend caller did not pass a column array "
"of size " << COLUMN_COUNT << " to getNextRecord()");
}
sqlite3_stmt* current_stmt = dbparameters_->q_any_;
const int rc = sqlite3_step(current_stmt);
if (rc == SQLITE_ROW) {
for (int column = 0; column < column_count; ++column) {
try {
columns[column] = convertToPlainChar(sqlite3_column_text(
current_stmt, column),
dbparameters_);
} catch (const std::bad_alloc&) {
isc_throw(DataSourceError,
"bad_alloc in Sqlite3Connection::getNextRecord");
}
}
return (true);
} else if (rc == SQLITE_DONE) {
// reached the end of matching rows
resetSearch();
return (false);
}
isc_throw(DataSourceError, "Unexpected failure in sqlite3_step: " <<
sqlite3_errmsg(dbparameters_->db_));
// Compilers might not realize isc_throw always throws
return (false);
}
void
SQLite3Database::resetSearch() {
sqlite3_reset(dbparameters_->q_any_);
sqlite3_clear_bindings(dbparameters_->q_any_);
}
}
}
......@@ -99,52 +99,6 @@ public:
virtual IteratorContextPtr getAllRecords(const isc::dns::Name&,
int id) const;
/**
* \brief Start a new search for the given name in the given zone.
*
* This implements the searchForRecords from DatabaseConnection.
* This particular implementation does not raise DataSourceError.
*
* \exception DataSourceError when sqlite3_bind_int() or
* sqlite3_bind_text() fails
*
* \param zone_id The zone to seach in, as returned by getZone()
* \param name The name to find records for
*/
virtual void searchForRecords(int zone_id, const std::string& name);
/**
* \brief Retrieve the next record from the search started with
* searchForRecords
*
* This implements the getNextRecord from DatabaseConnection.
* See the documentation there for more information.
*
* If this method raises an exception, the contents of columns are undefined.
*
* \exception DataSourceError if there is an error returned by sqlite_step()
* When this exception is raised, the current
* search as initialized by searchForRecords() is
* NOT reset, and the caller is expected to take
* care of that.
* \param columns This vector will be cleared, and the fields of the record will
* be appended here as strings (in the order rdtype, ttl, sigtype,
* and rdata). If there was no data (i.e. if this call returns
* false), the vector is untouched.
* \return true if there was a next record, false if there was not
*/
virtual bool getNextRecord(std::string columns[], size_t column_count);
/**
* \brief Resets any state created by searchForRecords
*
* This implements the resetSearch from DatabaseConnection.
* See the documentation there for more information.
*
* This function never throws.
*/
virtual void resetSearch();
/// The SQLite3 implementation of this method returns a string starting
/// with a fixed prefix of "sqlite3_" followed by the DB file name
/// removing any path name. For example, for the DB file
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment