(file) Return to CQLSelectStatementRep.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / CQL

  1 chuck 1.1.2.3 //%2004////////////////////////////////////////////////////////////////////////
  2               //
  3               // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
  4               // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
  5               // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L. P.;
  6               // IBM Corp.; EMC Corporation, The Open Group.
  7               //
  8               // Permission is hereby granted, free of charge, to any person obtaining a copy
  9               // of this software and associated documentation files (the "Software"), to
 10               // deal in the Software without restriction, including without limitation the
 11               // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 12               // sell copies of the Software, and to permit persons to whom the Software is
 13               // furnished to do so, subject to the following conditions:
 14               // 
 15               // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 16               // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 17               // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 18               // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 19               // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 20               // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 21               // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 22 chuck 1.1.2.3 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 23               //
 24               //==============================================================================
 25               //
 26               // Authors: David Rosckes (rosckes@us.ibm.com)
 27               //          Bert Rivero (hurivero@us.ibm.com)
 28               //          Chuck Carmack (carmack@us.ibm.com)
 29               //          Brian Lucier (lucier@us.ibm.com)
 30               //
 31               // Modified By: 
 32               //
 33               //%/////////////////////////////////////////////////////////////////////////////
 34               
 35 humberto 1.1.2.1 #include "CQLSelectStatement.h"
 36                  #include "CQLSelectStatementRep.h"
 37                  
 38 chuck    1.1.2.5 #include <Pegasus/Common/CIMValue.h>
 39                  #include <Pegasus/Common/CIMInstance.h>
 40                  #include <Pegasus/Common/CIMProperty.h>
 41                  #include <Pegasus/Common/InternalException.h>
 42                  #include "CQLValue.h"
 43                  #include "CQLIdentifier.h"
 44                  #include "CQLChainedIdentifier.h"
 45                  
 46                  
 47 humberto 1.1.2.1 PEGASUS_NAMESPACE_BEGIN
 48                  
 49 chuck    1.1.2.5 struct EmbeddedPropertyNode
 50                  {
 51                    CIMName name;
 52                    Boolean wildcard;
 53                    EmbeddedPropertyNode * parent;
 54                    EmbeddedPropertyNode * sibling;
 55                    EmbeddedPropertyNode * firstChild;
 56                  };
 57                  
 58                  
 59 chuck    1.1.2.3 CQLSelectStatementRep::CQLSelectStatementRep()
 60                    :SelectStatementRep()
 61 humberto 1.1.2.1 {
 62                  }
 63                  
 64 chuck    1.1.2.3 CQLSelectStatementRep::CQLSelectStatementRep(String& inQlang, String& inQuery, QueryContext* inCtx)
 65                    :SelectStatementRep(inQlang, inQuery, inCtx)
 66                  {
 67 humberto 1.1.2.2 }
 68                  
 69 chuck    1.1.2.3 CQLSelectStatementRep::CQLSelectStatementRep(const CQLSelectStatementRep& rep)
 70                    :SelectStatementRep(rep),
 71                     _selectIdentifiers(rep._selectIdentifiers),
 72                     _whereIdentifiers(rep._whereIdentifiers),
 73                     _predicate(rep._predicate)
 74 humberto 1.1.2.1 {
 75                  }
 76                  
 77 chuck    1.1.2.3 CQLSelectStatementRep::~CQLSelectStatementRep()
 78 humberto 1.1.2.1 {
 79                  }
 80                  
 81 chuck    1.1.2.3 CQLSelectStatementRep& CQLSelectStatementRep::operator=(const CQLSelectStatementRep& rhs)
 82 humberto 1.1.2.1 {
 83 chuck    1.1.2.3   if (this ==  &rhs)
 84                      return *this;
 85                  
 86                    SelectStatementRep::operator=(rhs);
 87                  
 88                    _whereIdentifiers = rhs._whereIdentifiers;
 89                    _selectIdentifiers = rhs._selectIdentifiers;
 90                    _predicate = rhs._predicate;
 91                  
 92                    return *this;
 93                  }
 94                  
 95                  Boolean CQLSelectStatementRep::evaluate(const CIMInstance& inCI)
 96                  {
 97 chuck    1.1.2.4   if (!hasWhereClause())
 98                      return true;
 99                    else
100                      return _predicate.evaluate(inCI, *_ctx);
101 chuck    1.1.2.3 }
102                  
103                  void CQLSelectStatementRep::applyProjection(CIMInstance& inCI) throw(Exception)
104                  {
105 chuck    1.1.2.5   // assumes that applyContext had been called.
106 chuck    1.1.2.3 
107 chuck    1.1.2.5   EmbeddedPropertyNode* rootNode = new EmbeddedPropertyNode;
108                    Array<CQLIdentifier> fromList = _ctx->getFromList();
109                    rootNode->name = fromList[0].getName();  // not doing joins
110                    
111                    for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
112                    {
113                      CQLValue val(_selectIdentifiers[i]);
114                  
115                      // ATTN: assuming the CQLValue takes care of class aliasing
116                      // ATTN: assumes that the instance's class name is first subId.
117                  // ATTN: UNCOMMENT when API is available
118                  CQLChainedIdentifier resolvedId; // = val.getResolvedIdentifier(inCI, *_ctx);
119                      Array<CQLIdentifier> ids = resolvedId.getSubIdentifiers();
120                  
121                      EmbeddedPropertyNode * curNode = rootNode;
122                      EmbeddedPropertyNode * curChild = curNode->firstChild;
123                  
124                      for (Uint32 j = 1; j < ids.size(); j++)
125                      {
126                        if (ids[j].isWildcard())
127                        {
128 chuck    1.1.2.5 	curNode->wildcard = true;
129                  	break;
130                        }
131                  
132                        Boolean found = false;
133                        while (curChild != NULL && !found)
134                        {
135                  	if (curChild->name == ids[j].getName())
136                          {
137                  	  found = true;
138                  	}
139                  	else
140                          {
141                  	  curChild = curChild->sibling;
142                  	}
143                        }
144                  
145                        if (!found)
146                        {
147                  	curChild = new EmbeddedPropertyNode;
148                  	curChild->parent = curNode;
149 chuck    1.1.2.5 	curChild->sibling = curNode->firstChild;
150                  	curChild->name = ids[j].getName();
151                  	curNode->firstChild = curChild;
152                  	curNode->wildcard = false;
153                        }
154                  
155                        curNode = curChild;
156                        curChild = curNode->firstChild;
157                      }
158                    }
159                  
160                    Array<CIMName> requiredProps;
161                  
162                    EmbeddedPropertyNode* projNode = rootNode->firstChild;
163                    while (projNode != NULL)
164                    {
165                      if (!projNode->wildcard && !(projNode->firstChild == NULL))
166                      {
167                        Uint32 index = inCI.findProperty(projNode->name);
168                        CIMProperty projProp = inCI.getProperty(index);
169                        inCI.removeProperty(index);
170 chuck    1.1.2.5       applyProjection(projNode, projProp);
171                        inCI.addProperty(projProp);
172                      }
173                  
174                      // ATTN: what to do about selecting one element of an array.  Is this allowed
175                      // in basic, and if so, then it would cause a property type change.  
176                      // Line 461.  May need to call CQLValue to figure this out.
177                  
178                      if (!projNode->wildcard)
179                        requiredProps.append(projNode->name);   
180                   
181                      projNode = projNode->sibling;
182                    }
183                  
184                    if (!projNode->wildcard)
185                      removeUnneededProperties(inCI, requiredProps);
186                  
187                    // ATTN delete the tree  
188                  
189                  }
190                  
191 chuck    1.1.2.5 // spec compliance
192                  // assertions
193                  // optimize
194                  // Need a func to check well formed identifiers - ie. all emb props are scoped.  Or does
195                  // applyContext or bison do that?
196                  
197                  void CQLSelectStatementRep::applyProjection(EmbeddedPropertyNode* node,
198                  					    CIMProperty& nodeProp)
199                  {
200                    if (node->wildcard)
201                      return;
202                  
203                    PEGASUS_ASSERT(node->firstChild != NULL);
204                  
205                    CIMInstance nodeInst;
206                    CIMValue nodeVal = nodeProp.getValue();
207                  // ATTN - UNCOMMENT when emb objs are supported
208                  //PEGASUS_ASSERT(nodeVal.getType() == CIMTYPE_INSTANCE);
209                  //nodeVal.get(nodeInst);
210                  
211                    Array<CIMName> requiredProps;
212 chuck    1.1.2.5 
213                    EmbeddedPropertyNode * curChild = node->firstChild;
214                    while (curChild != NULL)
215                    {
216                      if (curChild->firstChild != NULL)
217                      {
218                        Uint32 index = nodeInst.findProperty(curChild->name);
219                        CIMProperty childProp = nodeInst.getProperty(index); 
220                        nodeInst.removeProperty(index);
221                        applyProjection(curChild, childProp);
222                        nodeInst.addProperty(childProp);
223                      }
224                  
225                      // ATTN: what to do about selecting one element of an array.  Is this allowed
226                      // in basic, and if so, then it would cause a property type change.  
227                      // Line 461.  May need to call CQLValue to figure this out.
228                  
229                      requiredProps.append(curChild->name);
230                  
231                      curChild = curChild->sibling;
232                    }
233 chuck    1.1.2.5 
234                    removeUnneededProperties(nodeInst, requiredProps);
235                  
236                  // ATTN - UNCOMMENT when emb objs are supported
237                  //CIMValue newNodeVal(nodeInst);
238                  //nodeProp.setValue(newNodeVal);
239                  } 
240                  
241                  void CQLSelectStatementRep::removeUnneededProperties(CIMInstance& inst, 
242                  						     Array<CIMName>& requiredProps)
243                  {
244                    for (Uint32 i = 0; i < inst.getPropertyCount(); i++)
245                    {
246                      Boolean found = false;
247                      for (Uint32 j = 0; j < requiredProps.size(); j++)
248                      {
249                        if (inst.getProperty(i).getName() == requiredProps[j])
250                        {
251                  	found = true;
252                  	break;
253                        }  
254 chuck    1.1.2.5     }
255                  
256                      if (!found)
257                      {
258                        inst.removeProperty(i);
259                      }
260                    }
261 humberto 1.1.2.1 }
262                  
263                  void CQLSelectStatementRep::validateClass(const CIMObjectPath& inClassName) throw(Exception)
264                  {
265 chuck    1.1.2.5   Array<CQLIdentifier> fromList = _ctx->getFromList();
266                    PEGASUS_ASSERT(fromList.size() == 1);  // no joins yet
267                  
268                    if (!inClassName.getClassName().equal(fromList[0].getName()))
269                    {
270                      throw Exception("TEMP MSG:  not in the FROM list ");
271                    }
272                  
273                    try
274                    {
275                      _ctx->getClass(inClassName.getClassName());
276                    }
277                    catch (CIMException& ce)
278                    {
279                      if (ce.getCode() == CIM_ERR_INVALID_CLASS || 
280                  	ce.getCode() == CIM_ERR_NOT_FOUND)
281                      {
282                        // ATTN may just want to throw the CIMException rather than
283                        // CQL exception
284                        throw Exception("TEMP MSG - class does not exist");
285                      }
286 chuck    1.1.2.5   }
287 humberto 1.1.2.1 }
288                  
289                  void CQLSelectStatementRep::validateProperties() throw(Exception)
290                  {
291 chuck    1.1.2.5   // assumes applyContext has been called
292                  
293                    for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
294                    {
295                      validateProperty(_selectIdentifiers[i]);
296                    }
297                  
298                    for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
299                    {
300                      validateProperty(_whereIdentifiers[i]);
301                    }
302                  }
303                  
304                  void CQLSelectStatementRep::validateProperty(CQLChainedIdentifier& chainId)
305                  {
306                    // assumes that applyContext has been called and all identfiers are well-formed
307                  
308                    Array<CQLIdentifier> ids = chainId.getSubIdentifiers();
309                  
310                    // Normalize to prepend the FROM class
311                    // see the description of CQLIdentifier::applyContext
312 chuck    1.1.2.5   CIMName prevContext;
313                    Uint32 startingPos = 0;
314                    if (ids[0].isScoped())
315                    {
316                      Array<CQLIdentifier> fromList = _ctx->getFromList();
317                      PEGASUS_ASSERT(fromList.size() == 1);   // no joins yet
318                      prevContext = fromList[0].getName();
319                    }
320                    else
321                    {
322                      prevContext = ids[0].getName();
323                      startingPos = 1;
324                    }
325                    
326                    for (Uint32 pos = startingPos; pos < ids.size(); pos++)
327                    {
328                      CIMName classContext;
329                      if (ids[pos].isScoped())
330                      {
331                        classContext = lookupFromClass(ids[pos].getScope());
332                        if (classContext.getString() == String::EMPTY)
333 chuck    1.1.2.5       {
334                  	classContext = CIMName(ids[pos].getScope());
335                        }      
336                      }
337                      else
338                      {
339                        PEGASUS_ASSERT(pos == 1);
340                        classContext = prevContext;
341                      }
342                  
343                      CIMClass classDef = _ctx->getClass(classContext);
344                      if (classDef.findProperty(ids[pos].getName()) == PEG_NOT_FOUND)
345                      {
346                        throw Exception("TEMP MSG: prop not on scoped class");
347                      }
348                  
349                      if (!classContext.equal(prevContext))
350                      {
351                        if (!isSubClass(classContext, prevContext) &&
352                  	  !isSubClass(prevContext, classContext))
353                        {
354 chuck    1.1.2.5 	throw Exception("TEMP MSG: section 5.4.1 violation!");
355                        }
356                      }
357                  
358                      prevContext = classContext;
359                    }
360                  }
361                  
362                  CIMName CQLSelectStatementRep::lookupFromClass(const String&  lookup)
363                  {
364                    CQLIdentifier id = _ctx->findClass(lookup);
365                  
366                    return id.getName();
367 humberto 1.1.2.1 }
368                  
369 chuck    1.1.2.3 Array<CIMObjectPath> CQLSelectStatementRep::getClassPathList()
370 humberto 1.1.2.1 {
371 chuck    1.1.2.5   Array<CQLIdentifier> ids = _ctx->getFromList();
372                    PEGASUS_ASSERT(ids.size() == 1);  // no joins yet
373                  
374                    // No wbem-uri support yet.
375                    CIMObjectPath path(String::EMPTY, _ctx->getNamespace(), ids[0].getName());
376                  
377                    Array<CIMObjectPath> paths;
378                    paths.append(path);
379                  
380                    return paths;
381 humberto 1.1.2.1 }
382                  
383                  CIMPropertyList CQLSelectStatementRep::getPropertyList(const CIMObjectPath& inClassName)
384                  {
385 chuck    1.1.2.5   // assumes that applyContext had been called.
386                  
387                    // check if namespace matches default namespace?
388                    
389                    // No wbem-uri support yet
390                    CIMName className = inClassName.getClassName();
391                    CIMClass theClass = _ctx->getClass(className);
392                   
393                    Boolean isWildcard;
394                    Array<CIMName> reqProps;
395                    for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
396                    {
397                      isWildcard = addRequiredProperty(reqProps, theClass, _selectIdentifiers[i]);
398                      
399                      if (isWildcard)
400                      {
401                        return CIMPropertyList();
402                      }
403                    }
404                  
405                    for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
406 chuck    1.1.2.5   {
407                      isWildcard = addRequiredProperty(reqProps, theClass, _whereIdentifiers[i]);
408                  
409                      PEGASUS_ASSERT(!isWildcard);
410                    }
411                  
412                    Uint32 propCnt = theClass.getPropertyCount();
413                    Boolean allProps = true;
414                    for (Uint32 i = 0; i < propCnt; i++)
415                    {
416                      if (!containsProperty(theClass.getProperty(i).getName(), reqProps))
417                      {
418                        allProps = false;
419                        break;
420                      }
421                    }
422                  
423                    if (allProps)
424                    {
425                      return CIMPropertyList();
426                    }
427 chuck    1.1.2.5   else
428                    {
429                      return CIMPropertyList(reqProps);
430                    }
431                  }
432                  
433                  Boolean CQLSelectStatementRep::addRequiredProperty(Array<CIMName>& reqProps,
434                  						     CIMClass& theClass,
435                  						     CQLChainedIdentifier& chainId)
436                  {
437                    // Assumes that applyContext had been called
438                    // Does not look at properties on embedded objects
439                  
440                    Array<CQLIdentifier> ids = chainId.getSubIdentifiers();
441                  
442                    // see the description of CQLIdentifier::applyContext
443                  
444                    if (ids[0].isScoped())
445                    {
446                      PEGASUS_ASSERT(!ids[0].isWildcard());
447                  
448 chuck    1.1.2.5     // Check if the scoped property is exposed by the class passed in.
449                      if (theClass.findProperty(ids[0].getName()) != PEG_NOT_FOUND) 
450                      {
451                        CIMName scopingClass = lookupFromClass(ids[0].getScope());
452                        if (scopingClass.getString() == String::EMPTY)
453                        {
454                  	scopingClass = CIMName(ids[0].getScope());
455                        }    
456                  
457                        // Check if the scoping class is a subclass of the class passed in
458                        Boolean sub  = isSubClass(scopingClass, theClass.getClassName());
459                        
460                        // Add to the required properties only if the scoping class 
461                        // is not a subclass of the class passed in
462                        if (!sub)
463                        {
464                  	if (!containsProperty(ids[0].getName(), reqProps))
465                  	{  
466                  	  reqProps.append(ids[0].getName());
467                  	}
468                        }
469 chuck    1.1.2.5     }
470                    }
471                    else
472                    {
473                      if (ids[1].isWildcard())
474                      {
475                        return true;
476                      }
477                  
478                      if (theClass.findProperty(ids[1].getName()) != PEG_NOT_FOUND) 
479                      {
480                        if (!containsProperty(ids[1].getName(), reqProps))
481                        {  
482                  	reqProps.append(ids[1].getName());
483                        }
484                      }
485                    }
486                    
487                    return false;
488                  }
489                  
490 chuck    1.1.2.5 Boolean CQLSelectStatementRep::containsProperty(const CIMName& name,
491                  						const Array<CIMName>& props) 
492                  {
493                    for (Uint32 i = 0; i < props.size(); i++)
494                    {
495                      if (props[i] == name)
496                      {
497                        return true;
498                      }
499                    }
500                  
501                    return false;
502                  }
503                  
504                  Boolean CQLSelectStatementRep::isSubClass(const CIMName& derived,
505                  					  const CIMName& base)
506                  {
507                    Array<CIMName> subClasses = _ctx->enumerateClassNames(base);
508                    for (Uint32 i = 0; i < subClasses.size(); i++)
509                    {
510                      if (subClasses[i] == derived)
511 chuck    1.1.2.5     {
512                        return true;
513                      }	
514                    }
515                    
516                    return false;
517 humberto 1.1.2.1 }
518                  
519                  void CQLSelectStatementRep::appendClassPath(const CQLIdentifier& inIdentifier)
520                  {
521 chuck    1.1.2.3   _ctx->insertClassPath(inIdentifier);
522 humberto 1.1.2.1 }
523                  
524                  void CQLSelectStatementRep::setPredicate(CQLPredicate inPredicate)
525                  {
526 chuck    1.1.2.3   _predicate = inPredicate;
527 humberto 1.1.2.1 }
528                  
529                  void CQLSelectStatementRep::insertClassPathAlias(const CQLIdentifier& inIdentifier, String inAlias)
530                  {
531 chuck    1.1.2.3   _ctx->insertClassPath(inIdentifier,inAlias);
532 humberto 1.1.2.1 }
533                  
534                  void CQLSelectStatementRep::appendSelectIdentifier(const CQLChainedIdentifier& x)
535                  {
536 chuck    1.1.2.3   _selectIdentifiers.append(x);
537 humberto 1.1.2.1 }
538                  
539                  Boolean CQLSelectStatementRep::appendWhereIdentifier(const CQLChainedIdentifier& x)
540                  {
541 chuck    1.1.2.3   _whereIdentifiers.append(x);
542                    return true;
543 humberto 1.1.2.1 }
544                  
545 chuck    1.1.2.5 void CQLSelectStatementRep::applyContext()
546                  {
547                  //   ATTN - wait for applyContext API
548                    /*
549                    for (Uint32 i = 0; i < _selectIdentifiers.size(); i++)
550                    {
551                      _selectIdentifiers[i].applyContext(*_ctx);
552                    }
553                  
554                    for (Uint32 i = 0; i < _whereIdentifiers.size(); i++)
555                    {
556                      _whereIdentifiers[i].applyContext(*_ctx);
557                    }
558                  
559                    if (hasWhereClause())
560                      _predicate.applyContext(*_ctx);
561                    */
562                  }
563                  
564                  void CQLSelectStatementRep::normalizeToDOC()
565                  {
566 chuck    1.1.2.5 
567                  }
568                  
569                  String CQLSelectStatementRep::toString()
570                  {
571 chuck    1.1.2.4     printf("CQLSelectStatementRep::toString()\n");
572                  	String s("SELECT ");
573                  	for(Uint32 i = 0; i < _selectIdentifiers.size(); i++){
574                  		s.append(_selectIdentifiers[i].toString());
575                  	}	
576                  	s.append(" FROM ");
577                  	Array<CQLIdentifier> _ids = _ctx->getFromList();
578                  	for(Uint32 i = 0; i < _ids.size(); i++){
579                  		s.append(_ids[i].toString());
580                  	}
581                  	if(_hasWhereClause){
582                  		s.append(" WHERE ");
583                  		s.append(_predicate.toString());
584                  	}
585                  	return s;
586                  }
587                  
588 chuck    1.1.2.5 void CQLSelectStatementRep::setHasWhereClause()
589                  {
590 chuck    1.1.2.4         _hasWhereClause = true;
591                  }
592                  
593 chuck    1.1.2.5 Boolean CQLSelectStatementRep::hasWhereClause()
594                  {
595 chuck    1.1.2.4         return _hasWhereClause;
596                  }
597                  
598 chuck    1.1.2.5 void  CQLSelectStatementRep::clear()
599                  {
600 chuck    1.1.2.4 	_ctx->clear();
601                  }
602                  
603 humberto 1.1.2.1 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2