OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 142 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 142 Rev 174
Line 14... Line 14...
14
 package org.openconcerto.sql.model;
14
 package org.openconcerto.sql.model;
15
 
15
 
16
import org.openconcerto.sql.Log;
16
import org.openconcerto.sql.Log;
17
import org.openconcerto.sql.State;
17
import org.openconcerto.sql.State;
18
import org.openconcerto.sql.request.SQLCache;
18
import org.openconcerto.sql.request.SQLCache;
-
 
19
import org.openconcerto.sql.utils.SQLUtils;
19
import org.openconcerto.utils.CompareUtils;
20
import org.openconcerto.utils.CompareUtils;
20
import org.openconcerto.utils.ExceptionHandler;
21
import org.openconcerto.utils.ExceptionHandler;
21
import org.openconcerto.utils.ExceptionUtils;
22
import org.openconcerto.utils.ExceptionUtils;
22
import org.openconcerto.utils.RTInterruptedException;
23
import org.openconcerto.utils.RTInterruptedException;
23
import org.openconcerto.utils.ThreadFactory;
24
import org.openconcerto.utils.ThreadFactory;
-
 
25
import org.openconcerto.utils.Tuple2;
24
import org.openconcerto.utils.cache.CacheResult;
26
import org.openconcerto.utils.cache.CacheResult;
25
import org.openconcerto.utils.cache.ICacheSupport;
27
import org.openconcerto.utils.cache.ICacheSupport;
26
 
28
 
27
import java.beans.PropertyChangeEvent;
29
import java.beans.PropertyChangeEvent;
28
import java.beans.PropertyChangeListener;
30
import java.beans.PropertyChangeListener;
Line 46... Line 48...
46
import java.util.WeakHashMap;
48
import java.util.WeakHashMap;
47
import java.util.concurrent.ExecutorService;
49
import java.util.concurrent.ExecutorService;
48
import java.util.concurrent.LinkedBlockingQueue;
50
import java.util.concurrent.LinkedBlockingQueue;
49
import java.util.concurrent.ThreadPoolExecutor;
51
import java.util.concurrent.ThreadPoolExecutor;
50
import java.util.concurrent.TimeUnit;
52
import java.util.concurrent.TimeUnit;
-
 
53
import java.util.concurrent.atomic.AtomicLong;
-
 
54
import java.util.concurrent.atomic.AtomicReference;
51
import java.util.logging.Level;
55
import java.util.logging.Level;
52
 
56
 
53
import org.apache.commons.dbcp.AbandonedConfig;
57
import org.apache.commons.dbcp.AbandonedConfig;
54
import org.apache.commons.dbcp.BasicDataSource;
58
import org.apache.commons.dbcp.BasicDataSource;
55
import org.apache.commons.dbcp.ConnectionFactory;
59
import org.apache.commons.dbcp.ConnectionFactory;
Line 991... Line 995...
991
            Log.get().log(Level.INFO, "executeOnce() failed for " + queryInfo, exn);
995
            Log.get().log(Level.INFO, "executeOnce() failed for " + queryInfo, exn);
992
        }
996
        }
993
        return res;
997
        return res;
994
    }
998
    }
995
 
999
 
-
 
1000
    private static final Tuple2<Long, int[]> NO_QUERIES_RES = Tuple2.create(0l, new int[0]);
-
 
1001
 
-
 
1002
    /**
-
 
1003
     * Execute multiple queries in batch.
-
 
1004
     * 
-
 
1005
     * @param queries what to execute.
-
 
1006
     * @param atomic <code>true</code> if all queries should be executed in a transaction.
-
 
1007
     * @return the total update count (&lt; 0 if unknown), followed by the individual update counts.
-
 
1008
     * @throws SQLException if an error occurs.
-
 
1009
     * @see Statement#executeBatch()
-
 
1010
     */
-
 
1011
    public final Tuple2<Long, int[]> executeBatch(final List<String> queries, final boolean atomic) throws SQLException {
-
 
1012
        if (queries.isEmpty())
-
 
1013
            return NO_QUERIES_RES;
-
 
1014
        final long timeMs = System.currentTimeMillis();
-
 
1015
        final long time = System.nanoTime();
-
 
1016
        final long afterCache = time;
-
 
1017
        final AtomicLong afterQueryInfo = new AtomicLong();
-
 
1018
        final AtomicLong afterExecute = new AtomicLong();
-
 
1019
        final AtomicReference<Connection> conn = new AtomicReference<>();
-
 
1020
        final ConnectionHandlerNoSetup<int[], SQLException> handler = new ConnectionHandlerNoSetup<int[], SQLException>() {
-
 
1021
            @Override
-
 
1022
            public int[] handle(SQLDataSource ds) throws SQLException {
-
 
1023
                afterQueryInfo.set(System.nanoTime());
-
 
1024
                conn.set(ds.getConnection());
-
 
1025
                final int[] res;
-
 
1026
                try (final Statement stmt = conn.get().createStatement()) {
-
 
1027
                    for (final String s : queries) {
-
 
1028
                        stmt.addBatch(s);
-
 
1029
                    }
-
 
1030
                    if (Thread.currentThread().isInterrupted())
-
 
1031
                        throw new RTInterruptedException("Interrupted before executing : " + queries);
-
 
1032
                    res = stmt.executeBatch();
-
 
1033
                }
-
 
1034
                afterExecute.set(System.nanoTime());
-
 
1035
                return res;
-
 
1036
            }
-
 
1037
        };
-
 
1038
        final int[] res = atomic ? SQLUtils.executeAtomic(this, handler) : this.useConnection(handler);
-
 
1039
        long totalCount = 0;
-
 
1040
        int i = 0;
-
 
1041
        for (final int count : res) {
-
 
1042
            if (count == Statement.SUCCESS_NO_INFO) {
-
 
1043
                totalCount = -1;
-
 
1044
                break;
-
 
1045
            } else {
-
 
1046
                if (count < 0)
-
 
1047
                    throw new SQLException("Invalid count (" + count + ") for query " + i + " : " + queries.get(i));
-
 
1048
                totalCount += count;
-
 
1049
            }
-
 
1050
            i++;
-
 
1051
        }
-
 
1052
        if (SQLRequestLog.isEnabled()) {
-
 
1053
            final long afterHandle = System.nanoTime();
-
 
1054
            SQLRequestLog.log(queries.toString(), "executeBatch", conn.get(), timeMs, time, afterCache, afterQueryInfo.get(), afterExecute.get(), afterHandle, afterHandle, (int) totalCount);
-
 
1055
        }
-
 
1056
        return Tuple2.create(totalCount, res);
-
 
1057
    }
-
 
1058
 
996
    /**
1059
    /**
997
     * Try to execute a {@link #getValidationQuery() simple query} on the database server. This
1060
     * Try to execute a {@link #getValidationQuery() simple query} on the database server. This
998
     * method even works when the pool is exhausted.
1061
     * method even works when the pool is exhausted.
999
     * 
1062
     * 
1000
     * @throws SQLException if the query couldn't be executed.
1063
     * @throws SQLException if the query couldn't be executed.