Status readRows(sqlite3_stmt* prepared_statement,
                QueryDataTyped& results,
                const SQLiteDBInstanceRef& instance) {
  // Do nothing with a null prepared_statement (eg, if the sql was just
  // whitespace)
  if (prepared_statement == nullptr) {
    return Status::success();
  }
  int rc = sqlite3_step(prepared_statement);
  /* if we have a result set row... */
  if (SQLITE_ROW == rc) {
    // First collect the column names
    int num_columns = sqlite3_column_count(prepared_statement);
    std::vector<std::string> colNames;
    colNames.reserve(num_columns);
    for (int i = 0; i < num_columns; i++) {
      colNames.push_back(sqlite3_column_name(prepared_statement, i));
    }

    do {
      RowTyped row;
      for (int i = 0; i < num_columns; i++) {
        switch (sqlite3_column_type(prepared_statement, i)) {
        case SQLITE_INTEGER:
          row[colNames[i]] = static_cast<long long>(
              sqlite3_column_int64(prepared_statement, i));
          break;
        case SQLITE_FLOAT:
          row[colNames[i]] = sqlite3_column_double(prepared_statement, i);
          break;
        case SQLITE_NULL:
          row[colNames[i]] = FLAGS_nullvalue;
          break;
        default:
          // Everything else (SQLITE_TEXT, SQLITE3_TEXT, SQLITE_BLOB) is
          // obtained/conveyed as text/string
          row[colNames[i]] = std::string(reinterpret_cast<const char*>(
              sqlite3_column_text(prepared_statement, i)));
        }
      }
      results.push_back(std::move(row));
      rc = sqlite3_step(prepared_statement);
    } while (SQLITE_ROW == rc);
  }
  if (rc != SQLITE_DONE) {
    auto s = Status::failure(sqlite3_errmsg(instance->db()));
    sqlite3_finalize(prepared_statement);
    return s;
  }

  rc = sqlite3_finalize(prepared_statement);
  if (rc != SQLITE_OK) {
    return Status::failure(sqlite3_errmsg(instance->db()));
  }

  return Status::success();
}
Status readRows(sqlite3_stmt* prepared_statement,
                QueryDataTyped& results,
                const SQLiteDBInstanceRef& instance) {
   
   
  if (prepared_statement == nullptr) {
    return Status::success();
  }
  int rc = sqlite3_step(prepared_statement);
   
  if (SQLITE_ROW == rc) {
     
    int num_columns = sqlite3_column_count(prepared_statement);
    std::vector<std::string> colNames;
    colNames.reserve(num_columns);
    for (int i = 0; i < num_columns; i++) {
      colNames.push_back(sqlite3_column_name(prepared_statement, i));
    }

    do {
      RowTyped row;
      for (int i = 0; i < num_columns; i++) {
        switch (sqlite3_column_type(prepared_statement, i)) {
        case SQLITE_INTEGER:
          row[colNames[i]] = static_cast<long long>(
              sqlite3_column_int64(prepared_statement, i));
          break;
        case SQLITE_FLOAT:
          row[colNames[i]] = sqlite3_column_double(prepared_statement, i);
          break;
        case SQLITE_NULL:
          row[colNames[i]] = FLAGS_nullvalue;
          break;
        default:
           
           
          row[colNames[i]] = std::string(reinterpret_cast<const char*>(
              sqlite3_column_text(prepared_statement, i)));
        }
      }
      results.push_back(std::move(row));
      rc = sqlite3_step(prepared_statement);
    } while (SQLITE_ROW == rc);
  }
  if (rc != SQLITE_DONE) {
    auto s = Status::failure(sqlite3_errmsg(instance->db()));
    sqlite3_finalize(prepared_statement);
    return s;
  }

  rc = sqlite3_finalize(prepared_statement);
  if (rc != SQLITE_OK) {
    return Status::failure(sqlite3_errmsg(instance->db()));
  }

  return Status::success();
}