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(); } }