1 56 package org.objectstyle.cayenne.access; 57 58 import java.sql.SQLException ; 59 import java.util.List ; 60 61 import org.apache.log4j.Level; 62 import org.apache.log4j.Logger; 63 import org.objectstyle.cayenne.access.jdbc.ParameterBinding; 64 import org.objectstyle.cayenne.conn.DataSourceInfo; 65 import org.objectstyle.cayenne.query.Query; 66 import org.objectstyle.cayenne.util.Util; 67 68 84 public class QueryLogger { 85 private static final Logger logObj = Logger.getLogger(QueryLogger.class); 86 87 public static final Level DEFAULT_LOG_LEVEL = Query.DEFAULT_LOG_LEVEL; 88 public static final int TRIM_VALUES_THRESHOLD = 300; 89 90 100 public static void sqlLiteralForObject(StringBuffer buf, Object anObject) { 101 if (anObject == null) { 103 buf.append("NULL"); 104 } 105 else if (anObject instanceof String ) { 107 buf.append('\''); 108 String literal = (String ) anObject; 110 if (literal.length() > TRIM_VALUES_THRESHOLD) { 111 literal = literal.substring(0, TRIM_VALUES_THRESHOLD) + "..."; 112 } 113 114 int curPos = 0; 115 int endPos = 0; 116 117 while ((endPos = literal.indexOf('\'', curPos)) >= 0) { 118 buf.append(literal.substring(curPos, endPos + 1)).append('\''); 119 curPos = endPos + 1; 120 } 121 122 if (curPos < literal.length()) 123 buf.append(literal.substring(curPos)); 124 125 buf.append('\''); 126 } 127 else if (anObject instanceof Number ) { 129 buf.append(anObject); 131 } 132 else if (anObject instanceof java.sql.Date ) { 134 buf.append('\'').append(anObject).append('\''); 135 } 136 else if (anObject instanceof java.sql.Time ) { 138 buf.append('\'').append(anObject).append('\''); 139 } 140 else if (anObject instanceof java.util.Date ) { 142 long time = ((java.util.Date ) anObject).getTime(); 143 buf.append('\'').append(new java.sql.Timestamp (time)).append('\''); 144 } 145 else if (anObject instanceof byte[]) { 147 buf.append("< "); 148 byte[] b = (byte[]) anObject; 149 150 int len = b.length; 151 boolean trimming = false; 152 if (len > TRIM_VALUES_THRESHOLD) { 153 len = TRIM_VALUES_THRESHOLD; 154 trimming = true; 155 } 156 157 for (int i = 0; i < len; i++) { 158 appendFormattedByte(buf, b[i]); 159 buf.append(' '); 160 } 161 162 if (trimming) { 163 buf.append("..."); 164 } 165 buf.append('>'); 166 } 167 else if (anObject instanceof Boolean ) { 168 buf.append('\'').append(anObject).append('\''); 169 170 } 171 else if (anObject instanceof ParameterBinding) { 172 sqlLiteralForObject(buf, ((ParameterBinding) anObject).getValue()); 173 } 174 else { 175 buf 177 .append("[") 178 .append(anObject.getClass().getName()) 179 .append(": ") 180 .append(anObject) 181 .append("]"); 182 } 183 } 184 185 188 protected static void appendFormattedByte(StringBuffer buffer, byte byteValue) { 189 final String digits = "0123456789ABCDEF"; 190 191 buffer.append(digits.charAt((byteValue >>> 4) & 0xF)); 192 buffer.append(digits.charAt(byteValue & 0xF)); 193 } 194 195 198 public static Level getLoggingLevel() { 199 Level level = logObj.getLevel(); 200 return (level != null) ? level : DEFAULT_LOG_LEVEL; 201 } 202 203 206 public static void setLoggingLevel(Level level) { 207 logObj.setLevel(level); 208 } 209 210 213 public static void logConnect(Level logLevel, String dataSource) { 214 if (isLoggable(logLevel)) { 215 logObj.log(logLevel, "Connecting. JNDI path: " + dataSource); 216 } 217 } 218 219 public static void logConnect( 220 Level logLevel, 221 String url, 222 String userName, 223 String password) { 224 if (isLoggable(logLevel)) { 225 StringBuffer buf = new StringBuffer ("Opening connection: "); 226 227 buf.append(url); 229 buf.append("\n\tLogin: ").append(userName); 230 buf.append("\n\tPassword: *******"); 231 232 logObj.log(logLevel, buf.toString()); 233 } 234 } 235 236 239 public static void logPoolCreated(Level logLevel, DataSourceInfo dsi) { 240 if (isLoggable(logLevel)) { 241 StringBuffer buf = new StringBuffer ("Created connection pool: "); 242 243 if (dsi != null) { 244 buf.append(dsi.getDataSourceUrl()); 246 247 if (dsi.getAdapterClassName() != null) { 248 buf.append("\n\tCayenne DbAdapter: ").append( 249 dsi.getAdapterClassName()); 250 } 251 252 buf.append("\n\tDriver class: ").append(dsi.getJdbcDriver()); 253 254 if (dsi.getMinConnections() >= 0) { 255 buf.append("\n\tMin. connections in the pool: ").append( 256 dsi.getMinConnections()); 257 } 258 if (dsi.getMaxConnections() >= 0) { 259 buf.append("\n\tMax. connections in the pool: ").append( 260 dsi.getMaxConnections()); 261 } 262 } 263 else { 264 buf.append(" pool information unavailable"); 265 } 266 267 logObj.log(logLevel, buf.toString()); 268 } 269 } 270 271 public static void logConnectSuccess(Level logLevel) { 272 logObj.log(logLevel, "+++ Connecting: SUCCESS."); 273 } 274 275 public static void logConnectFailure(Level logLevel, Throwable th) { 276 logObj.log(logLevel, "*** Connecting: FAILURE.", th); 277 } 278 279 public static void logQuery(Level logLevel, String queryStr, List params) { 280 logQuery(logLevel, queryStr, params, -1); 281 } 282 283 290 public static void logQuery( 291 Level logLevel, 292 String queryStr, 293 List params, 294 long time) { 295 if (isLoggable(logLevel)) { 296 StringBuffer buf = new StringBuffer (queryStr); 297 if (params != null && params.size() > 0) { 298 buf.append(" [bind: "); 299 sqlLiteralForObject(buf, params.get(0)); 300 301 int len = params.size(); 302 for (int i = 1; i < len; i++) { 303 buf.append(", "); 304 sqlLiteralForObject(buf, params.get(i)); 305 } 306 307 buf.append(']'); 308 } 309 310 if (time > 5) { 312 buf.append(" - prepared in ").append(time).append(" ms."); 313 } 314 315 logObj.log(logLevel, buf.toString()); 316 } 317 } 318 319 public static void logQueryParameters( 320 Level logLevel, 321 String label, 322 List parameters) { 323 324 if (isLoggable(logLevel) && parameters.size() > 0) { 325 int len = parameters.size(); 326 StringBuffer buf = new StringBuffer ("["); 327 buf.append(label).append(": "); 328 329 sqlLiteralForObject(buf, parameters.get(0)); 330 331 for (int i = 1; i < len; i++) { 332 buf.append(", "); 333 sqlLiteralForObject(buf, parameters.get(i)); 334 } 335 336 buf.append(']'); 337 logObj.log(logLevel, buf.toString()); 338 } 339 } 340 341 public static void logSelectCount(Level logLevel, int count) { 342 logSelectCount(logLevel, count, -1); 343 } 344 345 public static void logSelectCount(Level logLevel, int count, long time) { 346 if (isLoggable(logLevel)) { 347 StringBuffer buf = new StringBuffer (); 348 349 if (count == 1) { 350 buf.append("=== returned 1 row."); 351 } 352 else { 353 buf.append("=== returned ").append(count).append(" rows."); 354 } 355 356 if (time >= 0) { 357 buf.append(" - took ").append(time).append(" ms."); 358 } 359 360 logObj.log(logLevel, buf.toString()); 361 } 362 } 363 364 public static void logUpdateCount(Level logLevel, int count) { 365 if (isLoggable(logLevel)) { 366 String countStr = 367 (count == 1) ? "=== updated 1 row." : "=== updated " + count + " rows."; 368 logObj.log(logLevel, countStr); 369 } 370 } 371 372 375 public static void logBeginTransaction(Level logLevel, String transactionLabel) { 376 if (isLoggable(logLevel)) { 377 logObj.log(logLevel, "--- " + transactionLabel); 378 } 379 } 380 381 384 public static void logCommitTransaction(Level logLevel, String transactionLabel) { 385 if (isLoggable(logLevel)) { 386 logObj.log(logLevel, "+++ " + transactionLabel); 387 } 388 } 389 390 393 public static void logRollbackTransaction(Level logLevel, String transactionLabel) { 394 if (isLoggable(logLevel)) { 395 logObj.log(logLevel, "*** " + transactionLabel); 396 } 397 } 398 399 public static void logQueryError(Level logLevel, Throwable th) { 400 if (th != null) { 401 th = Util.unwindException(th); 402 } 403 404 logObj.log(logLevel, "*** error.", th); 405 406 if (th instanceof SQLException ) { 407 SQLException sqlException = ((SQLException ) th).getNextException(); 408 while (sqlException != null) { 409 logObj.log(logLevel, "*** nested SQL error.", sqlException); 410 sqlException = sqlException.getNextException(); 411 } 412 } 413 } 414 415 public static void logQueryStart(Level logLevel, int count) { 416 if (isLoggable(logLevel)) { 417 String countStr = 418 (count == 1) 419 ? "--- will run 1 query." 420 : "--- will run " + count + " queries."; 421 logObj.log(logLevel, countStr); 422 } 423 } 424 425 public static boolean isLoggable(Level logLevel) { 426 return logObj.isEnabledFor(logLevel); 427 } 428 429 } 430 | Popular Tags |