Моя задача - создать построитель журналов для jooq-подпрограмм. я начал прибегая к помощи вокруг и в конечном итоге с помощью этого: http://www.jooq.org/doc/latest/manual/sql-execution/execute-listeners/pretty logging in jooq
В данном примере автор использует доступный из коробки
DSL.using(configuration).renderInlined(ctx.routine());
Это выглядело многообещающим, но не было достаточно, потому что jooq не показал имена полей в подпрограммах, просто значения. Результат был трудно понять с помощью более крупных процедур. Я пробовал играть с другими возможностями, но безрезультатно ...
Я написал свой собственный форматор журналов, который даже работает. На данный момент :)
Итак, вот моя проблема: она работает только для результатов.
Почему? Потому что я могу получить доступ только к ctx.routine().getReturnValue()
. ctx.routine().getInValues()
защищен.
Итак, вот некоторые вопросы: почему getInValues()
защищен? Можно ли его изменить на публику? Или, может быть, есть обходной путь для этого ...?
В качестве обходного решения я попытался использовать отражение, которое показывает еще одну проблему. getReturnValue()
дает мне UDTRecord
, у которого intoMap()
метод возвращается Map<String, Object>
. getInValues
Map<Parameter<?>, Field<?>>
. Я понятия не имею, как работать с ним ... я решил не связываться с целой библиотекой и задать свои вопросы здесь :)
с нетерпением ждет ваших ответов
С наилучшими пожеланиями
редактировать : вставка первого черновика моего кода ниже. возможно, это поможет вам понять, чего я пытаюсь достичь.
import org.jooq.*;
import org.jooq.impl.*;
import java.util.Map;
public class OutputLogBuilder
{
private final static String NEW_LINE = System.getProperty("line.separator");
private final static String TAB = "\t";
private final static String COL_RECORD_SEPARATOR = " --> ";
static String buildOutputLog(final ExecuteContext ctx)
{
StringBuilder sb = new StringBuilder(NEW_LINE);
handleUDTRecord(sb, ctx.routine().getReturnValue(), 0);
return sb.toString();
}
private static void handleUDTRecord(final StringBuilder sb, final Object input, int depth)
{
UDTRecordImpl record = (UDTRecordImpl) input;
appendData(sb, record.getUDT().getName(), "", depth);
depth++;
for (Map.Entry<String, Object> entry : record.intoMap().entrySet()) {
String entryKey = entry.getKey();
Object entryValue = entry.getValue();
if (isArrayUDTRecord(entryValue)) {
handleArrayUDTRecord(sb, entryValue, depth);
} else if (isUDTRecord(entryValue)) {
handleUDTRecord(sb, entryValue, depth);
} else {
appendData(sb, entryKey, entryValue, depth);
}
}
}
private static boolean isArrayUDTRecord(final Object object)
{
return object instanceof ArrayRecordImpl;
}
private static boolean isUDTRecord(final Object object)
{
return object instanceof UDTRecordImpl;
}
private static void handleArrayUDTRecord(final StringBuilder sb, final Object input, int depth)
{
ArrayRecordImpl arrayRecord = (ArrayRecordImpl) input;
appendData(sb, arrayRecord.getName(), "", depth);
depth++;
for (Object arrayElement : arrayRecord.getList()) {
if (isArrayUDTRecord(arrayElement)) {
handleArrayUDTRecord(sb, arrayElement, depth);
} else if (isUDTRecord(arrayElement)) {
handleUDTRecord(sb, arrayElement, depth);
} else {
appendData(sb, input, "", depth);
}
}
}
private static void appendData(final StringBuilder sb, final Object key, final Object value, int depth)
{
for (int i = 0; i < depth; i++) {
sb.append(TAB);
}
sb.append(key + COL_RECORD_SEPARATOR + value);
sb.append(NEW_LINE);
}
}
edit2: С отражением мне удалось выяснить, как построить свой журнал с AbstractParam
, UDTConstant
и такие, но они защищены пакет ... ниже приведен пример фрагмента кода, чтобы проверить тип элементов
for (Map.Entry<Parameter<?>, Field<?>> entry : inValues.entrySet()) {
Parameter entryKey = entry.getKey();
Field entryValue = entry.getValue();
if(entryValue instanceof UDTConstant){ //access error
//do smth
}
}
поэтому, когда я проверить их тип я получаю
Caused by: java.lang.IllegalAccessError: tried to access class org.jooq.impl.UDTConstant from class org.jooq.impl.OutputLogBuilder
даже если (как вы можете видеть) я разместил свой код его в том же пакете ...
так снова - почему эти классы НЕ публичны? можно ли его изменить? есть ли какое-нибудь обходное решение?
@ Lukas Eder - любые идеи? :) – WrRaThY
[См. Мой ответ] (http://stackoverflow.com/a/31389243/521799). Хотя, ваш собственный ответ лучше, так что вы могли бы перенести эту часть своего вопроса и ответить на свой собственный вопрос, вот на Stack Overflow –