boost::optional<OutputAttributeVariableRecord> OutputAttributeVariableRecord::factoryFromQuery(
    const QSqlQuery& query, ProjectDatabase& database)
{
  OptionalOutputAttributeVariableRecord result;
  try {
    result = OutputAttributeVariableRecord(query,database);
  }
  catch (const std::exception& e) {
    LOG(Error,"Unable to construct OutputAttributeVariableRecord from query, because '"
        << e.what() << "'.");
  }
  return result;
}
OutputVariableRecord OutputVariableRecord::factoryFromOutputVariable(const analysis::OutputVariable& outputVariable,
                                                                     FunctionRecord& functionRecord,
                                                                     int variableVectorIndex,
                                                                     boost::optional<double> functionCoefficient)
{
  if (outputVariable.optionalCast<analysis::OutputAttributeVariable>()) {
    return OutputAttributeVariableRecord(outputVariable.cast<analysis::OutputAttributeVariable>(),
                                         functionRecord,
                                         variableVectorIndex,
                                         functionCoefficient);
  }

  OS_ASSERT(false);
  return OutputVariableRecord(std::shared_ptr<detail::OutputVariableRecord_Impl>());
}
boost::optional<OutputVariableRecord> OutputVariableRecord::factoryFromQuery(const QSqlQuery& query,
                                                                             ProjectDatabase& database)
{
  OptionalOutputVariableRecord result;

  int outputVariableRecordType = query.value(VariableRecordColumns::outputVariableRecordType).toInt();

  switch (outputVariableRecordType) {
    case OutputVariableRecordType::OutputAttributeVariableRecord :
      result = OutputAttributeVariableRecord(query, database).cast<OutputVariableRecord>();
     break;
    default :
      LOG(Error,"Unknown OutputVariableRecordType " << outputVariableRecordType);
      return boost::none;
  }

  return result;
}
std::vector<OutputAttributeVariableRecord>
OutputAttributeVariableRecord::getOutputAttributeVariableRecords(
    ProjectDatabase& database)
{
  std::vector<OutputAttributeVariableRecord> result;

  QSqlQuery query(*(database.qSqlDatabase()));
  query.prepare(toQString("SELECT * FROM " + VariableRecord::databaseTableName() +
      " WHERE variableRecordType=:variableRecordType AND " +
      "outputVariableRecordType=:outputVariableRecordType"));
  query.bindValue(":variableRecordType", VariableRecordType::OutputVariableRecord);
  query.bindValue(":outputVariableRecordType",OutputVariableRecordType::OutputAttributeVariableRecord);
  assertExec(query);
  while (query.next()) {
    result.push_back(OutputAttributeVariableRecord(query, database));
  }

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

  QSqlQuery query(*(database.qSqlDatabase()));
  query.prepare(toQString("SELECT * FROM " + VariableRecord::databaseTableName() +
      " WHERE variableRecordType=:variableRecordType AND " +
      "outputVariableRecordType=:outputVariableRecordType AND id=:id"));
  query.bindValue(":variableRecordType", VariableRecordType::OutputVariableRecord);
  query.bindValue(":outputVariableRecordType",OutputVariableRecordType::OutputAttributeVariableRecord);
  query.bindValue(":id",id);
  assertExec(query);
  if (query.first()) {
    result = OutputAttributeVariableRecord(query, database);
  }

  return result;
}