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

  1 chuck 1.1.2.7 //%2003////////////////////////////////////////////////////////////////////////
  2 chuck 1.1.2.6 //
  3               // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
  4               // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
  5 chuck 1.1.2.8 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
  6 chuck 1.1.2.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               // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 23               //
 24               //==============================================================================
 25               //
 26               // Authors: David Rosckes (rosckes@us.ibm.com)
 27 chuck 1.1.2.6 //          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 "CQLChainedIdentifier.h"
 36                  #include "CQLChainedIdentifierRep.h"
 37 humberto 1.1.2.2 #include <Pegasus/CQL/CQLFactory.h>
 38 humberto 1.1.2.1 PEGASUS_NAMESPACE_BEGIN
 39                  
 40 humberto 1.1.2.3 CQLChainedIdentifierRep::CQLChainedIdentifierRep(){
 41                  }
 42                  
 43 humberto 1.1.2.1 CQLChainedIdentifierRep::CQLChainedIdentifierRep(String inString)
 44                  {
 45                  	parse(inString);
 46                  }
 47                  
 48 humberto 1.1.2.12 CQLChainedIdentifierRep::CQLChainedIdentifierRep(const CQLIdentifier &id)
 49 humberto 1.1.2.1  {
 50                           _subIdentifiers.append(id);
 51                   }
 52                   
 53 humberto 1.1.2.3  CQLChainedIdentifierRep::CQLChainedIdentifierRep(const CQLChainedIdentifierRep* rep){
 54                   	_subIdentifiers = rep->_subIdentifiers;
 55                   }
 56                   
 57                   CQLChainedIdentifierRep::~CQLChainedIdentifierRep(){
 58                   	
 59 humberto 1.1.2.1  }
 60                   
 61                   const Array<CQLIdentifier>& CQLChainedIdentifierRep::getSubIdentifiers()const
 62                   {
 63                   	return _subIdentifiers;
 64                   }
 65                   
 66 humberto 1.1.2.12 CQLIdentifier CQLChainedIdentifierRep::getLastIdentifier()const{
 67 humberto 1.1.2.1  	if(_subIdentifiers.size() > 0)
 68                   		return _subIdentifiers[_subIdentifiers.size()-1];
 69                   	return CQLIdentifier();
 70                   }
 71                   
 72                   String CQLChainedIdentifierRep::toString()const{
 73                   	String s;
 74                   	for(Uint32 i = 0; i < _subIdentifiers.size(); i++){
 75                   		s.append(_subIdentifiers[i].toString());
 76                   		if(i < _subIdentifiers.size() - 1)
 77                   			s.append(".");
 78                   	}
 79                   	return s;
 80                   }
 81                   
 82 humberto 1.1.2.12 void CQLChainedIdentifierRep::append(const CQLIdentifier & id){
 83 humberto 1.1.2.1  	_subIdentifiers.append(id);
 84                   }
 85                   
 86 humberto 1.1.2.12 Boolean CQLChainedIdentifierRep::isSubChain(const CQLChainedIdentifier & chain)const{
 87 humberto 1.1.2.1  	Array<CQLIdentifier> ids = chain.getSubIdentifiers();
 88                   	for(Uint32 i = 0; i < ids.size(); i++){
 89                   		if(ids[i] != _subIdentifiers[i].getName())
 90                   			return false;
 91                   	}
 92                   	return true;
 93                   }
 94                   
 95 david    1.1.2.15 CQLIdentifier CQLChainedIdentifierRep::operator[](Uint32 index)const
 96                   {
 97                   	return CQLIdentifier(_subIdentifiers[index]);
 98 humberto 1.1.2.1  }
 99                   
100 humberto 1.1.2.3  CQLChainedIdentifierRep& CQLChainedIdentifierRep::operator=(const CQLChainedIdentifierRep& rhs){
101                   	if(&rhs != this){
102                   		_subIdentifiers = rhs._subIdentifiers;
103                   	}
104                   	return *this;
105                   }
106                   
107 humberto 1.1.2.12 Uint32 CQLChainedIdentifierRep::size()const{
108 humberto 1.1.2.1  	return _subIdentifiers.size();
109                   }
110                   
111 humberto 1.1.2.12 Boolean CQLChainedIdentifierRep::prepend(const CQLIdentifier & id){
112 humberto 1.1.2.1  	/*
113                   	   Compare id against the first element in _subIdentifiers, 
114                   	   if not an exact match, then prepend.  This is used to fully
115                   	   qualify the chained identifier.
116                   	*/
117                   	if(id != _subIdentifiers[0]){
118                   		_subIdentifiers.prepend(id);
119                   		return true;
120                   	}
121                   	return false;
122                   }
123                   
124 chuck    1.1.2.4  void CQLChainedIdentifierRep::applyContext(QueryContext& inContext)
125                   {
126 chuck    1.1.2.9    if (_subIdentifiers.size() == 0)
127                       return;
128                   
129 chuck    1.1.2.11   // Chained identifiers that are standalone symbolic constants 
130                     // should have had the context applied already.  If this method
131                     // is called and this is still a standalone symbolic constant,
132                     // then that is an error.
133                     if (_subIdentifiers.size() == 1 &&
134                         _subIdentifiers[0].getName().getString().size() == 0 &&
135                         _subIdentifiers[0].isSymbolicConstant())
136                     {
137                       throw Exception("TEMP MSG: CQLChainedIdentifierRep::applyContext - standalone symb const");
138                     }
139                   
140 chuck    1.1.2.5    CQLIdentifier firstId = _subIdentifiers[0];
141                     
142 chuck    1.1.2.13   // Process if the first identifier has some contents.
143                     if ((firstId.getName().getString().size() != 0) || firstId.isWildcard()) 
144 chuck    1.1.2.5    {
145                       Array<CQLIdentifier> fromList = inContext.getFromList();
146                   
147                       if (firstId.isWildcard())
148                       {
149 chuck    1.1.2.13       // Single element chain that is wildcarded.
150                         // Prepend the FROM class.
151 chuck    1.1.2.5        _subIdentifiers.prepend(fromList[0]);
152                       }  
153                       else
154                       {
155 chuck    1.1.2.13       // Not a single element wildcard.
156 chuck    1.1.2.10       if (firstId.isScoped())
157 chuck    1.1.2.5        {
158 chuck    1.1.2.13         // The first identifier is a scoped property or a 
159                           // scoped symbolic constant.
160                           // Prepend the FROM class.
161                           // Example: SELECT * FROM F WHERE someprop = X::p#'OK'
162 chuck    1.1.2.5  	_subIdentifiers.prepend(fromList[0]);
163                         }
164                         else
165 chuck    1.1.2.10       {
166 chuck    1.1.2.13         // The first identifier is not a scoped property or a scoped
167                           // symbolic constant.
168                   
169                           // Determine if the first identifier's name is in the FROM list.
170 chuck    1.1.2.10 	String classContext = firstId.getName().getString();
171                   	CQLIdentifier matchedId = inContext.findClass(classContext);
172 chuck    1.1.2.14 	if (matchedId.getName().getString().size() == 0)
173 chuck    1.1.2.5  	{
174 chuck    1.1.2.10 	  // Could not find the firstId in the FROM list.
175 chuck    1.1.2.13 	  // Assume the firstId is a property on the FROM class,
176                             // and prepend the FROM class, except in the case described below.
177                             //
178                             // NOTE:
179                             // We need special handling for symbolic constants, because there are cases
180                             // where the first id is a class that is not the FROM class.
181                             // Refer to section 5.4.3 of the CQL spec.
182                             //
183                             // Examples:
184                             // SELECT * FROM F WHERE F.someprop = ClassNotInFromList.prop#'OK'
185                             // We don't want to prepend the FROM class to ClassNotInFromList 
186                             // in this case.
187                             //
188                             // SELECT * FROM F WHERE F.someprop = embeddedObject.X::p#'OK'
189                             // Even though embeddedObject may an property on F, and not
190                             // a classname, we still don't need to prepend F because the
191                             // scoping class X will be used to get the value of 'OK' on property
192                             // p.
193                             //
194                             // SELECT * FROM F WHERE F.someprop = propOnClassF#'OK'
195                             // We want to prepend in this case.  The identifier propOnClassF
196 chuck    1.1.2.13           // is assumed to be a property on the FROM class, not a classname
197                             // itself.
198                             //
199                             // Note that standalone symbolic constants, like #'OK'
200                             // are errors in this code.
201                             // See above for details.
202                             //
203 chuck    1.1.2.10 	  if (_subIdentifiers.size() == 1 ||
204                   	      !_subIdentifiers[_subIdentifiers.size()-1].isSymbolicConstant())
205                   	  {
206                   	    _subIdentifiers.prepend(fromList[0]);
207                   	  }
208                   	}
209                   	else
210                   	{	
211                   	  // The firstId was found in the FROM list, but it could have been 
212                   	  // an alias
213                   	  if (!matchedId.getName().equal(firstId.getName()))
214                   	  {
215                   	    // It was an alias.
216                   	    // Replace the alias with the FROM class
217                   	    _subIdentifiers[0] = matchedId;
218                   	  }
219                   	  else 
220                   	  {
221                   	    // It was not an alias. Do nothing.
222                   	    ;
223                   	  }
224 chuck    1.1.2.5  	}
225                         }
226                       }
227                     }
228 chuck    1.1.2.10   
229 chuck    1.1.2.13   // Go through and replace any aliases on scoping classes
230 chuck    1.1.2.10   for (Uint32 i = 0; i < _subIdentifiers.size(); i++)
231                     {
232                       if (_subIdentifiers[i].isScoped())
233                       {
234                         CQLIdentifier match = inContext.findClass(_subIdentifiers[i].getScope());
235 chuck    1.1.2.13       if (match.getName().getString().size() != 0)
236 chuck    1.1.2.10       {
237 chuck    1.1.2.13         // The scoping class was either the FROM class, or an alias of the
238                           // FROM class.  Replace the scoping class with the FROM class.
239 chuck    1.1.2.10 	_subIdentifiers[i].applyScope(match.getName().getString());
240                         }
241                       }
242                     }
243 humberto 1.1.2.1  }
244                   
245                   void CQLChainedIdentifierRep::parse(String & string){
246                   	/* 
247                   	  - parse string on "."
248                   	  - start from the end of string
249                   	  - if more than one substring found, 
250                   		-- store first found string then
251                   		-- prepend remaining substrings 
252                   	*/
253                   	Char16 delim('.');
254                   	Uint32 index;
255                   	String range;
256                   
257                   	/* remove any array ranges so we dont parse a false . */
258                   	if((index = string.find("[")) != PEG_NOT_FOUND){
259                   		range = string.subString(index);
260                   		string.remove(index);
261                   	}
262                   
263                   	index = string.reverseFind(delim);
264 humberto 1.1.2.1  	if(index == PEG_NOT_FOUND){
265                   		/* append the range we may have removed */
266                   		string.append(range);
267                   		_subIdentifiers.append(CQLIdentifier(string));
268                   	}else{
269                   		/* append the range we may have removed */
270                   		String tmp = string.subString(index+1);
271                   		tmp.append(range);
272                   		PEGASUS_STD(cout) << "tmp = " << tmp << PEGASUS_STD(endl);
273                   		_subIdentifiers.append(CQLIdentifier(tmp));
274                   
275                   		while(index != PEG_NOT_FOUND){
276                   			tmp = string.subString(0,index);
277                   			index = tmp.reverseFind(delim);
278                   			if(index == PEG_NOT_FOUND){
279                   				_subIdentifiers.prepend(CQLIdentifier(tmp));
280                   			}
281                   			else{
282                   				_subIdentifiers.prepend(CQLIdentifier(tmp.subString(index+1)));
283                   			}
284                   		}
285 humberto 1.1.2.1  	}
286                   }
287                   
288                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2