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 + -
显示快捷键?