1 mike 1.1.2.1 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 mike 1.1.2.1 //==============================================================================
23 //
24 // Author: Mike Brasher (mbrasher@bmc.com)
25 //
26 // Modified By:
27 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
30 #include <iostream>
|
31 mike 1.1.2.4 #include <Pegasus/Common/Stack.h>
|
32 mike 1.1.2.1 #include "WQLSelectStatement.h"
33
34 PEGASUS_USING_STD;
35
36 PEGASUS_NAMESPACE_BEGIN
37
|
38 mike 1.1.2.4 template<class T>
39 inline static Boolean _Compare(const T& x, const T& y, WQLOperation op)
40 {
41 switch (op)
42 {
43 case WQL_EQ:
44 return x == y;
45
46 case WQL_NE:
47 return x != y;
48
49 case WQL_LT:
50 return x < y;
51 case WQL_LE:
52 return x <= y;
53
54 case WQL_GT:
55 return x > y;
56
57 case WQL_GE:
58 return x >= y;
59 mike 1.1.2.4
60 default:
61 PEGASUS_ASSERT(0);
62 }
63
64 return false;
65 }
66
67 static Boolean _Evaluate(
68 const WQLOperand& lhs,
69 const WQLOperand& rhs,
70 WQLOperation op)
71 {
72 switch (lhs.getType())
73 {
74 case WQLOperand::NULL_VALUE:
75 {
|
76 mike 1.1.2.6 // This cannot happen since expressions of the form
77 // OPERAND OPERATOR NULL are converted to unary form.
78 // For example: "count IS NULL" is treated as a unary
79 // operation in which IS_NULL is the unary operation
80 // and count is the the unary operand.
81
|
82 mike 1.1.2.4 PEGASUS_ASSERT(0);
83 break;
84 }
85
86 case WQLOperand::INTEGER_VALUE:
87 {
88 return _Compare(
|
89 mike 1.1.2.8 lhs.getIntegerValue(),
90 rhs.getIntegerValue(),
|
91 mike 1.1.2.4 op);
92 }
93
94 case WQLOperand::DOUBLE_VALUE:
95 {
96 return _Compare(
|
97 mike 1.1.2.8 lhs.getDoubleValue(),
98 rhs.getDoubleValue(),
|
99 mike 1.1.2.4 op);
100 }
101
102 case WQLOperand::BOOLEAN_VALUE:
103 {
104 return _Compare(
|
105 mike 1.1.2.8 lhs.getBooleanValue(),
106 rhs.getBooleanValue(),
|
107 mike 1.1.2.4 op);
108 }
109
110 case WQLOperand::STRING_VALUE:
111 {
112 return _Compare(
|
113 mike 1.1.2.8 lhs.getStringValue(),
114 rhs.getStringValue(),
|
115 mike 1.1.2.4 op);
116 }
117
118 default:
119 PEGASUS_ASSERT(0);
120 }
121
122 return false;
123 }
124
|
125 mike 1.1.2.1 WQLSelectStatement::WQLSelectStatement()
126 {
127 //
128 // Reserve space for a where clause with up to sixteen terms.
129 //
130
131 _operations.reserve(16);
132 _operands.reserve(16);
133 }
134
135 WQLSelectStatement::~WQLSelectStatement()
136 {
137
138 }
139
140 void WQLSelectStatement::clear()
141 {
142 _className.clear();
143 _propertyNames.clear();
144 _operations.clear();
145 _operands.clear();
146 mike 1.1.2.1 }
147
|
148 mike 1.1.2.8 static inline void _ResolveProperty(
149 WQLOperand& op,
150 const WQLPropertySource* source)
151 {
152 //
153 // Resolve the operand: if it's a property name, look up its value:
154 //
155
156 if (op.getType() == WQLOperand::PROPERTY_NAME)
157 {
158 const String& propertyName = op.getPropertyName();
159
160 if (!source->getValue(propertyName, op))
161 throw NoSuchProperty(propertyName);
162 }
163 }
164
|
165 mike 1.1.2.1 Boolean WQLSelectStatement::evaluateWhereClause(
|
166 mike 1.1.2.4 const WQLPropertySource* source) const
|
167 mike 1.1.2.1 {
|
168 mike 1.1.2.8 if (!hasWhereClause())
169 return true;
170
|
171 mike 1.1.2.4 WQLSelectStatement* that = (WQLSelectStatement*)this;
172 Stack<Boolean> stack;
173 stack.reserve(16);
174
175 //
176 // Counter for operands:
177 //
178
179 Uint32 j = 0;
180
181 //
182 // Process each of the operations:
183 //
184
185 for (Uint32 i = 0, n = _operations.size(); i < n; i++)
186 {
187 WQLOperation op = _operations[i];
188
189 switch (op)
190 {
191 case WQL_OR:
192 mike 1.1.2.4 {
193 PEGASUS_ASSERT(stack.size() >= 2);
194
195 Boolean op1 = stack.top();
196 stack.pop();
197
198 Boolean op2 = stack.top();
199
200 stack.top() = op1 || op2;
201 break;
202 }
203
204 case WQL_AND:
205 {
206 PEGASUS_ASSERT(stack.size() >= 2);
207
208 Boolean op1 = stack.top();
209 stack.pop();
210
211 Boolean op2 = stack.top();
212
213 mike 1.1.2.4 stack.top() = op1 && op2;
214 break;
215 }
216
217 case WQL_NOT:
218 {
219 PEGASUS_ASSERT(stack.size() >= 1);
220
221 Boolean op = stack.top();
222 stack.top() = !op;
223 break;
224 }
225
226 case WQL_EQ:
227 case WQL_NE:
228 case WQL_LT:
229 case WQL_LE:
230 case WQL_GT:
231 case WQL_GE:
232 {
233 PEGASUS_ASSERT(_operands.size() >= 2);
234 mike 1.1.2.4
235 //
236 // Resolve the left-hand-side to a value (if not already
237 // a value).
238 //
239
240 WQLOperand& lhs = that->_operands[j++];
|
241 mike 1.1.2.8 _ResolveProperty(lhs, source);
|
242 mike 1.1.2.4
243 //
244 // Resolve the right-hand-side to a value (if not already
245 // a value).
246 //
247
248 WQLOperand& rhs = that->_operands[j++];
|
249 mike 1.1.2.8 _ResolveProperty(rhs, source);
|
250 mike 1.1.2.4
251 //
252 // Check for a type mismatch:
253 //
254
255 // PEGASUS_OUT(lhs.toString());
256 // PEGASUS_OUT(rhs.toString());
257
258 if (rhs.getType() != lhs.getType())
259 throw TypeMismatch();
260
261 //
262 // Now that the types are known to be alike, apply the
263 // operation:
264 //
265
266 stack.push(_Evaluate(lhs, rhs, op));
267 break;
268 }
269
270 case WQL_IS_TRUE:
|
271 mike 1.1.2.6 case WQL_IS_NOT_FALSE:
272 {
273 PEGASUS_ASSERT(stack.size() >= 1);
274 break;
275 }
276
|
277 mike 1.1.2.4 case WQL_IS_FALSE:
278 case WQL_IS_NOT_TRUE:
|
279 mike 1.1.2.6 {
280 PEGASUS_ASSERT(stack.size() >= 1);
281 stack.top() = !stack.top();
|
282 mike 1.1.2.4 break;
|
283 mike 1.1.2.6 }
284
285 case WQL_IS_NULL:
286 {
|
287 mike 1.1.2.8 PEGASUS_ASSERT(_operands.size() >= 1);
288 WQLOperand& op = that->_operands[j++];
289 _ResolveProperty(op, source);
290 stack.push(op.getType() == WQLOperand::NULL_VALUE);
|
291 mike 1.1.2.6 break;
292 }
293
294 case WQL_IS_NOT_NULL:
295 {
|
296 mike 1.1.2.8 PEGASUS_ASSERT(_operands.size() >= 1);
297 WQLOperand& op = that->_operands[j++];
298 _ResolveProperty(op, source);
299 stack.push(op.getType() != WQLOperand::NULL_VALUE);
|
300 mike 1.1.2.6 break;
301 }
|
302 mike 1.1.2.4 }
303 }
304
305 PEGASUS_ASSERT(stack.size() == 1);
306 return stack.top();
|
307 mike 1.1.2.1 }
308
309 void WQLSelectStatement::print() const
310 {
311 //
312 // Print the header:
313 //
314
315 cout << "WQLSelectStatement" << endl;
316 cout << "{" << endl;
317
318 //
319 // Print the class name:
320 //
321
322 cout << " _className: \"" << _className << '"' << endl;
323
324 //
325 // Print the property:
326 //
327
328 mike 1.1.2.1 for (Uint32 i = 0; i < _propertyNames.size(); i++)
329 {
|
330 mike 1.1.2.2 if (i == 0)
331 cout << endl;
332
|
333 mike 1.1.2.1 cout << " _propertyNames[" << i << "]: ";
334 cout << '"' << _propertyNames[i] << '"' << endl;
335 }
336
337 //
338 // Print the operations:
339 //
340
341 for (Uint32 i = 0; i < _operations.size(); i++)
342 {
|
343 mike 1.1.2.2 if (i == 0)
344 cout << endl;
345
|
346 mike 1.1.2.1 cout << " _operations[" << i << "]: ";
347 cout << '"' << WQLOperationToString(_operations[i]) << '"' << endl;
348 }
349
350 //
351 // Print the operands:
352 //
353
354 for (Uint32 i = 0; i < _operands.size(); i++)
355 {
|
356 mike 1.1.2.2 if (i == 0)
357 cout << endl;
358
359 cout << " _operands[" << i << "]: ";
|
360 mike 1.1.2.1 cout << '"' << _operands[i].toString() << '"' << endl;
361 }
362
363 //
364 // Print the trailer:
365 //
366
367 cout << "}" << endl;
368 }
369
370 PEGASUS_NAMESPACE_END
|