Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * ProjectionIterator.java
- *
- * DBMS Implementation
- */
- import java.io.FileNotFoundException;
- import com.sleepycat.bind.tuple.TupleOutput;
- import com.sleepycat.db.*;
- /**
- * A class that serves as an iterator over some or all of the tuples
- * in a relation that results from performing a projection on an
- * another relation. It is used to implement all SELECT statements
- * except ones that specify SELECT *
- */
- public class ProjectionIterator extends RelationIterator {
- private Column[] columns;
- private RelationIterator subrel;
- private boolean checkDistinct;
- private int numTuples;
- ConditionalExpression where ;
- /**
- * Constructs a ProjectionIterator object for the relation formed by
- * applying a projection to the relation over which the specified
- * subrel iterator will iterate. This other relation is referred to
- * as the "subrelation" of this iterator.
- *
- * @param stmt the SQL SELECT statement that specifies the projection
- * @param subrel the subrelation
- * @throws DatabaseException
- * @throws IllegalStateException if subrel is null
- */
- public ProjectionIterator(SelectStatement stmt, RelationIterator subrel){
- SelectStatement st = stmt;
- this.where = st.getWhere();
- if (this.where == null)
- this.where = new TrueExpression();
- columns = new Column[stmt.numColumns()];
- if (subrel!= null)
- this.subrel = subrel;
- else
- throw new IllegalStateException();
- for (int i = 0; i < stmt.numColumns(); i++) {
- columns[i] = stmt.getColumn(i);
- }
- if(stmt.distinctSpecified())
- this.checkDistinct = true;
- else
- this.checkDistinct = false;
- this.numTuples = 0;
- }
- /**
- * Closes the iterator, which closes any BDB handles that it is using.
- *
- * @throws DatabaseException if Berkeley DB encounters a problem
- * while closing a handle
- */
- public void close() throws DatabaseException {
- if (this.subrel != null)
- this.subrel.close();
- this.subrel = null;
- }
- /**
- * Advances the iterator to the next tuple in the relation. If
- * there is a WHERE clause that limits which tuples should be
- * included in the relation, this method will advance the iterator
- * to the next tuple that satisfies the WHERE clause. If the
- * iterator is newly created, this method will position it on the first
- * tuple in the relation (that satisfies the WHERE clause).
- *
- * @return true if the iterator was advanced to a new tuple, and false
- * if there are no more tuples to visit
- * @throws DeadlockException if deadlock occurs while accessing the
- * underlying BDB database(s)
- * @throws DatabaseException if Berkeley DB encounters another problem
- * while accessing the underlying database(s)
- */
- public boolean next() throws DatabaseException, DeadlockException {
- /* not yet implemented */
- TupleOutput keyBuffer = new TupleOutput();
- DatabaseEntry key = null;
- DatabaseEntry data = null;
- if (this.subrel == null)
- throw new IllegalStateException("this iterator has been closed");
- if (this.checkDistinct){
- OperationStatus ret = OperationStatus.SUCCESS;
- Table tempTable = new Table("tempTable");
- // Create the BDB database for the table.
- DatabaseConfig config = new DatabaseConfig();
- config.setType(DatabaseType.RECNO);
- config.setAllowCreate(true);
- try {
- tempTable.setDB(DBMS.getEnv().openDatabase(null, null,
- null, config));
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- Object val = null;
- if(columns.length == 1){
- val = columns[0].getTableIterator().getColumnVal(0);
- }
- else {
- for (int i = 0; i < columns.length; i++) {
- val = columns[i].getTableIterator().getColumnVal(i);
- }
- }
- if (val instanceof Integer)
- keyBuffer.writeInt((Integer)val);
- else if (val instanceof Double)
- keyBuffer.writeDouble((Double)val);
- else {
- String newVal = (String)val ;
- keyBuffer.writeBytes(newVal);
- }
- if (keyBuffer != null){
- key = new DatabaseEntry(keyBuffer.getBufferBytes(), 0,
- keyBuffer.getBufferLength());
- }
- data = new DatabaseEntry();
- ret = tempTable.getDB().append(null, key, data);
- if (ret == OperationStatus.KEYEXIST){
- subrel.next();
- return true;
- }
- else {
- do {
- if(!this.subrel.next())
- return false;
- this.numTuples++;
- } while (!this.where.isTrue());
- return true;
- }
- }
- else{
- if (this.numTuples() == 0 && this.where.isTrue()){
- this.subrel.next();
- this.numTuples++;
- }
- else {
- do {
- if(!this.subrel.next())
- return false;
- this.numTuples++;
- } while (!this.where.isTrue());
- }
- }
- return true;
- }
- /**
- * Gets the column at the specified index in the relation that
- * this iterator iterates over. The leftmost column has an index of 0.
- *
- * @return the column
- * @throws IndexOutOfBoundsException if the specified index is invalid
- */
- public Column getColumn(int colIndex) {
- return this.columns[colIndex];
- }
- /**
- * Gets the value of the column at the specified index in the row
- * on which this iterator is currently positioned. The leftmost
- * column has an index of 0.
- *
- * This method will unmarshall the relevant bytes from the
- * key/data pair and return the corresponding Object -- i.e.,
- * an object of type String for CHAR and VARCHAR values, an object
- * of type Integer for INTEGER values, or an object of type Double
- * for REAL values.
- *
- * @return the value of the column
- * @throws IllegalStateException if the iterator has not yet been
- * been positioned on a tuple using first() or next()
- * @throws IndexOutOfBoundsException if the specified index is invalid
- */
- public Object getColumnVal(int colIndex) {
- return columns[colIndex].getTableIterator().getColumnVal(colIndex);
- }
- public int numColumns() {
- return this.columns.length;
- }
- public int numTuples() {
- return this.numTuples;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement