Package com.alvazan.orm.layer9z.spi.db.mongodb

Source Code of com.alvazan.orm.layer9z.spi.db.mongodb.CursorColumnSliceMDB

package com.alvazan.orm.layer9z.spi.db.mongodb;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import com.alvazan.orm.api.z8spi.BatchListener;
import com.alvazan.orm.api.z8spi.ColumnSliceInfo;
import com.alvazan.orm.api.z8spi.action.Column;
import com.alvazan.orm.api.z8spi.conv.StandardConverters;
import com.alvazan.orm.api.z8spi.iter.AbstractCursor;
import com.alvazan.orm.api.z8spi.iter.StringLocal;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;


class CursorColumnSliceMDB<T> extends AbstractCursor<T> {

  private DBCollection dbCollection;
  private BatchListener batchListener;
  private Integer batchSize;
  private int pointer = -1;
  private List<DBObject> subList;
  private Boolean forward = null;
  private byte[] from;
  private byte[] to;
  private byte[] rowKey;
  private Class columnNameType;
 
  public CursorColumnSliceMDB(ColumnSliceInfo sliceInfo, BatchListener bListener, Integer batchSize, DBCollection dbCollection2) {
    this.batchListener = bListener;
    this.batchSize = null;
    dbCollection = dbCollection2;
    this.from = sliceInfo.getFrom();
    this.to = sliceInfo.getTo();
    this.rowKey = sliceInfo.getRowKey();
        this.columnNameType = sliceInfo.getColumnNameType();
    beforeFirst();
  }

  @Override
  public String toString() {
    String tabs = StringLocal.getAndAdd();
    String retVal = "CursorColumnSlice["+tabs+tabs+"]";
    StringLocal.set(tabs.length());
    return retVal;
  }
 
  @Override
  public void beforeFirst() {
     pointer = -1;
     subList = null;
     forward = true;
  }
 
  @Override
  public void afterLast() {
     pointer = -1;
     subList = null;
     forward = false;
  }

  @Override
  public Holder<T> nextImpl() {
    if(!forward)
      throw new IllegalStateException("You must call beforeFirst to traverse the cursor forward, you cannot call next after calling previous due to limitations of talking to noSql apis");
    fetchMoreResultsImpl();
    pointer++;
    if (pointer >= subList.size())
      return null; // no more results
    DBObject column = subList.get(pointer);

    return buildHolder(column);
  }
 
  @Override
  public Holder<T> previousImpl() {
    if(forward)
      throw new IllegalStateException("You must call afterLast to traverse reverse.  You cannot call previous after calling next due to limitations of calling into noSQL apis");
    fetchMoreResultsImpl();
    pointer++;
    if (pointer >= subList.size())
      return null; // no more results

    DBObject column = subList.get(pointer);
    return buildHolder(column);
  }

  @SuppressWarnings("unchecked")
  private Holder<T> buildHolder(DBObject col) {
    Set<String> singleKey = col.keySet();
    String colName = singleKey.iterator().next();
    byte[] name = StandardConverters.convertFromString(byte[].class, colName);
    byte[] val = StandardConverters.convertToBytes(col.get(colName));
    Column c = new Column();
    c.setName(name);
    if (val.length != 0)
      c.setValue(val);
    return new Holder<T>((T) c);

  }

  private void fetchMoreResultsImpl() {
    if(subList != null){
      //If subIterator is not null, we have already previously fetched results!!!
      if(pointer < subList.size()-1)
        return; //no need to fetch next subiterator since this subIterator has more
      else if(batchSize == null) //then we already fetched everything in first round
        return;
      else if(subList.size() < batchSize) {
        //since we have previous results, we then have a count of those results BUT they
        //did NOT fill up the batch so no need to go to database as we know it has no more results
        return;
      }
    }

    //reset the point...
    pointer = -1;
    if(batchListener != null)
      batchListener.beforeFetchingNextBatch();

    DBObject row = dbCollection.findOne(rowKey);
    if(row == null) {
      return;
    }
    else {
            Set<String> fieldSet = row.keySet();
            if (BigInteger.class.equals(columnNameType)) {
                intColumnSlice(fieldSet, row);
            } else if (BigDecimal.class.equals(columnNameType)) {
                decimalColumnSlice(fieldSet, row);
            } else if (String.class.equals(columnNameType)) {
                stringColumSlice(fieldSet, row);
            } else
                throw new UnsupportedOperationException("Type " + columnNameType.getName() + " is not allowed for ColumnSlice");
        }
    if (subList == null) {
      subList = new ArrayList<DBObject>();
    }
    if(batchListener != null)
      batchListener.afterFetchingNextBatch(subList.size());
  }

    private void intColumnSlice(Set<String> fieldSet, DBObject row) {
        subList = new ArrayList<DBObject>();
        Map<BigInteger, Object> map = new TreeMap<BigInteger, Object>();
        BigInteger fromField = StandardConverters.convertFromBytes(BigInteger.class, from);
        BigInteger toField = StandardConverters.convertFromBytes(BigInteger.class, to);
        for (String field : fieldSet) {
            if (!field.equalsIgnoreCase("_id")) {
                BigInteger name = StandardConverters.convertFromBytes(BigInteger.class, StandardConverters.convertFromString(byte[].class, field));
                if (name.compareTo(fromField) >= 0 && name.compareTo(toField) <= 0) {
                    Object value = row.get(field);
                    map.put(name, value);
                }
            }
        }
        for (BigInteger field : map.keySet()) {
            String newField = StandardConverters.convertToString(StandardConverters.convertToBytes(field));
            BasicDBObject dbObject = new BasicDBObject(newField, map.get(field));
            subList.add(dbObject);
        }
    }

    private void decimalColumnSlice(Set<String> fieldSet, DBObject row) {
        subList = new ArrayList<DBObject>();
        Map<BigDecimal, Object> map = new TreeMap<BigDecimal, Object>();
        BigDecimal fromField = StandardConverters.convertFromBytes(BigDecimal.class, from);
        BigDecimal toField = StandardConverters.convertFromBytes(BigDecimal.class, to);
        for (String field : fieldSet) {
            if (!field.equalsIgnoreCase("_id")) {
                BigDecimal name = StandardConverters.convertFromBytes(BigDecimal.class, StandardConverters.convertFromString(byte[].class, field));
                if (name.compareTo(fromField) >= 0 && name.compareTo(toField) <= 0) {
                    Object value = row.get(field);
                    map.put(name, value);
                }
            }
        }
        for (BigDecimal field : map.keySet()) {
            String newField = StandardConverters.convertToString(StandardConverters.convertToBytes(field));
            BasicDBObject dbObject = new BasicDBObject(newField, map.get(field));
            subList.add(dbObject);
        }
    }

    private void stringColumSlice(Set<String> fieldSet, DBObject row) {
        subList = new ArrayList<DBObject>();
        Map<String, Object> map = new TreeMap<String, Object>();
        String fromField = StandardConverters.convertFromBytes(String.class, from);
        String toField = StandardConverters.convertFromBytes(String.class, to);
        for (String field : fieldSet) {
            if (!field.equalsIgnoreCase("_id")) {
                if (field.compareTo(fromField) >= 0 && field.compareTo(toField) <= 0) {
                    Object value = row.get(field);
                    map.put(field, value);
                }
            }
        }
        for (String field : map.keySet()) {
            BasicDBObject dbObject = new BasicDBObject(field, map.get(field));
            subList.add(dbObject);
        }
    }
}
TOP

Related Classes of com.alvazan.orm.layer9z.spi.db.mongodb.CursorColumnSliceMDB

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.