Ejemplo n.º 1
0
      def __setitem__(self, key, value):
         key_column = self._sqldict.child_key_column.column         
         for validator in self._sqldict.child_key_column.validators:
             validator.check(self._dbobj, self._sqldict.child_key_column, key)
         key_literal = self._sqldict.child_key_column.sql_literal_class(
             self._sqldict.child_key_column.__convert__(key))

         value_column = self._sqldict.child_value_column.column
         for validator in self._sqldict.child_value_column.validators:
             validator.check(self._dbobj, self._sqldict.child_value_column,
                             value)         
         value_literal = self._sqldict.child_value_column.sql_literal_class(
             self._sqldict.child_value_column.__convert__(value))         

         if self.has_key(key):
             if self[key] != value:
                 where = sql.where.and_(self._sqldict.child_where(self._dbobj),
                                        sql.where(key_column, "=", key_literal))
             
                 command = sql.update(self._sqldict.child_relation, where,
                                      { str(value_column): value_literal })
             else:
                 command = None
         else:
             command = sql.insert( self._sqldict.child_relation,
                                   ( self._sqldict.child_key,
                                     key_column,
                                     value_column, ),
                                   ( self._dbobj.__primary_key__.sql_literal(),
                                     key_literal, value_literal, ) )

         if command is not None:
             self._dbobj.__ds__().execute(command)
            
         dict.__setitem__(self, key, value)
Ejemplo n.º 2
0
    def insert(self, dbobj, dont_select=False, cursor=None):
        """
        @param dbobj: The dbobj to be inserted (must not be created by a
            select statement.
        @param dont_select: Do not perform a SELECT query for those columns
            whoes values are provided by the backend, either through
            AUTO_INCREMENT mechanisms or default column values.
        """
        if dbobj.__is_stored__():
            raise ObjectAlreadyInserted(repr(dbobj))
        
        sql_columns = []
        sql_values = []
        for property in dbobj.__dbproperties__():
            
            if property.isset(dbobj) and property.column not in sql_columns:
                update_expression = property.update_expression(dbobj)
                if update_expression is not None:
                    sql_columns.append(property.column)
                    sql_values.append(update_expression)

        if len(sql_columns) == 0:
            raise DBObjContainsNoData(
                "Please set at least one of the attributes of this dbobj")

        statement = sql.insert(dbobj.__relation__, sql_columns, sql_values)

        self.execute(statement)
        dbobj.__insert__(self)

        if dbobj.__primary_key__ is not None and not dont_select:
            self.select_after_insert(dbobj)

        return cursor
Ejemplo n.º 3
0
    def __set__(self, dbobj, new_values):
        self.check_dbobj(dbobj)
        
        if new_values is None:
            raise ValueError("You cannot set a sqltuple to None, sorry.")

        # Convert each of the values in the new tuple to the
        # child_column's type and run its validators on each of them.

        new = []
        for value in new_values:
            value = self.child_column.__convert__(value)
            for validator in self.child_column.validators:
                validator.check(dbobj, self, value)

            new.append(value)

        # Let's see if it's just an addition of values. In that case
        # we'll not delete anything, just create a couple of INSERT
        # statements.
        
        if self.isset(dbobj):
           dont_delete = True
           old = getattr(dbobj, self.data_attribute_name())
           
           if len(old) <= len(new):
              for o, n in zip(old, new):
                 if o != n:
                    dont_delete = False
                    break
        else:
           old = ()
           dont_delete = False
           
        if dont_delete:
            to_insert = new[len(old):]
        else:
            to_insert = new

            dbobj.__ds__().execute(sql.delete(self.child_relation,
                                              self.child_where(dbobj)))
        
        for value in to_insert:
            if value is None:
                literal = sql.NULL
            else:
                literal = self.child_column.sql_literal_class(value)
                
            dbobj.__ds__().execute(
                sql.insert(self.child_relation,
                           ( self.child_key,
                             self.child_column.column, ),
                           ( dbobj.__primary_key__.sql_literal(),
                             literal, ) ))
            
        setattr(dbobj, self.data_attribute_name(), tuple(new))
Ejemplo n.º 4
0
        def append(self, *new_child_objects):
            """
            Appends new child objects to the parent's many2many dbproperty. 
            """
            for dbobj in new_child_objects:
                if not isinstance(dbobj, self.child_class()):
                    msg = "This relationship can only handle %s" % \
                                           repr(self.child_class())
                    raise TypeError(msg)

                if not dbobj.__is_stored__():
                    # The many2many relationship will insert fresh objects
                    # into the database.
                    self.ds().insert(dbobj)

                # insert a row into the link_relation
                command = sql.insert(self.relationship.link_relation,
                  ( self.relationship.parent_link_column(self.dbobj),
                    self.relationship.child_link_column(), ),
                  ( self.relationship.parent_own_key(
                                         self.dbobj).sql_literal(self.dbobj),
                    self.relationship.child_own_key().sql_literal(dbobj), ))
                
                self.ds().execute(command)
Ejemplo n.º 5
0
   def __set__(self, dbobj, new_dict):       
       if new_dict is None:
          raise ValueError("You cannot set a sqldict to None, sorry.")

       self.check_dbobj(dbobj)

       if self.isset(dbobj):
           # We have a new version of the dict in memory and can compare
           # values against it.
           old_dict = getattr(dbobj, self.data_attribute_name())
           old_dict.update(new_dict)

           new_keys = set(new_dict.keys())
           old_keys = set(old_dict.keys())
           obsolete_keys = old_keys.difference(new_keys)

           for key in obsolete_keys:
               old_dict[key]
       else:
           if dbobj.__ds__():
               raise ValueError("Can’t initialize a sqldict on "
                                "dbobject creation, only after insert().")
           
           # Convert each of the keys and values in the new dict to the
           # appropriate types and run the validators on each of the values.
           new = {}
           for key, value in new_dict.items():
              key = self.child_key_column.__convert__(key)
              value = self.child_value_column.__convert__(value)

              for validator in self.child_key_column.validators:
                 validator.check(dbobj, self, key)

              for validator in self.child_value_column.validators:
                 validator.check(dbobj, self, value)

              new[key] = value

           # Delete the rows currently in the database
           dbobj.__ds__().execute(sql.delete(self.child_relation,
                                             self.child_where(dbobj)))

           # And insert new ones
           for key, value in new.items():
              key_literal = self.child_key_column.sql_literal_class(
                  self.child_key_column.__convert__(key))

              if value is None:
                 value_literal = sql.NULL
              else:
                 value_literal = self.child_value_column.sql_literal_class(
                     self.child_value_column.__convert__(value))

              query = sql.insert( self.child_relation,
                                  ( self.child_key,
                                    self.child_key_column.column,
                                    self.child_value_column.column, ),
                                  ( dbobj.__primary_key__.sql_literal(),
                                    key_literal, value_literal, ) )
              dbobj.__ds__().execute(query)

              setattr(dbobj, self.data_attribute_name(),
                      self.sqldict_dict(self, dbobj, new))