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))
def __delitem__(self, key): key_column = self._sqldict.child_key_column.column key_literal = self._sqldict.child_key_column.sql_literal_class(key) where = self.child_where(dbobj) + sql.where( key_column, " = ", key_literal) dbobj.__ds__().execute(sql.delete(self.child_relation, where)) dict.__delitem__(self, key)
def __set__(self, dbobj, value): # make sure value is a sequence. try: value = list(value) except TypeError: raise ValueError( ("You must assing a sequence of %s to this " "dbproperty!") % repr(self.child_class)) # delete all links from the link_relation that point to the dbobj command = sql.delete(self.link_relation, sql.where(self.parent_link_column(dbobj), " = ", dbobj.__primary_key__.sql_literal())) dbobj.__ds__().execute(command) # use the result class to (re-)insert the links result = self.result(dbobj, self) result.append(*value)
def unlink_by_primary_key(self, pkey): """ Remove an entry from the link relation that links the parent dbobj to a child identfyed by pkey @param pkey: An sql.literal instance """ if not isinstance(pkey, sql.literal): raise TypeError("pkey must be an sql.literal instance!") cmd = sql.delete(self.relationship.link_relation, sql.where(self.relationship.parent_link_column(self.dbobj), " = ", self.dbobj.__primary_key__.sql_literal(), " AND ", self.relationship.child_link_column(), " = ", pkey)) self.ds().execute(cmd)
def __delete__(self): cmd = sql.delete(self.__relation__, self.__primary_key__.where()) self.__ds__().execute(cmd)
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))
def delete(self, dbclass, where, cursor=None): command = sql.delete(dbclass.__relation__, where) self.execute(command, cursor)