package er.neo4jadaptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webobjects.eoaccess.EOAdaptorChannel;
import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOSQLExpression;
import com.webobjects.eoaccess.EOStoredProcedure;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import er.neo4jadaptor.ersatz.Ersatz;
import er.neo4jadaptor.ersatz.webobjects.NSDictionaryErsatz;
import er.neo4jadaptor.storage.Store;
import er.neo4jadaptor.utils.cursor.Cursor;
public class Neo4JChannel <T extends Ersatz> extends EOAdaptorChannel {
private static final Logger log = LoggerFactory.getLogger(Neo4JChannel.class);
private boolean isOpen = false;
private boolean isFetchInProgress = false;
private EOEntity fetchedEntity;
private Cursor<? extends Ersatz> fetchResult;
private int fetchLimit;
private int countFetched = 0;
private EOFetchSpecification fetchSpec;
private int fetchTimeTaken;
public Neo4JChannel(Neo4JContext<T> context) {
super(context);
}
@Override
public boolean isOpen() {
return isOpen;
}
@Override
public void openChannel() {
isOpen = true;
}
@Override
public void closeChannel() {
isOpen = false;
}
@Override
public NSDictionary<String, Object> primaryKeyForNewRowWithEntity(EOEntity entity) {
return adaptorContext()._newPrimaryKey(null, entity);
}
@SuppressWarnings("unchecked")
@Override
public Neo4JContext<T> adaptorContext() {
return (Neo4JContext<T>) super.adaptorContext();
}
@Override
public void insertRow(NSDictionary<String, Object> row, EOEntity entity) {
Store<Ersatz, ?> store = adaptorContext().entityStoreForEntity(entity);
NSDictionaryErsatz ultimate = NSDictionaryErsatz.full(entity, row);
store.insert(ultimate);
}
@SuppressWarnings("unchecked")
@Override
public void executeStoredProcedure(EOStoredProcedure paramEOStoredProcedure, NSDictionary paramNSDictionary) {
throw new UnsupportedOperationException();
}
@Override
public void cancelFetch() {
isFetchInProgress = false;
if (fetchResult != null) {
fetchResult.close();
}
fetchResult = null;
fetchedEntity = null;
log.debug("Fetch took {}ms and returned {} results (query from {}: {})", fetchTimeTaken, countFetched, fetchSpec.entityName(), fetchSpec.qualifier());
}
@Override
public boolean isFetchInProgress() {
return isFetchInProgress;
}
private void beginFetch(EOEntity entity, EOFetchSpecification fetchSpec) {
isFetchInProgress = true;
fetchedEntity = entity;
countFetched = 0;
this.fetchSpec = fetchSpec;
fetchTimeTaken = 0;
}
@Override
public void selectAttributes(NSArray<EOAttribute> attributes, EOFetchSpecification fetchSpec, boolean isLocking, EOEntity entity) {
beginFetch(entity, fetchSpec);
Store<?, ?> store = adaptorContext().entityStoreForEntity(entity);
this.fetchLimit = fetchSpec.fetchLimit();
try {
long before = System.currentTimeMillis();
fetchResult = store.query(fetchSpec.qualifier());
if (fetchSpec.sortOrderings() != null && ! fetchSpec.sortOrderings().isEmpty()) {
fetchResult = er.neo4jadaptor.utils.EOUtilities.sort(fetchResult, entity, fetchSpec.sortOrderings());
}
long after = System.currentTimeMillis();
fetchTimeTaken += (after - before);
} catch (RuntimeException e) {
cancelFetch();
throw e;
}
}
@Override
public NSMutableDictionary<String, Object> fetchRow() {
if (fetchLimit != 0 && countFetched >= fetchLimit) {
// fetch limit reached
return null;
}
if (fetchResult == null) {
return null;
}
long before = System.currentTimeMillis();
if (! fetchResult.hasNext()) {
return null;
} else {
Ersatz ultimate = fetchResult.next();
long after = System.currentTimeMillis();
NSMutableDictionary<String, Object> ret = toSnapshot(fetchedEntity, ultimate);
countFetched++;
fetchTimeTaken += (after - before);
return ret;
}
}
public NSMutableDictionary<String, Object> toSnapshot(EOEntity entity, Ersatz ultimate) {
return NSDictionaryErsatz.toSnapshot(ultimate);
}
@Override
public int updateValuesInRowsDescribedByQualifier(NSDictionary<String, Object> dict, EOQualifier qualifier, EOEntity entity) {
NSDictionaryErsatz ultimate = NSDictionaryErsatz.partial(entity, dict);
Store<Ersatz, T> store = adaptorContext().entityStoreForEntity(entity);
Cursor<T> result = store.query(qualifier);
try {
int counter = 0;
while (result.hasNext()) {
T existingNeo = result.next();
store.update(ultimate, existingNeo);
counter++;
}
return counter;
} finally {
result.close();
}
}
@Override
public int deleteRowsDescribedByQualifier(EOQualifier qualifier, EOEntity entity) {
Store<Ersatz, T> store = adaptorContext().entityStoreForEntity(entity);
Cursor<T> result = store.query(qualifier);
try {
int counter = 0;
while (result.hasNext()) {
T existingNeo = result.next();
store.delete(existingNeo);
counter++;
}
return counter;
} finally {
result.close();
}
}
@Override
public void evaluateExpression(EOSQLExpression paramEOSQLExpression) {
throw new UnsupportedOperationException();
}
@Override
public NSDictionary<?, ?> returnValuesForLastStoredProcedureInvocation() {
throw new UnsupportedOperationException();
}
@Override
public NSArray<EOAttribute> attributesToFetch() {
// TODO Auto-generated method stub
return null;
}
@Override
public NSArray<EOAttribute> describeResults() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setAttributesToFetch(NSArray<EOAttribute> paramNSArray) {
// TODO Auto-generated method stub
}
}