package me.xhh.hector06;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import me.xhh.hector06.DBA.ColumnMap;
import me.xhh.hector06.DBA.ColumnName;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.SuperColumn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility for database operations
*
* @author xhh
*/
public class DBUtil {
private static final String ENC_UTF_8 = "UTF-8";
private static final Logger log = LoggerFactory.getLogger(DBUtil.class);
public static byte[] bytesForName(Object o) {
if (o == null)
return null;
else if (o instanceof Integer)
return bytesFromLong((Integer) o);
else if (o instanceof Long)
return bytesFromLong((Long) o);
else if (o instanceof byte[])
return (byte[]) o;
else
return bytes(String.valueOf(o));
}
public static byte[] bytes(String s) {
if (s == null)
return null;
try {
return s.getBytes(ENC_UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static byte[] bytesFromLong(Long val) {
if (val == null)
return null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeLong(val);
} catch (IOException e) {
throw new RuntimeException(e);
}
return baos.toByteArray();
}
public static byte[] bytesFromLong(Integer val) {
return bytesFromLong(val == null ? null : val.longValue());
}
public static Long longFromBytes(byte[] b) {
if (b == null)
return null;
return new BigInteger(b).longValue();
}
public static String string(byte[] bytes) {
if (bytes == null)
return null;
try {
return new String(bytes, ENC_UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static Column createColumn(Object name, Object value, long timestamp) {
return new Column(bytesForName(name), bytes(value == null ? null : value.toString()), timestamp);
}
/**
* Create a new column with the given data.<br/>
* Note: make sure name and value are <strong>NOT</strong> null.
*
* @param name
* @param value
* @return
*/
public static Column createColumn(Object name, Object value) {
return createColumn(name, value, System.currentTimeMillis());
}
/**
* Create a new column. Use {@link DBUtil#toString(Boolean)} for the value "bool".
*/
public static Column createColumnBool(Object name, Boolean bool) {
return createColumn(name, toString(bool));
}
public static Column createColumnDate(Object colName, Date value) {
return createColumn(colName, value == null ? null : String.valueOf(value.getTime()));
}
public static ColumnMap<String> columnsToMap(List<Column> cols) {
if (cols == null)
return new ColumnMap<String>(0);
Map<String, String> map = new LinkedHashMap<String, String>(cols.size());
for (Column c : cols) {
if (c == null)
continue;
map.put(string(c.getName()), string(c.getValue()));
}
return new ColumnMap<String>(map);
}
/**
* @param colNames
* column names to include
*/
public static ColumnMap<String> columnsToMap(List<Column> cols, List<ColumnName> colNames) {
if (colNames == null)
return columnsToMap(cols);
if (cols == null || colNames.isEmpty())
return new ColumnMap<String>(0);
Map<String, String> map = new LinkedHashMap<String, String>(Math.min(cols.size(), colNames.size()));
for (Column c : cols) {
if (c == null)
continue;
String colName = string(c.getName());
for (ColumnName each : colNames) {
if (colName.equals(each.toString())) {
map.put(colName, string(c.getValue()));
break;
}
}
}
return new ColumnMap<String>(map);
}
public static ColumnMap<Long> columnsToMapTypeLong(List<Column> cols) {
if (cols == null)
return new ColumnMap<Long>(0);
Map<Long, String> map = new LinkedHashMap<Long, String>(cols.size());
for (Column c : cols) {
if (c == null)
continue;
map.put(longFromBytes(c.getName()), string(c.getValue()));
}
return new ColumnMap<Long>(map);
}
public static boolean valueExists(SuperColumn sc, Object colName, String value) {
if (sc == null)
return false;
if (value == null)
throw new IllegalArgumentException("valueExists: value can not be null!");
for (Iterator<Column> itr = sc.getColumnsIterator(); itr.hasNext();) {
Column c = itr.next();
if (Arrays.equals(c.getName(), bytesForName(colName)) && value.equals(string(c.getValue())))
return true;
}
return false;
}
public static SuperColumn createSuperColumn(Object superColName, Column... columns) {
if (columns == null)
columns = new Column[0];
return new SuperColumn(bytesForName(superColName), Arrays.asList(columns));
}
public static SuperColumn createSuperColumn(Object superColName, List<Column> columns) {
if (columns == null)
columns = new ArrayList<Column>(0);
return new SuperColumn(bytesForName(superColName), columns);
}
public static boolean isTrue(String str) {
return "1".equals(str) || "true".equalsIgnoreCase(str) || "yes".equalsIgnoreCase(str) || "on".equalsIgnoreCase(str);
}
public static boolean isFalse(String str) {
return "0".equals(str) || "false".equalsIgnoreCase(str) || "no".equalsIgnoreCase(str) || "off".equalsIgnoreCase(str);
}
public static Boolean toBoolean(String str) {
if (isTrue(str))
return true;
if (isFalse(str))
return false;
return null;
}
/**
* Convert boolean to string.
*
* @return "0" for false, "1" for "true"
*/
public static String toString(Boolean b) {
if (b == null)
return null;
else
return b.booleanValue() ? "1" : "0";
}
public static String nullIfEmpty(String value) {
return isValueEmpty(value) ? null : value;
}
/**
* Create a new Column and add into columns. If any of colName and colValue is null, it is NOT added.<br/>
* Note: colValue.toString() will be stored as the value.
*
* @param colName
* @param colValue
* @param columns
* must NOT be null
*/
public static void addColumn(ColumnName colName, String colValue, List<Column> columns) {
if (colName != null && colValue != null)
columns.add(createColumn(colName, colValue));
}
public static void addColumnDate(ColumnName colName, Date value, List<Column> columns) {
if (colName != null && value != null)
columns.add(createColumnDate(colName, value));
}
public static void addColumnBool(ColumnName colName, Boolean value, List<Column> columns) {
if (colName != null && value != null)
columns.add(createColumnBool(colName, value));
}
public static void addColumnInteger(ColumnName colName, Integer value, List<Column> columns) {
addColumnObject(colName, value, columns);
}
public static void addColumnLong(ColumnName colName, Long value, List<Column> columns) {
addColumnObject(colName, value, columns);
}
public static void addColumnDouble(ColumnName colName, Double value, List<Column> columns) {
addColumnObject(colName, value, columns);
}
/**
* @param value
* null or value.toString will be used for the column value
*/
public static void addColumnObject(ColumnName colName, Object value, List<Column> columns) {
if (colName != null && value != null)
columns.add(createColumn(colName, value));
}
/**
* @param date
* @return date.getTime(), or null if date is null
*/
public static Long date2Long(Date date) {
return date == null ? null : date.getTime();
}
/**
* @param date
* @return string format of date.getTime() (the milliseconds since January 1, 1970, 00:00:00 GMT).<br/>
* Null is returned if date is null.
*/
public static String date2Str(Date date) {
return date == null ? null : String.valueOf(date.getTime());
}
/**
* @param time
* the milliseconds since January 1, 1970, 00:00:00 GMT
* @return new Date(time), or null if "time" is null
*/
public static Date long2Date(Long time) {
return time == null ? null : new Date(time);
}
public static <T extends Enum<T>> T str2Enum(Class<T> enumCls, String item) {
if (enumCls == null || item == null)
return null;
try {
return Enum.valueOf(enumCls, item);
} catch (IllegalArgumentException e) {
log.warn("str2Enum failed! Enum class: {}, item: {}", enumCls.getName(), item);
return null;
}
}
/**
* @param time
* the milliseconds since January 1, 1970, 00:00:00 GMT, in String format
* @return null will be returned if "time" is null or an empty string
*/
public static Date str2Date(String time) {
if (isValueEmpty(time))
return null;
try {
return new Date(Long.parseLong(time));
} catch (NumberFormatException e) {
log.error("Bad time string: {} !!", time);
return null;
}
}
public static Integer str2Int(String intValue) {
if (isValueEmpty(intValue))
return null;
try {
return Integer.parseInt(intValue);
} catch (NumberFormatException e) {
log.error("Bad integer string: {} !!", intValue);
return null;
}
}
public static Double str2Double(String doubleValue) {
if (isValueEmpty(doubleValue))
return null;
try {
return Double.parseDouble(doubleValue);
} catch (NumberFormatException e) {
log.error("Bad double string: {} !!", doubleValue);
return null;
}
}
public static boolean isValueEmpty(String value) {
return value == null || value.length() == 0;
}
public static boolean isColumnComplete(Column c) {
return c.getName() != null && c.getValue() != null;
}
public static Long str2Long(String longValue) {
if (isValueEmpty(longValue))
return null;
try {
return Long.parseLong(longValue);
} catch (NumberFormatException e) {
log.error("Bad long string: {} !!", longValue);
return null;
}
}
/**
* @param value
* @return value.toString(), or empty string ("") if value if null
*/
public static String toStringDefaultEmpty(Object value) {
return value == null ? "" : value.toString();
}
}