1
package org.hisp.dhis.jdbc.batchhandler;
4
* Copyright (c) 2004-2007, University of Oslo
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
9
* * Redistributions of source code must retain the above copyright notice, this
10
* list of conditions and the following disclaimer.
11
* * Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
* * Neither the name of the HISP project nor the names of its contributors may
15
* be used to endorse or promote products derived from this software without
16
* specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
import java.sql.Connection;
31
import java.sql.DriverManager;
32
import java.sql.ResultSet;
33
import java.sql.SQLException;
34
import java.sql.Statement;
35
import java.util.ArrayList;
36
import java.util.Collection;
38
import org.apache.commons.logging.Log;
39
import org.apache.commons.logging.LogFactory;
40
import org.hisp.dhis.jdbc.BatchHandler;
41
import org.hisp.dhis.jdbc.JDBCConfiguration;
42
import org.hisp.dhis.jdbc.StatementBuilder;
43
import org.hisp.dhis.jdbc.factory.IdentifierExtractorFactory;
44
import org.hisp.dhis.jdbc.factory.StatementBuilderFactory;
45
import org.hisp.dhis.jdbc.identifier.IdentifierExtractor;
48
* @author Lars Helge Overland
49
* @version $Id: AbstractBatchHandler.java 5808 2008-10-03 15:18:48Z larshelg $
51
public abstract class AbstractBatchHandler
52
implements BatchHandler
54
private static final Log log = LogFactory.getLog( AbstractBatchHandler.class );
56
private JDBCConfiguration configuration;
58
private Connection connection;
60
private Statement statement;
62
protected StatementBuilder statementBuilder;
64
private IdentifierExtractor identifierExtractor;
66
protected StringBuffer sqlBuffer;
68
private final int maxLength = 200000;
70
private int statementCount = 0;
72
private Collection<Integer> identifiers;
74
protected boolean hasSinglePrimaryKey = true; // Should be overriden by subclasses
76
protected String tableName;
78
// -------------------------------------------------------------------------
80
// -------------------------------------------------------------------------
82
@SuppressWarnings( "unused" )
83
private AbstractBatchHandler()
87
protected AbstractBatchHandler( JDBCConfiguration configuration )
89
this.configuration = configuration;
90
this.statementBuilder = StatementBuilderFactory.createStatementBuilder( configuration.getDialect() );
91
this.identifierExtractor = IdentifierExtractorFactory.createIdentifierExtractor( configuration.getDialect() );
96
// -------------------------------------------------------------------------
97
// BatchHandler implementation
98
// -------------------------------------------------------------------------
104
Class.forName( configuration.getDriverClass() );
106
connection = DriverManager.getConnection(
107
configuration.getConnectionUrl(),
108
configuration.getUsername(),
109
configuration.getPassword() );
111
statement = connection.createStatement();
113
sqlBuffer = new StringBuffer( maxLength );
117
identifiers = new ArrayList<Integer>();
121
catch ( Exception ex )
123
throw new RuntimeException( "Failed to create statement", ex );
127
public final int insertObject( Object object, boolean returnGeneratedIdentifier )
131
sqlBuffer = new StringBuffer();
137
addSqlStatement( object );
139
sqlBuffer.deleteCharAt( sqlBuffer.length() - 1 );
141
statement.executeUpdate( sqlBuffer.toString() );
143
return returnGeneratedIdentifier ? identifierExtractor.extract( statement ) : 0;
145
catch ( SQLException ex )
147
throw new RuntimeException( "Failed to insert " + object.getClass().getName(), ex );
151
public final void addObject( Object object )
153
addSqlStatement( object );
157
if ( sqlBuffer.length() >= maxLength )
161
sqlBuffer.deleteCharAt( sqlBuffer.length() - 1 );
163
statement.executeUpdate( sqlBuffer.toString() );
165
if ( hasSinglePrimaryKey )
167
identifiers.addAll( identifierExtractor.extract( statement, statementCount ) );
170
sqlBuffer = new StringBuffer();
176
catch ( SQLException ex )
178
log.debug( "SQL statement leading to exception: '" + sqlBuffer.toString() + "'" );
180
throw new RuntimeException( "Failed to add objects", ex );
185
public final void updateObject( Object object )
189
String sql = getUpdateSqlStatement( object );
191
statement.executeUpdate( sql );
193
catch ( SQLException ex )
195
throw new RuntimeException( "Failed to update object", ex );
199
public final boolean objectExists( Object objectName )
203
String sql = getUniquenessStatement( objectName );
205
ResultSet resultSet = statement.executeQuery( sql );
207
return resultSet.next();
209
catch ( SQLException ex )
211
throw new RuntimeException( "Failed to check uniqueness of object", ex );
215
public int getObjectIdentifier( Object objectName )
219
String sql = getIdentifierStatement( objectName );
221
ResultSet resultSet = statement.executeQuery( sql );
223
return resultSet.next() ? resultSet.getInt( 1 ) : 0;
225
catch ( SQLException ex )
227
throw new RuntimeException( "Failed to get object identifier", ex );
231
public final Collection<Integer> flush()
235
if ( sqlBuffer.length() > 2 && statementCount != 0 )
237
sqlBuffer.deleteCharAt( sqlBuffer.length() - 1 );
239
statement.executeUpdate( sqlBuffer.toString() );
241
if ( hasSinglePrimaryKey )
243
identifiers.addAll( identifierExtractor.extract( statement, statementCount ) );
251
catch ( SQLException ex )
253
log.debug( "SQL statement leading to exception: '" + sqlBuffer.toString() + "'" );
255
throw new RuntimeException( "Failed to flush BatchHandler", ex );
259
if ( statement != null )
265
catch ( SQLException statementEx )
267
statementEx.printStackTrace();
271
if ( connection != null )
277
catch ( SQLException connectionEx )
279
connectionEx.printStackTrace();
285
// -------------------------------------------------------------------------
286
// Supportive methods
287
// -------------------------------------------------------------------------
289
private void addSqlStatement( Object object )
293
sqlBuffer.append( statementBuilder.getInsertStatementValues() );
296
public void setTableName( String tableName )
298
this.tableName = tableName;
301
// -------------------------------------------------------------------------
303
// -------------------------------------------------------------------------
305
protected abstract void setTableName();
307
protected abstract void openSqlStatement();
309
protected abstract String getUpdateSqlStatement( Object object );
311
protected abstract String getIdentifierStatement( Object objectName );
313
protected abstract String getUniquenessStatement( Object object );
315
protected abstract void addColumns();
317
protected abstract void addValues( Object object );