hd3gtv.mydmam.db.orm.CassandraOrm.java Source code

Java tutorial

Introduction

Here is the source code for hd3gtv.mydmam.db.orm.CassandraOrm.java

Source

/*
 * This file is part of MyDMAM
 * 
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * Copyright (C) hdsdi3g for hd3g.tv 2013-2014
 * 
*/
package hd3gtv.mydmam.db.orm;

import hd3gtv.log2.Log2;
import hd3gtv.log2.Log2Dump;
import hd3gtv.mydmam.db.AllRowsFoundRow;
import hd3gtv.mydmam.db.CassandraDb;
import hd3gtv.mydmam.db.DeployColumnDef;
import hd3gtv.mydmam.db.orm.annotations.CassandraIndexed;

import java.io.IOException;
import java.io.InvalidClassException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.persistence.Transient;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import com.google.gson.Gson;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.BadRequestException;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.model.ColumnFamily;
import com.netflix.astyanax.model.ColumnList;
import com.netflix.astyanax.model.Row;
import com.netflix.astyanax.model.Rows;
import com.netflix.astyanax.query.ColumnFamilyQuery;
import com.netflix.astyanax.query.IndexQuery;

@SuppressWarnings("unchecked")
public class CassandraOrm<T extends OrmModel> {

    private MutationBatch mutator;
    private ColumnFamily<String, String> columnfamily;
    private Class<? extends T> reference;
    private String[] column_names;

    /**
     * Stupid string for null value.
     */
    private static final String null_value = "null\0" + "BEA3CFC0-36F4-4B3A-905D-4F54419B41E1";

    public CassandraOrm(Class<T> constructor_reference, ColumnFamily<String, String> columnfamily)
            throws ConnectionException, IOException {
        this.columnfamily = columnfamily;
        if (columnfamily == null) {
            throw new NullPointerException("\"columnfamily\" can't to be null");
        }
        reference = constructor_reference;

        if (isColumnFamilyExists() == false) {
            createColumnFamily();
        }
    }

    public void executeMutation() throws ConnectionException {
        if (mutator == null) {
            return;
        }
        try {
            mutator.execute();
        } catch (BadRequestException e) {
            if (isColumnFamilyExists() == false) {
                try {
                    createColumnFamily();
                    mutator.execute();
                } catch (IOException e2) {
                    Log2Dump dump = new Log2Dump();
                    dump.add("referer", e);
                    dump.add("columnfamily", this.columnfamily.getName());
                    Log2.log.error("Can't create ColumnFamily", e2, dump);
                }
            } else {
                throw e;
            }
        }
        mutator = null;
    }

    public void resetMutator() throws ConnectionException {
        mutator = CassandraDb.prepareMutationBatch();
    }

    static String serialize(Object o) {
        Gson g = new Gson();
        return g.toJson(o);
    }

    private static Object deserialize(String src, Class<?> type) {
        Gson g = new Gson();
        return g.fromJson(src, type);
    }

    public void pushColumn(String rowkey, Integer ttl, String name, Object o)
            throws InvalidClassException, ConnectionException {
        if (rowkey == null) {
            return;
        }
        if (rowkey.equals("")) {
            return;
        }
        if (mutator == null) {
            mutator = CassandraDb.prepareMutationBatch();
        }
        if (ttl == 0) {
            ttl = null;
        }
        if (o == null) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, null_value, ttl);
        } else if (o instanceof String) {
            if (((String) o).equals(null_value)) {
                StringBuffer sb = new StringBuffer();
                sb.append("String value equals to null String reference : security problem ?");
                sb.append("[");
                sb.append(rowkey);
                sb.append("]");
                sb.append(name);
                throw new InvalidClassException(o.getClass().getName(), sb.toString());
            }
            mutator.withRow(columnfamily, rowkey).putColumn(name, (String) o, ttl);
        } else if (o instanceof byte[]) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, (byte[]) o, ttl);
        } else if (o instanceof Integer) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, (Integer) o, ttl);
        } else if (o instanceof Long) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, (Long) o, ttl);
        } else if (o instanceof Boolean) {
            if ((Boolean) o) {
                mutator.withRow(columnfamily, rowkey).putColumn(name, "true", ttl);
            } else {
                mutator.withRow(columnfamily, rowkey).putColumn(name, "false", ttl);
            }
        } else if (o instanceof Date) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, (Date) o, ttl);
        } else if (o instanceof Float) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, String.valueOf((Float) o), ttl);
        } else if (o instanceof Double) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, String.valueOf((Double) o), ttl);
        } else if (o instanceof UUID) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, (UUID) o, ttl);
        } else if (o instanceof JSONObject) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, ((JSONObject) o).toJSONString(), ttl);
        } else if (o instanceof JSONArray) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, ((JSONArray) o).toJSONString(), ttl);
        } else if (o instanceof InetAddress) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, ((InetAddress) o).getHostAddress(), ttl);
        } else if (o instanceof StringBuffer) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, ((StringBuffer) o).toString(), ttl);
        } else if (o instanceof Calendar) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, ((Calendar) o).getTimeInMillis(), ttl);
        } else if (o instanceof String[]) {
            JSONArray ja = new JSONArray();
            String[] o_str = (String[]) o;
            for (int pos = 0; pos < o_str.length; pos++) {
                ja.add(o_str[pos]);
            }
            mutator.withRow(columnfamily, rowkey).putColumn(name, ja.toJSONString(), ttl);
        } else if (o instanceof Serializable) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, serialize(o), ttl);
        } else if (o instanceof Enum) {
            mutator.withRow(columnfamily, rowkey).putColumn(name, serialize(o), ttl);
        } else {
            StringBuffer sb = new StringBuffer();
            sb.append("Class type is not managed for this record ");
            sb.append("[");
            sb.append(rowkey);
            sb.append("]");
            sb.append(name);
            throw new InvalidClassException(o.getClass().getName(), sb.toString());
        }
    }

    private ArrayList<Field> getOrmobjectUsableFields() {
        ArrayList<Field> result = new ArrayList<Field>();

        Field[] fields = this.reference.getFields();
        Field field;
        int mod;
        for (int pos_df = 0; pos_df < fields.length; pos_df++) {
            field = fields[pos_df];
            if (field.isAnnotationPresent(Transient.class)) {
                /**
                 * Is transient ?
                 */
                continue;
            }
            if (field.getName().equals("key")) {
                /**
                 * Not this (primary key)
                 */
                continue;
            }
            mod = field.getModifiers();

            if ((mod & Modifier.PROTECTED) != 0)
                continue;
            if ((mod & Modifier.PRIVATE) != 0)
                continue;
            if ((mod & Modifier.ABSTRACT) != 0)
                continue;
            if ((mod & Modifier.STATIC) != 0)
                continue;
            if ((mod & Modifier.FINAL) != 0)
                continue;
            if ((mod & Modifier.TRANSIENT) != 0)
                continue;
            if ((mod & Modifier.INTERFACE) != 0)
                continue;

            try {
                result.add(field);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    /**
     * ttl form ormobject
     */
    public void pushObject(T ormobject) throws InvalidClassException, ConnectionException {
        pushObject(ormobject, ormobject.getTTL());
    }

    /**
     * @param ttl overwrite from ormobject
     */
    public void pushObject(T ormobject, int ttl) throws InvalidClassException, ConnectionException {
        if (ormobject.key == null) {
            throw new NullPointerException("\"key\" can't to be null");
        }
        ArrayList<Field> fields = getOrmobjectUsableFields();
        for (int pos_df = 0; pos_df < fields.size(); pos_df++) {
            try {
                pushColumn(ormobject.key, ttl, fields.get(pos_df).getName(),
                        this.reference.getField(fields.get(pos_df).getName()).get(ormobject));
            } catch (IllegalAccessException e) {
                Log2Dump dump = new Log2Dump();
                dump.add("ormobject", ormobject);
                dump.add("ormobject.class", ormobject.getClass());
                dump.add("fields.name", fields.get(pos_df).getName());
                Log2.log.error("Grave problem with ORM object", e, dump);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
    }

    private T createOrmObject() {
        try {
            return (T) reference.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void prepareColumnlistnames() {
        if (column_names != null) {
            return;
        }
        ArrayList<String> colnamelist = new ArrayList<String>();

        ArrayList<Field> fields = getOrmobjectUsableFields();
        for (int pos_df = 0; pos_df < fields.size(); pos_df++) {
            colnamelist.add(fields.get(pos_df).getName());
        }
        column_names = colnamelist.toArray(new String[colnamelist.size()]);
    }

    public String[] getColumnNames() {
        prepareColumnlistnames();
        return column_names;
    }

    public T pullObject(String rowkey) throws ConnectionException {
        if (rowkey == null) {
            return null;
        }
        if (rowkey.equals("")) {
            return null;
        }
        prepareColumnlistnames();
        ColumnFamilyQuery<String, String> rows_asset = CassandraDb.getkeyspace().prepareQuery(this.columnfamily);
        OperationResult<ColumnList<String>> row = rows_asset.getKey(rowkey).withColumnSlice(this.column_names)
                .execute();
        return pullObject(rowkey, row.getResult());
    }

    public boolean exists(String rowkey) throws ConnectionException {
        if (rowkey == null) {
            return false;
        }
        if (rowkey.equals("")) {
            return false;
        }
        prepareColumnlistnames();
        ColumnFamilyQuery<String, String> rows_asset = CassandraDb.getkeyspace().prepareQuery(this.columnfamily);
        OperationResult<ColumnList<String>> row = rows_asset.getKey(rowkey).withColumnSlice(this.column_names)
                .execute();
        return (row.getResult().isEmpty() == false);
    }

    public List<T> pullObjects(String... rowkey) throws ConnectionException {
        if (rowkey == null) {
            return null;
        }
        if (rowkey.length == 0) {
            return null;
        }
        ArrayList<String> rowkeys = new ArrayList<String>(rowkey.length);
        for (int pos = 0; pos < rowkey.length; pos++) {
            if (rowkey[pos] == null) {
                continue;
            }
            if (rowkey[pos].equals("")) {
                continue;
            }
            rowkeys.add(rowkey[pos]);
        }
        if (rowkeys.size() == 0) {
            return null;
        }

        prepareColumnlistnames();
        ColumnFamilyQuery<String, String> rows_asset = CassandraDb.getkeyspace().prepareQuery(this.columnfamily);
        OperationResult<Rows<String, String>> rows = rows_asset.getKeySlice(rowkeys)
                .withColumnSlice(this.column_names).execute();
        return pullObjects(rows.getResult());
    }

    public void pullAllObjectsToExporter(final CassandraOrmExporter<T> exporter) throws Exception {
        prepareColumnlistnames();

        CassandraDb.allRowsReader(columnfamily, new AllRowsFoundRow() {
            public void onFoundRow(Row<String, String> row) throws Exception {
                if (exporter.exportFromCassandra(pullObject(row.getKey(), row.getColumns())) == false) {
                    throw new Exception("Exporter from Cassandra want to stop");
                }
                exporter.count++;
            }
        }, column_names);
    }

    public JSONArray pullAllObjectsToJSON() throws Exception {
        prepareColumnlistnames();
        final JSONArray ja = new JSONArray();
        final JSONParser jp = new JSONParser();
        CassandraDb.allRowsReader(columnfamily, new AllRowsFoundRow() {
            public void onFoundRow(Row<String, String> row) throws Exception {
                jp.reset();
                ja.add(jp.parse((new Gson()).toJson(pullObject(row.getKey(), row.getColumns()))));
            }
        }, column_names);

        return ja;
    }

    public List<T> pullAllObjects() throws Exception {
        prepareColumnlistnames();
        final List<T> results = new ArrayList<T>();
        CassandraDb.allRowsReader(columnfamily, new AllRowsFoundRow() {
            public void onFoundRow(Row<String, String> row) throws Exception {
                results.add(pullObject(row.getKey(), row.getColumns()));
            }
        }, column_names);
        return results;
    }

    public List<T> pullObjects(Rows<String, String> rows) throws ConnectionException {
        List<T> result = new ArrayList<T>();
        T temp;
        for (Row<String, String> row : rows) {
            temp = pullObject(row.getKey(), row.getColumns());
            if (temp != null) {
                result.add(temp);
            }
        }
        return result;
    }

    public int countAllRows() throws Exception {
        prepareColumnlistnames();
        final List<Boolean> count = new ArrayList<Boolean>();
        CassandraDb.allRowsReader(columnfamily, new AllRowsFoundRow() {
            public void onFoundRow(Row<String, String> row) throws Exception {
                count.add(true);
            }
        }, column_names);

        return count.size();
    }

    public T pullObject(String rowkey, ColumnList<String> columnlist) {
        if (rowkey == null) {
            return null;
        }
        if (rowkey.equals("")) {
            return null;
        }
        if (columnlist.size() == 0) {
            return null;
        }

        T recevier = createOrmObject();
        recevier.key = rowkey;

        ArrayList<Field> fields = getOrmobjectUsableFields();
        Field field;
        Object o;
        for (int pos_df = 0; pos_df < fields.size(); pos_df++) {
            try {
                field = fields.get(pos_df);
                o = pullColumn(columnlist, field);
                if (o == null) {
                    continue;
                }
                field.set(recevier, o);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvalidClassException e) {
                e.printStackTrace();
            }
        }
        return recevier;
    }

    private Object pullColumn(ColumnList<String> columnlist, Field field) throws InvalidClassException {
        String name = field.getName();
        Class<?> fieldtype = field.getType();

        if (columnlist.getColumnByName(name) == null) {
            return null;
        }
        if (columnlist.getColumnByName(name).hasValue() == false) {
            return null;
        }

        if (columnlist.getColumnByName(name).getStringValue().equals(null_value)) {
            return null;
        } else if (fieldtype.isAssignableFrom(String.class)) {
            return columnlist.getColumnByName(name).getStringValue();
        } else if (fieldtype.isAssignableFrom(Byte[].class) | fieldtype.isAssignableFrom(byte[].class)) {
            return columnlist.getColumnByName(name).getByteArrayValue();
        } else if (fieldtype.isAssignableFrom(Integer.class) | fieldtype.isAssignableFrom(int.class)) {
            return columnlist.getColumnByName(name).getIntegerValue();
        } else if (fieldtype.isAssignableFrom(Long.class) | fieldtype.isAssignableFrom(long.class)) {
            return columnlist.getColumnByName(name).getLongValue();
        } else if (fieldtype.isAssignableFrom(Boolean.class) | fieldtype.isAssignableFrom(boolean.class)) {
            return columnlist.getColumnByName(name).getStringValue().equals("true");
        } else if (fieldtype.isAssignableFrom(Date.class)) {
            return columnlist.getColumnByName(name).getDateValue();
        } else if (fieldtype.isAssignableFrom(Float.class) | fieldtype.isAssignableFrom(float.class)) {
            return Float.valueOf(columnlist.getColumnByName(name).getStringValue());
        } else if (fieldtype.isAssignableFrom(Double.class) | fieldtype.isAssignableFrom(double.class)) {
            return Double.valueOf(columnlist.getColumnByName(name).getStringValue());
        } else if (fieldtype.isAssignableFrom(UUID.class)) {
            return columnlist.getColumnByName(name).getUUIDValue();
        } else if (fieldtype.isAssignableFrom(JSONObject.class)) {
            String value = "";
            try {
                Object o = fieldtype.newInstance();
                if (o instanceof JSONObject) {
                    value = columnlist.getColumnByName(name).getStringValue();
                    return (JSONObject) (new JSONParser()).parse(value);
                } else {
                    return deserialize(columnlist.getColumnByName(name).getStringValue(), JSONObject.class);
                }
            } catch (InstantiationException e1) {
                return null;
            } catch (IllegalAccessException e1) {
                return null;
            } catch (ParseException e) {
                e.printStackTrace();
                System.err.println(value);
                return null;
            }
        } else if (fieldtype.isAssignableFrom(JSONArray.class)) {
            String value = "";
            try {
                Object o = fieldtype.newInstance();
                if (o instanceof JSONArray) {
                    value = columnlist.getColumnByName(name).getStringValue();
                    return (JSONArray) (new JSONParser()).parse(value);
                } else {
                    return deserialize(columnlist.getColumnByName(name).getStringValue(), JSONArray.class);
                }
            } catch (InstantiationException e1) {
                return null;
            } catch (IllegalAccessException e1) {
                return null;
            } catch (ParseException e) {
                e.printStackTrace();
                System.err.println(value);
                return null;
            }
        } else if (fieldtype.isAssignableFrom(InetAddress.class)) {
            String value = columnlist.getColumnByName(name).getStringValue();
            try {
                return InetAddress.getByName(value);
            } catch (UnknownHostException e) {
                e.printStackTrace();
                System.err.println(value);
                return null;
            }
        } else if (fieldtype.isAssignableFrom(StringBuffer.class)) {
            String value = columnlist.getColumnByName(name).getStringValue();
            return new StringBuffer(value);
        } else if (fieldtype.isAssignableFrom(Calendar.class)) {
            long value = columnlist.getColumnByName(name).getLongValue();
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(value);
            return c;
        } else if (fieldtype.isAssignableFrom(String[].class)) {
            String value = columnlist.getColumnByName(name).getStringValue();
            try {
                JSONArray ja = (JSONArray) (new JSONParser()).parse(value);
                String[] result = new String[ja.size()];
                for (int pos = 0; pos < ja.size(); pos++) {
                    result[pos] = (String) ja.get(pos);
                }
                return result;
            } catch (ParseException e) {
                e.printStackTrace();
                System.err.println(value);
                return null;
            }
        } else {
            return deserialize(columnlist.getColumnByName(name).getStringValue(), fieldtype);
        }
    }

    public void dropColumnFamily() throws ConnectionException {
        if (isColumnFamilyExists()) {
            Log2.log.info("Drop " + columnfamily.getName() + " CF");
            CassandraDb.dropColumnFamilyString(CassandraDb.getkeyspace(), columnfamily.getName());
        }
    }

    public void truncateColumnFamily() throws ConnectionException {
        if (isColumnFamilyExists()) {
            CassandraDb.getkeyspace().truncateColumnFamily(columnfamily.getName()).getResult();
        }
    }

    ColumnFamily<String, String> getColumnfamily() {
        return columnfamily;
    }

    private boolean isColumnFamilyExists() throws ConnectionException {
        return CassandraDb.isColumnFamilyExists(CassandraDb.getkeyspace(), columnfamily.getName());
    }

    private void createColumnFamily() throws IOException, ConnectionException {

        CassandraDb.createColumnFamilyString(CassandraDb.getDefaultKeyspacename(), columnfamily.getName(),
                createOrmObject().hasLongGracePeriod());

        ArrayList<Field> fields = getOrmobjectUsableFields();
        Field field;
        String colstype;
        Class<?> fieldtype;
        for (int pos_df = 0; pos_df < fields.size(); pos_df++) {
            field = fields.get(pos_df);
            if (field.isAnnotationPresent(CassandraIndexed.class) == false) {
                continue;
            }
            fieldtype = field.getType();
            if (fieldtype.isAssignableFrom(String.class)) {
                colstype = DeployColumnDef.ColType_UTF8Type;
            } else if (fieldtype.isAssignableFrom(Byte[].class) | fieldtype.isAssignableFrom(byte.class)) {
                colstype = DeployColumnDef.ColType_BytesType;
            } else if (fieldtype.isAssignableFrom(Integer.class) | fieldtype.isAssignableFrom(int.class)) {
                colstype = DeployColumnDef.ColType_IntegerType;
            } else if (fieldtype.isAssignableFrom(Long.class) | fieldtype.isAssignableFrom(long.class)) {
                colstype = DeployColumnDef.ColType_LongType;
            } else if (fieldtype.isAssignableFrom(Boolean.class) | fieldtype.isAssignableFrom(boolean.class)) {
                colstype = DeployColumnDef.ColType_IntegerType;
            } else if (fieldtype.isAssignableFrom(Date.class)) {
                colstype = DeployColumnDef.ColType_LongType;
            } else if (fieldtype.isAssignableFrom(Float.class) | fieldtype.isAssignableFrom(float.class)) {
                colstype = DeployColumnDef.ColType_AsciiType;
            } else if (fieldtype.isAssignableFrom(Double.class) | fieldtype.isAssignableFrom(double.class)) {
                colstype = DeployColumnDef.ColType_AsciiType;
            } else if (fieldtype.isAssignableFrom(UUID.class)) {
                colstype = DeployColumnDef.ColType_LexicalUUIDType;
            } else if (fieldtype.isAssignableFrom(JSONObject.class)) {
                colstype = DeployColumnDef.ColType_UTF8Type;
            } else if (fieldtype.isAssignableFrom(JSONArray.class)) {
                colstype = DeployColumnDef.ColType_UTF8Type;
            } else if (fieldtype.isAssignableFrom(InetAddress.class)) {
                colstype = DeployColumnDef.ColType_AsciiType;
            } else if (fieldtype.isAssignableFrom(StringBuffer.class)) {
                colstype = DeployColumnDef.ColType_UTF8Type;
            } else if (fieldtype.isAssignableFrom(Calendar.class)) {
                colstype = DeployColumnDef.ColType_LongType;
            } else if (fieldtype.isAssignableFrom(String[].class)) {
                colstype = DeployColumnDef.ColType_UTF8Type;
            } else {
                colstype = DeployColumnDef.ColType_BytesType;
            }

            CassandraDb.declareIndexedColumn(CassandraDb.getkeyspace(), columnfamily, field.getName(),
                    getIndexName(field.getName()), colstype);
        }
    }

    public String getIndexName(String fieldname) {
        return columnfamily.getName() + "_" + fieldname;
    }

    /**
     * Atomic (prepare and execute mutation)
     */
    public void delete(String rowkey) throws ConnectionException {
        if (rowkey == null) {
            return;
        }
        if (rowkey.equals("")) {
            return;
        }
        resetMutator();
        ArrayList<ColumnFamily<String, String>> cf = new ArrayList<ColumnFamily<String, String>>();
        cf.add(columnfamily);
        mutator.deleteRow(cf, rowkey);
        executeMutation();
    }

    /**
     * Atomic (prepare and execute mutation)
     */
    public void delete(T element) throws ConnectionException {
        delete(element.key);
    }

    /**
     * Used for special internal ORM debugging.
     */
    public static void autotest() throws Exception {
        int count = 1000;

        CassandraOrm<AutotestOrm> cassandraorm = new CassandraOrm<AutotestOrm>(AutotestOrm.class, AutotestOrm.CF);
        cassandraorm.prepareColumnlistnames();

        Log2Dump dump = new Log2Dump();
        for (int pos = 0; pos < cassandraorm.column_names.length; pos++) {
            dump.add("cols", cassandraorm.column_names[pos]);
        }
        Log2.log.debug("List cols", dump);

        if (cassandraorm.isColumnFamilyExists()) {
            Log2.log.debug("Column family exist !");
        }

        cassandraorm.createColumnFamily();

        for (int pos = 0; pos < count; pos++) {
            cassandraorm.pushObject(AutotestOrm.populate(pos), 3600);
        }
        cassandraorm.executeMutation();

        final ArrayList<AutotestOrm> elements = new ArrayList<AutotestOrm>();
        CassandraOrmExporter<AutotestOrm> orm_expr = new CassandraOrmExporter<AutotestOrm>() {
            public boolean exportFromCassandra(AutotestOrm element) {
                elements.add(element);
                return true;
            }
        };
        cassandraorm.pullAllObjectsToExporter(orm_expr);

        if (elements.size() != count) {
            throw new Exception("Missing elements ! " + String.valueOf(elements.size() - count));
        }
        for (int pos = 0; pos < elements.size(); pos++) {
            if (elements.get(pos).check(elements.get(pos).iamanindex) == false) {
                throw new Exception("Bad element ! " + elements.get(pos).key);
            }
        }

        cassandraorm.dropColumnFamily();
    }

    /**
     * Limited to 1M rows
     */
    public List<T> pullObjectsByIndexes(Expression... indexqueryexpressions) throws ConnectionException {
        prepareColumnlistnames();
        IndexQuery<String, String> idx_rows = CassandraDb.getkeyspace().prepareQuery(columnfamily)
                .searchWithIndex();

        for (int pos = 0; pos < indexqueryexpressions.length; pos++) {
            indexqueryexpressions[pos].applyExpression(idx_rows, this);
        }
        idx_rows.withColumnSlice(column_names);
        idx_rows.setRowLimit(1000000);

        OperationResult<Rows<String, String>> rows = idx_rows.execute();
        List<T> results = new ArrayList<T>();
        for (Row<String, String> row : rows.getResult()) {
            results.add(pullObject(row.getKey(), row.getColumns()));
        }
        return results;
    }

    /**
     * Limited to 1M rows
     */
    public void pullAllObjectsToExporter(final CassandraOrmExporter<T> exporter,
            Expression... indexqueryexpressions) throws Exception {
        prepareColumnlistnames();
        IndexQuery<String, String> idx_rows = CassandraDb.getkeyspace().prepareQuery(columnfamily)
                .searchWithIndex();

        for (int pos = 0; pos < indexqueryexpressions.length; pos++) {
            indexqueryexpressions[pos].applyExpression(idx_rows, this);
        }
        idx_rows.withColumnSlice(column_names);
        idx_rows.setRowLimit(1000000);

        OperationResult<Rows<String, String>> rows = idx_rows.execute();
        for (Row<String, String> row : rows.getResult()) {
            if (exporter.exportFromCassandra(pullObject(row.getKey(), row.getColumns())) == false) {
                return;
            }
        }
    }

    public JSONArray pullObjectsByIndexesToJSON(Expression... indexqueryexpressions)
            throws ConnectionException, ParseException {
        List<T> values = pullObjectsByIndexes(indexqueryexpressions);
        JSONArray ja = new JSONArray();
        JSONParser jp = new JSONParser();
        for (int pos = 0; pos < values.size(); pos++) {
            jp.reset();
            ja.add(jp.parse((new Gson()).toJson(values.get(pos))));
        }
        return ja;
    }
}