boost::optional<OpenStudioAlgorithmRecord> OpenStudioAlgorithmRecord::factoryFromQuery(
    const QSqlQuery& query, ProjectDatabase& database)
{
  OptionalOpenStudioAlgorithmRecord result;

  QVariant value = query.value(AlgorithmRecordColumns::openStudioAlgorithmRecordType);
  if (!value.isValid() || value.isNull()) {
    return boost::none;
  }
  int openStudioAlgorithmRecordType = value.toInt();

  switch (openStudioAlgorithmRecordType) {
    case OpenStudioAlgorithmRecordType::DesignOfExperimentsRecord : 
      result = DesignOfExperimentsRecord(query, database).cast<OpenStudioAlgorithmRecord>();
     break;
    case OpenStudioAlgorithmRecordType::SequentialSearchRecord :
      result = SequentialSearchRecord(query, database).cast<OpenStudioAlgorithmRecord>();
     break;
    default :
      LOG(Error,"Unknown OpenStudioAlgorithmRecordType " << openStudioAlgorithmRecordType);
      return boost::none;
  }

  return result;
}
boost::optional<DesignOfExperimentsRecord> DesignOfExperimentsRecord::factoryFromQuery(
    const QSqlQuery& query, ProjectDatabase& database)
{
  OptionalDesignOfExperimentsRecord result;
  try {
    result = DesignOfExperimentsRecord(query,database);
  }
  catch (const std::exception& e) {
    LOG(Error,"Unable to construct DesignOfExperimentsRecord from query, because '" 
        << e.what() << "'.");
  }
  return result;
}
OpenStudioAlgorithmRecord OpenStudioAlgorithmRecord::factoryFromOpenStudioAlgorithm(
    const analysis::OpenStudioAlgorithm& openStudioAlgorithm, AnalysisRecord& analysisRecord)
{
  if (openStudioAlgorithm.optionalCast<analysis::DesignOfExperiments>()) {
    return DesignOfExperimentsRecord(openStudioAlgorithm.cast<analysis::DesignOfExperiments>(),
                                     analysisRecord);
  }
  else if (openStudioAlgorithm.optionalCast<analysis::SequentialSearch>()) {
    return SequentialSearchRecord(openStudioAlgorithm.cast<analysis::SequentialSearch>(),
                                  analysisRecord);
  }

  OS_ASSERT(false);
  return OpenStudioAlgorithmRecord(std::shared_ptr<detail::OpenStudioAlgorithmRecord_Impl>());
}
std::vector<DesignOfExperimentsRecord> DesignOfExperimentsRecord::getDesignOfExperimentsRecords(ProjectDatabase& database) {
  std::vector<DesignOfExperimentsRecord> result;

  QSqlQuery query(*(database.qSqlDatabase()));
  query.prepare(toQString("SELECT * FROM " + AlgorithmRecord::databaseTableName() + 
                          " WHERE algorithmRecordType=:algorithmRecordType AND " + 
                          "openStudioAlgorithmRecordType=:openStudioAlgorithmRecordType"));
  query.bindValue(":algorithmRecordType", AlgorithmRecordType::OpenStudioAlgorithmRecord);
  query.bindValue(":openStudioAlgorithmRecordType", OpenStudioAlgorithmRecordType::DesignOfExperimentsRecord);
  assertExec(query);
  while (query.next()) {
    result.push_back(DesignOfExperimentsRecord(query, database));
  }

  return result;
}
boost::optional<DesignOfExperimentsRecord> DesignOfExperimentsRecord::getDesignOfExperimentsRecord(int id, ProjectDatabase& database) {
  boost::optional<DesignOfExperimentsRecord> result;

  QSqlQuery query(*(database.qSqlDatabase()));
  query.prepare(toQString("SELECT * FROM " + AlgorithmRecord::databaseTableName() + 
                          " WHERE algorithmRecordType=:algorithmRecordType AND " + 
                          "openStudioAlgorithmRecordType=:openStudioAlgorithmRecordType AND " +
                          "id=:id"));
  query.bindValue(":algorithmRecordType", AlgorithmRecordType::OpenStudioAlgorithmRecord);
  query.bindValue(":openStudioAlgorithmRecordType", OpenStudioAlgorithmRecordType::DesignOfExperimentsRecord);
  query.bindValue(":id",id);
  assertExec(query);
  if (query.first()) {
    result = DesignOfExperimentsRecord(query, database);
  }

  return result;
}