package com.jqmobile.core.server.db.orm;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.jqmobile.core.orm.ORMS;
import com.jqmobile.core.orm.RsAccessor;
import com.jqmobile.core.orm.exception.ORMParamNotRecognitionException;
import com.jqmobile.core.utils.plain.GUIDUtils;
class ORMSImpl extends OImpl implements ORMS{
public ORMSImpl(Connection conn) {
super(conn);
}
public <D> List<D> queryRaw(String sql, Object[] args, ICallBack<D> back)
throws SQLException, InstantiationException, IllegalAccessException {
PreparedStatement ps = getPreparedStatement(sql, args);
try{
ResultSet rs = ps.executeQuery();
try{
return getResultList(back, rs);
}finally{
rs.close();
}
}finally{
ps.close();
}
}
private <D> List<D> getResultList(ICallBack<D> back, ResultSet rs)
throws SQLException, InstantiationException, IllegalAccessException {
List<D> list = new ArrayList<D>();
while(rs.next()){
list.add(back.get(new RsAccessorImpl(rs)));
}
return list;
}
protected PreparedStatement getPreparedStatement(String sql, Object... args)
throws SQLException {
PreparedStatement ps = getPrepareStatement(sql);
if(args!=null&&args.length>0){
for(int i=0; i<args.length; i++){
ps.setObject(i+1, getParam(args[i]));
}
}
return ps;
}
//只能传递uuid、主键、二进制字节流,其他均报异常
protected Object getParam(Object obj) {
if(obj instanceof UUID){
return GUIDUtils.getBytes((UUID)obj);
}else if(obj.getClass().isPrimitive()){
return obj;
}else if(obj instanceof byte[] || obj instanceof Byte[]){
return obj;
}else{
return obj;
}
}
public <D> List<D> queryRaw(String sql, long startIndex, long endIndex,
Object[] args, ICallBack<D> iCallBack) throws SQLException, InstantiationException, IllegalAccessException {
sql += " limit ?,? ";
PreparedStatement ps = getPreparedStatement(sql, args);
ps.setLong(args.length+1, startIndex);
ps.setLong(args.length+2, endIndex);
try{
ResultSet rs = ps.executeQuery();
try{
return getResultList(iCallBack, rs);
}finally{
rs.close();
}
}finally{
ps.close();
}
}
public <D> D queryRawFirst(String sql, Object[] args, ICallBack<D> back)
throws SQLException, InstantiationException, IllegalAccessException {
PreparedStatement ps = getPreparedStatement(sql, args);
try{
ResultSet rs = ps.executeQuery();
try{
if(rs.next()){
return back.get(new RsAccessorImpl(rs));
}
}finally{
rs.close();
}
}finally{
ps.close();
}
return null;
}
public int modifyRaw(String sql, Object... args) throws SQLException {
PreparedStatement ps = getPreparedStatement(sql, args);
try{
return ps.executeUpdate();
}finally{
ps.close();
}
}
public int deleteRaw(String sql, Object... args) throws SQLException {
PreparedStatement ps = getPreparedStatement(sql, args);
try{
return ps.executeUpdate();
}finally{
ps.close();
}
}
public PreparedStatement getPrepareStatement(String sql)
throws SQLException {
return getConnection().prepareStatement(sql);
}
//
class RsAccessorImpl implements RsAccessor {
private final ResultSet rs;
private RsAccessorImpl(ResultSet rs) {
this.rs = rs;
}
@Override
public UUID getUUID(int columnIndex) throws SQLException {
return GUIDUtils.getGUID(rs.getBytes(columnIndex));
}
@Override
public String getString(int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
return rs.getBoolean(columnIndex);
}
@Override
public byte getByte(int columnIndex) throws SQLException {
return rs.getByte(columnIndex);
}
@Override
public short getShort(int columnIndex) throws SQLException {
return rs.getShort(columnIndex);
}
@Override
public int getInt(int columnIndex) throws SQLException {
return rs.getInt(columnIndex);
}
@Override
public long getLong(int columnIndex) throws SQLException {
return rs.getLong(columnIndex);
}
@Override
public float getFloat(int columnIndex) throws SQLException {
return rs.getFloat(columnIndex);
}
@Override
public double getDouble(int columnIndex) throws SQLException {
return rs.getDouble(columnIndex);
}
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
return rs.getBytes(columnIndex);
}
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
return rs.getAsciiStream(columnIndex);
}
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
return rs.getBinaryStream(columnIndex);
}
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
return rs.getBigDecimal(columnIndex);
}
@Override
public Blob getBlob(int columnIndex) throws SQLException {
return rs.getBlob(columnIndex);
}
@Override
public Clob getClob(int columnIndex) throws SQLException {
return rs.getClob(columnIndex);
}
@Override
public String getColumnName(int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public Object getObject(int i) throws SQLException {
return rs.getObject(i);
}
@Override
public Timestamp getTimestamp(int i) throws SQLException {
return rs.getTimestamp(i);
}
}
}