In DFC one can execute SQL directly (bypassing DQL) using the IDfSession.apiExec()
method. The problem is that the method is marked as deprecated in the current (6.x, 7.x) versions of the DFC API.
Here's some example code using the deprecated method:
IDfSession session;
(...)
String sql = "UPDATE dm_sysobject_s SET r_modifier = 'hacker' WHERE r_object_id = '<some_id>'";
session.apiExec("execsql", sql);
This works fine, but as already mentioned apiExec
is deprecated.
I've also tried an alternative approach:
(...)
IDfQuery query = new DfQuery(sql);
query.execute(session, IDfQuery.DF_EXEC_QUERY);
To my knowledge this ought to work, but I keep getting the following message:
[DM_QUERY_E_REG_TABLE_PERMIT_IN]error: "You have insufficient privilege to UPDATE the dbo.dm_sysobject_s table."
I get the same error message when using IDfQuery.DF_QUERY
, but anyway DF_EXEC_QUERY is the one that should be working -- or? I am of course trying this out with a super user account, so I wouldn't know which privileges I'm missing.
Is there a good, non-deprecated way to execute raw SQL statements from within DFC?
I would also like to add that I am very aware that raw SQL is strongly discouraged because it bypasses Documentum's security model. I am also aware that I can use @SuppressWarnings("deprecation")
in my Java code, but that doesn't make the method any less deprecated.
I looked into this myself and decompiled DfSession
. In the apiExec()
method DFC uses some internal calls that are available to "outsiders", and this enables the possibility of creating your own "apiExec() equivalent".
Here's a simple example from within a BOF class (a TBO implementation, for instance):
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());
}
...
}
(One should probably restructure this into static util classes or whatever is preferred.)
The crucial part here is of course the DmclApi.getInstance().exec()
call. This is an ugly hack, but no worse than the original apiExec()
in my opinion. It's a reimplementation, really.