/**
* Copyright (c) 2004-2011 Wang Jinbao(Julian Wong), http://www.ralasafe.com
* Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
*/
package org.ralasafe.db.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ralasafe.EntityExistException;
import org.ralasafe.RalasafeException;
import org.ralasafe.db.Column;
import org.ralasafe.db.ColumnAdapter;
import org.ralasafe.db.DBLevelException;
import org.ralasafe.db.DBPower;
import org.ralasafe.db.Table;
import org.ralasafe.db.TableSaver;
import org.ralasafe.util.DBUtil;
import org.ralasafe.util.DefaultPageBatch;
import org.ralasafe.util.Util;
public class TableSaverImpl implements TableSaver {
private Table table;
private String insertSql;
private TableSelectorImpl selector;
private static Log logger=LogFactory.getLog( TableSelectorImpl.class );
public Table getTable() {
return table;
}
public void setTable( Table table ) {
this.table=table;
insertSql=DBUtil.insertSql( table.getName(), table.getColumnNames() );
selector=new TableSelectorImpl();
selector.setTable( table );
}
public int[] batchSave( Object[] os )
throws DBLevelException {
Connection conn=null;
try {
conn=DBPower.getConnection( table.getId() );
return batchSave( conn, os );
} finally {
DBUtil.close( conn );
}
}
public Collection batchSave( Collection coll )
throws DBLevelException {
Connection conn=null;
try {
conn=DBPower.getConnection( table.getId() );
return batchSave( conn, coll );
} finally {
DBUtil.close( conn );
}
}
public int[] batchSave( Connection conn, Object[] os )
throws DBLevelException {
if( os==null )
return null;
PreparedStatement pstmt=null;
try {
pstmt=conn.prepareStatement( insertSql );
Column[] columns=table.getColumns();
ArrayPageBatch apb=new ArrayPageBatch();
apb.setPageSize( DBPower.getMaxBatchSize() );
apb.setColumns( columns );
apb.setPreparedStatement( pstmt );
apb.doBatch( os );
return apb.getResult();
} catch( SQLException e ) {
logger.error( "", e );
throw new DBLevelException( e );
} catch( Exception e ) {
logger.error( "", e );
throw new RalasafeException( e );
} finally {
DBUtil.close( pstmt );
}
}
public Collection batchSave( Connection conn,
Collection coll ) throws DBLevelException {
if( coll==null )
return null;
PreparedStatement pstmt=null;
try {
pstmt=conn.prepareStatement( insertSql );
Column[] columns=table.getColumns();
CollectionPageBatch cpb=new CollectionPageBatch();
cpb.setPageSize( DBPower.getMaxBatchSize() );
cpb.setColumns( columns );
cpb.setPreparedStatement( pstmt );
cpb.doBatch( coll );
return cpb.getResult();
} catch( SQLException e ) {
logger.error( "", e );
throw new DBLevelException( e );
} catch( Exception e ) {
logger.error( "", e );
throw new RalasafeException( e );
} finally {
DBUtil.close( pstmt );
}
}
public void save( Object o ) throws EntityExistException,
DBLevelException {
Connection conn=null;
try {
conn=DBPower.getConnection( table.getId() );
save( conn, o );
} finally {
DBUtil.close( conn );
}
}
public void save( Connection conn, Object o )
throws EntityExistException, DBLevelException {
PreparedStatement pstmt=null;
try {
pstmt=conn.prepareStatement( insertSql );
Column[] columns=table.getColumns();
for( int i=0; i<columns.length; i++ ) {
Column column=columns[i];
ColumnAdapter columnAdapter=column.getAdapter();
columnAdapter.setPreparedStatement( pstmt, i+1, o );
}
pstmt.executeUpdate();
} catch( SQLException e ) {
logger.error( "", e );
if( conn!=null ) {
// violate pk or unique constraints?
if( !Util.isEmpty( table.getIdColumns() ) ) {
boolean isExist=selector.isExistByIdColumns( conn, o );
if( isExist ) {
throw new EntityExistException( o );
}
}
if( !Util.isEmpty( table.getUniqueColumns() ) ) {
boolean isExist=selector.isExistByUniqueColumns( conn, o );
if( isExist ) {
throw new EntityExistException( o );
}
}
throw new DBLevelException( e );
} else {
throw new DBLevelException( e );
}
} finally {
DBUtil.close( pstmt );
}
}
class ArrayPageBatch extends DefaultPageBatch {
private Column[] columns;
private PreparedStatement pstmt;
private int[] result;
private int index=0;
public int[] getResult() {
return result;
}
public void setColumns( Column[] columns ) {
this.columns=columns;
}
public void setPreparedStatement( PreparedStatement pstmt ) {
this.pstmt=pstmt;
}
public void doBatch( Object[] objs ) throws Exception {
result=new int[ objs.length ];
super.doBatch( objs );
}
public void doInPage( Object[] objs ) throws SQLException {
for( int osIndex=0; osIndex<objs.length; osIndex++ ) {
for( int colIndex=0; colIndex<columns.length; colIndex++ ) {
Column column=columns[colIndex];
ColumnAdapter columnAdapter=column.getAdapter();
columnAdapter.setPreparedStatement( pstmt, colIndex+1, objs[osIndex] );
}
pstmt.addBatch();
}
int[] pageResult=pstmt.executeBatch();
//COPY insert page result into batch result
for( int i=0;i<pageResult.length; i++ ) {
result[index]=pageResult[i];
index++;
}
}
}
class CollectionPageBatch extends DefaultPageBatch {
private Column[] columns;
private PreparedStatement pstmt;
private Collection result;
public Collection getResult() {
return result;
}
public void setColumns( Column[] columns ) {
this.columns=columns;
}
public void setPreparedStatement( PreparedStatement pstmt ) {
this.pstmt=pstmt;
}
public void doBatch( Collection coll ) throws Exception {
result=new ArrayList( coll.size() );
super.doBatch( coll );
}
public void doInPage( Collection coll ) throws SQLException {
for( Iterator iter=coll.iterator(); iter.hasNext(); ) {
Object o=iter.next();
for( int colIndex=0; colIndex<columns.length; colIndex++ ) {
Column column=columns[colIndex];
ColumnAdapter columnAdapter=column.getAdapter();
columnAdapter.setPreparedStatement( pstmt, colIndex+1, o );
}
pstmt.addBatch();
}
int[] pageResult=pstmt.executeBatch();
//COPY insert page result into batch result
for( int i=0;i<pageResult.length; i++ ) {
result.add( new Integer( pageResult[i] ) );
}
}
}
}