示例#1
0
文件: datasource.py 项目: dvorberg/t4
    def insert(self, dbobj, dont_select=False):
        """
        Firebird does not provide a mechanism that let's me query the id of
        the last row I inserted. This has to be done *before* the INSERT. 
        """

        for property in dbobj.__dbproperties__():
            if isinstance(property, common_serial):
                sequence_name = "GEN_PK_%s" % dbobj.__relation__
            elif isinstance(property, datatypes.serial):
                sequence_name = property.sequence
            else:
                continue

            query = sql.select(sql.expression("GEN_ID(", sequence_name,
                                              ", 1) AS new_id"),
                               "RDB$DATABASE")
            cursor = self.execute(query)
            tpl = cursor.fetchone()
            new_id = tpl[0]

            property.__set_from_result__(self, dbobj, new_id)
        

        orm2.datasource.datasource_base.insert(self, dbobj, dont_select)
示例#2
0
        def all(self, *clauses):
            """
            This method will return all entries in the child relation (or a
            subset specified by clauses) and a list of those primary keys
            which are present in the link table. You can check if a dbobj is
            linked by doing:

                >>> result, active_keys = dbobj.relation.all()
                >>> for a in result:
                ...     if a.__primary_key__.values() in active_keys:
                ...         do_something(a)
                ...     else:
                ...         do_somethin_else(a)

            
            """
            if self.dbobj.__is_stored__():
                relations = (self.relationship.link_relation, self.child_class().__relation__)
                join_clauses = self.add_where(clauses)

                child_pkey = keys.primary_key(self.child_class())
                query = sql.select(tuple(child_pkey.columns()), relations, *join_clauses)

                cursor = self.ds().execute(query)
                active_keys = list(cursor.fetchall())
            else:
                active_keys = []

            result = self.ds().select(self.child_class(), *clauses)

            return (result, active_keys)
示例#3
0
    def __get__(self, dbobj, owner="I don't know what this is for"):
        if dbobj is None: return self

        self.check_dbobj(dbobj)

        if self.isset(dbobj):
            return getattr(dbobj, self.data_attribute_name())
        else:
            query = sql.select((self.column, ), dbobj.__relation__,
                               dbobj.__primary_key__.where())
            cursor = dbobj.__ds__().execute(query)
            row = cursor.fetchone()

            if row is None: raise IllegelPrimaryKey()  # This shouldn't happen

            value = row[0]

            # The way this is handled is a little strange. Let me explain!
            # The point is, __set_from_result__() may convert the
            # data retreived from the RDBMS into some other Python
            # representation (orm2.util.pickle works that way for instance).
            # So we use the function to do its job and, if we're not supposed
            # to cache the value, *undo* the changes it made on the dbobj.
            # This presumes that the data_attribute_name() mechanism is used
            # by __set_from_result__(), which is relatively save, I guess.

            self.inside_datatype.__set_from_result__(dbobj.__ds__(), dbobj,
                                                     value)

            ret = getattr(dbobj, self.data_attribute_name())

            if not self.cache and hasattr(dbobj, self.data_attribute_name()):
                delattr(dbobj, self.data_attribute_name())

            return ret
示例#4
0
    def insert(self, dbobj, dont_select=False):
        """
        Firebird does not provide a mechanism that let's me query the id of
        the last row I inserted. This has to be done *before* the INSERT. 
        """

        for property in dbobj.__dbproperties__():
            if isinstance(property, common_serial):
                sequence_name = "GEN_PK_%s" % dbobj.__relation__
            elif isinstance(property, datatypes.serial):
                sequence_name = property.sequence
            else:
                continue

            query = sql.select(sql.expression("GEN_ID(", sequence_name,
                                              ", 1) AS new_id"),
                               "RDB$DATABASE")
            cursor = self.execute(query)
            tpl = cursor.fetchone()
            new_id = tpl[0]

            property.__set_from_result__(self, dbobj, new_id)
        

        orm2.datasource.datasource_base.insert(self, dbobj, dont_select)
示例#5
0
        def len(self, *clauses):
            """
            Return the number of child objects associated with a parent.
            You may supply a where clause. The same things apply as for the
            where clause for select(), see above.
            """
            clauses = self.add_where(clauses)

            query = sql.select("COUNT(*)", (self.relationship.link_relation, self.child_class().__relation__), *clauses)

            return self.ds().query_one(query)
示例#6
0
        def len(self, *clauses):
            """
            Return the number of child objects associated with a parent.
            You may supply a where clause. The same things apply as for the
            where clause for select(), see above.
            """
            clauses = self.add_where(clauses)

            query = sql.select("COUNT(*)", (
                self.relationship.link_relation,
                self.child_class().__relation__,
            ), *clauses)

            return self.ds().query_one(query)
示例#7
0
    def select(self, dbclass, *clauses):
        """
        SELECT dbobjs from the database, according to clauses.

        @param dbclass: The dbclass of the objects to be selected.

        @param clauses: A list of orm2.sql clauses instances (or
                        equivalent Python object i.e. strings) that
                        are added to the sql.select query.  See
                        orm2.sql.select for details

        
        """
        query = sql.select(dbclass.__select_columns__(),
                           dbclass.__relation__, *clauses)
        
        return self.run_select(dbclass, query)
示例#8
0
    def select(self, dbclass, *clauses):
        """
        SELECT dbobjs from the database, according to clauses.

        @param dbclass: The dbclass of the objects to be selected.

        @param clauses: A list of orm2.sql clauses instances (or
                        equivalent Python object i.e. strings) that
                        are added to the sql.select query.  See
                        orm2.sql.select for details

        
        """
        query = sql.select(dbclass.__select_columns__(), dbclass.__relation__,
                           *clauses)

        return self.run_select(dbclass, query)
示例#9
0
        def select(self, *clauses):
            """
            Use like this:

               >>> result = dbobj.children.select(sql.where(...))

            This will yield those child objects that fit the condition
            in the where statements. Note that your WHERE will be
            integrated into a more complex WHERE clause. The many2many
            relationship uses a LEFT JOIN to connect the link_relation
            and the child relation.  You must do that by hand. Also,
            doing so might mess up your db, so you might want to use
            FOREIGN KEY constraints on the link relation.
            """
            relations = (self.relationship.link_relation, self.child_class().__relation__)
            clauses = self.add_where(clauses)

            query = sql.select(self.child_class().__select_columns__(), relations, *clauses)

            return self.ds().run_select(self.child_class(), query)
示例#10
0
    def select_after_insert(self, dbobj):
        """
        This method will be run after each INSERT statement automaticaly
        generated by a ds to pick up default values and primary keys set
        by the backend. See insert().
        """
        properties = []
        columns = []
        for property in dbobj.__dbproperties__():
            if property.__select_after_insert__(dbobj):
                properties.append(property)
                columns.append(property.column)

        if len(properties) > 0:
            where = self.select_after_insert_where(dbobj)
            query = sql.select(columns, dbobj.__relation__, where)

            cursor = self.execute(query)
            tpl = cursor.fetchone()

            for property, value in zip(properties, tpl):
                property.__set_from_result__(self, dbobj, value)
示例#11
0
    def select_after_insert(self, dbobj):
        """
        This method will be run after each INSERT statement automaticaly
        generated by a ds to pick up default values and primary keys set
        by the backend. See insert().
        """
        properties = []
        columns = []
        for property in dbobj.__dbproperties__():
            if property.__select_after_insert__(dbobj):
                properties.append(property)
                columns.append(property.column)

        if len(properties) > 0:
            where = self.select_after_insert_where(dbobj)
            query = sql.select(columns, dbobj.__relation__, where)

            cursor = self.execute(query)
            tpl = cursor.fetchone()

            for property, value in zip(properties, tpl):
                property.__set_from_result__(self, dbobj, value)
示例#12
0
        def all(self, *clauses):
            """
            This method will return all entries in the child relation (or a
            subset specified by clauses) and a list of those primary keys
            which are present in the link table. You can check if a dbobj is
            linked by doing:

                >>> result, active_keys = dbobj.relation.all()
                >>> for a in result:
                ...     if a.__primary_key__.values() in active_keys:
                ...         do_something(a)
                ...     else:
                ...         do_somethin_else(a)

            
            """
            if self.dbobj.__is_stored__():
                relations = (
                    self.relationship.link_relation,
                    self.child_class().__relation__,
                )
                join_clauses = self.add_where(clauses)

                child_pkey = keys.primary_key(self.child_class())
                query = sql.select(tuple(child_pkey.columns()), relations,
                                   *join_clauses)

                cursor = self.ds().execute(query)
                active_keys = list(cursor.fetchall())
            else:
                active_keys = []

            result = self.ds().select(self.child_class(), *clauses)

            return (
                result,
                active_keys,
            )
示例#13
0
    def count(self, dbclass, *clauses):
        """
        All clauses except the WHERE clause will be ignored
        (including OFFSET and LIMIT!)
        
        @param dbclass: See select() above.
        @param clauses: See select() above.
        
        @return: An integer value indicating the number of objects
                 of dbclass select() would return if run with these clauses.
        """

        where = None
        for clause in clauses:
            if isinstance(clause, sql.where):
                where = clause
                
        if where is not None:
            clauses = [where]
        else:
            clauses = []
            
        query = sql.select("COUNT(*)", dbclass.__relation__, *clauses)
        return self.query_one(query)
示例#14
0
        def select(self, *clauses):
            """
            Use like this:

               >>> result = dbobj.children.select(sql.where(...))

            This will yield those child objects that fit the condition
            in the where statements. Note that your WHERE will be
            integrated into a more complex WHERE clause. The many2many
            relationship uses a LEFT JOIN to connect the link_relation
            and the child relation.  You must do that by hand. Also,
            doing so might mess up your db, so you might want to use
            FOREIGN KEY constraints on the link relation.
            """
            relations = (
                self.relationship.link_relation,
                self.child_class().__relation__,
            )
            clauses = self.add_where(clauses)

            query = sql.select(self.child_class().__select_columns__(),
                               relations, *clauses)

            return self.ds().run_select(self.child_class(), query)
示例#15
0
    def __get__(self, dbobj, owner="I don't know what this is for"):
        if dbobj is None: return self
        
        self.check_dbobj(dbobj)
            
        if self.isset(dbobj):
            return getattr(dbobj, self.data_attribute_name())
        else:
            query = sql.select(( self.column, ),
                               dbobj.__relation__,
                               dbobj.__primary_key__.where())
            cursor = dbobj.__ds__().execute(query)
            row = cursor.fetchone()

            if row is None: raise IllegelPrimaryKey() # This shouldn't happen

            value = row[0]

            # The way this is handled is a little strange. Let me explain!
            # The point is, __set_from_result__() may convert the 
            # data retreived from the RDBMS into some other Python
            # representation (orm2.util.pickle works that way for instance).
            # So we use the function to do its job and, if we're not supposed
            # to cache the value, *undo* the changes it made on the dbobj.
            # This presumes that the data_attribute_name() mechanism is used
            # by __set_from_result__(), which is relatively save, I guess.
            
            self.inside_datatype.__set_from_result__(dbobj.__ds__(),
                                                     dbobj, value)

            ret = getattr(dbobj, self.data_attribute_name())

            if not self.cache and hasattr(dbobj, self.data_attribute_name()):
                delattr(dbobj, self.data_attribute_name())

            return ret
示例#16
0
    def count(self, dbclass, *clauses):
        """
        All clauses except the WHERE clause will be ignored
        (including OFFSET and LIMIT!)
        
        @param dbclass: See select() above.
        @param clauses: See select() above.
        
        @return: An integer value indicating the number of objects
                 of dbclass select() would return if run with these clauses.
        """

        where = None
        for clause in clauses:
            if isinstance(clause, sql.where):
                where = clause

        if where is not None:
            clauses = [where]
        else:
            clauses = []

        query = sql.select("COUNT(*)", dbclass.__relation__, *clauses)
        return self.query_one(query)