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

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.3 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 mike  1.2 // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.3 // 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 mike  1.2 // 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 kumpf 1.3 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.2 // 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 kumpf 1.3 // 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 mike  1.2 // 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           //==============================================================================
 23           //
 24           // Author: Mike Brasher (mbrasher@bmc.com)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           #include <iostream>
 31           #include <Pegasus/Common/Stack.h>
 32           #include "WQLSelectStatement.h"
 33           
 34           PEGASUS_USING_STD;
 35           
 36           PEGASUS_NAMESPACE_BEGIN
 37           
 38           template<class T>
 39           inline static Boolean _Compare(const T& x, const T& y, WQLOperation op)
 40 mike  1.2 {
 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           
 60           	default:
 61 mike  1.2 	    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           	    // 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.2 	    PEGASUS_ASSERT(0);
 83           	    break;
 84           	}
 85           
 86           	case WQLOperand::INTEGER_VALUE:
 87           	{
 88           	    return _Compare(
 89           		lhs.getIntegerValue(),
 90           		rhs.getIntegerValue(),
 91           		op);
 92           	}
 93           
 94           	case WQLOperand::DOUBLE_VALUE:
 95           	{
 96           	    return _Compare(
 97           		lhs.getDoubleValue(),
 98           		rhs.getDoubleValue(),
 99           		op);
100           	}
101           
102           	case WQLOperand::BOOLEAN_VALUE:
103 mike  1.2 	{
104           	    return _Compare(
105           		lhs.getBooleanValue(),
106           		rhs.getBooleanValue(),
107           		op);
108           	}
109           
110           	case WQLOperand::STRING_VALUE:
111           	{
112           	    return _Compare(
113           		lhs.getStringValue(),
114           		rhs.getStringValue(),
115           		op);
116           	}
117           
118           	default:
119           	    PEGASUS_ASSERT(0);
120               }
121           
122               return false;
123           }
124 mike  1.2 
125           WQLSelectStatement::WQLSelectStatement()
126           {
127               //
128               // Reserve space for a where clause with up to sixteen terms.
129               //
130           
131 kumpf 1.4     _operations.reserveCapacity(16);
132               _operands.reserveCapacity(16);
133 mike  1.2 }
134           
135           WQLSelectStatement::~WQLSelectStatement()
136           {
137           
138           }
139           
140           void WQLSelectStatement::clear()
141           {
142               _className.clear();
143               _selectPropertyNames.clear();
144               _operations.clear();
145               _operands.clear();
146           }
147           
148           Boolean WQLSelectStatement::appendWherePropertyName(const String& x)
149           {
150               //
151               // Reject duplicate property names by returning false.
152               //
153           
154 mike  1.2     for (Uint32 i = 0, n = _wherePropertyNames.size(); i < n; i++)
155               {
156           	if (_wherePropertyNames[i] == x)
157           	    return false;
158               }
159           
160               //
161               // Append the new property.
162               //
163           
164               _wherePropertyNames.append(x);
165               return true;
166           }
167           
168           static inline void _ResolveProperty(
169               WQLOperand& op,
170               const WQLPropertySource* source)
171           {
172               //
173               // Resolve the operand: if it's a property name, look up its value:
174               //
175 mike  1.2 
176               if (op.getType() == WQLOperand::PROPERTY_NAME)
177               {
178           	const String& propertyName = op.getPropertyName();
179           
180           	if (!source->getValue(propertyName, op))
181           	    throw NoSuchProperty(propertyName);
182               }
183           }
184           
185           Boolean WQLSelectStatement::evaluateWhereClause(
186               const WQLPropertySource* source) const
187           {
188               if (!hasWhereClause())
189           	return true;
190           
191               WQLSelectStatement* that = (WQLSelectStatement*)this;
192               Stack<Boolean> stack;
193 kumpf 1.4     stack.reserveCapacity(16);
194 mike  1.2 
195               // 
196               // Counter for operands:
197               //
198           
199               Uint32 j = 0;
200           
201               //
202               // Process each of the operations:
203               //
204           
205               for (Uint32 i = 0, n = _operations.size(); i < n; i++)
206               {
207           	WQLOperation op = _operations[i];
208           
209           	switch (op)
210           	{
211           	    case WQL_OR:
212           	    {
213           		PEGASUS_ASSERT(stack.size() >= 2);
214           
215 mike  1.2 		Boolean op1 = stack.top();
216           		stack.pop();
217           
218           		Boolean op2 = stack.top();
219           
220           		stack.top() = op1 || op2;
221           		break;
222           	    }
223           
224           	    case WQL_AND:
225           	    {
226           		PEGASUS_ASSERT(stack.size() >= 2);
227           
228           		Boolean op1 = stack.top();
229           		stack.pop();
230           
231           		Boolean op2 = stack.top();
232           
233           		stack.top() = op1 && op2;
234           		break;
235           	    }
236 mike  1.2 
237           	    case WQL_NOT:
238           	    {
239           		PEGASUS_ASSERT(stack.size() >= 1);
240           
241           		Boolean op = stack.top();
242           		stack.top() = !op;
243           		break;
244           	    }
245           
246           	    case WQL_EQ:
247           	    case WQL_NE:
248           	    case WQL_LT:
249           	    case WQL_LE:
250           	    case WQL_GT:
251           	    case WQL_GE:
252           	    {
253           		PEGASUS_ASSERT(_operands.size() >= 2);
254           
255           		//
256           		// Resolve the left-hand-side to a value (if not already
257 mike  1.2 		// a value).
258           		//
259           
260           		WQLOperand& lhs = that->_operands[j++];
261           		_ResolveProperty(lhs, source);
262           
263           		//
264           		// Resolve the right-hand-side to a value (if not already
265           		// a value).
266           		//
267           
268           		WQLOperand& rhs = that->_operands[j++];
269           		_ResolveProperty(rhs, source);
270           
271           		//
272           		// Check for a type mismatch:
273           		//
274           
275           		// PEGASUS_OUT(lhs.toString());
276           		// PEGASUS_OUT(rhs.toString());
277           
278 mike  1.2 		if (rhs.getType() != lhs.getType())
279           		    throw TypeMismatch();
280           
281           		//
282           		// Now that the types are known to be alike, apply the
283           		// operation:
284           		//
285           
286           		stack.push(_Evaluate(lhs, rhs, op));
287           		break;
288           	    }
289           
290           	    case WQL_IS_TRUE:
291           	    case WQL_IS_NOT_FALSE:
292           	    {
293           		PEGASUS_ASSERT(stack.size() >= 1);
294           		break;
295           	    }
296           
297           	    case WQL_IS_FALSE:
298           	    case WQL_IS_NOT_TRUE:
299 mike  1.2 	    {
300           		PEGASUS_ASSERT(stack.size() >= 1);
301           		stack.top() = !stack.top();
302           		break;
303           	    }
304           
305           	    case WQL_IS_NULL:
306           	    {
307           		PEGASUS_ASSERT(_operands.size() >= 1);
308           		WQLOperand& op = that->_operands[j++];
309           		_ResolveProperty(op, source);
310           		stack.push(op.getType() == WQLOperand::NULL_VALUE);
311           		break;
312           	    }
313           
314           	    case WQL_IS_NOT_NULL:
315           	    {
316           		PEGASUS_ASSERT(_operands.size() >= 1);
317           		WQLOperand& op = that->_operands[j++];
318           		_ResolveProperty(op, source);
319           		stack.push(op.getType() != WQLOperand::NULL_VALUE);
320 mike  1.2 		break;
321           	    }
322           	}
323               }
324           
325               PEGASUS_ASSERT(stack.size() == 1);
326               return stack.top();
327           }
328           
329           void WQLSelectStatement::print() const
330           {
331               //
332               // Print the header:
333               //
334               
335               cout << "WQLSelectStatement" << endl;
336               cout << "{" << endl;
337           
338               //
339               // Print the class name:
340               //
341 mike  1.2 
342               cout << "    _className: \"" << _className << '"' << endl;
343           
344               // 
345               // Print the property:
346               //
347           
348               for (Uint32 i = 0; i < _selectPropertyNames.size(); i++)
349               {
350           	if (i == 0)
351           	    cout << endl;
352           
353           	cout << "    _selectPropertyNames[" << i << "]: ";
354           	cout << '"' << _selectPropertyNames[i] << '"' << endl;
355               }
356           
357               //
358               // Print the operations:
359               //
360           
361               for (Uint32 i = 0; i < _operations.size(); i++)
362 mike  1.2     {
363           	if (i == 0)
364           	    cout << endl;
365           
366           	cout << "    _operations[" << i << "]: ";
367           	cout << '"' << WQLOperationToString(_operations[i]) << '"' << endl;
368               }
369           
370               //
371               // Print the operands:
372               //
373           
374               for (Uint32 i = 0; i < _operands.size(); i++)
375               {
376           	if (i == 0)
377           	    cout << endl;
378           
379           	cout << "    _operands[" << i << "]: ";
380           	cout << '"' << _operands[i].toString() << '"' << endl;
381               }
382           
383 mike  1.2     //
384               // Print the trailer:
385               //
386           
387               cout << "}" << endl;
388           }
389           
390           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2