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
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