public Object invoke()

in src/main/java/org/mariadb/jdbc/internal/failover/FailoverProxy.java [161:295]


  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    String methodName = method.getName();
    switch (methodName) {
      case METHOD_GET_LOCK:
        return this.lock;
      case METHOD_GET_NO_BACKSLASH:
        return listener.noBackslashEscapes();
      case METHOD_IS_MARIADB:
        return listener.isServerMariaDb();
      case METHOD_GET_CATALOG:
        return listener.getCatalog();
      case METHOD_GET_TIMEOUT:
        return listener.getTimeout();
      case METHOD_VERSION_GREATER_OR_EQUAL:
        return listener.versionGreaterOrEqual((int) args[0], (int) args[1], (int) args[2]);
      case METHOD_SESSION_STATE_AWARE:
        return listener.sessionStateAware();
      case METHOD_IS_EXPLICIT_CLOSED:
        return listener.isExplicitClosed();
      case METHOD_GET_OPTIONS:
        return listener.getUrlParser().getOptions();
      case METHOD_GET_MAJOR_VERSION:
        return listener.getMajorServerVersion();
      case METHOD_GET_SERVER_THREAD_ID:
        return listener.getServerThreadId();
      case METHOD_GET_URLPARSER:
        return listener.getUrlParser();
      case METHOD_GET_PROXY:
        return this;
      case METHOD_IS_CLOSED:
        return listener.isClosed();
      case METHOD_IS_VALID:
        return listener.isValid((int) args[0]);
      case METHOD_PROLOG:
        listener.prolog((long) args[0], (MariaDbConnection) args[2], (MariaDbStatement) args[3]);
        return null;
      case METHOD_EXECUTE_QUERY:
        boolean isClosed = this.listener.isClosed();
        try {
          this.listener.preExecute();
        } catch (SQLException e) {
          // handle failover only if connection error
          // normal error can be thrown upon reconnection if there was a transaction in progress.
          if (hasToHandleFailover(e)) {
            return handleFailOver(e, method, args, listener.getCurrentProtocol(), isClosed);
          }
        }
        break;
      case METHOD_SET_READ_ONLY:
        this.listener.switchReadOnlyConnection((Boolean) args[0]);
        return null;
      case METHOD_GET_READ_ONLY:
        return this.listener.isReadOnly();
      case METHOD_IN_TRANSACTION:
        return this.listener.inTransaction();
      case METHOD_IS_MASTER_CONNECTION:
        return this.listener.isMasterConnection();
      case METHOD_ABORT:
        this.listener.preAbort();
        return null;
      case METHOD_CLOSED_EXPLICIT:
        this.listener.preClose();
        return null;
      case METHOD_COM_MULTI_PREPARE_EXECUTES:
      case METHOD_EXECUTE_PREPARED_QUERY:
        boolean mustBeOnMaster = (Boolean) args[0];
        ServerPrepareResult serverPrepareResult = (ServerPrepareResult) args[1];
        if (serverPrepareResult != null) {
          if (!mustBeOnMaster
              && serverPrepareResult.getUnProxiedProtocol().isMasterConnection()
              && !this.listener.hasHostFail()) {
            // PrepareStatement was to be executed on slave, but since a failover was running on
            // master connection. Slave connection is up
            // again, so has to be re-prepared on slave
            try {
              logger.trace(
                  "re-prepare query \"{}\" on slave (was " + "temporary on master since failover)",
                  serverPrepareResult.getSql());
              this.listener.rePrepareOnSlave(serverPrepareResult, false);
            } catch (SQLException q) {
              // error during re-prepare, will do executed on master.
            }
          }
          boolean wasClosed = this.listener.isClosed();
          try {
            return listener.invoke(method, args, serverPrepareResult.getUnProxiedProtocol());
          } catch (InvocationTargetException e) {
            if (e.getTargetException() != null) {
              if (e.getTargetException() instanceof SQLException
                  && hasToHandleFailover((SQLException) e.getTargetException())) {
                return handleFailOver(
                    (SQLException) e.getTargetException(),
                    method,
                    args,
                    serverPrepareResult.getUnProxiedProtocol(),
                    wasClosed);
              }
              throw e.getTargetException();
            }
            throw e;
          }
        }
        break;
      case METHOD_PROLOG_PROXY:
        boolean wasClosed = this.listener.isClosed();
        try {
          if (args[0] != null) {
            return listener.invoke(
                method, args, ((ServerPrepareResult) args[0]).getUnProxiedProtocol());
          }
          return null;
        } catch (InvocationTargetException e) {
          if (e.getTargetException() != null) {
            if (e.getTargetException() instanceof SQLException
                && hasToHandleFailover((SQLException) e.getTargetException())) {
              return handleFailOver(
                  (SQLException) e.getTargetException(),
                  method,
                  args,
                  ((ServerPrepareResult) args[0]).getUnProxiedProtocol(),
                  wasClosed);
            }
            throw e.getTargetException();
          }
          throw e;
        }
      case METHOD_RESET:
        // listener will report reset on any active connections (Master/slave)
        listener.reset();
        return null;
      default:
    }

    return executeInvocation(method, args, false);
  }