예제 #1
0
    def getMany(self, *args, **kwargs):
        if isinstance(kls, basestring):
            # resolve it to a class
            realkls = string_to_obj(kls)
        else:
            realkls = kls
        eq = [EQ(FIELD(x), self[y]) for x, y in zipped]
        if args and isinstance(args[0], basestring):
            # combining a string requires awkward special casing...
            conn = self.getDBI()
            converter = conn.getConverter()
            sql, values = self._processWhere(conn, eq, {}, converter=converter)
            converter.reset()
            extrasql, extravalues = self._processWhere(conn,
                                                       args,
                                                       kwargs,
                                                       converter=converter)
            # merge sql strings
            sql = ' AND '.join((sql, extrasql))
            # merge values
            if isinstance(values, dict):
                if not isinstance(extravalues, dict):
                    raise ValueError, "expected dictionary of bind variables!"
                values.update(extravalues)
                newargs = (sql, values)
            else:
                values = tuple(values) + tuple(extravalues)
                newargs = (sql, ) + values
            del converter
            return realkls.getSome(*newargs)

        else:
            return realkls.getSome(*(tuple(eq) + args), **kwargs)
예제 #2
0
    def _processWhere(conn, args, fieldData, converter=None):
        if args and isinstance(args[0], basestring):
            if fieldData:
                raise ValueError, "cannot pass keyword args when including sql string"
            sql = args[0]
            values = args[1:]

            if len(values) == 1 and isinstance(values[0], dict):
                values = values[0]
        else:
            # N.B. -- we don't call _validateFields here, as we permit
            # fields expressed as keyword arguments that aren't
            # declared in the class/projection.
            andValues = list(args)
            for k, v in fieldData.items():
                if v is None or v == NULL:
                    andValues.append(IS(FIELD(k), NULL))
                else:
                    andValues.append(EQ(FIELD(k), v))
            andlen = len(andValues)
            if converter is None:
                converter = conn.getConverter()
            if andlen == 0:
                sql = ''
            elif andlen == 1:
                andValues[0].setConverter(converter)
                sql = repr(andValues[0])
            else:
                sql = repr(AND(converter=converter, *andValues))
            values = converter.values
        return sql, values
예제 #3
0
 def _uniqueWhere(cls, conn, kw, converter=None):
     """given a connection and kw, using _matchUnique, generate a
     where clause to select a unique row.
     """
     unique = cls._matchUnique(kw)
     if not unique:
         raise ValueError, 'No way to get unique row! %s %s' % \
               (str(kw), unique)
     if converter is None:
         converter = conn.getConverter()
     if len(unique) == 1:
         u = tuple(unique)[0]
         sql = str(EQ(FIELD(u), kw[u], converter=converter))
     else:
         sql = str(
             AND(converter=converter,
                 *[EQ(FIELD(u), kw[u]) for u in unique]))
     return sql, converter.values
예제 #4
0
 def _processWhere(conn, args, fieldData, converter=None):
     if args and isinstance(args[0], basestring):
         if fieldData:
             raise ValueError, "cannot pass keyword args when including sql string"
         sql = args[0]
         values = args[1:]
         if len(values) == 1 and isinstance(values[0], dict):
             values = values[0]
         # the converter may conceivably contain values as well;
         # merging them in this case is not foolproof, but can be done
         # is some cases.
         if converter:
             origVals = converter.values
             if origVals:
                 if isinstance(values, dict):
                     if isinstance(origVals, dict):
                         origVals.update(values)
                         values = origVals
                     else:
                         # two different bind formats are being used, that's a no-no.
                         raise ValueError, "incompatible bind variable format"
                 else:
                     if isinstance(origVals, dict):
                         raise ValueError, "incompatible bind variable format"
                     assert isinstance(origVals, (list, tuple))
                     values = list(origVals) + list(values)
     else:
         # N.B. -- we don't call _validateFields here, as we permit
         # fields expressed as keyword arguments that aren't
         # declared in the class/projection.
         andValues = list(args)
         for k, v in fieldData.items():
             if v is None or v == NULL:
                 andValues.append(IS(FIELD(k), NULL))
             else:
                 andValues.append(EQ(FIELD(k), v))
         andlen = len(andValues)
         if converter is None:
             converter = conn.getConverter()
         if andlen == 0:
             sql = ''
         elif andlen == 1:
             andValues[0].setConverter(converter)
             sql = repr(andValues[0])
         else:
             sql = repr(AND(converter=converter, *andValues))
         values = converter.values
     return sql, values