package org.reldb.rel.v0.storage.relvars;
import org.reldb.rel.exceptions.*;
import org.reldb.rel.v0.generator.Generator;
import org.reldb.rel.v0.interpreter.*;
import org.reldb.rel.v0.languages.tutoriald.parser.ParseException;
import org.reldb.rel.v0.storage.RelDatabase;
import org.reldb.rel.v0.types.*;
import org.reldb.rel.v0.values.*;
import org.reldb.rel.v0.vm.Context;
import org.reldb.rel.v0.vm.Operator;
public class RelvarVirtual extends RelvarGlobal {
public RelvarVirtual(String name, RelDatabase database) {
super(name, database);
}
public long getCardinality(Generator generator) {
TupleIterator iterator = iterator(generator);
try {
long count = 0;
while (iterator.hasNext()) {
iterator.next();
count++;
}
return count;
} finally {
iterator.close();
}
}
public boolean contains(Generator generator, final ValueTuple tuple) {
TupleIterator iterator = iterator(generator);
try {
while (iterator.hasNext())
if (tuple.equals(iterator.next()))
return true;
return false;
} finally {
iterator.close();
}
}
// Get a TupleIterator
public TupleIterator iterator(final Generator generator) {
// TODO - cache result of virtual relvar evaluation to improve performance
return new TupleIterator() {
private ValueRelation getRelationFromVirtualRelvar() {
try {
RelvarVirtualMetadata metadata = (RelvarVirtualMetadata)getRelvarMetadata();
// TODO - using System.out for the output stream should never be a problem, but it's not a good idea, either.
Evaluation eval = Interpreter.evaluateExpression(getDatabase(), metadata.getSourceCode(), System.out);
if (!(eval.getType() instanceof TypeRelation))
throw new ExceptionSemantic("RS0228: VIRTUAL relation-valued variable expected to evaluate to RELATION, but got " + eval.getType());
Heading evalResultHeading = ((TypeRelation)eval.getType()).getHeading();
if (!metadata.getHeadingDefinition(getDatabase()).getHeading().canAccept(evalResultHeading))
throw new ExceptionSemantic("RS0229: VIRTUAL relation-valued variable expected to have heading of " + metadata.getHeadingDefinition(getDatabase()).getHeading() + " but got " + evalResultHeading);
// TODO - Check compatibility of expected vs. actual RelvarHeading here.
return (ValueRelation)eval.getValue();
} catch (ParseException pe) {
throw new ExceptionSemantic("RS0230: Error in VIRTUAL relation-valued variable: " + pe.toString());
}
}
TupleIterator iterator = getRelationFromVirtualRelvar().iterator();
public boolean hasNext() {
return iterator.hasNext();
}
public ValueTuple next() {
return iterator.next();
}
public void close() {
iterator.close();
}
};
}
private void noUpdates() {
throw new ExceptionSemantic("RS0231: VIRTUAL relation-valued variables are not yet updateable.");
}
public void setValue(ValueRelation relation) {
noUpdates();
}
public long insert(Generator generator, final ValueTuple tuple) {
noUpdates();
return 0;
}
public long insert(Generator generator, final ValueRelation relation) {
noUpdates();
return 0;
}
public long insertNoDuplicates(Generator generator, final ValueRelation relation) {
noUpdates();
return 0;
}
// Delete all tuples
public void purge() {
noUpdates();
}
// Delete selected tuples
public long delete(final Context context, final Operator whereTupleOperator) {
noUpdates();
return 0;
}
// Delete selected tuples
public long delete(Generator generator, TupleFilter filter) {
noUpdates();
return 0;
}
// Delete specified tuples. If there are tuplesToDelete not found in this Relvar, and errorIfNotIncluded is true, throw an error.
public long delete(Context context, ValueRelation tuplesToDelete, boolean errorIfNotIncluded) {
noUpdates();
return 0;
}
// Update all tuples using a given update operator
public long update(final Context context, final Operator updateTupleOperator) {
noUpdates();
return 0;
}
// Update selected tuples using a given update operator
public long update(final Context context, final Operator whereTupleOperator, final Operator updateTupleOperator) {
noUpdates();
return 0;
}
}