Changeset 108:866354af13b9 in livinglogic.python.orasql

Show
Ignore:
Timestamp:
05/09/06 15:33:38 (13 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Add positional arguments to Proc and LLProc().

Enhanced error messages for procedure calling.

Files:
2 modified

Legend:

Unmodified
Added
Removed
  • NEWS.xml

    r106 r108  
    77<item><class>LLProc</class> now recognizes the <lit>c_out</lit> 
    88parameter used by <module>ll.toxic</module> 0.8.</item> 
     9<item>Support for positional arguments has been added for <class>Proc</class> 
     10and <class>LLProc</class>. Error messages for calling procedures 
     11have been enhanced.</item> 
    912</ulist> 
    1013</section> 
  • orasql.py

    r107 r108  
    8282 
    8383 
     84_default = object() # marker object for unset parameters 
     85 
     86 
    8487class Proc: 
    8588    """ 
     
    9598    } 
    9699     
    97     def __init__(self, name): 
     100    def __init__(self, name, encoding=None): 
    98101        """ 
    99102        Create a <class>Proc</class> object. <arg>name</arg> is the name of the 
     
    102105        self.name = name 
    103106        self._realargs = None 
     107        self.encoding = encoding 
    104108 
    105109    def __repr__(self): 
    106         return "Proc(%r)" % self.name 
     110        if self.encoding is None: 
     111            return "Proc(%r)" % self.name 
     112        else: 
     113            return "Proc(%r, %r)" % (self.name, self.encoding) 
    107114 
    108115    def _calcrealargs(self, cursor): 
     
    114121                self._realargs[0][record.name] = (i, record.datatype, "in" in record.in_out, "out" in record.in_out) 
    115122 
    116     def __call__(self, cursor, **kwargs): 
    117         """ 
    118         Call the procedure with keyword arguments <arg>kwargs</arg>. <arg>cursor</arg> 
    119         must be a <module>cx_Oracle</module> cursor. This will return a 
    120         <pyref class="Record"><class>Record</class></pyref> object containing the result 
    121         of the call. 
     123    def __call__(self, cursor, *args, **kwargs): 
     124        """ 
     125        Call the procedure with arguments <arg>args</arg> and keyword arguments 
     126        <arg>kwargs</arg>. <arg>cursor</arg> must be a <module>cx_Oracle</module> 
     127        cursor. This will return a <pyref class="Record"><class>Record</class></pyref> 
     128        object containing the result of the call. 
    122129        """ 
    123130        self._calcrealargs(cursor) 
    124         realargs = [None]*len(self._realargs[1]) 
     131 
     132        # Get preinitialized parameter array 
     133        la = len(args) 
     134        lra = len(self._realargs[1]) 
     135        if la > lra: 
     136            raise TypeError("too many parameters for %s: %d given, %d expected" % (self.name, la, lra)) 
     137        realargs = list(args) + [_default]*(lra-la) 
     138 
     139        # Put keyword arguments into the parameter array 
    125140        for (key, value) in kwargs.iteritems(): 
    126             (pos, datatype, isin, isout) = self._realargs[0][key.lower()] 
    127             if isinstance(value, unicode): 
    128                 value = value.encode("iso-8859-1") 
     141            try: 
     142                (pos, datatype, isin, isout) = self._realargs[0][key.lower()] 
     143            except KeyError: 
     144                raise TypeError("unknown parameter for %s: %s" % (self.name, key)) 
     145            else: 
     146                if realargs[pos] is not _default: 
     147                    raise TypeError("duplicate argument for %s: %s" % (self.name, key)) 
     148            if isinstance(value, unicode) and self.encoding is not None: 
     149                value = value.encode(self.encoding) 
    129150            realargs[pos] = value 
    130151 
    131152        # Replace out parameters (and strings that are longer than the allowed 
    132         # maximum) with variables 
     153        # maximum) with variables; replace inspecified parameters with None 
    133154        for (pos, (name, datatype, isin, isout)) in enumerate(self._realargs[1]): 
    134155            realarg = realargs[pos] 
     156            if realarg is _default: 
     157                realarg = None 
    135158            if isout or (isinstance(realarg, str) and len(realarg) >= 32768): 
    136159                var = cursor.var(self._ora2cx[datatype]) 
     
    145168 
    146169class LLProc(Proc): 
    147     def __call__(self, cursor, **kwargs): 
    148         args = {} 
     170    def __call__(self, cursor, *args, **kwargs): 
     171        realkwargs = {} 
    149172        for (key, value) in kwargs.iteritems(): 
    150173            if key == "user": 
     
    154177            else: 
    155178                key = "p_%s" % key 
    156             args[key] = value 
     179            realkwargs[key] = value 
    157180 
    158181        result = Record() 
    159         for (key, value) in Proc.__call__(self, cursor, **args).iteritems(): 
     182        for (key, value) in Proc.__call__(self, cursor, *args, **realkwargs).iteritems(): 
    160183            if key == "c_user": 
    161184                key = "user" 
     
    165188                key = key[2:] 
    166189            else: 
    167                 raise ValueError("unknown parameter name %r in result" % key) 
     190                raise TypeError("unknown parameter name %r in result" % key) 
    168191            result[key] = value 
    169192        return result