Необработанный SQL в DFC (Documentum)

В DFC можно выполнять SQL напрямую (минуя DQL) с помощью метода IDfSession.apiExec(). Проблема в том, что этот метод помечен как устаревший в текущих (6.x, 7.x) версиях DFC API.

Вот пример кода с использованием устаревшего метода:

IDfSession session;
(...)
String sql = "UPDATE dm_sysobject_s SET r_modifier = 'hacker' WHERE r_object_id = '<some_id>'";
session.apiExec("execsql", sql);

Это прекрасно работает, но, как уже упоминалось, apiExec устарело.

Я также пробовал альтернативный подход:

(...)
IDfQuery query = new DfQuery(sql);
query.execute(session, IDfQuery.DF_EXEC_QUERY);

Насколько мне известно, это должно работать, но я продолжаю получать следующее сообщение:

[DM_QUERY_E_REG_TABLE_PERMIT_IN]error:  "You have insufficient privilege to UPDATE the dbo.dm_sysobject_s table."

Я получаю то же сообщение об ошибке при использовании IDfQuery.DF_QUERY, но в любом случае DF_EXEC_QUERY должен работать - или? Я, конечно, пробую это с учетной записью суперпользователя, поэтому я не знаю, каких привилегий мне не хватает.

Есть ли хороший, нерекомендуемый способ выполнения необработанных операторов SQL из DFC?

Я также хотел бы добавить, что я мне очень хорошо известно, что необработанный SQL настоятельно не рекомендуется, поскольку он обходит модель безопасности Documentum. Я также знаю, что могу использовать @SuppressWarnings("deprecation") в своем Java-коде, но это не делает этот метод менее устаревшим.


person eivamu    schedule 07.03.2014    source источник


Ответы (3)


Вы можете поддерживать прямое подключение к вашему sql-серверу как к Documentum Content Server. И выполните ваши операторы sql в этом соединении. Другое дело — найти способ заменить ваш SQL-материал чем-то другим. Создавайте представления sql, хранимые процедуры и т.д.

person Yegoshin Maxim    schedule 07.03.2014
comment
Но что, если клиент DFC не имеет прямого доступа к службе БД? Это часто бывает (только привилегированные клиенты, такие как Content Server, могут подключаться к БД, или БД находится в другом сегменте сети и т. д.). Это также еще более обескураживающий способ сделать это, поскольку никто, кроме CS, действительно должен получить доступ к БД. Но спасибо за ваш ответ, это, безусловно, творческий подход, о котором я не думал, что в некоторых случаях он может сработать. - person eivamu; 07.03.2014

Я сам изучил это и декомпилировал DfSession. В методе apiExec() DFC использует некоторые внутренние вызовы, доступные «посторонним», и это позволяет создать собственный «эквивалент APIExec()».

Вот простой пример из класса BOF (например, реализация TBO):

import static com.google.common.base.Strings.isNullOrEmpty;
...
import com.documentum.dmcl.impl.DmclApi;
...

public class MyBofClass extends MyBofInterface {
    ...

    private boolean execSql(String sql) throws DfException {
        return execApi("execsql", sql);
    }

    private boolean execApi(String command, String args) throws DfException {
        return execApi(getSession(), command, args);
    }

    private boolean execApi(IDfSession session, String command, String args) throws DfException {
        StringBuilder apiBuilder = new StringBuilder(command);
        apiBuilder.append(',');
        apiBuilder.append(session.getSessionId());
        if (!isNullOrEmpty(args)) {
            apiBuilder.append(',');
            apiBuilder.append(args);
        }
        return DmclApi.getInstance().exec(apiBuilder.toString());
    }
    ...
}

(Вероятно, следует реструктурировать это в статические классы использования или что-то еще предпочтительнее.)

Важнейшей частью здесь, конечно же, является вызов DmclApi.getInstance().exec(). Это уродливый хак, но на мой взгляд не хуже оригинального apiExec(). Это повторная реализация, на самом деле.

person eivamu    schedule 10.03.2014

Попробуйте цепочку getCommand, setQuery и execute, например:

IDfApplyExecSQL execSQL = DfAdminCommand
        .getCommand(IDfAdminCommand.APPLY_EXEC_SQL);
execSQL.setQuery("UPDATE....");
execSQL.execute(session);

Если вы по-прежнему получаете сообщение о разрешениях, это может быть проблема с вашим SQL-сервером или вашим подключением к нему.

person Andrey B. Panfilov    schedule 18.03.2014