Browse Source

[1183] make sure getNext() when done does not error

Jelte Jansen 13 years ago
parent
commit
9d48d19645

+ 3 - 0
src/lib/datasrc/database.h

@@ -148,6 +148,9 @@ public:
          * \throw DataSourceError if there's database-related error. If the
          * \throw DataSourceError if there's database-related error. If the
          *     exception (or any other in case of derived class) is thrown,
          *     exception (or any other in case of derived class) is thrown,
          *     the iterator can't be safely used any more.
          *     the iterator can't be safely used any more.
+         * \return true if a record was found, and the columns array was
+         *         updated. false if there was no more data, in which case
+         *         the columns array is untouched.
          */
          */
         virtual bool getNext(std::string (&columns)[COLUMN_COUNT]) = 0;
         virtual bool getNext(std::string (&columns)[COLUMN_COUNT]) = 0;
     };
     };

+ 5 - 0
src/lib/datasrc/sqlite3_accessor.cc

@@ -369,6 +369,11 @@ public:
 
 
     bool getNext(std::string (&data)[COLUMN_COUNT]) {
     bool getNext(std::string (&data)[COLUMN_COUNT]) {
         // If there's another row, get it
         // If there's another row, get it
+        // If finalize has been called (e.g. when previous getNext() got
+        // SQLITE_DONE), directly return false
+        if (statement_ == NULL) {
+            return false;
+        }
         const int rc(sqlite3_step(statement_));
         const int rc(sqlite3_step(statement_));
         if (rc == SQLITE_ROW) {
         if (rc == SQLITE_ROW) {
             // For both types, we copy the first four columns
             // For both types, we copy the first four columns

+ 6 - 0
src/lib/datasrc/tests/sqlite3_accessor_unittest.cc

@@ -190,6 +190,9 @@ TEST_F(SQLite3Access, iterator) {
 
 
     // Check there's no other
     // Check there's no other
     EXPECT_FALSE(context->getNext(data));
     EXPECT_FALSE(context->getNext(data));
+
+    // And make sure calling it again won't cause problems.
+    EXPECT_FALSE(context->getNext(data));
 }
 }
 
 
 TEST(SQLite3Open, getDBNameExample2) {
 TEST(SQLite3Open, getDBNameExample2) {
@@ -321,6 +324,9 @@ TEST_F(SQLite3Access, getRecords) {
     checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
     checkRecordRow(columns, "RRSIG", "3600", "DNSKEY",
                    "DNSKEY 5 2 3600 20100322084538 20100220084538 "
                    "DNSKEY 5 2 3600 20100322084538 20100220084538 "
                    "33495 example.com. FAKEFAKEFAKEFAKE", "");
                    "33495 example.com. FAKEFAKEFAKEFAKE", "");
+
+    // check that another getNext does not cause problems
+    EXPECT_FALSE(context->getNext(columns));
 }
 }
 
 
 } // end anonymous namespace
 } // end anonymous namespace