package ddth.dasp.handlersocket.hsc.hs4j;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import com.google.code.hs4j.FindOperator;
import com.google.code.hs4j.HSClient;
import com.google.code.hs4j.IndexSession;
import com.google.code.hs4j.ModifyStatement;
import com.google.code.hs4j.exception.HandlerSocketException;
import com.google.code.hs4j.impl.HSClientImpl;
import ddth.dasp.handlersocket.hsc.IHsc;
public class Hs4jHsc implements IHsc {
private String name;
private String server;
private int port;
private boolean readWrite;
private HSClient hsClient;
private Map<String, IndexSession> indexSessions = new HashMap<String, IndexSession>();
public Hs4jHsc(String connName, String server, int port, boolean readWrite) {
this.name = connName;
this.server = server;
this.port = port;
this.readWrite = readWrite;
}
public boolean isReadWrite() {
return readWrite;
}
/**
* {@inheritDoc}
*/
@Override
public void init() {
int availableProcessors = Runtime.getRuntime().availableProcessors();
try {
hsClient = new HSClientImpl(server, port, availableProcessors);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public void destroy() {
try {
hsClient.shutdown();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
hsClient = null;
}
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return name;
}
protected void setName(String connName) {
this.name = connName;
}
protected String calcHash(String dbName, String tableName,
String tableIndexName, String[] columns) {
HashCodeBuilder hcb = new HashCodeBuilder(19, 81);
hcb.append(dbName);
hcb.append(tableName);
hcb.append(tableIndexName);
hcb.append(columns);
int hashCode = hcb.hashCode();
return String.valueOf(hashCode);
}
protected IndexSession openIndex(String dbName, String tableName,
String tableIndexName, String[] columns)
throws InterruptedException, TimeoutException,
HandlerSocketException {
String hash = calcHash(dbName, tableName, tableIndexName, columns);
synchronized (indexSessions) {
IndexSession indexSession = indexSessions.get(hash);
if (indexSession == null) {
indexSession = hsClient.openIndexSession(dbName, tableName,
tableIndexName, columns);
indexSessions.put(hash, indexSession);
}
return indexSession;
}
}
protected void assignValue(ModifyStatement stm, int index, Object value) {
if (value instanceof Boolean) {
stm.setBoolean(index, (Boolean) value);
} else if (value instanceof Byte) {
stm.setByte(index, (Byte) value);
} else if (value instanceof byte[]) {
stm.setBytes(index, (byte[]) value);
} else if (value instanceof Double) {
stm.setDouble(index, (Double) value);
} else if (value instanceof Float) {
stm.setFloat(index, (Float) value);
} else if (value instanceof Integer) {
stm.setInt(index, (Integer) value);
} else if (value instanceof Long) {
stm.setLong(index, (Long) value);
} else if (value instanceof Short) {
stm.setShort(index, (Short) value);
} else if (value instanceof Date) {
stm.setDate(index, (Date) value);
} else {
stm.setString(index, value != null ? value.toString() : null);
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean insert(String dbName, String tableName,
String tableIndexName, String[] columns, Object[] values)
throws SQLException {
if (!isReadWrite()) {
String msg = "This Handler Socket connection is read-only!";
throw new SQLException(msg);
}
try {
IndexSession indexSession = openIndex(dbName, tableName,
tableIndexName, columns);
ModifyStatement stm = indexSession.createStatement();
for (int i = 0; i < columns.length; i++) {
assignValue(stm, i + 1, values[i]);
}
return stm.insert();
} catch (InterruptedException e) {
throw new SQLException(e);
} catch (TimeoutException e) {
throw new SQLException(e);
} catch (HandlerSocketException e) {
throw new SQLException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public int update(String dbName, String tableName, String tableIndexName,
String[] columns, Object[] values, Object[] findValues)
throws SQLException {
if (!isReadWrite()) {
String msg = "This Handler Socket connection is read-only!";
throw new SQLException(msg);
}
try {
IndexSession indexSession = openIndex(dbName, tableName,
tableIndexName, columns);
ModifyStatement stm = indexSession.createStatement();
for (int i = 0; i < columns.length; i++) {
assignValue(stm, i + 1, values[i]);
}
String[] keys = new String[findValues != null ? findValues.length
: 0];
if (findValues != null) {
for (int i = 0; i < findValues.length; i++) {
keys[i] = findValues[i] != null ? findValues[i].toString()
: null;
}
}
return stm.update(keys, FindOperator.EQ);
} catch (InterruptedException e) {
throw new SQLException(e);
} catch (TimeoutException e) {
throw new SQLException(e);
} catch (HandlerSocketException e) {
throw new SQLException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public int delete(String dbName, String tableName, String tableIndexName,
String[] columns, Object[] findValues) throws SQLException {
if (!isReadWrite()) {
String msg = "This Handler Socket connection is read-only!";
throw new SQLException(msg);
}
try {
IndexSession indexSession = openIndex(dbName, tableName,
tableIndexName, columns);
String[] keys = new String[findValues != null ? findValues.length
: 0];
if (findValues != null) {
for (int i = 0; i < findValues.length; i++) {
keys[i] = findValues[i] != null ? findValues[i].toString()
: null;
}
}
return indexSession.delete(keys, FindOperator.EQ);
} catch (InterruptedException e) {
throw new SQLException(e);
} catch (TimeoutException e) {
throw new SQLException(e);
} catch (HandlerSocketException e) {
throw new SQLException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet select(String dbName, String tableName,
String tableIndexName, String[] columns, Object[] findValues)
throws SQLException {
return select(dbName, tableName, tableIndexName, columns, findValues,
Integer.MAX_VALUE, 0);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet select(String dbName, String tableName,
String tableIndexName, String[] columns, Object[] findValues,
int limit) throws SQLException {
return select(dbName, tableName, tableIndexName, columns, findValues,
limit, 0);
}
/**
* {@inheritDoc}
*/
@Override
public ResultSet select(String dbName, String tableName,
String tableIndexName, String[] columns, Object[] findValues,
int limit, int offset) throws SQLException {
try {
IndexSession indexSession = openIndex(dbName, tableName,
tableIndexName, columns);
String[] keys = new String[findValues != null ? findValues.length
: 0];
if (findValues != null) {
for (int i = 0; i < findValues.length; i++) {
keys[i] = findValues[i] != null ? findValues[i].toString()
: null;
}
}
return indexSession.find(keys, FindOperator.EQ, limit, offset);
} catch (InterruptedException e) {
throw new SQLException(e);
} catch (TimeoutException e) {
throw new SQLException(e);
} catch (HandlerSocketException e) {
throw new SQLException(e);
}
}
}