void QgsSpatiaLiteSourceSelect::on_mTablesTreeView_doubleClicked( const QModelIndex &index )
{
  setSql( index );
}
void QgsSpatiaLiteSourceSelect::buildQuery()
{
  setSql( mTablesTreeView->currentIndex() );
}
void SaSourceSelect::buildQuery()
{
  setSql( mTablesTreeView->currentIndex() );
}
BinaryFilterCondition::BinaryFilterCondition(const FieldDescriptionPtr& field, 
    ConditionType conditionType, const QString& rightValueText, 
    const QVariant& rightValue)
  : OneFieldBasedFilterCondition(field)
  , conditionType_(conditionType)
  , rightValueText_(rightValueText)
  , rightValue_(rightValue)
{
  static const char* conditionTypeTextFormat = QT_TR_NOOP("Field \"%1\" %2 %3");
  static const char* conditionTypeText[conditionTypeCount] = 
  {
    QT_TR_NOOP("=="),
    QT_TR_NOOP("!="),
    QT_TR_NOOP(">"),
    QT_TR_NOOP("<"),
    QT_TR_NOOP(">="),
    QT_TR_NOOP("<="),
    QT_TR_NOOP("like"),
    QT_TR_NOOP("not like"),
    QT_TR_NOOP("contains"),
    QT_TR_NOOP("not contains")
  };

  QString conditionTextFormat(
      qApp->translate(translationContext, conditionTypeTextFormat));
  setConditionText(conditionTextFormat
      .arg(field->title())
      .arg(qApp->translate(
          translationContext, conditionTypeText[conditionType_]))
      .arg(rightValueText_));

  static const char* conditionTypeSql[conditionTypeCount] = 
  {
    "%1 = ?",
    "%1 <> ?",
    "%1 > ?",
    "%1 < ?",
    "%1 >= ?",        
    "%1 <= ?",                
    "%1 like ? escape '\\'",
    "%1 not like ? escape '\\'",
    "exists (select 1 from %2 where %3 = %2.%4 and %2.%1 = ?)",
    "not exists (select 1 from %2 where %3 = %2.%4 and %2.%1 = ?)"
  };               

  QString sql(conditionTypeSql[conditionType_]);      
  if (FieldDescription::entitySetField != field->fieldType())
  {
    setSql(sql.arg(field->fieldName()));
  }
  else if (containsCondition == conditionType 
      || notContainsCondition == conditionType)
  {        
    setSql(sql
        .arg(field->fieldName())
        .arg(field->entitySetTableName())
        .arg(field->relationFieldName())
        .arg(field->entitySetRelationFieldName()));
  }
  else 
  {
    boost::throw_exception(
        std::invalid_argument("unsupported entity set condition"));
  }
}
db::UpdateQueryPtr AuthorQueryFactory::updateValue(Value value) const
{
    if (!isDataValid())
        return nullptr;

    QString strSql;
    db::sql::AuthorSqlFactory sqlFactory;

    switch (value) {
    case Value::NAME:
        strSql = sqlFactory.updateNameStmt();
        break;
    case Value::EMAIL:
        strSql = sqlFactory.updateEmailStmt();
        break;
    case Value::WEBSITE:
        strSql = sqlFactory.updateWebsiteStmt();
        break;
    default:
        return nullptr;
    }

    assert(!strSql.isEmpty());

    db::ContentValues bindValues;
    const AuthorCVFactory cvFactory{m_pAuthor};

    switch (value) {
    case Value::NAME:
        bindValues.put(cvFactory.fieldName());
        break;
    case Value::EMAIL:
        bindValues.put(cvFactory.fieldEmail());
        break;
    case Value::WEBSITE:
        bindValues.put(cvFactory.fieldWebsite());
        break;
    default:
        return nullptr;
    }

    assert(!bindValues.empty());
    bindValues.put(cvFactory.fieldID());

    auto ptrUpdateWork = std14_stl::make_unique<db::UpdateQuery>();

    switch (value) {
    case Value::NAME:
        ptrUpdateWork->setKey(toInt(db::update::authors::NAME));
        break;
    case Value::EMAIL:
        ptrUpdateWork->setKey(toInt(db::update::authors::EMAIL));
        break;
    case Value::WEBSITE:
        ptrUpdateWork->setKey(toInt(db::update::authors::WEBSITE));
        break;
    default:
        return nullptr;
    }

    assert(ptrUpdateWork->key() >= 0);

    auto varExtraKey = QVariant{m_pAuthor->id()};

    ptrUpdateWork->setSql(std::move(strSql));
    ptrUpdateWork->setModelType(db::SQLModelType::AUTHOR);
    ptrUpdateWork->setExtraKey(std::move(varExtraKey));
    ptrUpdateWork->setBindValues(std::move(bindValues));

    return ptrUpdateWork;
}
db::UpdateQueryPtr SnippetQueryFactory::updateValue(Value value) const
{
    if (!isDataValid())
        return nullptr;

    QString strSql;
    db::sql::SnippetSqlFactory sqlFactory;

    switch (value) {
        case Value::NAME:
            strSql = sqlFactory.updateNameStmt();
            break;
        case Value::CONTENT:
            strSql = sqlFactory.updateContentStmt();
            break;
        case Value::VERSION:
            strSql = sqlFactory.updateVersionStmt();
            break;
        case Value::DESCRIPTION:
            strSql = sqlFactory.updateDescriptionStmt();
            break;
        case Value::LANGUAGE_ID:
            strSql = sqlFactory.updateLanguageIDStmt();
            break;
        case Value::CREATED:
            strSql = sqlFactory.updateDTCreatedStmt();
            break;
        case Value::MODIFIED:
            strSql = sqlFactory.updateDTModifiedStmt();
            break;
        default:
            return nullptr;
    }

    assert(!strSql.isEmpty());

    db::ContentValues bindValues;
    const SnippetCVFactory cvFactory{m_pSnippet};

    switch (value) {
        case Value::NAME:
            bindValues.put(cvFactory.fieldName());
            break;
        case Value::CONTENT:
            bindValues.put(cvFactory.fieldContent());
            break;
        case Value::VERSION:
            bindValues.put(cvFactory.fieldVersion());
            break;
        case Value::DESCRIPTION:
            bindValues.put(cvFactory.fieldDescription());
            break;
        case Value::LANGUAGE_ID:
            bindValues.put(cvFactory.fieldLanguageID());
            break;
        case Value::CREATED:
            bindValues.put(cvFactory.fieldDTCreated());
            break;
        case Value::MODIFIED:
            bindValues.put(cvFactory.fieldDTModified());
            break;
        default:
            return nullptr;
    }

    assert(!bindValues.empty());
    bindValues.put(cvFactory.fieldID());

    auto ptrUpdateWork = std14_stl::make_unique<db::UpdateQuery>();

    switch (value) {
        case Value::NAME:
            ptrUpdateWork->setKey(toInt(update::snippets::NAME));
            break;
        case Value::CONTENT:
            ptrUpdateWork->setKey(toInt(update::snippets::CONTENT));
            break;
        case Value::VERSION:
            ptrUpdateWork->setKey(toInt(update::snippets::VERSION));
            break;
        case Value::DESCRIPTION:
            ptrUpdateWork->setKey(toInt(update::snippets::DESCRIPTION));
            break;
        case Value::LANGUAGE_ID:
            ptrUpdateWork->setKey(toInt(update::snippets::LANGUAGE_ID));
            break;
        case Value::CREATED:
            ptrUpdateWork->setKey(toInt(update::snippets::CREATED));
            break;
        case Value::MODIFIED:
            ptrUpdateWork->setKey(toInt(update::snippets::MODIFIED));
            break;
        default:
            return nullptr;
    }

    assert(ptrUpdateWork->key() >= 0);

    auto varExtraKey = QVariant{m_pSnippet->id()};

    ptrUpdateWork->setSql(std::move(strSql));
    ptrUpdateWork->setModelType(db::SQLModelType::SNIPPET);
    ptrUpdateWork->setExtraKey(std::move(varExtraKey));
    ptrUpdateWork->setBindValues(std::move(bindValues));

    return ptrUpdateWork;
}