2015-06-29 11 views
1

我的任务是为jooq例程创建一个日志生成器。 我开始周围的Googling,结束了使用这个:http://www.jooq.org/doc/latest/manual/sql-execution/execute-listeners/漂亮的登录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:与反思我设法弄清楚如何建立我的日志,AbstractParamUDTConstant等,但它们是包保护... 下面是示例代码片段来检查元素的类型

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
即使(如u可以看到),我把我的代码是在同一个包...
如此 - 这些类为什么不公开?它可以改变吗?有没有解决方法?

+0

@Lukas Eder - 有什么想法? :) – WrRaThY

+0

[看我的回答](http://stackoverflow.com/a/31389243/521799)。虽然,你自己的答案是更好的,所以你可以实际移动你的问题的一部分,并回答自己的问题,在这里堆栈溢出 –

回答

1

什么你要找的实际上是这个缺失的功能:

Routine API是根本不适合你正在试图做什么足够的经验。任何解决方法(例如使用反射)或修补源将不得不现在做。

+0

thx为答案。 PS。它回答我自己的问题感觉有点奇怪,所以我只是接受你的答案:) – WrRaThY

+0

@WrRaThY:[这根本不奇怪](https://blog.stackexchange.com/2011/07/its-ok -to-问一答,你自己的问题/)。我自己做了很多次,所以继续吧!事实上,它甚至比用部分解决方案编辑你的问题更好,因为在堆栈溢出问题中解决问题并不常见 –