All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.appland.appmap.process.hooks.SqlQuery Maven / Gradle / Ivy

package com.appland.appmap.process.hooks;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import com.appland.appmap.output.v1.Event;
import com.appland.appmap.record.Recorder;
import com.appland.appmap.transform.annotations.ArgumentArray;
import com.appland.appmap.transform.annotations.HookClass;
import com.appland.appmap.transform.annotations.MethodEvent;
import com.appland.appmap.transform.annotations.Unique;
import com.appland.appmap.util.Logger;

/**
 * Hooks to capture {@code sql_query} data from classes included in
 * configuration.
 */
@Unique("sql_query")
public class SqlQuery {
  private static final Recorder recorder = Recorder.getInstance();

  // ================================================================================================
  // Calls
  // ================================================================================================

  public static void recordSql(Event event, String databaseType, String sql) {
    event.setSqlQuery(databaseType, sql);
    event.setParameters(null);
    recorder.add(event);
  }

  private static boolean isMock(Object o) {
    final Class c = o.getClass();
    final Package p = c.getPackage();
    if (p == null) {
      // If there's no package info, it's not a Mockito object.
      return false;
    }

    return p.getName().startsWith("org.mockito");
  }

  private static String getDbName(Connection c) {
    String dbname = "";
    if (c == null) {
      return dbname;
    }

    try {
      DatabaseMetaData metadata;
      if (isMock(c) || isMock(metadata = c.getMetaData())) {
        return "[mocked]";
      }

      dbname = metadata.getDatabaseProductName();
    } catch (SQLException e) {
      Logger.println("WARNING, failed to get database name");
      e.printStackTrace(System.err);
    }
    return dbname;
  }

  private static String getDbName(Statement s) {
    String dbname = "";
    if (s == null) {
      return dbname;
    }

    try {
      if (isMock(s)) {
        return "[mocked]";
      }

      dbname = getDbName(s.getConnection());
    } catch (SQLException e) {
      Logger.println("WARNING, failed to get statement's connection");
      e.printStackTrace(System.err);
    }
    return dbname;
  }

  public static void recordSql(Event event, Connection c, String sql) {
    recordSql(event, getDbName(c), sql);
  }

  public static void recordSql(Event event, Statement s, String sql) {
    recordSql(event, getDbName(s), sql);
  }

  @HookClass("java.sql.Connection")
  public static void nativeSQL(Event event, Connection c, String sql) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareCall(Event event, Connection c, String sql) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareCall(Event event, Connection c, String sql, int resultSetType, int resultSetConcurrency) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareCall(Event event, Connection c, String sql, int resultSetType, int resultSetConcurrency,
      int resultSetHoldability) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql, int autoGeneratedKeys) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql, int[] columnIndexes) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql, int resultSetType,
      int resultSetConcurrency) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql, int resultSetType,
      int resultSetConcurrency, int resultSetHoldability) {
    recordSql(event, c, sql);
  }

  @HookClass("java.sql.Connection")
  public static void prepareStatement(Event event, Connection c, String sql, String[] columnNames) {
    recordSql(event, c, sql);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void addBatch(Event event, Statement s, String sql) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void execute(Event event, Statement s, String sql) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void execute(Event event, Statement s, String sql, int autoGeneratedKeys) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void execute(Event event, Statement s, String sql, int[] columnIndexes) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void execute(Event event, Statement s, String sql, String[] columnNames) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void executeQuery(Event event, Statement s, String sql) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void executeUpdate(Event event, Statement s, String sql) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void executeUpdate(Event event, Statement s, String sql, int autoGeneratedKeys) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void executeUpdate(Event event, Statement s, String sql, int[] columnIndexes) {
    recordSql(event, s, sql);
  }

  @HookClass("java.sql.Statement")
  public static void executeUpdate(Event event, Statement s, String sql, String[] columnNames) {
    recordSql(event, s, sql);
  }

  // ================================================================================================
  // Returns
  // ================================================================================================

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void nativeSQL(Event event, Connection c, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareCall(Event event, Connection c, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareCall(Event event, Connection c, Object returnValue, String sql, int resultSetType,
      int resultSetConcurrency) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareCall(Event event, Connection c, Object returnValue, String sql, int resultSetType,
      int resultSetConcurrency, int resultSetHoldability) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql,
      int autoGeneratedKeys) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql, int[] columnIndexes) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql, int resultSetType,
      int resultSetConcurrency) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql, int resultSetType,
      int resultSetConcurrency, int resultSetHoldability) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN)
  public static void prepareStatement(Event event, Connection c, Object returnValue, String sql, String[] columnNames) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void addBatch(Event event, Statement s, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void execute(Event event, Statement s, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void execute(Event event, Statement s, Object returnValue, String sql, int autoGeneratedKeys) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void execute(Event event, Statement s, Object returnValue, String sql, int[] columnIndexes) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void execute(Event event, Statement s, Object returnValue, String sql, String[] columnNames) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void executeQuery(Event event, Statement s, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void executeUpdate(Event event, Statement s, Object returnValue, String sql) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void executeUpdate(Event event, Statement s, Object returnValue, String sql, int autoGeneratedKeys) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void executeUpdate(Event event, Statement s, Object returnValue, String sql, int[] columnIndexes) {
    recorder.add(event);
  }

  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN)
  public static void executeUpdate(Event event, Statement s, Object returnValue, String sql, String[] columnNames) {
    recorder.add(event);
  }

  // ================================================================================================
  // Exceptions
  // ================================================================================================

  /*
   * Many of the methods below are overloaded. However, the hook implementations
   * don't make use of the arguments passed to the original method. So, take
   * advantage of ArgumentArray's "feature" that causes it to match all
   * overloaded mehods by name, and have the hook apply to each of them.
   */

  @ArgumentArray
  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void nativeSQL(Event event, Connection c, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void prepareCall(Event event, Connection c, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void prepareStatement(Event event, Connection c, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void addBatch(Event event, Statement s, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void execute(Event event, Statement s, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void executeQuery(Event event, Statement s, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }

  @ArgumentArray
  @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION)
  public static void executeUpdate(Event event, Statement s, Throwable exception, Object[] args) {
    event.setException(exception);
    recorder.add(event);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy