tinydbquery.java

来自「nesC写的heed算法」· Java 代码 · 共 824 行 · 第 1/2 页

JAVA
824
字号
// $Id: TinyDBQuery.java,v 1.25.4.6 2003/09/09 16:58:22 whong Exp $/*									tab:4 * "Copyright (c) 2000-2003 The Regents of the University  of California.   * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. *  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Copyright (c) 2002-2003 Intel Corporation * All rights reserved. * * This file is distributed under the terms in the attached INTEL-LICENSE      * file. If you do not find these files, copies can be found by writing to * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,  * 94704.  Attention:  Intel License Inquiry. */package net.tinyos.tinydb;import java.util.*;import net.tinyos.message.*;/** TinyDBQuery is a Java data structure representing a query running (or to be run) on a set of motes.  Queries consist of: - a list of fields to select - a list of expressions over those fields, where an expression is - an filter that rejects some readings - an aggregate that combines local readings with readings from neighbors. In addition to allowing a query to be built, this class includes methods to generate radio messages so the query can be distributed over the network or to abort the query  */public class TinyDBQuery {        /** Constructor	 @param qid The id of the query	 @param epochDur The rate (in ms) at which results from the query should be generated	 */    public TinyDBQuery(byte qid, int epochDur) {		fields = new ArrayList();		exprs = new ArrayList();		this.qid = qid;		this.from_qid = NO_FROM_QUERY;		this.epochDur = (short)(epochDur / MS_PER_EPOCH_DUR_UNIT);		this.numEpochs = 0;    }	    /** Reload information about a detached query from the database	 Note that you must still register as a listener for results	 from this query to begin receiving results.	 @param name The name of the query to restore	 @param nw The network to instantiate the query in	 @returns The restored query, or null if the query could not be found.	 */    public static TinyDBQuery restore(String name, TinyDBNetwork nw) {		try {			DBLogger db = new DBLogger();			QueryState qs = db.restoreQueryState(name);			if (qs != null) {				TinyDBQuery q = net.tinyos.tinydb.parser.SensorQueryer.translateQuery(qs.queryString, (byte)qs.qid);				if (q == null) return null;				TinyDBMain.notifyAddedQuery(q);				nw.setLastEpoch(qs.qid, qs.lastEpoch);				if (qs.tableName != null) db.setupLoggingInfo(q, nw, qs.tableName);				return q;			} else return null;					} catch (java.sql.SQLException e) {			return null;		} catch (net.tinyos.tinydb.parser.ParseException e) {			//weird !			return null;		}    }	    /** Write information about this query to the database, using	 the specified name as the key with which it can be	 restored.	 @param name The name to save this query under	 @param nw Network to fetch current query info from	 @returns true iff the query was successfully saved.	 */	    public boolean saveQuery(String name, TinyDBNetwork nw) {		boolean ok = false;		try {			DBLogger db = DBLogger.getLoggerForQid(getId());			if (db == null) db = new DBLogger();			QueryState qs = new QueryState();						qs.qid = getId();			qs.queryString = getSQL();			qs.lastEpoch = nw.getLastEpoch(getId());			qs.tableName = db.getTableName();			ok = db.saveQueryState(name, qs);			db.close();					} catch (java.sql.SQLException e) {			//oh well		}		return ok;    }	    /** Return the id of the query */    public int getId() {		return qid;    }	    /** Set the id of the query.  Added by Kyle */    public void setId(byte qid) {		this.qid = qid;    }	    /** Set the epoch duration of the query in ms*/    public void setEpoch(int epochDur) {	if (epochDur == kEPOCH_DUR_ONE_SHOT)	    this.epochDur = kEPOCH_DUR_ONE_SHOT;	else	    this.epochDur = (short)(epochDur/MS_PER_EPOCH_DUR_UNIT);    }    /** Get the epoch duration of the query in ms*/    public int getEpoch() {	if (epochDur == kEPOCH_DUR_ONE_SHOT)	    return kEPOCH_DUR_ONE_SHOT;	else	    return epochDur * MS_PER_EPOCH_DUR_UNIT;    }	    /** Set the number of epochs for whicht this query will run*/    public void setNumEpochs(short n) {		this.numEpochs = n;    }	    /** Add the specified field to the query */    public void addField(QueryField f) {		int idx = f.getIdx();				/* Ick -- insure that the field is inserted at the correct		 index (as indicated by f.getIdx)		 		 ArrayList.insureCapacity doesn't work, so explicitly insert nulls		 for fields we haven't seen yet.		 */		int diff = (idx + 1) - fields.size();		while (diff-- > 0)			fields.add(null);				try {			fields.set(idx,f);		} catch (Exception e) {			e.printStackTrace();		}    }	    /** Add the specified expression to the query */    public void addExpr(QueryExpr e) {	/*  Aggregate expressions must appear at the end of the expression list	    or else the query won't run properly. */	if (e.isAgg()) {	    exprs.add(exprs.size(), e);	    	    AggExpr ae = (AggExpr)e;	    	    if (TinyDBMain.debug) System.out.println("ae's groupField = " + ae.getGroupField());	    	    if (ae.getGroupField() != AggExpr.NO_GROUPING) {		isGrouped = true;		groupExpr = ae;	    }	} else {	    SelExpr se = (SelExpr)e;	    //assume that whoever's submitting the query has already verified	    //that this is a "proper" expression... -- e.g., if it's a string	    //based query the types of the fields are strings	    exprs.add(0,e);	    lastSelExpr++;	}	    }	    /** Return true if the query is grouped (e.g. contains one or more aggregates with a	 group by expression)	 */    public boolean grouped() {		return isGrouped;    }		public void setGrouped(boolean isGrouped) {		this.isGrouped = isGrouped;	}	  public void setGroupExpr(AggExpr ae) {    groupExpr = ae;  }    public AggExpr getGroupExpr() {    return groupExpr;  }        /** Return the name of the group by column */  public String groupColName() {    if (TinyDBMain.debug) System.out.println("isGrouped = " + isGrouped);		    if (isGrouped) {      String fname = getField(groupExpr.getGroupField()).getName();            return (fname + " " + ArithOps.getStringValue(groupExpr.getGroupFieldOp()) + " " + 	      groupExpr.getGroupFieldConst());    } else return null;  }      /** Return the text of the SQL for this query as set by setSQL (Note that TinyDBQuery does not	 include an interface for generating SQL from an arbitrary query.)	 */    public String getSQL() {		return sql;    }	    /** Set the SQL string associated with this query.  Note that this string doesn't not neccessarily have	 any relationship to the fields / expressions in this object	 */    public void setSQL(String s) {		sql = s;    }        /** Return true if this query contains one or more aggregate expressions */    public boolean isAgg() {		Iterator i = exprs.iterator();		while (i.hasNext()) {			QueryExpr e = (QueryExpr)i.next();			if (e.isAgg()) return true;		}		return false;    }	    /* Return the number of expressions in this query */    public int numExprs() {	return exprs.size();    }        /* Return the ith expression in this query       Expression are (currently) either selections or aggregates       @throws ArrayIndexOutOfBoundsException if i < 0 or i >= numExprs()    */    public QueryExpr getExpr(int i) throws ArrayIndexOutOfBoundsException {	try {	    return (QueryExpr)exprs.get(i);	} catch (IndexOutOfBoundsException e) {	    throw new ArrayIndexOutOfBoundsException(i);	}    }	  /* Return the number of selection expressions in this query */  public int numSelExprs() {    return lastSelExpr+1;  }  /* Return the ith selection expression in this query     @throws ArrayIndexOutOfBoundsException if i < 0 or i >= numSelExprs()  */  public QueryExpr getSelExpr(int i) throws ArrayIndexOutOfBoundsException {    if (i >= numSelExprs() || i < 0) throw new ArrayIndexOutOfBoundsException(i);    return (QueryExpr)exprs.get(i);  }      /* Replace the selection expressions with the ones in the specified       vector.       @throws IllegalArgumentException if an element of v is not a QueryExpr       @throws ArrayIndexOutOfBoundsExcpetion if v.size() != numSelExprs()           */    public void setSelExprs(Vector v) throws IllegalArgumentException, ArrayIndexOutOfBoundsException{	if (v.size() != numSelExprs()) throw new ArrayIndexOutOfBoundsException();	for (int i = 0; i < v.size(); i ++)	    exprs.set(i, (QueryExpr)v.elementAt(i));    }    /* Display list of expressions contained in query */    public String toString() {		QueryExpr temp;		String result = "";		int i;				result += "Fields in query:\n";				for (i = 0; i < numFields(); i++)			result += (i + "  " + getField(i) + "\n");				result += numExprs() + " expressions representing query:\n";		for (i = 0; i < numExprs(); i++) {			try {				temp = getExpr(i);				result += temp;			} catch (IndexOutOfBoundsException e) {}		}		result += "Epoch Duration = " + epochDur + "\n";		result += "Query ID = " + qid + "\n";				return result;    }	    /** Returns true iff the query contains a field that isn't contained in any aggregate.	 NOTE:  Will return FALSE in this example "Select light, avg(light) from sensors"	 But, tinydb processes this query if it were "Select avg(light) from sensors"	 */    public boolean containsNonAggFields() {		QueryField qf;		QueryExpr qe;		boolean isAggField;				for (int i = 0; i < numFields(); i++) {			qf = getField(i);			isAggField = false;			for (int expIndx = 0; expIndx < numExprs(); expIndx++) {				qe = getExpr(expIndx);								//if the query field is found in an aggregate expression				if ((qe.getField() == qf.getIdx()) && qe.isAgg())					isAggField = true;			}			if (!isAggField) return true;		}				return false;    }		    public void setOutputCommand(String cmd, short param) {		hasCmd = true;		paramVal = param;		cmdName = cmd;		hasParam = false;    }	    public void setOutputCommand(String cmd) {		setOutputCommand(cmd, (short)0);		hasParam = false;    }	        public boolean hasOutputAction() {		//if we're logging results or executing a commands, we won't hear values over the radio		return hasCmd || hasName;    }    	    public boolean hasEvent() {		return hasEvent;    }	    public String getEvent() {		if (hasEvent)			return eventName;		else			return null;    }	    public void setEvent(String name) {		hasEvent = true;		eventName = name;    }	    /** Return the number of fields in this query */    public int numFields() {		return fields.size();    }        /** Return the ith field in this query	 @throws ArrayIndexOutOfBoundsException if i < 0 or i >= numFields()	 */    public QueryField getField(int i) throws ArrayIndexOutOfBoundsException {		try {			return (QueryField)fields.get(i);		} catch (IndexOutOfBoundsException e) {			throw new ArrayIndexOutOfBoundsException(i);		}    }	    /** Return a byte array representing a radio message that will tell	 motes to abort this query */    public Message abortMessage() {		QueryMsg m = new QueryMsg();	initCommonFields(m);	m.set_u_ttl(DEL_MSG_TTL);	m.set_msgType(DEL_MSG);	return m;    }	    /** Return a message that, when injected, will change the rate of

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?