# -*- coding: iso-8859-1 -*-
#-----------------------------------------------------------------------------
# Modeling Framework: an Object-Relational Bridge for python
#
# Copyright (c) 2001-2004 Sbastien Bigaret <sbigaret@users.sourceforge.net>
# All rights reserved.
#
# This file is part of the Modeling Framework.
#
# This code is distributed under a "3-clause BSD"-style license;
# see the LICENSE file for details.
#-----------------------------------------------------------------------------
"""
Qualifier
CVS Information
$Id: Qualifier.py 932 2004-07-20 06:21:57Z sbigaret $
"""
__version__='$Revision: 932 $'[11:-2]
from interfaces.Qualifier import QualifierInterface
from string import find,strip
import re
single=re.compile('\?')
multi=re.compile('\*')
def __likeExprToRegexpString__(value):
"""
Converts the 'like' expression into a real regexp. Basically, character '?'
is translated to '.', and '*' to '.*'
"""
value=single.sub('.', value)
value=multi.sub('.*', value)
return value
# Predefined Operators
def QualifierOperatorEqual(value1, value2):
return value1 == value2 # Q: est-ce bien suffisant??
def QualifierOperatorNotEqual(value1, value2):
return value1 != value2
def QualifierOperatorGreaterThan(value1, value2):
return value1>value2
def QualifierOperatorLessThan(value1, value2):
return value1<value2
def QualifierOperatorGreaterThanOrEqualTo(value1, value2):
return value1>=value2
def QualifierOperatorLessThanOrEqualTo(value1, value2):
return value1<=value2
def QualifierOperatorContains(value1, value2):
return find(value1, value2)!=-1
def QualifierOperatorLike(value1, value2):
return re.match(__likeExprToRegexpString__(value2), str(value1))
def QualifierOperatorCaseInsensitiveLike(value1, value2):
return re.match(__likeExprToRegexpString__(value2),str(value1),re.IGNORECASE)
def QualifierOperatorIn(value1, value2):
if type(value2)==type(''):
value2=eval(value2)
return value1 in value2
def QualifierOperatorNotIn(value1, value2):
return not QualifierOperatorIn(value1, value2)
# Module
def allQualifierOperators():
return ('==', '!=', '<', '<=', '>', '>=', 'like', 'caseInsensitiveLike', 'ilike', 'in', 'not_in')
def filteredArrayWithQualifier(objects, qualifier):
result=[]
for object in objects:
if qualifier.evaluateWithObject(object):
result.append(object)
return result
def operatorForString(aString):
op=strip(aString)
if op in ('=', '=='): return QualifierOperatorEqual
if op == '!=': return QualifierOperatorNotEqual
if op == '<': return QualifierOperatorLessThan
if op == '<=': return QualifierOperatorLessThanOrEqualTo
if op == '>': return QualifierOperatorGreaterThan
if op == '>=': return QualifierOperatorGreaterThanOrEqualTo
if op == 'like': return QualifierOperatorLike
if op == 'in': return QualifierOperatorIn
if op == 'not_in': return QualifierOperatorNotIn
if op in ('caseInsensitiveLike', 'ilike'):
return QualifierOperatorCaseInsensitiveLike
raise ValueError, aString
def qualifierToMatchAllValues(aDictionary):
qualifiers=[]
for key in aDictionary.keys():
qualifiers.append(KeyValueQualifier(key, QualifierOperatorEqual,
aDictionary[key]))
return AndQualifier(qualifiers)
def qualifierToMatchAnyValues(aDictionary):
qualifiers=[]
for key in aDictionary.keys():
qualifiers.append(KeyValueQualifier(key, QualifierOperatorEqual,
aDictionary[key]))
return OrQualifier(qualifiers)
def qualifierWithQualifierFormat(expression): #, arguments
import QualifierParser
return QualifierParser.qualifierWithQualifierFormat(expression)
def relationalQualifierOperators():
return ('==', '!=', '<', '<=', '>', '>=')
def stringForQualifierOperator(operator):
if operator == QualifierOperatorEqual: return '=='
if operator == QualifierOperatorNotEqual: return '!='
if operator == QualifierOperatorLessThan: return '<'
if operator == QualifierOperatorLessThanOrEqualTo: return '<='
if operator == QualifierOperatorGreaterThan: return '>'
if operator == QualifierOperatorGreaterThanOrEqualTo: return '>='
if operator == QualifierOperatorLike: return 'like'
if operator == QualifierOperatorCaseInsensitiveLike: return 'caseInsensitiveLike'
if operator == QualifierOperatorIn: return 'in'
if operator == QualifierOperatorNotIn: return 'not_in'
raise ValueError
class Qualifier:
__implements__ = (QualifierInterface,)
def __init__(self):
raise 'Abstract class'
def addQualifierKeysToSet(self, qualifierKeysList): # must be overridden
raise 'Unimplemented', 'Should be overriden'
def allQualifierKeys(self):
qualifierKeysList=[]
self.addQualifierKeysToSet(qualifierKeysList)
_dict = {}
for key in qualifierKeysList:
_dict[key] = 0
return tuple(_dict.keys())
def bindingKeys(self):
raise 'Unimplemented'
def evaluateWithObject(self, object): # object implements KeyValueCoding
raise 'Unimplemented'
def keyPathForBindingKey(self, aKey):
raise 'Unimplemented'
def validateKeysWithRootClassDescription(self, aClassDescription): # abstract
from string import split
keys=self.allQualifierKeys()
allCDkeys=aClassDescription.allAttributesKeys()+\
aClassDescription.allToOneRelationshipKeys()+\
aClassDescription.allToManyRelationshipKeys()
for key in keys:
key=split(key, '.')[0] ## the first element in keyPath
if key not in allCDkeys:
raise ValueError, 'Qualifier does not match class description for entity name %s'%aClassDescription.entityName()
return None
#### KeyComparisonQualifier
class KeyComparisonQualifier(Qualifier):
"""
"""
__implements__ = (QualifierInterface,)
def __init__(self, leftKey, operator, rightKey):
"-"
self._leftKey=leftKey
self._operator=operator
self._rightKey=rightKey
def addQualifierKeysToSet(self, qualifierKeys): # must be overridden
qualifierKeys.append(self.leftKey())
def bindingKeys(self):
raise 'Unimplemented'
def evaluateWithObject(self, object): # object implements KeyValueCoding
return self._operator(object.valueForKeyPath(self._leftKey),
object.valueForKeyPath(self._rightKey))
def leftKey(self):
return self._leftKey
def keyPathForBindingKey(self, aKey):
if aKey==self.value():
return self.key()
def operator(self):
return self._operator
def qualifierWithBindings(self, dict, requiresAll): # abstract
raise 'Unimplemented'
def rightKey(self):
return self._rightKey
def __str__(self):
res='('
res+=self._leftKey+stringForQualifierOperator(self._operator)+self._rightKey
res+=')'
return res
#### KeyValueQualifier
class KeyValueQualifier(Qualifier):
__implements__ = (QualifierInterface,)
def __init__(self, key, operator, value):
self._key=key
self._operator=operator
self._value=value
def addQualifierKeysToSet(self, qualifierKeys): # must be overridden
qualifierKeys.append(self.key())
#def allQualifierKeys(self):
# raise 'Unimplemented'
def bindingKeys(self):
raise 'Unimplemented'
def evaluateWithObject(self, object): # object implements KeyValueCoding
return self._operator(object.valueForKeyPath(self._key), self._value)
def key(self):
return self._key
def keyPathForBindingKey(self, aKey):
if aKey==self.value():
return self.key()
def qualifierWithBindings(self, dict, requiresAll): # abstract
raise 'Unimplemented'
def operator(self):
return self._operator
def value(self):
return self._value
def __str__(self):
res='('
res+=self._key+stringForQualifierOperator(self._operator) +str(self._value)
res+=')'
return res
#
#### NotQualifier
class NotQualifier(Qualifier):
"""
"""
__implements__ = (QualifierInterface,)
def __init__(self, aQualifier):
self._qualifier=aQualifier
def addQualifierKeysToSet(self, qualifierKeys):
self._qualifier.addQualifierKeysToSet(qualifierKeys)
def bindingKeys(self):
return self._qualifier.bindingKeys()
def evaluateWithObject(self, object): # object implements KeyValueCoding
return not self._qualifier.evaluateWithObject(object)
def keyPathForBindingKey(self, aKey):
return self._qualifier.keyPathForBindingKey(aKey)
def qualifierWithBindings(self, dict, requiresAll):
return self._qualifier.qualifierWithBindings(dict, requiresAll)
def qualifier(self):
return self._qualifier
def __str__(self):
res='('
res+='NOT '+str(self._qualifier)
res+=')'
return res
#
#### AndQualifier
class AndQualifier(Qualifier):
"""
"""
__implements__ = (QualifierInterface,)
def __init__(self, qualifiers):
self._qualifiers=qualifiers
def addQualifierKeysToSet(self, qualifierKeys):
for qualifier in self._qualifiers:
qualifier.addQualifierKeysToSet(qualifierKeys)
#def allQualifierKeys(self):
# raise 'Unimplemented'
def bindingKeys(self):
bindingKeys=[]
for qualifier in self._qualifiers:
bindingKeys.append(qualifier.bindingKeys())
def evaluateWithObject(self, object): # object implements KeyValueCoding
for qualifier in self._qualifiers:
if not qualifier.evaluateWithObject(object):
return 0
return 1
def keyPathForBindingKey(self, aKey):
raise "Unimplemented"
def qualifierWithBindings(self, dict, requiresAll):
raise 'Unimplemented'
def qualifiers(self):
return self._qualifiers
def __str__(self):
res='('
for qualifier in self._qualifiers:
res+=str(qualifier)+ ' AND '
res=res[:-5]+')'
return res
#
#### OrQualifier
class OrQualifier(Qualifier):
"""
"""
__implements__ = (QualifierInterface,)
def __init__(self, qualifiers):
self._qualifiers=qualifiers
def addQualifierKeysToSet(self, qualifierKeys):
for qualifier in self._qualifiers:
qualifier.addQualifierKeysToSet(qualifierKeys)
#def allQualifierKeys(self):
# raise 'Unimplemented'
def bindingKeys(self):
bindingKeys=[]
for qualifier in self._qualifiers:
bindingKeys.append(qualifier.bindingKeys())
def evaluateWithObject(self, object): # object implements KeyValueCoding
for qualifier in self._qualifiers:
if qualifier.evaluateWithObject(object):
return 1
return 0
def keyPathForBindingKey(self, aKey):
raise "Unimplemented"
def qualifierWithBindings(self, dict, requiresAll):
raise 'Unimplemented'
def qualifiers(self):
return self._qualifiers
def __str__(self):
res='('
for qualifier in self._qualifiers:
res+=str(qualifier)+ ' OR '
res=res[:-5]+')'
return res
#### utils
def isQuoted(aString):
"Tells whether the string is surroundered by simple quotes"
return len(aString)>2 and \
strip(aString)[0]=="'" and strip(aString)[-1:]=="'"
# Misc. notes
#par=re.compile('(\(.*\))')
#par.findall("(truc =='truc') or ( machin=chose AND (bidule=chouette OR glop!=pasglop) )")
#>>> ["(truc =='truc')", '(bidule=chouette OR glop!=pasglop)']
|