⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cqlselectstatementrep.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//%2006//////////////////////////////////////////////////////////////////////////// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation, The Open Group.// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; VERITAS Software Corporation; The Open Group.// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;// EMC Corporation; Symantec Corporation; The Open Group.//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions:// // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.////==============================================================================//// Authors: David Rosckes (rosckes@us.ibm.com)//          Bert Rivero (hurivero@us.ibm.com)//          Chuck Carmack (carmack@us.ibm.com)//          Brian Lucier (lucier@us.ibm.com)//// Modified By: David Dillard, VERITAS Software Corp.//                  (david.dillard@veritas.com)////%/////////////////////////////////////////////////////////////////////////////#include "CQLSelectStatement.h"#include "CQLSelectStatementRep.h"#include <Pegasus/Common/CIMValue.h>#include <Pegasus/Common/CIMInstance.h>#include <Pegasus/Common/CIMProperty.h>#include <Pegasus/Query/QueryCommon/QueryException.h>#include <Pegasus/Query/QueryCommon/QueryIdentifier.h>#include <Pegasus/Query/QueryCommon/QueryChainedIdentifier.h>#include <Pegasus/Common/Tracer.h>#include <Pegasus/Common/InternalException.h>#include <Pegasus/Common/CIMStatusCode.h>#include <Pegasus/Common/AutoPtr.h>#include "CQLValue.h"#include "CQLIdentifier.h"#include "CQLChainedIdentifier.h"#include "Cql2Dnf.h"// ATTN: TODOs -// optimize// documentationPEGASUS_NAMESPACE_BEGINstruct PropertyNode{  CIMName name;              // property name  CIMName scope;             // class the property is on  Boolean wildcard;          // true if this property is wildcarded  Boolean endpoint;          // true if this property is an endpoint                             // of a chained identifier  AutoPtr<PropertyNode> sibling;  AutoPtr<PropertyNode> firstChild;  PropertyNode()    : wildcard(false),      endpoint(false),      sibling(NULL),      firstChild(NULL)  {}  ~PropertyNode() {}};CQLSelectStatementRep::CQLSelectStatementRep()  :SelectStatementRep(),   _hasWhereClause(false),   _contextApplied(false){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep()");  PEG_METHOD_EXIT();}CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang,                                             String& inQuery,                                             QueryContext& inCtx)  :SelectStatementRep(inQlang, inQuery, inCtx),   _hasWhereClause(false),   _contextApplied(false){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery,inCtx)");  PEG_METHOD_EXIT();}CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang,                                             String& inQuery)  :SelectStatementRep(inQlang, inQuery),   _hasWhereClause(false),   _contextApplied(false){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(inQlang,inQuery)");  PEG_METHOD_EXIT();}CQLSelectStatementRep::CQLSelectStatementRep(const CQLSelectStatementRep& rep)  :SelectStatementRep(rep),   _selectIdentifiers(rep._selectIdentifiers),   _hasWhereClause(rep._hasWhereClause),   _predicate(rep._predicate),   _contextApplied(rep._contextApplied){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep(rep)");  PEG_METHOD_EXIT();}CQLSelectStatementRep::~CQLSelectStatementRep(){  PEG_METHOD_ENTER (TRC_CQL, "~CQLSelectStatementRep()");  PEG_METHOD_EXIT();}CQLSelectStatementRep& CQLSelectStatementRep::operator=(const CQLSelectStatementRep& rhs){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::operator=");  if (this ==  &rhs)  {    PEG_METHOD_EXIT();    return *this;  }  SelectStatementRep::operator=(rhs);  _selectIdentifiers = rhs._selectIdentifiers;  _predicate = rhs._predicate;  _contextApplied = rhs._contextApplied;  _hasWhereClause = rhs._hasWhereClause;  PEG_METHOD_EXIT();  return *this;}Boolean CQLSelectStatementRep::evaluate(const CIMInstance& inCI){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::evaluate");  if(_ctx == NULL)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",                             "Trying to process a query with a NULL Query Context.");    throw CQLRuntimeException(parms);  }  // Apply to class contexts to the identifiers.  // This will check for a well-formed statement.  if (!_contextApplied)    applyContext();  // Make sure the type of instance passed in is the FROM class,  // or a subclass of the FROM class.  if (!isFromChild(inCI.getClassName()))  {    PEG_METHOD_EXIT();    return false;  }  if (!hasWhereClause())  {    PEG_METHOD_EXIT();    return true;  }  else  {    try    {      PEG_METHOD_EXIT();      return _predicate.evaluate(inCI, *_ctx);    }    catch (CQLNullContagionException& )    {      // The null contagion rule.      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"null contagion");      PEG_METHOD_EXIT();      return false;    }  }  PEGASUS_UNREACHABLE( PEGASUS_ASSERT(false); )  PEGASUS_UNREACHABLE( PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"should not get here in evaluate"); )  PEGASUS_UNREACHABLE( return true; ) //should never get here}void CQLSelectStatementRep::applyProjection(CIMInstance& inCI,    Boolean allowMissing){  PEG_METHOD_ENTER (TRC_CQL, "CQLSelectStatementRep::applyProjection(inCI)");  if(_ctx == NULL)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"QC not set");    PEG_METHOD_EXIT();    MessageLoaderParms parms("CQL.CQLSelectStatementRep.QUERY_CONTEXT_IS_NULL",                             "Trying to process a query with a NULL Query Context.");    throw CQLRuntimeException(parms);  }  // Apply to class contexts to the identifiers.  // This will check for a well-formed statement.  if (!_contextApplied)    applyContext();  //  // Build a tree to represent the projected properties from the select list  // of chained identifiers.  This is needed because embedded instances below  // the FROM class form a tree structure when projected.  //  // The design of the tree is to gather all the required properties for  // an instance at a node as child nodes.  The root node  // of the tree represents the instance passed in to this function.  Below the  // root there can be nodes that are required embedded instance properties.  // The child nodes of these embedded instance nodes represent the required  // properties on the embedded instance (which may themselves be embedded instances).  //  // Each node has a name, which is in 2 parts -- the property name and the  // scope (ie. the class the property is on).  This allows the scoping  // operator to be handled correctly, so that the parent instance can be  // checked to see if it is the right class to provide the property.  // Note that the scoping is a base class; ie. the parent instance of a node  // may be a subclass of the scope.  //  // Set up the root node of the tree.  This represents the instance  // passed in.  AutoPtr<PropertyNode> rootNode(new PropertyNode);  Array<QueryIdentifier> fromList = _ctx->getFromList();  rootNode->name = fromList[0].getName();  // not doing joins  rootNode->scope = fromList[0].getName(); // not used on root, just to fill in the var  rootNode->wildcard = false;  // Build the tree below the root.  for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"select chained id = " +                      _selectIdentifiers[i].toString());    // Get the chain elements    Array<CQLIdentifier> ids = _selectIdentifiers[i].getSubIdentifiers();    PEGASUS_ASSERT(ids.size() > 1);    PropertyNode * curNode = rootNode.get();    PropertyNode * curChild = curNode->firstChild.get();    // Loop through the identifiers in the chain.    // NOTE: this starts at the position *after* the FROM class    // So, the loop index is always one position after the current node,    // ie. it will become a child node of the current node.    for (Uint32 j = 1; j < ids.size(); j++)    {      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"curNode = " + curNode->name.getString());      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id = " + ids[j].toString());      // If the child is wildcarded, then every property exposed by the      // class of the instance at the current node is required.      // Mark the current node as wildcarded.      if (ids[j].isWildcard())      {        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is wildcard");        curNode->wildcard = true;        break;      }      // Determine if this identifier is already a child node of      // the current node.      Boolean found = false;      while (curChild != NULL && !found)      {        // The scoping class is either the scope of the identifier        // or the FROM class if the identifier is not scoped.        String scope = fromList[0].getName().getString();        if (ids[j].isScoped())        {          scope = ids[j].getScope();        }        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"scope to compare = " + scope);        if (curChild->name == ids[j].getName() &&            String::equalNoCase(curChild->scope.getString(), scope))        {          // Name and scope match.  The identifier is already child node.          PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"id is already a child node");          found = true;        }        else        {          curChild = curChild->sibling.get();        }      }      if (!found)      {        // The identifier is not already a child node.        // Create a node and add it as a child to the current node.        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"new child" +                          ids[j].getName().getString());        curChild = new PropertyNode;        curChild->sibling.reset(curNode->firstChild.release());        curChild->name = ids[j].getName();        curChild->wildcard = false;        curChild->endpoint = false;        curNode->firstChild.reset(curChild);  // safer than using the = operator      }      // Set the scope for the child node      if (ids[j].isScoped())      {        // Child node has a scoping class        PEGASUS_ASSERT(ids[j].getScope().size() > 0);        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " +                          ids[j].getScope());        curChild->scope =  CIMName(ids[j].getScope());      }      else      {        // Not scoped.  The scope is the FROM class.        PEGASUS_ASSERT(j == 1);        PEGASUS_ASSERT(fromList[0].getName().getString().size() > 0);        PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"child set with scoping class: " +                          fromList[0].getName().getString());        curChild->scope = fromList[0].getName();      }      // If the identifier is the last element of the chain,      // then mark it as an endpoint      if ((ids.size() - 1) == j)      {        curChild->endpoint = true;      }      curNode = curChild;      curChild = curNode->firstChild.get();    }  }  //  // Do the projection.  //  Array<CIMName> requiredProps;  Boolean allPropsRequired = rootNode->wildcard;  // Loop through the children of the root node.  // The root node represents the FROM class,  // and the child nodes are the required properties on the FROM class.  PropertyNode* childNode = rootNode->firstChild.get();  while (childNode != NULL)  {    PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"project childNode = " + childNode->name.getString());    // Determine if the instance passed in meets the class scoping    // rules for the current child node.    Boolean filterable = isFilterable(inCI, childNode);    // Indicates if the child node is still required after the recursive call.    Boolean childRequired = true;    // If the instance is filterable, and the child node has children,    // or is wildcarded, then the child is assumed to be an embedded instance,    // and we need to recurse to apply the projection on the embedded instance.    // (the check for embedded instance is done in the recursive call)    if (filterable &&        (childNode->firstChild.get() != NULL || childNode->wildcard))    {      // We need to project on an embedded instance property. The steps are to      // remove the embedded instance property from the instance passed in,      // project on that embedded instance property, and then add the projected      // embedded instance property back to the instance passed in.      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"about to recurse: " + childNode->name.getString());      Uint32 index = inCI.findProperty(childNode->name);      if (index != PEG_NOT_FOUND)      {        // The instance passed in has the required embedded instance property.        // Note: embedded instance property missing is caught below.        // Remove the embedded instance property        CIMProperty childProp = inCI.getProperty(index);        inCI.removeProperty(index);        // Project onto the embedded instance property.        // If the last parameter is true, then the childNode        // will not remove properties when filtering the embedded instance.        // This call returns whether the embedded instance property        // should be added to the required property list.        childRequired = applyProjection(childNode, childProp, allPropsRequired,            allowMissing);        inCI.addProperty(childProp);      }    }    // If the instance passed in is filterable,    // then add the current child to the list if it is still required.    if (filterable && childRequired)    {      PEG_TRACE_STRING (TRC_CQL, Tracer::LEVEL4,"add req prop: " + childNode->name.getString());      requiredProps.append(childNode->name);    }    childNode = childNode->sibling.get();  }  // Remove the properties that are not in the projection.  // This also checks for missing required properties.  Boolean preserve = false;  filterInstance(inCI,                 allPropsRequired,                 fromList[0].getName(),                 requiredProps,                 preserve,

⌨️ 快捷键说明

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