package io.digdag.core.database;

import org.skife.jdbi.v2.Handle;

public interface TransactionManager
{
    /**
     * Return the current transaction object.
     */
    Handle getHandle(ConfigMapper configMapper);

    /**
     * Create a new transaction and set it as the current transaction object.
     */
    <T> T begin(SupplierInTransaction<T, RuntimeException, RuntimeException, RuntimeException> func);

    /**
     * Create a new transaction and set it as the current transaction object.
     */
    <T, E1 extends Exception> T begin(
            SupplierInTransaction<T, E1, RuntimeException, RuntimeException> func, Class<E1> e1)
        throws E1;

    /**
     * Create a new transaction and set it as the current transaction object.
     */
    <T, E1 extends Exception, E2 extends Exception> T begin(
            SupplierInTransaction<T, E1, E2, RuntimeException> func, Class<E1> e1, Class<E2> e2)
        throws E1, E2;

    /**
     * Create a new transaction and set it as the current transaction object.
     */
    <T, E1 extends Exception, E2 extends Exception, E3 extends Exception> T begin(
            SupplierInTransaction<T, E1, E2, E3> func, Class<E1> e1, Class<E2> e2, Class<E3> e3)
        throws E1, E2, E3;

    /**
     * Get the current transaction object if exists, otherwise uses a temporary transaction object with auto-commit mode.
     */
    <T> T autoCommit(SupplierInTransaction<T, RuntimeException, RuntimeException, RuntimeException> func);

    /**
     * Get the current transaction object if exists, otherwise uses a temporary transaction object with auto-commit mode.
     */
    <T, E1 extends Exception> T autoCommit(
            SupplierInTransaction<T, E1, RuntimeException, RuntimeException> func, Class<E1> e1)
        throws E1;

    /**
     * Get the current transaction object if exists, otherwise uses a temporary transaction object with auto-commit mode.
     */
    <T, E1 extends Exception, E2 extends Exception> T autoCommit(
            SupplierInTransaction<T, E1, E2, RuntimeException> func, Class<E1> e1, Class<E2> e2)
        throws E1, E2;

    /**
     * Get the current transaction object if exists, otherwise uses a temporary transaction object with auto-commit mode.
     */
    <T, E1 extends Exception, E2 extends Exception, E3 extends Exception> T autoCommit(
            SupplierInTransaction<T, E1, E2, E3> func, Class<E1> e1, Class<E2> e2, Class<E3> e3)
        throws E1, E2, E3;

    /**
     * Abort the current transaction and start a new transaction again.
     */
    void reset();

    @FunctionalInterface
    interface SupplierInTransaction<T, E1 extends Exception, E2 extends Exception, E3 extends Exception>
    {
        T get() throws E1, E2, E3;
    }
}

@@ -373,32 +373,50 @@
 untimeException,
+ RuntimeException,
  RuntimeExceptio
@@ -609,32 +609,50 @@
 untimeException,
+ RuntimeException,
  RuntimeExceptio
@@ -885,32 +885,50 @@
 ction%3CT, E1, E2,
+ RuntimeException,
  RuntimeExceptio
@@ -1204,32 +1204,50 @@
 on%3CT, E1, E2, E3
+, RuntimeException
 %3E func, Class%3CE1
@@ -1300,32 +1300,382 @@
 ws E1, E2, E3;%0A%0A
+    /**%0A     * Create a new transaction and set it as the current transaction object.%0A     */%0A    %3CT, E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception%3E T begin(%0A            SupplierInTransaction%3CT, E1, E2, E3, E4%3E func, Class%3CE1%3E e1, Class%3CE2%3E e2, Class%3CE3%3E e3, Class%3CE4%3E e4)%0A            throws E1, E2, E3, E4;%0A%0A
     /**%0A     * G
@@ -1869,32 +1869,50 @@
 untimeException,
+ RuntimeException,
  RuntimeExceptio
@@ -2154,32 +2154,50 @@
 untimeException,
+ RuntimeException,
  RuntimeExceptio
@@ -2479,32 +2479,50 @@
 ction%3CT, E1, E2,
+ RuntimeException,
  RuntimeExceptio
@@ -2855,16 +2855,34 @@
 , E2, E3
+, RuntimeException
 %3E func, 
@@ -3169,32 +3169,54 @@
 ion, E3 extends 
+Exception, E4 extends 
 Exception%3E%0A    %7B
@@ -3231,16 +3231,32 @@
  T get()
+%0A               
  throws 
@@ -3265,16 +3265,20 @@
 , E2, E3
+, E4
 ;%0A    %7D%0A

Update parameters of begin,autoCommit methods in digdag-core's database.TransactionManager