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
|