Revision 46304 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/PerformChangesOperation.java

View differences:

PerformChangesOperation.java
47 47
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
48 48
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
49 49
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
50
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCUpdateWithoutChangesException;
51 50
import org.gvsig.fmap.dal.store.jdbc2.JDBCHelper;
52 51
import org.gvsig.fmap.dal.store.jdbc2.JDBCUtils;
53 52
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory.TableReference;
......
56 55
import static org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase.PROP_TABLE;
57 56
import org.gvsig.tools.dispose.Disposable;
58 57
import org.gvsig.tools.dispose.DisposeUtils;
58
import org.gvsig.tools.util.Invocable;
59 59

  
60 60
@SuppressWarnings("UseSpecificCatch")
61 61
public class PerformChangesOperation extends AbstractConnectionWritableOperation {
......
154 154
    }
155 155

  
156 156
    public void performDeletes(Connection conn) throws DataException {
157

  
158 157
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
159 158
        String sql = getDeleteSQL(sqlbuilder);
160

  
161
        PreparedStatement st = null;
162
        Disposable paramsDisposer = null;
163
        try {
164
            st = conn.prepareStatement(sql);
165
            while (deleteds.hasNext()) {
166
                FeatureReference reference = (FeatureReference) deleteds.next();
167
                paramsDisposer = sqlbuilder.setParameters(st, reference);
168
                int nAffected = JDBCUtils.executeUpdate(st,sql);
169
                if (nAffected == 0) {
170
                    throw new JDBCUpdateWithoutChangesException(
171
                            sqlbuilder.delete().toString(),
172
                            null
173
                    );
174
                }
175
                if (nAffected > 1) {
176
                    LOGGER.warn("Remove statement affectst to {} rows ( {} )",
177
                            nAffected, sql
178
                    );
179
                }
159
        perform_batchmode(conn, this.deleteds, sqlbuilder, sql, new Invocable() {
160
            @Override
161
            public Object call(Object... args) {
162
                JDBCSQLBuilderBase sqlbuilder = (JDBCSQLBuilderBase) args[0];
163
                PreparedStatement preparedStatement = (PreparedStatement) args[1];
164
                FeatureReference reference = (FeatureReference) args[2];
165
                Disposable theParametersDisposable = sqlbuilder.setParameters(preparedStatement, reference);
166
                return theParametersDisposable;
180 167
            }
181
        } catch (SQLException e) {
182
            throw new JDBCSQLException(e,sql);
183
        } finally {
184
            JDBCUtils.closeQuietly(st);
185
            DisposeUtils.disposeQuietly(paramsDisposer);
186
        }
168
        });
187 169
    }
188 170
    
189 171
    public String getInsertSQL() {
......
232 214
    }
233 215

  
234 216
    public void performInserts(Connection conn) throws DataException {
235
//        performInserts_normalmode(conn);
236
        performInserts_batchmode(conn);
237
    }
238
    
239
    private void performInserts_normalmode(Connection conn) throws DataException {
240 217
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
241 218
        String sql = getInsertSQL(sqlbuilder);
242
        
243
        PreparedStatement st;
244
        Disposable paramsDisposer;
245
        try {
246
            st = conn.prepareStatement(sql);
247
            while (inserteds.hasNext()) {
248
                FeatureProvider feature = inserteds.next();
249
                paramsDisposer = sqlbuilder.setParameters(st, feature);
250
                try {
251
                    if (JDBCUtils.executeUpdate(st,sql) == 0) {
252
                        throw new JDBCExecuteSQLException(
253
                                sqlbuilder.insert().toString(),
254
                                null
255
                        );
256
                    }
257
                } finally {
258
                    DisposeUtils.disposeQuietly(paramsDisposer);
259
                }
260
            }
261
        } catch (JDBCExecuteSQLException ex) {
262
            throw ex;
263
        } catch (Exception ex) {
264
            throw new JDBCExecuteSQLException(sql,ex);
265
        }
266
    }
267

  
268
    @SuppressWarnings("UnusedAssignment")
269
    private void performInserts_batchmode(Connection conn) throws DataException {
270
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
271
        String sql = getInsertSQL(sqlbuilder);
272
        
273
        PreparedStatement preparedStatement;
274
        Disposable[] disposableParameters;
275
        try {
276
            preparedStatement = conn.prepareStatement(sql);
277
            int batchSize = this.helper.getConnectionParameters().getBatchSize();
278
            if( batchSize<1 ) {
279
                batchSize = 200;
280
            }
281
            int batchCount = 0;
282
            disposableParameters = new Disposable[batchSize];
283
            
284
            while (inserteds.hasNext()) {
285
                FeatureProvider feature = inserteds.next();
286
                
219
        perform_batchmode(conn, this.inserteds, sqlbuilder, sql, new Invocable() {
220
            @Override
221
            public Object call(Object... args) {
222
                JDBCSQLBuilderBase sqlbuilder = (JDBCSQLBuilderBase) args[0];
223
                PreparedStatement preparedStatement = (PreparedStatement) args[1];
224
                FeatureProvider feature = (FeatureProvider) args[2];
287 225
                Disposable theParametersDisposable = sqlbuilder.setParameters(preparedStatement, feature);
288
                JDBCUtils.addBatch(preparedStatement,sql);
289
                disposableParameters[batchCount++] = theParametersDisposable;
290

  
291
                if( batchCount >= batchSize || (!inserteds.hasNext() && batchCount>0) ) {
292
                    int[] status = JDBCUtils.executeBatch(preparedStatement,sql);
293

  
294
                    preparedStatement.clearParameters();
295
                    preparedStatement.clearBatch();
296
                    for (int i = 0; i < batchCount && i < disposableParameters.length; i++) {
297
                        DisposeUtils.dispose(disposableParameters[i]);
298
                        disposableParameters[i] = null;
299
                    }
300
                    batchCount = 0;
301
                    
302
                    for (int n : status) {
303
                        if( n<=Statement.EXECUTE_FAILED ) { //-3
304
                            throw new RuntimeException("Can't insert feature (n="+n+").");
305
                        }
306
                    }                
307
                }
226
                return theParametersDisposable;
308 227
            }
309
            
310
        } catch (Exception ex) {
311
            throw new JDBCExecuteSQLException(sql,ex);
312
        }
228
        });
313 229
    }
314 230
    
315 231
    public String getUpdateSQL() {
......
371 287
    }
372 288
    
373 289
    public void performUpdates(Connection conn) throws DataException {
374

  
375 290
        JDBCSQLBuilderBase sqlbuilder = createSQLBuilder();
376 291
        String sql = getUpdateSQL(sqlbuilder);
377
        
378
        PreparedStatement st = null;
379
        Disposable paramsDisposer = null;
292
        perform_batchmode(conn, this.updateds, sqlbuilder, sql, new Invocable() {
293
            @Override
294
            public Object call(Object... args) {
295
                JDBCSQLBuilderBase sqlbuilder = (JDBCSQLBuilderBase) args[0];
296
                PreparedStatement preparedStatement = (PreparedStatement) args[1];
297
                FeatureProvider feature = (FeatureProvider) args[2];
298
                Disposable theParametersDisposable = sqlbuilder.setParameters(preparedStatement, feature);
299
                return theParametersDisposable;
300
            }
301
        });
302
    }
303
    
304
       
305
    private void perform_batchmode(Connection conn, Iterator elements, JDBCSQLBuilderBase sqlbuilder, String sql, Invocable fillPreparedStatement) throws DataException {       
306
        PreparedStatement preparedStatement;
307
        Disposable[] disposableParameters;
380 308
        try {
381
            st = conn.prepareStatement(sql);
382
            while (updateds.hasNext()) {
383
                FeatureProvider featureProvider = (FeatureProvider) updateds.next();
384
                paramsDisposer = sqlbuilder.setParameters(st, featureProvider);
385
                if (JDBCUtils.executeUpdate(st,sql) == 0) {
386
                    throw new JDBCUpdateWithoutChangesException(sql,null);
309
            preparedStatement = conn.prepareStatement(sql);
310
            int batchSize = this.helper.getConnectionParameters().getBatchSize();
311
            if( batchSize<1 ) {
312
                batchSize = 200;
313
            }
314
            int batchCount = 0;
315
            disposableParameters = new Disposable[batchSize];
316
            
317
            while (elements.hasNext()) {
318
                Object element = elements.next();
319
                
320
                Disposable theParametersDisposable = (Disposable) fillPreparedStatement.call(sqlbuilder,preparedStatement, element );
321
                JDBCUtils.addBatch(preparedStatement,sql);
322
                disposableParameters[batchCount++] = theParametersDisposable;
323

  
324
                if( batchCount >= batchSize || (!elements.hasNext() && batchCount>0) ) {
325
                    int[] status = JDBCUtils.executeBatch(preparedStatement,sql);
326

  
327
                    preparedStatement.clearParameters();
328
                    preparedStatement.clearBatch();
329
                    for (int i = 0; i < batchCount && i < disposableParameters.length; i++) {
330
                        DisposeUtils.dispose(disposableParameters[i]);
331
                        disposableParameters[i] = null;
332
                    }
333
                    batchCount = 0;
334
                    
335
                    for (int n : status) {
336
                        if( n<=Statement.EXECUTE_FAILED ) { //-3
337
                            throw new RuntimeException("Can't process element (n="+n+").");
338
                        }
339
                    }                
387 340
                }
388 341
            }
389
        } catch (SQLException e) {
390
            throw new JDBCSQLException(e,sql);
391
        } finally {
392
            JDBCUtils.closeQuietly(st);
393
            DisposeUtils.disposeQuietly(paramsDisposer);
342
            
343
        } catch (Exception ex) {
344
            throw new JDBCExecuteSQLException(sql,ex);
394 345
        }
395 346
    }
396 347

  

Also available in: Unified diff