All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xerial.db.model.DataModel Maven / Gradle / Ivy

The newest version!
/*--------------------------------------------------------------------------
 *  Copyright 2007 Taro L. Saito
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *--------------------------------------------------------------------------*/
//--------------------------------------
// XerialJ Project
//
// DataModel.java
// Since: Apr 18, 2007
//
// $URL$ 
// $Author$
//--------------------------------------
package org.xerial.db.model;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Vector;

import org.xerial.db.DBException;
import org.xerial.db.Relation;
import org.xerial.db.datatype.DataTypeBase;
import org.xerial.db.datatype.TypeName;
import org.xerial.db.sql.sqlite.SQLiteAccess;
import org.xerial.db.sql.sqlite.SQLiteDataTypeInfo;
import org.xerial.util.CollectionUtil;
import org.xerial.util.Functor;
import org.xerial.util.Predicate;
import org.xerial.util.graph.AdjacencyList;
import org.xerial.util.graph.DepthFirstSearchBase;
import org.xerial.util.graph.Edge;
import org.xerial.util.log.Logger;

/**
 * 
 * A DataModel manages the graph structure of an ER-diagram.
 * 
 * person:(id, name, address) || author:(book_id, author_id) |* |1 book:(r2:id,
 * r2:title) || order:(id, book_id, customer_id, info) || customer:(id, name,
 * address, phone)
 * 
 * 
 * query examples (person:name, book:title = "Gone with the wind")
 * 
 * (book:id = 10, customer:name, order:info)
 * 
 * 
 * select customer:id, customer:name, count(*) from (select customer left join
 * order on customer:id = order:customer_id)
 * 
 * 
 * 
 * Multidimensional Hash Table can support this type of query?
 * 
 * 
 * 
 * 
 * 
 * @author leo
 * 
 */
public class DataModel
{
    private static Logger _logger = Logger.getLogger(DataModel.class);

    private AdjacencyList _graph = new AdjacencyList();

    public void addNode(String nodeName)
    {
        if (!contains(nodeName))
            _graph.addNode(nodeName);
    }

    public boolean contains(String nodeName)
    {
        return _graph.hasNode(nodeName);
    }

    public void connectNodes(String sourceNodeName, String destNodeName, Relationship rel) throws DBException
    {
        _graph.addEdge(sourceNodeName, destNodeName, rel);
    }

    public Set getRootNodeNameSet()
    {
        TreeSet rootNodeSet = new TreeSet();

        for (String node : _graph.getNodeLabelSet())
        {
            // if this node has no incoming edges
            if (_graph.getInEdgeSet(node).size() == 0)
                rootNodeSet.add(node);
        }

        return rootNodeSet;
    }

    @SuppressWarnings("unchecked")
    public List destinationOf(String nodeName)
    {
        Collection nodeIDSet = _graph.getDestNodeIDSetOf(_graph.getNodeID(nodeName));

        return CollectionUtil.collect(nodeIDSet, new Functor() {
            public String apply(Integer nodeID)
            {
                return _graph.getNodeLabel(nodeID);
            }
        });

    }

    class PathSearch extends DepthFirstSearchBase
    {
        public List getPath(String src, String dest)
        {
            run(_graph, src);

            // TODO improve by using Dijkstra's algorithm
            LinkedList path = new LinkedList();
            path.add(dest);
            String predecessor;
            String contextNode = dest;
            while (!(predecessor = getPredecessor(contextNode)).equals(contextNode))
            {
                path.addFirst(predecessor);
                if (predecessor.equals(src))
                {
                    return path;
                }
                contextNode = predecessor;
            }

            if (!path.getFirst().equals(src))
                return new LinkedList();

            return path;

        }
    }

    public List path(String src, String dest)
    {
        return new PathSearch().getPath(src, dest);
    }

    public boolean hasPath(String src, String dest)
    {
        return path(src, dest).size() > 0;
    }

    public void save(SQLiteAccess query) throws DBException
    {
        if (query.hasTable("node"))
            query.dropTable("node");
        if (query.hasTable("edge"))
            query.dropTable("edge");

        Relation nodeRelation = new Relation();
        nodeRelation.add(new DataTypeBase("id", TypeName.INTEGER, true, true));
        nodeRelation.add(new DataTypeBase("name", TypeName.STRING));
        query.createTable("node", nodeRelation);

        Relation edgeRelation = new Relation();
        edgeRelation.add(new DataTypeBase("id", TypeName.INTEGER, true, true));
        edgeRelation.add(new DataTypeBase("src", TypeName.INTEGER));
        edgeRelation.add(new DataTypeBase("dest", TypeName.INTEGER));
        edgeRelation.add(new DataTypeBase("relationship", TypeName.INTEGER));
        query.createTable("edge", edgeRelation);

        Vector nodeList = new Vector();
        for (int nodeID : _graph.getNodeIDSet())
        {
            nodeList.add(new NodeData(nodeID, _graph.getNodeLabel(nodeID)));
        }

        Vector edgeList = new Vector();
        for (Edge edge : _graph.getEdgeSet())
        {
            edgeList.add(new EdgeData(_graph.getEdgeID(edge), edge.getSourceNodeID(), edge.getDestNodeID(), _graph
                    .getEdgeLabel(edge)));
        }

        for (NodeData node : nodeList)
            query.insert("node", node);
        for (EdgeData edge : edgeList)
            query.insert("edge", edge);

    }

    public void load(SQLiteAccess query) throws DBException
    {

        TreeSet nodeList = CollectionUtil.sort(query.amoebaQuery(NodeData.class, "node"));
        TreeSet edgeList = CollectionUtil.sort(query.amoebaQuery(EdgeData.class, "edge"));

        for (NodeData node : nodeList)
        {
            _graph.addNode(node.getName());
        }
        for (EdgeData edge : edgeList)
        {
            _graph.addEdge(new Edge(edge.getSrc(), edge.getDest()), EdgeData.translate(edge.getRelationship()));
        }

    }

    public String toString()
    {
        return _graph.toString();
    }

    public void attachSQLiteDatabase(String sqliteDBFile) throws DBException
    {

        SQLiteAccess query = new SQLiteAccess(sqliteDBFile);

        Collection tableList = query.getTableList();
        List infoTableList = CollectionUtil.select(tableList, new Predicate() {
            public boolean apply(String input)
            {
                return isInfoTable(input);
            }
        });
        List dataTableList = CollectionUtil.select(tableList, new Predicate() {
            public boolean apply(String input)
            {
                return !isInfoTable(input);
            }
        });

        //HashMap> 
        for (String infoTable : infoTableList)
        {
            for (DataModelInfo info : query.amoebaQuery(DataModelInfo.class, infoTable))
            {

            }
        }

        for (String dataTable : dataTableList)
        {
            Relation relation = new Relation();
            for (SQLiteDataTypeInfo dataType : query.getSQLiteDataTypeInfo(dataTable))
            {
                relation.add(Relation.getDataType(dataType.getName(), dataType.getType()));
            }
            addRelation(relation);
        }
    }

    public void addRelation(Relation relation)
    {
        _logger.debug("add relation: " + relation.toString());
    }

    private static boolean isInfoTable(String tableName)
    {
        return tableName.endsWith("_info");
    }

    public boolean hasEdge(String src, String dest)
    {
        return _graph.hasEdge(src, dest);
    }

    public Relationship getRelationship(String src, String dest)
    {
        return _graph.getEdgeLabel(src, dest);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy