Package org.dbwiki.driver.rdbms

Source Code of org.dbwiki.driver.rdbms.RDBMSDatabaseListing

/*
    BEGIN LICENSE BLOCK
    Copyright 2010-2011, Heiko Mueller, Sam Lindley, James Cheney and
    University of Edinburgh

    This file is part of Database Wiki.

    Database Wiki is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Database Wiki is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Database Wiki.  If not, see <http://www.gnu.org/licenses/>.
    END LICENSE BLOCK
*/
package org.dbwiki.driver.rdbms;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Vector;

import org.dbwiki.data.index.DatabaseContent;

import org.dbwiki.data.resource.NodeIdentifier;
import org.dbwiki.data.time.TimeSequence;
import org.dbwiki.exception.WikiFatalException;

/** A listing of the entries in a database.
* Entries can be looked up by node id or by integer index in the vector.
* FIXME #query: Put the queries somewhere else.
* @author jcheney
*
*/

public class RDBMSDatabaseListing implements DatabaseContent {
  /*
   * Private Variables
   */
 
  private Hashtable<Integer, RDBMSDatabaseEntry> _entryIndex;
  private Vector<RDBMSDatabaseEntry> _entryList;
  private boolean _isSorted = false;
 
 
  /*
   * Constructors
   */
 
  public RDBMSDatabaseListing() {
    _entryIndex = new Hashtable<Integer, RDBMSDatabaseEntry>();
    _entryList = new Vector<RDBMSDatabaseEntry>();
  }
 
  /**
   * Creates a RDBMSDatabaseListing whose contents are loaded from the database
   * FIXME #queries: Put queries into DatabaseConstants??
   * @param con
   * @param database
   * @throws org.dbwiki.exception.WikiException
   */
  public  RDBMSDatabaseListing(Connection con, RDBMSDatabase database) throws org.dbwiki.exception.WikiException {
    this();
   
    if (database.getDisplaySchemaNode() != null) {
      try {
        String relData = database.name() + DatabaseConstants.RelationData;
        String relTimestamp = database.name() + DatabaseConstants.RelationTimesequence;
        String relVersion = database.name() + DatabaseConstants.RelationVersion;
       
        PreparedStatement pStmtSelectContent = con.prepareStatement("SELECT " +
          relData + "." + DatabaseConstants.RelDataColID + ", " +
          relTimestamp + "." + DatabaseConstants.RelTimesequenceColStart + ", " +
          relTimestamp + "." + DatabaseConstants.RelTimesequenceColStop + " " +
          "FROM " + relData + ", " + relTimestamp + " " +
          "WHERE " + relData + "." + DatabaseConstants.RelDataColID + " = " + relData + "." + DatabaseConstants.RelDataColEntry + " AND " +
          relData + "." + DatabaseConstants.RelDataColTimesequence + " = " + relTimestamp + "." + DatabaseConstants.RelTimesequenceColID + " " +
          "ORDER BY " +relData + "." + DatabaseConstants.RelDataColID + ", " + relTimestamp + "." + DatabaseConstants.RelTimesequenceColStart);
         
        PreparedStatement pStmtSelectLabel = con.prepareStatement("SELECT d." +
            DatabaseConstants.RelDataColEntry + ", d." + DatabaseConstants.RelDataColValue + ", " +
            relTimestamp + "." + DatabaseConstants.RelTimesequenceColStart + ", " + relTimestamp + "." + DatabaseConstants.RelTimesequenceColStop + " FROM (" +
            "SELECT d1." + DatabaseConstants.RelDataColID + ", d1." + DatabaseConstants.RelDataColEntry + ", d1." + DatabaseConstants.RelDataColValue + ", " +
            "d1." + DatabaseConstants.RelDataColTimesequence + " " +
            "FROM " + relData + " d1, " + relData + " d2 " +
            "WHERE d1." + DatabaseConstants.RelDataColSchema + " = " + DatabaseConstants.RelDataColSchemaValUnknown + " AND " +
            "d1." + DatabaseConstants.RelDataColParent + " = d2." + DatabaseConstants.RelDataColID + " AND " +
            "d2." + DatabaseConstants.RelDataColSchema + " = ?) d " +
            "LEFT OUTER JOIN " + relTimestamp + " ON d." + DatabaseConstants.RelDataColTimesequence + " = " + relTimestamp + "." + DatabaseConstants.RelTimesequenceColID + " " +
            "ORDER BY d." + DatabaseConstants.RelDataColEntry + ", d." + DatabaseConstants.RelDataColID + " DESC, " + relTimestamp + "." + DatabaseConstants.RelTimesequenceColStop);
         
        PreparedStatement pStmtSelectLastChange = con.prepareStatement("SELECT " +
            relData + "." + DatabaseConstants.RelDataColEntry + ", MAX(" + relVersion + "." + DatabaseConstants.RelVersionColNumber + ") " +
            "FROM " + relData + ", " + relVersion + " " +
            "WHERE " + relVersion + "." + DatabaseConstants.RelVersionColNode + " = " + relData + "." + DatabaseConstants.RelDataColID + " " +
            "GROUP BY " + relData + "." + DatabaseConstants.RelDataColEntry);
       
        ResultSet rs = pStmtSelectContent.executeQuery();
        RDBMSDatabaseEntry entry = null;
        while (rs.next()) {
          int id = rs.getInt(1);
          int start = rs.getInt(2);
          int end = rs.getInt(3);
          if (entry == null) {
            entry = new RDBMSDatabaseEntry(new NodeIdentifier(id), new TimeSequence(start, end));
            add(entry);
          } else {
            if (entry.identifier().nodeID() == id) {
              entry.timestamp().elongate(start, end);
            } else {
              entry = new RDBMSDatabaseEntry(new NodeIdentifier(id), new TimeSequence(start, end));
              add(entry);
            }
          }
        }
        rs.close();
        pStmtSelectLabel.setInt(1, database.getDisplaySchemaNode().id());
        rs = pStmtSelectLabel.executeQuery();
        entry = null;
        int maxTime = Integer.MIN_VALUE;
        while (rs.next()) {
          int id = rs.getInt(1);
          String value = rs.getString(2);
          int end = DatabaseConstants.RelTimestampColEndValOpen;
          rs.getInt(3);
          if (!rs.wasNull()) {
            end = rs.getInt(4);
          }
          if (entry == null) {
            entry = get(new NodeIdentifier(id));
            maxTime = Integer.MIN_VALUE;
          } else if (entry.identifier().nodeID() != id) {
            entry = get(new NodeIdentifier(id));
            maxTime = Integer.MIN_VALUE;
          }
          if (end == DatabaseConstants.RelTimestampColEndValOpen) {
            entry.label(value);
            maxTime = Integer.MAX_VALUE;
          } else if (end > maxTime) {
            entry.label(value);
            maxTime = end;
          }
        }
        rs.close();
        rs = pStmtSelectLastChange.executeQuery();
        while (rs.next()) {
          get(new NodeIdentifier(rs.getInt(1))).lastChange(rs.getInt(2));
        }
        rs.close();
        pStmtSelectContent.close();
        pStmtSelectLabel.close();
        pStmtSelectLastChange.close();
        con.close();
      } catch (java.sql.SQLException sqlException) {
        throw new WikiFatalException(sqlException);
      }
    }
   
    sort();
  }
 
  /*
   * Public Methods
   */
 
  public void add(RDBMSDatabaseEntry entry) {
    _entryIndex.put(new Integer(entry.identifier().nodeID()), entry);
    _entryList.add(entry);
    _isSorted = false;
  }
 
  public RDBMSDatabaseEntry get(int index) {
    return _entryList.get(index);
  }
 
  public RDBMSDatabaseEntry get(String key) {
    if (_isSorted) {
      int low = 0;
      int high = _entryList.size() - 1;
      while(high >= low) {
        int middle = (low + high) / 2;
        RDBMSDatabaseEntry entry = _entryList.get(middle);
        int comp = entry.label().compareTo(key);
        if(comp == 0) {
          return entry;
        }
        if(comp < 0) {
          low = middle + 1;
        }
        if(comp > 0) {
          high = middle - 1;
        }
      }
    } else {
      for (RDBMSDatabaseEntry entry : _entryList) {
        if (entry.label().equals(key)) {
          return entry;
        }
      }
    }
    return null;
  }

  public RDBMSDatabaseEntry get(NodeIdentifier identifier) {
    return _entryIndex.get(new Integer(identifier.nodeID()));
  }
 
  public int size() {
    return _entryList.size();
  }
 
  public void sort() {
    Collections.sort(_entryList);
    _isSorted = true;
  }
}
TOP

Related Classes of org.dbwiki.driver.rdbms.RDBMSDatabaseListing

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.