[Zope-Checkins] CVS: Products/DCOracle2/DCOracle2 - DCOracle2.py:1.86

Matthew T. Kromer matt@zope.com
Fri, 10 May 2002 11:42:27 -0400


Update of /cvs-repository/Products/DCOracle2/DCOracle2
In directory cvs.zope.org:/tmp/cvs-serv6699/DCOracle2

Modified Files:
	DCOracle2.py 
Log Message:
Change default arg handling re collector 48


=== Products/DCOracle2/DCOracle2/DCOracle2.py 1.85 => 1.86 ===
         if type == "argument" or type == "column":
             if type == "argument":
+                hasdef = int(desc['OCI_ATTR_HAS_DEFAULT'])
                 mode = desc['OCI_ATTR_IOMODE']
-                if mode == 0: inout = ("IN",) 
+                if mode == 0:
+                    if hasdef:
+                        inout = ("IN","DEFAULT") 
+                    else:
+                        inout = ("IN",) 
                 elif mode == 1: inout = ("OUT",)
-                else: inout = ("IN","OUT")
+                else:
+                    if hasdef:
+                        inout = ("IN","OUT","DEFAULT")
+                    else:
+                        inout = ("IN","OUT")
             else: inout = ()
 
             size = desc.get('OCI_ATTR_DATA_SIZE',0)
@@ -601,9 +610,11 @@
         if type == "argument" or type == "column":
             if type == "argument":
                 mode = desc['OCI_ATTR_IOMODE']
+                hasdef = int(desc['OCI_ATTR_HAS_DEFAULT'])
                 if mode == 0: inout = "IN" 
                 elif mode == 1: inout = "OUT"
                 else: inout = "IN OUT"
+                if hasdef: inout = inout + " DEFAULT"
 
             precision = desc['OCI_ATTR_PRECISION']
             scale = desc['OCI_ATTR_SCALE']
@@ -1204,12 +1215,15 @@
         argmap = []
         argconvert = []
         arglist = []
+
+        procdesc = self._description[3]
         
         if self._description[2] == "function":
-            fcn = ":1 := "
+            fcn = ":1 := "          # fcn is base statement being built up
             base = 1
-            argmap.append([None, self._description[3][0][3][5],
-                          self._description[3][0][3]])
+            # Add to the argument map the [Name, type, description])
+            argmap.append([None, procdesc[0][3][5],
+                          procdesc[0][3]])
             argconvert.append(None)
         else:
             fcn = ""
@@ -1228,6 +1242,7 @@
 
         keymap = {}
 
+        # Keymap is an upper-cased version of our keyword dictionary
         for k in kw.keys():
             ku = upper(k)
             keymap[ku] = kw[k]
@@ -1237,37 +1252,55 @@
         # drawing them from the keyword arguments (by name) or from the
         # argument list (by position)  
 
-        # The argmap is a list of the actual arguments, the arglist is
-        # a list of the NAMES of the arguments
+        # The argmap is a list of the actual arguments, in the form
+        # [value, mode, description]
+
+        # The arglist is a list of the NAMES of the arguments
 
         #print "procedure %s" % self.__name__
 
-        for i in range(base,len(self._description[3])):
-            d = self._description[3][i]
-            v = d[1]
+        defaults = 0
+
+        # Iterate through each argument in the proc definition
+        for i in range(base,len(procdesc)):
+            d = procdesc[i]     # d is the description string for arg i
+            thisargName = d[1]  # v is the parameter name for arg i 
             # Now, if this is an IN parameter?
             #print d
-            mode = d[3][5]
+            thisargDesc = d[3]  # The description for this argument
+            mode = thisargDesc[5] # mode is the mode (IN/OUT/DEFAULT)
 
             if 'IN' in mode:
-                if keymap.has_key(v):
-                    argmap.append([keymap[v], mode, d[3]])
-                    #print "Binding argument %s= %s" % (v, keymap[v])
+                if keymap.has_key(thisargName):
+                    argmap.append([keymap[thisargName], mode, thisargDesc])
+                    #print "Binding argument %s= %s" % (thisargName, keymap[thisargName])
                 else:
                     if len(args) <= argsused:
+                        if 'DEFAULT' in mode:
+                            defaults = defaults + 1
+                            continue
                         raise ValueError, "Not enough arguments"
-                    argmap.append([args[argsused], mode, d[3]])
-                    #print "Binding argument %s= %s" % (v, args[argsused])
+                    if 'DEFAULT' in mode and args[argsused] is None:
+                            defaults = defaults + 1
+                            continue
+                    argmap.append([args[argsused], mode, thisargDesc])
+                    #print "Binding argument %s= %s" % (thisargName, args[argsused])
                     argsused = argsused + 1
             # Otherwise, it's an OUT parameter, and we pass in NULL for those
             else: 
-                argmap.append([None, mode, d[3]])
+                argmap.append([None, mode, thisargDesc])
 
             argconvert.append(None)
-            arglist.append(str(i+1))
+
+            thisargindex = str(i + 1 - defaults)
+
+            if defaults:
+                arglist.append("%s => :%s" % (thisargName, thisargindex))
+            else:
+                arglist.append(":%s" % thisargindex) 
 
         if len(arglist) > 0:
-            alist = ":%s" % join(arglist,',:')
+            alist = ','.join(arglist)
         else:
             alist = ""
 
@@ -1277,11 +1310,18 @@
         #print argmap
 
         for i in xrange(0, len(argmap)):
-            a = argmap[i]
+            a = argmap[i]   # The argument map for this argument
+
+            thisargValue = a[0]
+            thisargMode = a[1]
+            thisargDesc = a[2]
+
             # doesn't properly handle IN OUT
-            if 'OUT' in a[1] and type(a[0]) is not dco2.BindingArrayObjectType:
+            if ('OUT' in thisargMode and type(thisargValue) is
+                not dco2.BindingArrayObjectType):
+
                 # BindingArrays are made with count, size, type
-                l = a[2][2]
+                l = thisargDesc[2]      # Length
                 if cursor is not None:
                     try:
                         l = cursor._sizes[i]
@@ -1291,7 +1331,7 @@
                 if l == 0: 
                     l = DEFAULTPROCSIZE
 
-                dty = a[2][0]
+                dty = thisargDesc[0]    # data type
                 count = 1
 
                 # Based on the data type, we may need to do some special
@@ -1299,7 +1339,7 @@
 
                 if dty == 251: # PL/SQL Table of 
                     # go find out what the table is really of
-                    tabof = a[2][6][3]
+                    tabof = thisargDesc[6][3] # secondary description
                     dty = tabof[0]
                     l = tabof[1]
                     if len(cursor._sizes) > i:
@@ -1310,7 +1350,8 @@
                 if dty == 102:  # SQLT_CUR
                     dty = 'SQLT_RSET'
                     l = 4   # Was 38 ?  harumph
-                elif dty == 2 and 'IN' not in a[1]:  # SQLT_NUM but not IN OUT
+                elif dty == 2 and 'IN' not in thisargMode: 
+                    # SQLT_NUM but not IN OUT
                     dty = 'SQLT_STR'
                     argconvert[i] = 2
 
@@ -1321,7 +1362,7 @@
 
                 # I'm not going to worry about arrays of cursors going in
                 if dty == 'SQLT_RSET':  
-                    if not 'IN' in a[1]:
+                    if not 'IN' in thisargMode:
                         ba[0] = TypeCoercion(
                             cursor._connection.cursor(), dty)
                     else:
@@ -1329,7 +1370,7 @@
                             # It probably wasnt a cursor going in -- make one
                             olda = cursor._connection.cursor()
                         ba[0] = TypeCoercion(olda, dty)
-                elif 'IN' in a[1]:    # This is an in/out parameter
+                elif 'IN' in thisargMode:    # This is an in/out parameter
                     ba[0] = olda      # FIXME doesnt do the array case
                     ba = self._argconvertIn(ba, argconvert, i)
                     a[0] = ba         # Resave new arg