}
@Override
public Number nextValue(NextValueRequest request) {
DBCollection currentCollection = getCollection( request.getKey().getTable() );
DBObject query = this.prepareIdObject( request.getKey() );
//all columns should match to find the value
String valueColumnName = request.getKey().getMetadata().getValueColumnName();
BasicDBObject update = new BasicDBObject();
//FIXME how to set the initialValue if the document is not present? It seems the inc value is used as initial new value
Integer incrementObject = Integer.valueOf( request.getIncrement() );
this.addSubQuery( "$inc", update, valueColumnName, incrementObject );
DBObject result = currentCollection.findAndModify( query, null, null, false, update, false, true );
Object idFromDB;
idFromDB = result == null ? null : result.get( valueColumnName );
if ( idFromDB == null ) {
//not inserted yet so we need to add initial value to increment to have the right next value in the DB
//FIXME that means there is a small hole as when there was not value in the DB, we do add initial value in a non atomic way
BasicDBObject updateForInitial = new BasicDBObject();
this.addSubQuery( "$inc", updateForInitial, valueColumnName, request.getInitialValue() );
currentCollection.findAndModify( query, null, null, false, updateForInitial, false, true );
idFromDB = request.getInitialValue(); //first time we ask this value
}
else {
idFromDB = result.get( valueColumnName );
}
if ( idFromDB.getClass().equals( Integer.class ) || idFromDB.getClass().equals( Long.class ) ) {
Number id = (Number) idFromDB;
//idFromDB is the one used and the BD contains the next available value to use
return id;