2015-06-29 14 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-問一答,你自己的問題/)。我自己做了很多次,所以繼續吧!事實上,它甚至比用部分解決方案編輯你的問題更好,因爲在堆棧溢出問題中解決問題並不常見 –