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.10 if ((firstId.getName().getString() != String::EMPTY) || firstId.isWildcard())
|
142 chuck 1.1.2.5 {
143 Array<CQLIdentifier> fromList = inContext.getFromList();
144
145 if (firstId.isWildcard())
146 {
147 // Example: SELECT * FROM F AS A
148 _subIdentifiers.prepend(fromList[0]);
149 }
150 else
151 {
|
152 chuck 1.1.2.10 if (firstId.isScoped())
|
153 chuck 1.1.2.5 {
154 _subIdentifiers.prepend(fromList[0]);
155 }
156 else
|
157 chuck 1.1.2.10 {
158 String classContext = firstId.getName().getString();
159 CQLIdentifier matchedId = inContext.findClass(classContext);
160
161 if (firstId.isScoped() || (matchedId.getName().getString() == String::EMPTY))
|
162 chuck 1.1.2.5 {
|
163 chuck 1.1.2.10 // Could not find the firstId in the FROM list.
164 // Assume the firstId is a property, so prepend the FROM class.
|
165 chuck 1.1.2.5 // Examples:
|
166 chuck 1.1.2.10 // SELECT p FROM F AS A
167 // SELECT p.p1 FROM F AS A (illegal, but caught elsewhere)
168 // SELECT p.* FROM F AS A
169 // SELECT * FROM F AS A WHERE p ISA B
170 if (_subIdentifiers.size() == 1 ||
171 !_subIdentifiers[_subIdentifiers.size()-1].isSymbolicConstant())
172 {
173 _subIdentifiers.prepend(fromList[0]);
174 }
175 }
176 else
177 {
178 // The firstId was found in the FROM list, but it could have been
179 // an alias
180 if (!matchedId.getName().equal(firstId.getName()))
181 {
182 // It was an alias.
183 // Replace the alias with the FROM class
184 // Examples:
185 // SELECT A.p FROM F AS A
186 // SELECT A FROM F AS A (illegal, but caught elsewhere)
187 chuck 1.1.2.10 // SELECT A.* FROM F AS A
188 // SELECT * FROM F AS A WHERE A ISA B
189 // SELECT * FROM F AS A WHERE A.p ISA B
190 _subIdentifiers[0] = matchedId;
191 }
192 else
193 {
194 // It was not an alias. Do nothing.
195 // Examples:
196 // SELECT F.p FROM F AS A
197 // SELECT F FROM F AS A (illegal, but caught elsewhere)
198 // SELECT F.* FROM F AS A
199 // SELECT * FROM F AS A WHERE F ISA B
200 // SELECT * FROM F AS A WHERE F.p ISA B
201 ;
202 }
|
203 chuck 1.1.2.5 }
204 }
205 }
206 }
|
207 chuck 1.1.2.10
208 // Go through an replaces the aliases on scoping classes
209 for (Uint32 i = 0; i < _subIdentifiers.size(); i++)
210 {
211 if (_subIdentifiers[i].isScoped())
212 {
213 CQLIdentifier match = inContext.findClass(_subIdentifiers[i].getScope());
214 if (match.getName().getString() != String::EMPTY)
215 {
216 _subIdentifiers[i].applyScope(match.getName().getString());
217 }
218 }
219 }
|
220 humberto 1.1.2.1 }
221
222 void CQLChainedIdentifierRep::parse(String & string){
223 /*
224 - parse string on "."
225 - start from the end of string
226 - if more than one substring found,
227 -- store first found string then
228 -- prepend remaining substrings
229 */
230 Char16 delim('.');
231 Uint32 index;
232 String range;
233
234 /* remove any array ranges so we dont parse a false . */
235 if((index = string.find("[")) != PEG_NOT_FOUND){
236 range = string.subString(index);
237 string.remove(index);
238 }
239
240 index = string.reverseFind(delim);
241 humberto 1.1.2.1 if(index == PEG_NOT_FOUND){
242 /* append the range we may have removed */
243 string.append(range);
244 _subIdentifiers.append(CQLIdentifier(string));
245 }else{
246 /* append the range we may have removed */
247 String tmp = string.subString(index+1);
248 tmp.append(range);
249 PEGASUS_STD(cout) << "tmp = " << tmp << PEGASUS_STD(endl);
250 _subIdentifiers.append(CQLIdentifier(tmp));
251
252 while(index != PEG_NOT_FOUND){
253 tmp = string.subString(0,index);
254 index = tmp.reverseFind(delim);
255 if(index == PEG_NOT_FOUND){
256 _subIdentifiers.prepend(CQLIdentifier(tmp));
257 }
258 else{
259 _subIdentifiers.prepend(CQLIdentifier(tmp.subString(index+1)));
260 }
261 }
262 humberto 1.1.2.1 }
263 }
264
265 PEGASUS_NAMESPACE_END
|