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)
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
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
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