Пример #1
0
    def _joinTableSQL(self,
                      conn,
                      thisAttrNames,
                      pivotTable,
                      thisSideColumns,
                      thatSideColumns,
                      thatObject,
                      thatAttrNames,
                      extraTables,
                      wheresql,
                      wherevals,
                      order,
                      limit,
                      offset):
        """SQL generating function for joinTable"""
        if extraTables is None:
            extraTables=[]

        thisAttrNames = _tupleize(thisAttrNames)
        thisSideColumns = _tupleize(thisSideColumns)
        thatSideColumns = _tupleize(thatSideColumns)
        thatAttrNames = _tupleize(thatAttrNames)
        
        if len(thisSideColumns) != len(thisAttrNames):
            raise ValueError, ('thisSideColumns and thisAttrNames must '
                               'contain the same number of elements')
        if len(thatSideColumns) != len(thatAttrNames):
            raise ValueError, ('thatSideColumns and thatAttrNames must '
                               'contain the same number of elements')
        
        sql=[thatObject._baseSelect(True),
             ', ',
             ', '.join([pivotTable]+extraTables),
             ' WHERE ']
        
        joins = []
        converter=conn.getConverter()
        for attr, col in zip(thisAttrNames, thisSideColumns):
            lit=converter(self[attr])
            joins.append("%s.%s = %s" % (pivotTable, col, lit))
        vals=converter.values
        joins.extend(['%s.%s = %s.%s' % (pivotTable,
                                         col,
                                         thatObject.getTable(),
                                         attr) \
                      for attr, col in zip(thatAttrNames,
                                           thatSideColumns)])
        sql.append(' AND '.join(joins))
        if wheresql:
            sql.append(' AND (%s)' % wheresql)
            if wherevals:
                vals=vals+wherevals
        if filter(None, (order, limit, offset)):
            sql.append(conn.orderByString(order, limit, offset))                
        return ''.join(sql), vals
Пример #2
0
    def joinTable(self,
                  thisAttrNames,
                  pivotTable,
                  thisSideColumns,
                  thatSideColumns,
                  thatObject,
                  thatAttrNames,
                  *whereArgs,
                  **extra):

        """Handles many to many relations.  In short, do:
        
        SELECT thatObject.getColumns(1)
        FROM thatObject.table, pivotTable
        WHERE pivotTable.thisSideColumn = self.myAttrName
        AND pivotTable.thatSideColumn = thatObject.table.thatAttrName
        
        and return a list of thatObjects representing the resulting
        rows.  The parameters which accept column names
        (thisAttrNames, thisSideColumns, thatSideColumns,
        thatAttrNames) can be strings (silently turned to tuples of
        length 1) or tuples of strings.  For each pair P of the two
        pairs (thisSideColumns, thisAttrNames) and (thatSideColumns,
        thatAttrNames) len(P[0]) must equal len(P[1]).

        In addition, you can add extra tables and arbitrary sql to the
        where clause, as you can with getSome(), including order,
        limit and offset, using the "extraTables", "order", "limit"
        and "offset" keyword arguments, using SQLOperators or
        (sql-string, bind values) as positional arguments, and by
        specifying columns by keyword argument.
        
        """
        extraTables=extra.pop('extraTables', None)
        if extraTables:
            extraTables=list(_tupleize(extraTables))
        order=extra.pop('order', None)
        limit=extra.pop('limit', None)
        offset=extra.pop('offset', None)
        conn=self.getDBI()
        wheresql, wherevals=self._processWhere(conn, whereArgs, extra)
        sql, vals = self._joinTableSQL(conn,
                                       thisAttrNames,
                                       pivotTable,
                                       thisSideColumns,
                                       thatSideColumns,
                                       thatObject,
                                       thatAttrNames,
                                       extraTables,
                                       wheresql,
                                       wherevals,
                                       order,
                                       limit,
                                       offset)
        results = conn.execute(sql, vals)
        if results:
            return map(thatObject, results)
        return []
Пример #3
0
    def _joinTableSQL(self, conn, thisAttrNames, pivotTable, thisSideColumns,
                      thatSideColumns, thatObject, thatAttrNames, extraTables,
                      wheresql, wherevals, order, limit, offset):
        """SQL generating function for joinTable"""
        if extraTables is None:
            extraTables = []

        thisAttrNames = _tupleize(thisAttrNames)
        thisSideColumns = _tupleize(thisSideColumns)
        thatSideColumns = _tupleize(thatSideColumns)
        thatAttrNames = _tupleize(thatAttrNames)

        if len(thisSideColumns) != len(thisAttrNames):
            raise ValueError, ('thisSideColumns and thisAttrNames must '
                               'contain the same number of elements')
        if len(thatSideColumns) != len(thatAttrNames):
            raise ValueError, ('thatSideColumns and thatAttrNames must '
                               'contain the same number of elements')

        sql = [
            thatObject._baseSelect(True), ', ',
            ', '.join([pivotTable] + extraTables), ' WHERE '
        ]

        joins = []
        converter = conn.getConverter()
        for attr, col in zip(thisAttrNames, thisSideColumns):
            lit = converter(self[attr])
            joins.append("%s.%s = %s" % (pivotTable, col, lit))
        vals = converter.values
        joins.extend(['%s.%s = %s.%s' % (pivotTable,
                                         col,
                                         thatObject.getTable(),
                                         attr) \
                      for attr, col in zip(thatAttrNames,
                                           thatSideColumns)])
        sql.append(' AND '.join(joins))
        if wheresql:
            sql.append(' AND (%s)' % wheresql)
            if wherevals:
                vals = vals + wherevals
        if filter(None, (order, limit, offset)):
            sql.append(conn.orderByString(order, limit, offset))
        return ''.join(sql), vals
Пример #4
0
    def joinTable(self, thisAttrNames, pivotTable, thisSideColumns,
                  thatSideColumns, thatObject, thatAttrNames, *whereArgs,
                  **extra):
        """Handles many to many relations.  In short, do:
        
        SELECT thatObject.getColumns(1)
        FROM thatObject.table, pivotTable
        WHERE pivotTable.thisSideColumn = self.myAttrName
        AND pivotTable.thatSideColumn = thatObject.table.thatAttrName
        
        and return a list of thatObjects representing the resulting
        rows.  The parameters which accept column names
        (thisAttrNames, thisSideColumns, thatSideColumns,
        thatAttrNames) can be strings (silently turned to tuples of
        length 1) or tuples of strings.  For each pair P of the two
        pairs (thisSideColumns, thisAttrNames) and (thatSideColumns,
        thatAttrNames) len(P[0]) must equal len(P[1]).

        In addition, you can add extra tables and arbitrary sql to the
        where clause, as you can with getSome(), including order,
        limit and offset, using the "extraTables", "order", "limit"
        and "offset" keyword arguments, using SQLOperators or
        (sql-string, bind values) as positional arguments, and by
        specifying columns by keyword argument.
        
        """
        extraTables = extra.pop('extraTables', None)
        if extraTables:
            extraTables = list(_tupleize(extraTables))
        order = extra.pop('order', None)
        limit = extra.pop('limit', None)
        offset = extra.pop('offset', None)
        conn = self.getDBI()
        wheresql, wherevals = self._processWhere(conn, whereArgs, extra)
        sql, vals = self._joinTableSQL(conn, thisAttrNames, pivotTable,
                                       thisSideColumns, thatSideColumns,
                                       thatObject, thatAttrNames, extraTables,
                                       wheresql, wherevals, order, limit,
                                       offset)
        results = conn.execute(sql, vals)
        if results:
            return map(thatObject, results)
        return []