/* * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.message; import java.text.MessageFormat; import java.util.ArrayList; import org.h2.engine.SysProperties; import org.h2.expression.ParameterInterface; import org.h2.util.StatementBuilder; import org.h2.util.StringUtils; import org.h2.value.Value; /** * This class represents a trace module. */ public class Trace { /** * The trace module id for commands. */ public static final int COMMAND = 0; /** * The trace module id for constraints. */ public static final int CONSTRAINT = 1; /** * The trace module id for databases. */ public static final int DATABASE = 2; /** * The trace module id for functions. */ public static final int FUNCTION = 3; /** * The trace module id for file locks. */ public static final int FILE_LOCK = 4; /** * The trace module id for indexes. */ public static final int INDEX = 5; /** * The trace module id for the JDBC API. */ public static final int JDBC = 6; /** * The trace module id for locks. */ public static final int LOCK = 7; /** * The trace module id for schemas. */ public static final int SCHEMA = 8; /** * The trace module id for sequences. */ public static final int SEQUENCE = 9; /** * The trace module id for settings. */ public static final int SETTING = 10; /** * The trace module id for tables. */ public static final int TABLE = 11; /** * The trace module id for triggers. */ public static final int TRIGGER = 12; /** * The trace module id for users. */ public static final int USER = 13; /** * The trace module id for the page store. */ public static final int PAGE_STORE = 14; /** * The trace module id for the JDBCX API */ public static final int JDBCX = 15; /** * Module names by their ids as array indexes. */ public static final String[] MODULE_NAMES = { "command", "constraint", "database", "function", "fileLock", "index", "jdbc", "lock", "schema", "sequence", "setting", "table", "trigger", "user", "pageStore", "JDBCX" }; private final TraceWriter traceWriter; private final String module; private final String lineSeparator; private int traceLevel = TraceSystem.PARENT; Trace(TraceWriter traceWriter, int moduleId) { this(traceWriter, MODULE_NAMES[moduleId]); } Trace(TraceWriter traceWriter, String module) { this.traceWriter = traceWriter; this.module = module; this.lineSeparator = SysProperties.LINE_SEPARATOR; } /** * Set the trace level of this component. This setting overrides the parent * trace level. * * @param level the new level */ public void setLevel(int level) { this.traceLevel = level; } private boolean isEnabled(int level) { if (this.traceLevel == TraceSystem.PARENT) { return traceWriter.isEnabled(level); } return level <= this.traceLevel; } /** * Check if the trace level is equal or higher than INFO. * * @return true if it is */ public boolean isInfoEnabled() { return isEnabled(TraceSystem.INFO); } /** * Check if the trace level is equal or higher than DEBUG. * * @return true if it is */ public boolean isDebugEnabled() { return isEnabled(TraceSystem.DEBUG); } /** * Write a message with trace level ERROR to the trace system. * * @param t the exception * @param s the message */ public void error(Throwable t, String s) { if (isEnabled(TraceSystem.ERROR)) { traceWriter.write(TraceSystem.ERROR, module, s, t); } } /** * Write a message with trace level ERROR to the trace system. * * @param t the exception * @param s the message * @param params the parameters */ public void error(Throwable t, String s, Object... params) { if (isEnabled(TraceSystem.ERROR)) { s = MessageFormat.format(s, params); traceWriter.write(TraceSystem.ERROR, module, s, t); } } /** * Write a message with trace level INFO to the trace system. * * @param s the message */ public void info(String s) { if (isEnabled(TraceSystem.INFO)) { traceWriter.write(TraceSystem.INFO, module, s, null); } } /** * Write a message with trace level INFO to the trace system. * * @param s the message * @param params the parameters */ public void info(String s, Object... params) { if (isEnabled(TraceSystem.INFO)) { s = MessageFormat.format(s, params); traceWriter.write(TraceSystem.INFO, module, s, null); } } /** * Write a message with trace level INFO to the trace system. * * @param t the exception * @param s the message */ void info(Throwable t, String s) { if (isEnabled(TraceSystem.INFO)) { traceWriter.write(TraceSystem.INFO, module, s, t); } } /** * Format the parameter list. * * @param parameters the parameter list * @return the formatted text */ public static String formatParams( ArrayList<? extends ParameterInterface> parameters) { if (parameters.size() == 0) { return ""; } StatementBuilder buff = new StatementBuilder(); int i = 0; boolean params = false; for (ParameterInterface p : parameters) { if (p.isValueSet()) { if (!params) { buff.append(" {"); params = true; } buff.appendExceptFirst(", "); Value v = p.getParamValue(); buff.append(++i).append(": ").append(v.getTraceSQL()); } } if (params) { buff.append('}'); } return buff.toString(); } /** * Write a SQL statement with trace level INFO to the trace system. * * @param sql the SQL statement * @param params the parameters used, in the for {1:...} * @param count the update count * @param time the time it took to run the statement in ms */ public void infoSQL(String sql, String params, int count, long time) { if (!isEnabled(TraceSystem.INFO)) { return; } StringBuilder buff = new StringBuilder(sql.length() + params.length() + 20); buff.append(lineSeparator).append("/*SQL"); boolean space = false; if (params.length() > 0) { // This looks like a bug, but it is intentional: // If there are no parameters, the SQL statement is // the rest of the line. If there are parameters, they // are appended at the end of the line. Knowing the size // of the statement simplifies separating the SQL statement // from the parameters (no need to parse). space = true; buff.append(" l:").append(sql.length()); } if (count > 0) { space = true; buff.append(" #:").append(count); } if (time > 0) { space = true; buff.append(" t:").append(time); } if (!space) { buff.append(' '); } buff.append("*/"). append(StringUtils.javaEncode(sql)). append(StringUtils.javaEncode(params)). append(';'); sql = buff.toString(); traceWriter.write(TraceSystem.INFO, module, sql, null); } /** * Write a message with trace level DEBUG to the trace system. * * @param s the message * @param params the parameters */ public void debug(String s, Object... params) { if (isEnabled(TraceSystem.DEBUG)) { s = MessageFormat.format(s, params); traceWriter.write(TraceSystem.DEBUG, module, s, null); } } /** * Write a message with trace level DEBUG to the trace system. * * @param s the message */ public void debug(String s) { if (isEnabled(TraceSystem.DEBUG)) { traceWriter.write(TraceSystem.DEBUG, module, s, null); } } /** * Write a message with trace level DEBUG to the trace system. * @param t the exception * @param s the message */ public void debug(Throwable t, String s) { if (isEnabled(TraceSystem.DEBUG)) { traceWriter.write(TraceSystem.DEBUG, module, s, t); } } /** * Write Java source code with trace level INFO to the trace system. * * @param java the source code */ public void infoCode(String java) { if (isEnabled(TraceSystem.INFO)) { traceWriter.write(TraceSystem.INFO, module, lineSeparator + "/**/" + java, null); } } /** * Write Java source code with trace level DEBUG to the trace system. * * @param java the source code */ void debugCode(String java) { if (isEnabled(TraceSystem.DEBUG)) { traceWriter.write(TraceSystem.DEBUG, module, lineSeparator + "/**/" + java, null); } } }