1. Project Clover database Fri Jul 17 2026 06:10:26 UTC
  2. Package guru.mikelue.foxglove.jdbc

File JdbcTxWorker.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

16
34
4
2
136
96
14
0.41
8.5
2
3.5

Classes

Class Line # Actions
JdbcTxWorker 22 34 0% 14 1
0.981481598.1%
JdbcTxWorker.InsertionContext 26 0 - 0 0
-1.0 -
 

Contributing tests

This file is covered by 48 tests. .

Source view

1    package guru.mikelue.foxglove.jdbc;
2   
3    import org.slf4j.Logger;
4    import org.slf4j.LoggerFactory;
5   
6    import java.sql.Connection;
7    import java.sql.SQLException;
8    import java.util.List;
9    import java.util.Map;
10    import java.util.function.Consumer;
11    import java.util.function.Supplier;
12   
13    import guru.mikelue.foxglove.ColumnMeta;
14    import guru.mikelue.foxglove.TupleAccessor;
15    import guru.mikelue.foxglove.setting.DataSettingInfo;
16   
17    import static java.sql.Statement.RETURN_GENERATED_KEYS;
18   
19    /**
20    * This worker is responsible for performing JDBC transaction for insertion of generated rows.
21    */
 
22    class JdbcTxWorker implements AutoCloseable {
23    /**
24    * The context make JdbcTxWorker easier to be tested.
25    */
 
26    record InsertionContext (
27    String sql, int numberOfRows,
28    String[] namesOfGeneratedColumns,
29    Supplier<Map<ColumnMeta, Object>> rowParamsGenerator,
30    DataSettingInfo settingInfo
31    ) {}
32   
33    private Logger logger = LoggerFactory.getLogger(JdbcTxWorker.class);
34   
35    private final Connection conn;
36    private final TransactionGear txGear;
37    private final boolean oldAutoCommit;
38   
 
39  71 toggle JdbcTxWorker(
40    TransactionGear txGear
41    ) throws SQLException {
42  71 this.txGear = txGear;
43  71 this.conn = txGear.connection();
44   
45  71 oldAutoCommit = conn.getAutoCommit();
46   
47  71 if (!txGear.joinConnection()) {
48  61 conn.setAutoCommit(false);
49    }
50    }
51   
52    private int unCommittedNumberOfRows = 0;
53   
 
54  71 toggle @Override
55    public void close() throws SQLException
56    {
57  71 logger.debug("Closing JDBC transaction worker");
58  71 commitIfNeeded();
59   
60  71 if (!txGear.joinConnection()) {
61  61 conn.setAutoCommit(oldAutoCommit);
62    }
63    }
64   
65    /**
66    * This is stateful method, which would keep track of uncommitted rows.
67    *
68    * The {@link #close()} method would commit remaining uncommitted rows
69    * if joinConnection is false.
70    */
 
71  109 toggle int performInsert(
72    InsertionContext context,
73    Consumer<List<TupleAccessor>> generatedValuesConsumer
74    ) throws SQLException
75    {
76  109 var insertSql = context.sql();
77  109 var namesOfGeneratedColumns = context.namesOfGeneratedColumns();
78   
79  109 logger.debug(
80    "Going to insert [{}] rows by SQL:\n\t{}",
81    context.numberOfRows(), insertSql
82    );
83   
84  109 try (var stmt = namesOfGeneratedColumns.length > 0 ?
85    conn.prepareStatement(insertSql, namesOfGeneratedColumns) :
86    conn.prepareStatement(insertSql, RETURN_GENERATED_KEYS)
87    ) {
88  109 var batchWorker = BatchWorker.newInstance(
89    conn.getMetaData().getDriverName(),
90    stmt, namesOfGeneratedColumns, generatedValuesConsumer,
91    txGear.batchSize(),
92    context.settingInfo()
93    );
94  109 var rowParamsGenerator = context.rowParamsGenerator();
95   
96  1482 for (int rowIndex = 0; rowIndex < context.numberOfRows(); rowIndex++) {
97  1373 var valuesOfRow = rowParamsGenerator.get();
98   
99  1373 if (logger.isDebugEnabled()) {
100  1373 logger.trace("Preparing row[{}] for insertion: {}",
101    rowIndex, valuesOfRow.values());
102    }
103   
104  1373 batchWorker.addBatch(valuesOfRow);
105   
106  1373 unCommittedNumberOfRows++;
107  1373 if (unCommittedNumberOfRows >= txGear.batchSize()) {
108  32 commitIfNeeded();
109    }
110    }
111   
112    /*
113    * If there are existing statements not executed, execute them here.
114    */
115  109 batchWorker.executeBatch();
116    // :~)
117    }
118   
119  109 return context.numberOfRows();
120    }
121   
 
122  103 toggle private void commitIfNeeded() throws SQLException
123    {
124  103 if (txGear.joinConnection()) {
125  26 logger.debug("Skip committing [{}] remaining statements because of joining existing transaction.", unCommittedNumberOfRows);
126  26 unCommittedNumberOfRows = 0;
127  26 return;
128    }
129   
130  77 if (unCommittedNumberOfRows > 0) {
131  75 logger.debug("Committing [{}] remaining statements of batch[{}].", unCommittedNumberOfRows, txGear.batchSize());
132  75 conn.commit();
133  75 unCommittedNumberOfRows = 0;
134    }
135    }
136    }