package me.xhh.hector06; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import me.prettyprint.cassandra.dao.Command; import me.prettyprint.cassandra.service.KeyspaceService; import me.prettyprint.hector.api.exceptions.HNotFoundException; import me.prettyprint.hector.api.exceptions.HectorException; import org.apache.cassandra.thrift.Column; import org.apache.cassandra.thrift.ColumnParent; import org.apache.cassandra.thrift.ColumnPath; import org.apache.cassandra.thrift.KeyRange; import org.apache.cassandra.thrift.SlicePredicate; import org.apache.cassandra.thrift.SliceRange; import org.apache.cassandra.thrift.SuperColumn; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Database Accessor for accessing the Cassandra database. */ public class DBA { private static final Logger log = LoggerFactory.getLogger(DBA.class); /** * Interface for all Column Families. Note: please use enum as type of a Column Family and let it implement this interface (enum * constants' toString() must have the same names as the real (super) Column Families). */ public static interface ColumnFamily { String toString(); } /** * Interface for all Column names. Note: please use enum as type of a Column name and let it implement this interface (enum * constants' toString() must have the same names as the real column names). */ public static interface ColumnName { String toString(); } /** * @param <T> * type column name, must be String or Long */ public static class ColumnMap<T> implements Serializable { private static final long serialVersionUID = 6461999789967087137L; private Map<T, String> data; public ColumnMap(int initialCapacity) { this.data = new LinkedHashMap<T, String>(initialCapacity); } public ColumnMap(Map<T, String> data) { this.data = data; } /** * Use this when T is String * * @param colName * @return */ public String get(ColumnName colName) { return data.get(colName.toString()); } /** * Use this when T is String * * @param colName * @return */ public String get(String colName) { return data.get(colName); } /** * Use this when T is Long * * @param colName * @return */ public String get(Long colName) { return data.get(colName); } public int size() { return data.size(); } /** * Use this when T is String * * @param colName */ public boolean containsKey(ColumnName colNmae) { return data.containsKey(colNmae.toString()); } /** * Use this when T is Long * * @param colName */ public boolean containsKey(Long colNmae) { return data.containsKey(colNmae); } /** * @return */ public boolean isEmpty() { return data.isEmpty(); } public Set<T> keySet() { return data.keySet(); } } private DBConfig dbConfig; public DBA() { } public DBA(DBConfig dbConfig) { this.dbConfig = dbConfig; } public void insertValue(ColumnFamily colFamily, String key, Object colName, String colValue) throws HectorException { insertValue(colFamily, key, null, colName, colValue); } public void insertValue(final ColumnFamily colFamily, final String key, final Object superColName, final Object colName, final String colValue) throws HectorException { execute(new Command<Void>() { @Override public Void execute(KeyspaceService ks) throws HectorException { ks.insert(key, createColumnPath(colFamily, superColName, colName), DBUtil.bytes(colValue)); return null; } }); } public void insertColumnsOrSuperColumns(final ColumnFamily colFamily, final String key, final List<Column> cols, final List<SuperColumn> superCols) throws HectorException { // TODO batch /* * Map<String, List<Column>> colMap = new HashMap<String, List<Column>>(1); Map<String, List<SuperColumn>> superColMap = new * HashMap<String, List<SuperColumn>>(1); if (cols != null) colMap.put(colFamily.toString(), cols); if (superCols != null) * superColMap.put(colFamily.toString(), superCols); insertColumns(key, colMap, superColMap); */ /* * BatchMutation bm = new BatchMutation(); List<String> colFamilyList = new ArrayList<String>(1); * colFamilyList.add(colFamily.toString()); if (cols != null) { for (Column c : cols) bm.addInsertion(key, colFamilyList, c); } * if (superCols != null) { for (SuperColumn sc : superCols) bm.addSuperInsertion(key, colFamilyList, sc); } batchMutate(bm); */ execute(new Command<Void>() { public Void execute(KeyspaceService ks) throws HectorException { if (cols != null) { for (Column c : cols) ks.insert(key, createColumnPath(colFamily, null, c.getName()), c.getValue()); } if (superCols != null) { for (SuperColumn sc : superCols) { for (Column c : sc.getColumns()) ks.insert(key, createColumnPath(colFamily, sc.getName(), c.getName()), c.getValue()); } } return null; } }); } public void insertColumns(ColumnFamily colFamily, String key, List<Column> cols) throws HectorException { if (cols == null || cols.isEmpty()) throw new IllegalArgumentException("Columns can not be null or empty!"); else insertColumnsOrSuperColumns(colFamily, key, cols, null); } public void insertColumns(ColumnFamily colFamily, String key, Object superColName, List<Column> columns) throws HectorException { SuperColumn superCol = DBUtil.createSuperColumn(superColName, columns); insertSuperColumn(colFamily, key, superCol); } public void insertSuperColumn(ColumnFamily colFamily, String key, SuperColumn superCol) throws HectorException { if (superCol == null) throw new IllegalArgumentException("Super column can not be null!"); else insertColumnsOrSuperColumns(colFamily, key, null, Arrays.asList(superCol)); } /* * public void insertColumns(final String key, final Map<String, List<Column>> colMap, final Map<String, List<SuperColumn>> * superColMap) throws HectorException { execute(new Command<Void>() { // TODO batch public Void execute(KeyspaceService ks) throws * HectorException { ks.batchInsert(key, colMap, superColMap); return null; } }); } public void batchMutate(final Map<String, * Map<String, List<Mutation>>> mutationMap) throws HectorException { execute(new Command<Void>() { // TODO batch public Void * execute(KeyspaceService ks) throws HectorException { ks.batchMutate(mutationMap); return null; } }); } public void * batchMutate(final BatchMutation batchMutation) throws HectorException { execute(new Command<Void>() { public Void * execute(KeyspaceService ks) throws HectorException { ks.batchMutate(batchMutation); return null; } }); } */ public String getValue(final ColumnFamily colFamily, final String key, final Object colName) throws HectorException { return getValue(colFamily, key, null, colName); } /** * @return The string value; null if no value exists for the given key. */ public String getValue(final ColumnFamily colFamily, final String key, final Object superColName, final Object colName) throws HectorException { return execute(new Command<String>() { public String execute(KeyspaceService ks) throws HectorException { try { return DBUtil.string(ks.getColumn(key, createColumnPath(colFamily, superColName, colName)).getValue()); } catch (HNotFoundException e) { return null; } } }); } public boolean columnExists(ColumnFamily colFamily, String key, Object colName) throws HectorException { return columnExists(colFamily, key, null, colName); } public boolean columnExists(final ColumnFamily colFamily, final String key, final Object superColName, final Object colName) throws HectorException { return execute(new Command<Boolean>() { public Boolean execute(KeyspaceService ks) throws HectorException { try { return ks.getColumn(key, createColumnPath(colFamily, superColName, colName)) != null; } catch (HNotFoundException e) { return false; } } }); } public Column getFirstColumn(ColumnFamily colFamily, String key) throws HectorException { return getFirstColumn(colFamily, key, null); } public Column getFirstColumn(ColumnFamily colFamily, String key, Object superColName) throws HectorException { List<Column> columns = getColumns(colFamily, key, superColName, null, null, null, 1, false); return columns.isEmpty() ? null : columns.get(0); } public byte[] getFirstColumnName(ColumnFamily colFamily, String key) throws HectorException { return getFirstColumnName(colFamily, key, null); } public byte[] getFirstColumnName(ColumnFamily colFamily, String key, Object superColName) throws HectorException { Column c = getFirstColumn(colFamily, key, superColName); return c == null ? null : c.getName(); } public String getFirstValue(ColumnFamily colFamily, String key) throws HectorException { return getFirstValue(colFamily, key, null); } public String getFirstValue(ColumnFamily colFamily, String key, Object superColName) throws HectorException { Column c = getFirstColumn(colFamily, key, superColName); return c == null ? null : DBUtil.string(c.getValue()); } public Column getLastColumn(ColumnFamily colFamily, String key) throws HectorException { return getLastColumn(colFamily, key, null); } public Column getLastColumn(ColumnFamily colFamily, String key, Object superColName) throws HectorException { List<Column> columns = getColumns(colFamily, key, superColName, null, null, null, 1, true); return columns.isEmpty() ? null : columns.get(0); } public byte[] getLastColumnName(ColumnFamily colFamily, String key) throws HectorException { return getLastColumnName(colFamily, key, null); } public byte[] getLastColumnName(ColumnFamily colFamily, String key, Object superColName) throws HectorException { Column c = getLastColumn(colFamily, key, superColName); return c == null ? null : c.getName(); } public String getLastValue(ColumnFamily colFamily, String key) throws HectorException { return getLastValue(colFamily, key, null); } public String getLastValue(ColumnFamily colFamily, String key, Object superColName) throws HectorException { Column c = getLastColumn(colFamily, key, superColName); return c == null ? null : DBUtil.string(c.getValue()); } /** * Read all columns of the column family. This does NOT applies to super column families.<br/> * Note: reading all columns could be slow. * * @param colFamily * the column family, can NOT be super column family * @param key * @return * @throws HectorException */ public List<Column> getAllColumns(ColumnFamily colFamily, String key) throws HectorException { return getAllColumns(colFamily, key, null, false); } public List<Column> getAllColumns(final ColumnFamily colFamily, final String key, final Object superColName) throws HectorException { return getAllColumns(colFamily, key, superColName, false); } /** * Read all columns by reading 1000 columns at a time. * * @param colFamily * @param key * @param superColName * @param reversed * @return */ public List<Column> getAllColumns(final ColumnFamily colFamily, final String key, final Object superColName, final boolean reversed) throws HectorException { return getAllColumns(colFamily, key, superColName, 1000, reversed); } /** * Read all columns of the column family.<br/> * Note: reading all columns could be slow. * * @param colFamily * the (super) column family * @param key * @param superColName * the super column name when reading all columns from a super column family * @param count * how many columns to read at a time * @return */ public List<Column> getAllColumns(final ColumnFamily colFamily, final String key, final Object superColName, final int count, final boolean reversed) { if (count <= 1) throw new IllegalArgumentException("count must be bigger than 1!"); return execute(new Command<List<Column>>() { public List<Column> execute(KeyspaceService ks) throws HectorException { return _getAllColumns(colFamily, key, superColName, count, reversed, ks); } }); } private List<Column> _getAllColumns(final ColumnFamily colFamily, final String key, final Object superColName, final boolean reversed, final KeyspaceService ks) { return _getAllColumns(colFamily, key, superColName, 1000, reversed, ks); } /** * @param colFamily * @param key * @param superColName * @param count * @param reversed * @param ks * @return */ private List<Column> _getAllColumns(final ColumnFamily colFamily, final String key, final Object superColName, final int count, final boolean reversed, final KeyspaceService ks) { ColumnParent cp = new ColumnParent(colFamily.toString()); if (superColName != null) cp.setSuper_column(DBUtil.bytesForName(superColName)); SlicePredicate predicate = new SlicePredicate(); SliceRange range = new SliceRange(); range.setStart(new byte[0]); range.setFinish(new byte[0]); range.setCount(count); range.setReversed(reversed); predicate.setSlice_range(range); List<Column> all = new ArrayList<Column>(); do { List<Column> data = ks.getSlice(key, cp, predicate); int size = data.size(); if (size < count) { // end reached all.addAll(data); break; } else { // continue to read more range.setStart(data.remove(size - 1).getName()); all.addAll(data); } } while (true); return all; } public List<Column> getColumns(ColumnFamily colFamily, String key, Object superColName, List<ColumnName> colNames) throws HectorException { return getColumns(colFamily, key, superColName, colNames, null, null, 0, false); } public List<Column> getColumnsTypeLong(ColumnFamily colFamily, String key, Object superColName, List<Long> colNames) throws HectorException { return getColumnsTypeLong(colFamily, key, superColName, colNames, null, null, 0, false); } public List<Column> getColumns(ColumnFamily colFamily, String key, byte[] start, int count) throws HectorException { return getColumns(colFamily, key, null, null, start, null, count, false); } public List<Column> getColumnsTypeLong(ColumnFamily colFamily, String key, byte[] start, int count) throws HectorException { return getColumnsTypeLong(colFamily, key, null, null, start, null, count, false); } public List<Column> getColumns(ColumnFamily colFamily, String key, byte[] start, int count, boolean reversed) throws HectorException { return getColumns(colFamily, key, null, null, start, null, count, reversed); } public List<Column> getColumnsTypeLong(ColumnFamily colFamily, String key, byte[] start, int count, boolean reversed) throws HectorException { return getColumnsTypeLong(colFamily, key, null, null, start, null, count, reversed); } public List<Column> getColumns(ColumnFamily colFamily, String key, Object superColName, byte[] start, int count) throws HectorException { return getColumns(colFamily, key, superColName, null, start, null, count, false); } public List<Column> getColumnsTypeLong(ColumnFamily colFamily, String key, Object superColName, byte[] start, int count) throws HectorException { return getColumnsTypeLong(colFamily, key, superColName, null, start, null, count, false); } public List<Column> getColumns(final ColumnFamily colFamily, final String key, final Object superColName, final List<ColumnName> colNames, final byte[] start, final byte[] finish, final int count, final boolean reversed) throws HectorException { return execute(new Command<List<Column>>() { public List<Column> execute(KeyspaceService ks) throws HectorException { SlicePredicate predicate = new SlicePredicate(); if (colNames != null) { for (ColumnName cn : colNames) { if (cn != null) predicate.addToColumn_names(DBUtil.bytes(cn.toString())); } } else { SliceRange range = new SliceRange(); range.setStart(start == null ? new byte[0] : start); range.setFinish(finish == null ? new byte[0] : finish); if (count > 0) range.setCount(count); range.setReversed(reversed); predicate.setSlice_range(range); } ColumnParent cp = new ColumnParent(colFamily.toString()); if (superColName != null) cp.setSuper_column(DBUtil.bytesForName(superColName)); return ks.getSlice(key, cp, predicate); } }); } public List<Column> getColumnsTypeLong(final ColumnFamily colFamily, final String key, final Object superColName, final List<Long> colNames, final byte[] start, final byte[] finish, final int count, final boolean reversed) throws HectorException { return execute(new Command<List<Column>>() { public List<Column> execute(KeyspaceService ks) throws HectorException { SlicePredicate predicate = new SlicePredicate(); if (colNames != null) { for (Long cn : colNames) { if (cn != null) predicate.addToColumn_names(DBUtil.bytesFromLong(cn)); } } else { SliceRange range = new SliceRange(); range.setStart(start == null ? new byte[0] : start); range.setFinish(finish == null ? new byte[0] : finish); if (count > 0) range.setCount(count); range.setReversed(reversed); predicate.setSlice_range(range); } ColumnParent cp = new ColumnParent(colFamily.toString()); if (superColName != null) cp.setSuper_column(DBUtil.bytesForName(superColName)); return ks.getSlice(key, cp, predicate); } }); } public ColumnMap<String> getAllColumnsToMap(ColumnFamily colFamily, String key) throws HectorException { return getAllColumnsToMap(colFamily, key, null); } public ColumnMap<String> getAllColumnsToMap(ColumnFamily colFamily, String key, Object superColName) throws HectorException { return DBUtil.columnsToMap(getAllColumns(colFamily, key, superColName)); } public ColumnMap<String> getColumnsToMap(ColumnFamily colFamily, String key, Object superColName, List<ColumnName> colNames) throws HectorException { return DBUtil.columnsToMap(getColumns(colFamily, key, superColName, colNames, null, null, 0, false)); } public ColumnMap<String> getColumnsToMap(ColumnFamily colFamily, String key, Object superColName, ColumnName... colNames) throws HectorException { return DBUtil.columnsToMap(getColumns(colFamily, key, superColName, Arrays.asList(colNames), null, null, 0, false)); } public ColumnMap<Long> getColumnsToMapTypeLong(ColumnFamily colFamily, String key, Object superColName, List<Long> colNames) throws HectorException { return DBUtil.columnsToMapTypeLong(getColumnsTypeLong(colFamily, key, superColName, colNames, null, null, 0, false)); } public ColumnMap<Long> getColumnsToMapTypeLong(ColumnFamily colFamily, String key, Object superColName, Object... colNames) throws HectorException { return getColumnsToMapTypeLong(colFamily, key, superColName, Arrays.asList(colNames)); } public int getCount(ColumnFamily colFamily, String key) throws HectorException { return getCount(colFamily, key, null); } public int getCount(final ColumnFamily colFamily, final String key, final Object superColName) throws HectorException { if (key == null) throw new IllegalArgumentException("key can not be null!"); return execute(new Command<Integer>() { public Integer execute(KeyspaceService ks) throws HectorException { ColumnParent cp = new ColumnParent(colFamily.toString()); if (superColName != null) cp.setSuper_column(DBUtil.bytesForName(superColName)); return ks.getCount(key, cp); } }); } public SuperColumn getSuperColumn(final ColumnFamily colFamily, final String key, final Object superColName) throws HectorException { if (superColName == null) throw new IllegalArgumentException("super column name can not be null!"); return execute(new Command<SuperColumn>() { public SuperColumn execute(KeyspaceService ks) throws HectorException { try { SuperColumn sc = ks.getSuperColumn(key, createColumnPath(colFamily, superColName, null)); // Note: treat empty SuperColumn as nonexistent if (sc == null || !sc.getColumnsIterator().hasNext()) return null; else return sc; } catch (HNotFoundException e) { return null; } } }); } /** * @param size * Note: can NOT be smaller than 1 */ public SuperColumn getSuperColumn(final ColumnFamily colFamily, final String key, final Object superColName, final boolean reversed, final int size) throws HectorException { if (superColName == null) throw new IllegalArgumentException("super column name can not be null!"); return execute(new Command<SuperColumn>() { public SuperColumn execute(KeyspaceService ks) throws HectorException { if (size < 1) throw new IllegalArgumentException("getSuperColumn: size can NOT be small than 1!"); try { SuperColumn sc = ks.getSuperColumn(key, createColumnPath(colFamily, superColName, null), reversed, size); // Note: treat empty SuperColumn as nonexistent if (sc == null || !sc.getColumnsIterator().hasNext()) return null; else return sc; } catch (HNotFoundException e) { return null; } } }); } public boolean superColumnExists(ColumnFamily colFamily, String key, Object superColName) throws HectorException { return getSuperColumn(colFamily, key, superColName, false, 1) != null; } /** * Call {@link #getAllSuperColumns(ColumnFamily, String, int, boolean)}<br/> * with count: 100, reversed: false. * * @param colFamily * @param key * @return * @throws HectorException */ public List<SuperColumn> getAllSuperColumns(ColumnFamily colFamily, String key) throws HectorException { return getAllSuperColumns(colFamily, key, 100, false); } /** * @param colFamily * @param key * @param reversed * @return * @throws HectorException * @see {@link #getAllSuperColumns(ColumnFamily, String, int, boolean)} */ public List<SuperColumn> getAllSuperColumns(ColumnFamily colFamily, String key, boolean reversed) throws HectorException { return getAllSuperColumns(colFamily, key, 100, reversed); } /** * Read all super columns (together with all columns of each super column).<br/> * Note: reading all super columns might be slow. * * @param colFamily * @param key * @param count * @param reversed * @return * @throws HectorException */ public List<SuperColumn> getAllSuperColumns(final ColumnFamily colFamily, final String key, final int count, final boolean reversed) throws HectorException { if (count <= 1) throw new IllegalArgumentException("count must be bigger than 1!"); return execute(new Command<List<SuperColumn>>() { public List<SuperColumn> execute(KeyspaceService ks) throws HectorException { ColumnParent cp = new ColumnParent(colFamily.toString()); SlicePredicate predicate = new SlicePredicate(); SliceRange range = new SliceRange(); range.setStart(new byte[0]); range.setFinish(new byte[0]); range.setCount(count); range.setReversed(reversed); predicate.setSlice_range(range); List<SuperColumn> all = new ArrayList<SuperColumn>(); do { List<SuperColumn> data = ks.getSuperSlice(key, cp, predicate); int size = data.size(); if (size < count) { // end reached all.addAll(data); break; } else { // continue to read more range.setStart(data.remove(size - 1).getName()); all.addAll(data); } } while (true); return all; } }); } public List<SuperColumn> getSuperColumns(final ColumnFamily colFamily, final String key, final Object start, final int count) throws HectorException { return getSuperColumns(colFamily, key, null, start, null, count, false); } public List<SuperColumn> getSuperColumns(final ColumnFamily colFamily, final String key, final Object start, final int count, final boolean reversed) throws HectorException { return getSuperColumns(colFamily, key, null, start, null, count, reversed); } public List<SuperColumn> getSuperColumns(ColumnFamily colFamily, String key, byte[] start, byte[] finish, int count) throws HectorException { return getSuperColumns(colFamily, key, null, start, finish, count, false); } public List<SuperColumn> getSuperColumns(final ColumnFamily colFamily, final String key, final List<Object> superColNames) throws HectorException { return getSuperColumns(colFamily, key, superColNames, null, null, 0, false); } public List<SuperColumn> getSuperColumns(final ColumnFamily colFamily, final String key, final List<Object> superColNames, final Object start, final Object finish, final int count, final boolean reversed) throws HectorException { return execute(new Command<List<SuperColumn>>() { public List<SuperColumn> execute(KeyspaceService ks) throws HectorException { SlicePredicate predicate = new SlicePredicate(); if (superColNames != null) { for (Object scn : superColNames) predicate.addToColumn_names(DBUtil.bytesForName(scn)); } else { SliceRange range = new SliceRange(); range.setStart(DBUtil.bytesForName(start == null ? "" : start)); range.setFinish(DBUtil.bytesForName(finish == null ? "" : finish)); if (count > 0) range.setCount(count); range.setReversed(reversed); predicate.setSlice_range(range); } List<SuperColumn> result = ks.getSuperSlice(key, new ColumnParent(colFamily.toString()), predicate); /* * TODO Bug here! To reproduce: Insert 10 super columns for a key, then delete 3 super columns, then delete all keys, * then insert again the old 10 super columns, then getSuperColumn() with start=null,finish=null,count=5, then you get * 8 super columns! If the "delete 3 super columns... insert again..." things were not done, there is no problem. Also, * if count is 1 there is no problem (only one super column is returned). */ if (count > 1 && result.size() > count) return result.subList(0, count); else return result; } }); } public SuperColumn getFirstSuperColumn(ColumnFamily colFamily, String key) throws HectorException { List<SuperColumn> superColumns = getSuperColumns(colFamily, key, null, null, null, 1, false); return superColumns.isEmpty() ? null : superColumns.get(0); } public byte[] getFirstSuperColumnName(ColumnFamily colFamily, String key) throws HectorException { SuperColumn sc = getFirstSuperColumn(colFamily, key); return sc == null ? null : sc.getName(); } public SuperColumn getLastSuperColumn(ColumnFamily colFamily, String key) throws HectorException { List<SuperColumn> superColumns = getSuperColumns(colFamily, key, null, null, null, 1, true); return superColumns.isEmpty() ? null : superColumns.get(0); } public byte[] getLastSuperColumnName(ColumnFamily colFamily, String key) throws HectorException { SuperColumn sc = getLastSuperColumn(colFamily, key); return sc == null ? null : sc.getName(); } public List<String> getKeys(ColumnFamily colFamily, String start, int count) throws HectorException { return getKeys(colFamily, start, null, count); } public List<String> getKeys(ColumnFamily colFamily, String start, String end, int count) throws HectorException { Map<String, List<Column>> map = getKeysAndColumns(colFamily, start, end, count, null, null, null, null, 1, false); return new ArrayList<String>(map.keySet()); } public Map<String, List<Column>> getKeysAndColumns(ColumnFamily colFamily, String start, String end, int count, Object superColName, List<Object> colNames) throws HectorException { if (colNames == null || colNames.isEmpty()) throw new IllegalArgumentException("getKeysAndColumns: you must specify the Column names!"); return getKeysAndColumns(colFamily, start, end, count, superColName, colNames, null, null, 0, false); } /** * @return true is returned is the key doesn't exist or is empty (i.e. has no columns or super columns) */ public boolean isKeyEmpty(ColumnFamily colFamily, String key) throws HectorException { return getColumns(colFamily, key, null, 1).isEmpty(); } /** * @param colFamily * @param superColName * @return * @throws HectorException * @see {@link #getAllKeysAndColumns(ColumnFamily, Object, boolean)} */ public Map<String, List<Column>> getAllKeysAndColumns(final ColumnFamily colFamily, final Object superColName) throws HectorException { return getAllKeysAndColumns(colFamily, superColName, false); } /** * Read all keys and all columns of each key or the super column of each key (if the given super column name is not null). * * @param colFamily * @param superColName * super column name, should be null for normal column family (not super) * @param colReversed * whether to load columns reversely for each key * @return key: key, value: columns */ public Map<String, List<Column>> getAllKeysAndColumns(final ColumnFamily colFamily, final Object superColName, final boolean colReversed) throws HectorException { return execute(new Command<Map<String, List<Column>>>() { public Map<String, List<Column>> execute(KeyspaceService ks) throws HectorException { List<String> allKeys = _getAllKeys(colFamily, ks); if (allKeys.isEmpty()) return new HashMap<String, List<Column>>(0); LinkedHashMap<String, List<Column>> results = new LinkedHashMap<String, List<Column>>(allKeys.size()); for (String key : allKeys) results.put(key, _getAllColumns(colFamily, key, superColName, colReversed, ks)); return results; } }); } public Map<String, List<Column>> getAllKeysAndColumns(final ColumnFamily colFamily, final Object superColName, final List<ColumnName> colNames) throws HectorException { return execute(new Command<Map<String, List<Column>>>() { public Map<String, List<Column>> execute(KeyspaceService ks) throws HectorException { List<String> allKeys = _getAllKeys(colFamily, ks); if (allKeys.isEmpty()) return new HashMap<String, List<Column>>(0); LinkedHashMap<String, List<Column>> results = new LinkedHashMap<String, List<Column>>(allKeys.size()); for (String key : allKeys) results.put(key, getColumns(colFamily, key, superColName, colNames)); return results; } }); } public Map<String, List<Column>> getAllKeysAndColumnsTypeLong(final ColumnFamily colFamily, final Object superColName, final List<Long> colNames) throws HectorException { return execute(new Command<Map<String, List<Column>>>() { public Map<String, List<Column>> execute(KeyspaceService ks) throws HectorException { List<String> allKeys = _getAllKeys(colFamily, ks); if (allKeys.isEmpty()) return new HashMap<String, List<Column>>(0); LinkedHashMap<String, List<Column>> results = new LinkedHashMap<String, List<Column>>(allKeys.size()); for (String key : allKeys) results.put(key, getColumnsTypeLong(colFamily, key, superColName, colNames)); return results; } }); } public List<String> getAllKeys(final ColumnFamily colFamily) throws HectorException { return execute(new Command<List<String>>() { public List<String> execute(KeyspaceService ks) throws HectorException { return _getAllKeys(colFamily, ks); } }); } /** * @param colFamily * @param ks * @return */ private List<String> _getAllKeys(final ColumnFamily colFamily, final KeyspaceService ks) { final int count = 1000; // read 1000 keys at a time KeyRange keyRange = new KeyRange(); keyRange.setStart_key(""); keyRange.setEnd_key(""); keyRange.setCount(count); ColumnParent cp = new ColumnParent(colFamily.toString()); SlicePredicate slicePredicate = new SlicePredicate(); SliceRange sliceRange = new SliceRange(); sliceRange.setStart(new byte[0]); sliceRange.setFinish(new byte[0]); sliceRange.setCount(1); // only get the first column slicePredicate.setSlice_range(sliceRange); List<String> all = new ArrayList<String>(); do { LinkedHashMap<String, List<Column>> data = ks.getRangeSlices(cp, slicePredicate, keyRange); final int size = data.size(); String last = null; for (String each : data.keySet()) { // TODO Note: skip empty keys here if (!data.get(each).isEmpty()) all.add(each); last = each; } if (size < count) // end reached break; else // continue to read more keyRange.setStart_key(last); } while (true); return all; } public Map<String, List<Column>> getKeysAndColumns(final ColumnFamily colFamily, final String start, final String end, final int count, final Object superColName, final List<Object> colNames, final Object colStart, final Object colFinish, final int colCount, final boolean colReversed) throws HectorException { if (count <= 1) throw new IllegalArgumentException("count must be bigger than 1!"); return execute(new Command<Map<String, List<Column>>>() { public Map<String, List<Column>> execute(KeyspaceService ks) throws HectorException { int _count = count; KeyRange keyRange = new KeyRange(); keyRange.setStart_key(start == null ? "" : start); keyRange.setEnd_key(end == null ? "" : end); keyRange.setCount(_count); ColumnParent cp = new ColumnParent(colFamily.toString()); SlicePredicate slicePredicate = new SlicePredicate(); if (superColName != null) cp.setSuper_column(DBUtil.bytesForName(superColName)); if (colNames != null) { for (Object cn : colNames) slicePredicate.addToColumn_names(DBUtil.bytesForName(cn)); } else { SliceRange sliceRange = new SliceRange(); sliceRange.setStart(DBUtil.bytesForName(colStart == null ? "" : colStart)); sliceRange.setFinish(DBUtil.bytesForName(colFinish == null ? "" : colFinish)); if (colCount > 0) sliceRange.setCount(colCount); sliceRange.setReversed(colReversed); slicePredicate.setSlice_range(sliceRange); } Map<String, List<Column>> _results = new LinkedHashMap<String, List<Column>>(); do { LinkedHashMap<String, List<Column>> data = ks.getRangeSlices(cp, slicePredicate, keyRange); boolean allLoaded = data.size() < _count; boolean emptyFound = false; String last = null; for (String key : data.keySet()) { List<Column> cols = data.get(key); if (cols.isEmpty()) { // TODO Notice: skip empty keys here (that have no columns) emptyFound = true; } else if (_results.size() < count) { // not enough keys read _results.put(key, cols); } else { // OK, now enough keys are read, set the flag for stopping reading more allLoaded = true; break; } last = key; } if (!allLoaded && emptyFound) { // some empty keys got, continue to find other keys _results.remove(last); keyRange.setStart_key(last); _count = count - _results.size(); // number of more keys to read if (_count < 2) // note, the count must be bigger than 1 _count = 2; keyRange.setCount(_count); } else { break; } } while (true); return _results; } }); } public void deleteColumns(final ColumnFamily colFamily, final String key, final Object superColName, final List<Object> colNames) throws HectorException { // TODO use batchMutation instead if (colNames == null) throw new IllegalArgumentException("You must specify the Columns to delete!"); execute(new Command<Void>() { public Void execute(KeyspaceService ks) throws HectorException { for (Object cn : colNames) ks.remove(key, createColumnPath(colFamily, superColName, cn)); return null; } }); } public void deleteSuperColumns(final ColumnFamily colFamily, final String key, final List<Object> superColNames) throws HectorException { // TODO use batchMutation instead if (superColNames == null) throw new IllegalArgumentException("You must specify the Super Columns to delete!"); execute(new Command<Void>() { public Void execute(KeyspaceService ks) throws HectorException { for (Object scn : superColNames) { if (scn != null) ks.remove(key, createColumnPath(colFamily, scn, null)); } return null; } }); } public void deleteSuperColumns(final ColumnFamily colFamily, final String key, final SuperColumn[] superColumns) throws HectorException { // TODO use batchMutation instead if (superColumns == null) throw new IllegalArgumentException("You must specify the Super Columns to delete!"); execute(new Command<Void>() { public Void execute(KeyspaceService ks) throws HectorException { for (SuperColumn sc : superColumns) { if (sc != null) ks.remove(key, createColumnPath(colFamily, sc.getName(), null)); } return null; } }); } /** * Delete all (Super) Columns for a key */ public void deleteKey(ColumnFamily colFamily, String key) throws HectorException { if (key == null) throw new IllegalArgumentException("You must specify the Key to delete!"); delete(colFamily, key, null, null); } /** * Delete a super column for a key */ public void deleteSuperColumn(ColumnFamily colFamily, String key, Object superColName) throws HectorException { if (superColName == null) throw new IllegalArgumentException("You must specify the SuperColumn to delete!"); delete(colFamily, key, superColName, null); } public void deleteColumn(ColumnFamily colFamily, String key, Object superColName, Object colName) throws HectorException { if (colName == null) throw new IllegalArgumentException("You must specify the Column to delete!"); delete(colFamily, key, superColName, colName); } public void deleteColumn(ColumnFamily colFamily, String key, Object colName) throws HectorException { deleteColumn(colFamily, key, null, colName); } private void delete(final ColumnFamily colFamily, final String key, final Object superColName, final Object colName) throws HectorException { execute(new Command<Void>() { public Void execute(KeyspaceService ks) throws HectorException { ks.remove(key, createColumnPath(colFamily, superColName, colName)); return null; } }); } protected <T> T execute(Command<T> command) throws HectorException { return command.execute(dbConfig.host, dbConfig.port, dbConfig.keyspace); } protected ColumnPath createColumnPath(ColumnFamily colFamily, Object superColName, Object colName) { ColumnPath columnPath = new ColumnPath(colFamily.toString()); if (superColName != null) columnPath.setSuper_column(DBUtil.bytesForName(superColName)); if (colName != null) columnPath.setColumn(DBUtil.bytesForName(colName)); return columnPath; } public DBConfig getDbConfig() { return dbConfig; } public void setDbConfig(DBConfig dbConfig) { this.dbConfig = dbConfig; } protected <T extends DBA> T createInstance(Class<T> cls) { try { return cls.getConstructor(DBConfig.class).newInstance(this.dbConfig); } catch (Exception e) { log.error("createInstance", e); return null; } } }