(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                   CQLIdentifier& CQLChainedIdentifierRep::operator[](Uint32 index){
 96                   	return _subIdentifiers[index];
 97                   }
 98                   
 99 humberto 1.1.2.3  CQLChainedIdentifierRep& CQLChainedIdentifierRep::operator=(const CQLChainedIdentifierRep& rhs){
100                   	if(&rhs != this){
101                   		_subIdentifiers = rhs._subIdentifiers;
102                   	}
103                   	return *this;
104                   }
105                   
106 humberto 1.1.2.12 Uint32 CQLChainedIdentifierRep::size()const{
107 humberto 1.1.2.1  	return _subIdentifiers.size();
108                   }
109                   
110 humberto 1.1.2.12 Boolean CQLChainedIdentifierRep::prepend(const CQLIdentifier & id){
111 humberto 1.1.2.1  	/*
112                   	   Compare id against the first element in _subIdentifiers, 
113                   	   if not an exact match, then prepend.  This is used to fully
114                   	   qualify the chained identifier.
115                   	*/
116                   	if(id != _subIdentifiers[0]){
117                   		_subIdentifiers.prepend(id);
118                   		return true;
119                   	}
120                   	return false;
121                   }
122                   
123 chuck    1.1.2.4  void CQLChainedIdentifierRep::applyContext(QueryContext& inContext)
124                   {
125 chuck    1.1.2.9    if (_subIdentifiers.size() == 0)
126                       return;
127                   
128 chuck    1.1.2.11   // Chained identifiers that are standalone symbolic constants 
129                     // should have had the context applied already.  If this method
130                     // is called and this is still a standalone symbolic constant,
131                     // then that is an error.
132                     if (_subIdentifiers.size() == 1 &&
133                         _subIdentifiers[0].getName().getString().size() == 0 &&
134                         _subIdentifiers[0].isSymbolicConstant())
135                     {
136                       throw Exception("TEMP MSG: CQLChainedIdentifierRep::applyContext - standalone symb const");
137                     }
138                   
139 chuck    1.1.2.5    CQLIdentifier firstId = _subIdentifiers[0];
140                     
141 chuck    1.1.2.13   // Process if the first identifier has some contents.
142                     if ((firstId.getName().getString().size() != 0) || firstId.isWildcard()) 
143 chuck    1.1.2.5    {
144                       Array<CQLIdentifier> fromList = inContext.getFromList();
145                   
146                       if (firstId.isWildcard())
147                       {
148 chuck    1.1.2.13       // Single element chain that is wildcarded.
149                         // Prepend the FROM class.
150 chuck    1.1.2.5        _subIdentifiers.prepend(fromList[0]);
151                       }  
152                       else
153                       {
154 chuck    1.1.2.13       // Not a single element wildcard.
155 chuck    1.1.2.10       if (firstId.isScoped())
156 chuck    1.1.2.5        {
157 chuck    1.1.2.13         // The first identifier is a scoped property or a 
158                           // scoped symbolic constant.
159                           // Prepend the FROM class.
160                           // Example: SELECT * FROM F WHERE someprop = X::p#'OK'
161 chuck    1.1.2.5  	_subIdentifiers.prepend(fromList[0]);
162                         }
163                         else
164 chuck    1.1.2.10       {
165 chuck    1.1.2.13         // The first identifier is not a scoped property or a scoped
166                           // symbolic constant.
167                   
168                           // Determine if the first identifier's name is in the FROM list.
169 chuck    1.1.2.10 	String classContext = firstId.getName().getString();
170                   	CQLIdentifier matchedId = inContext.findClass(classContext);
171 chuck    1.1.2.13 	if (matchedId.getName().getString().size() != 0)
172 chuck    1.1.2.5  	{
173 chuck    1.1.2.10 	  // Could not find the firstId in the FROM list.
174 chuck    1.1.2.13 	  // Assume the firstId is a property on the FROM class,
175                             // and prepend the FROM class, except in the case described below.
176                             //
177                             // NOTE:
178                             // We need special handling for symbolic constants, because there are cases
179                             // where the first id is a class that is not the FROM class.
180                             // Refer to section 5.4.3 of the CQL spec.
181                             //
182                             // Examples:
183                             // SELECT * FROM F WHERE F.someprop = ClassNotInFromList.prop#'OK'
184                             // We don't want to prepend the FROM class to ClassNotInFromList 
185                             // in this case.
186                             //
187                             // SELECT * FROM F WHERE F.someprop = embeddedObject.X::p#'OK'
188                             // Even though embeddedObject may an property on F, and not
189                             // a classname, we still don't need to prepend F because the
190                             // scoping class X will be used to get the value of 'OK' on property
191                             // p.
192                             //
193                             // SELECT * FROM F WHERE F.someprop = propOnClassF#'OK'
194                             // We want to prepend in this case.  The identifier propOnClassF
195 chuck    1.1.2.13           // is assumed to be a property on the FROM class, not a classname
196                             // itself.
197                             //
198                             // Note that standalone symbolic constants, like #'OK'
199                             // are errors in this code.
200                             // See above for details.
201                             //
202 chuck    1.1.2.10 	  if (_subIdentifiers.size() == 1 ||
203                   	      !_subIdentifiers[_subIdentifiers.size()-1].isSymbolicConstant())
204                   	  {
205                   	    _subIdentifiers.prepend(fromList[0]);
206                   	  }
207                   	}
208                   	else
209                   	{	
210                   	  // The firstId was found in the FROM list, but it could have been 
211                   	  // an alias
212                   	  if (!matchedId.getName().equal(firstId.getName()))
213                   	  {
214                   	    // It was an alias.
215                   	    // Replace the alias with the FROM class
216                   	    _subIdentifiers[0] = matchedId;
217                   	  }
218                   	  else 
219                   	  {
220                   	    // It was not an alias. Do nothing.
221                   	    ;
222                   	  }
223 chuck    1.1.2.5  	}
224                         }
225                       }
226                     }
227 chuck    1.1.2.10   
228 chuck    1.1.2.13   // Go through and replace any aliases on scoping classes
229 chuck    1.1.2.10   for (Uint32 i = 0; i < _subIdentifiers.size(); i++)
230                     {
231                       if (_subIdentifiers[i].isScoped())
232                       {
233                         CQLIdentifier match = inContext.findClass(_subIdentifiers[i].getScope());
234 chuck    1.1.2.13       if (match.getName().getString().size() != 0)
235 chuck    1.1.2.10       {
236 chuck    1.1.2.13         // The scoping class was either the FROM class, or an alias of the
237                           // FROM class.  Replace the scoping class with the FROM class.
238 chuck    1.1.2.10 	_subIdentifiers[i].applyScope(match.getName().getString());
239                         }
240                       }
241                     }
242 humberto 1.1.2.1  }
243                   
244                   void CQLChainedIdentifierRep::parse(String & string){
245                   	/* 
246                   	  - parse string on "."
247                   	  - start from the end of string
248                   	  - if more than one substring found, 
249                   		-- store first found string then
250                   		-- prepend remaining substrings 
251                   	*/
252                   	Char16 delim('.');
253                   	Uint32 index;
254                   	String range;
255                   
256                   	/* remove any array ranges so we dont parse a false . */
257                   	if((index = string.find("[")) != PEG_NOT_FOUND){
258                   		range = string.subString(index);
259                   		string.remove(index);
260                   	}
261                   
262                   	index = string.reverseFind(delim);
263 humberto 1.1.2.1  	if(index == PEG_NOT_FOUND){
264                   		/* append the range we may have removed */
265                   		string.append(range);
266                   		_subIdentifiers.append(CQLIdentifier(string));
267                   	}else{
268                   		/* append the range we may have removed */
269                   		String tmp = string.subString(index+1);
270                   		tmp.append(range);
271                   		PEGASUS_STD(cout) << "tmp = " << tmp << PEGASUS_STD(endl);
272                   		_subIdentifiers.append(CQLIdentifier(tmp));
273                   
274                   		while(index != PEG_NOT_FOUND){
275                   			tmp = string.subString(0,index);
276                   			index = tmp.reverseFind(delim);
277                   			if(index == PEG_NOT_FOUND){
278                   				_subIdentifiers.prepend(CQLIdentifier(tmp));
279                   			}
280                   			else{
281                   				_subIdentifiers.prepend(CQLIdentifier(tmp.subString(index+1)));
282                   			}
283                   		}
284 humberto 1.1.2.1  	}
285                   }
286                   
287                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2