Index: pykota/trunk/pykota/storages/mysqlstorage.py
===================================================================
--- pykota/trunk/pykota/storages/mysqlstorage.py (revision 2741)
+++ pykota/trunk/pykota/storages/mysqlstorage.py (revision 2773)
@@ -130,4 +130,5 @@
             self.cursor.execute(query)
         except self.database.Error, msg :    
+            self.tool.logdebug("Query failed : %s" % repr(msg))
             raise PyKotaStorageError, str(msg)
         else :    
Index: pykota/trunk/pykota/storages/pgstorage.py
===================================================================
--- pykota/trunk/pykota/storages/pgstorage.py (revision 2741)
+++ pykota/trunk/pykota/storages/pgstorage.py (revision 2773)
@@ -115,4 +115,5 @@
             result = self.database.query(query)
         except PGError, msg :    
+            self.tool.logdebug("Query failed : %s" % repr(msg))
             raise PyKotaStorageError, str(msg)
         else :    
Index: pykota/trunk/pykota/storages/sql.py
===================================================================
--- pykota/trunk/pykota/storages/sql.py (revision 2771)
+++ pykota/trunk/pykota/storages/sql.py (revision 2773)
@@ -562,6 +562,7 @@
         
     def addUser(self, user) :        
-        """Adds a user to the quota storage, returns it."""
-        self.doModify("INSERT INTO users (username, limitby, balance, lifetimepaid, email, overcharge, description) VALUES (%s, %s, %s, %s, %s, %s, %s)" % \
+        """Adds a user to the quota storage, returns the old value if it already exists."""
+        try :
+            self.doModify("INSERT INTO users (username, limitby, balance, lifetimepaid, email, overcharge, description) VALUES (%s, %s, %s, %s, %s, %s, %s)" % \
                                          (self.doQuote(self.userCharsetToDatabase(user.Name)), \
                                           self.doQuote(user.LimitBy or 'quota'), \
@@ -571,13 +572,30 @@
                                           self.doQuote(user.OverCharge), \
                                           self.doQuote(self.userCharsetToDatabase(user.Description))))
-        return self.getUser(user.Name)
+        except PyKotaStorageError :    
+            # TODO : check if this is an error different from a duplicate insert
+            # return the existing entry which has to be modified
+            return self.getUser(user.Name)
+        else :    
+            if user.PaymentsBacklog :
+                for (value, comment) in user.PaymentsBacklog :
+                    self.writeNewPayment(user, value, comment)
+                user.PaymentsBacklog = []
+            user.isDirty = False
+            return None # the entry created doesn't need further modification
         
     def addGroup(self, group) :        
-        """Adds a group to the quota storage, returns it."""
-        self.doModify("INSERT INTO groups (groupname, limitby, description) VALUES (%s, %s, %s)" % \
-                                          (self.doQuote(self.userCharsetToDatabase(group.Name)), \
-                                           self.doQuote(group.LimitBy or "quota"), \
-                                           self.doQuote(self.userCharsetToDatabase(group.Description))))
-        return self.getGroup(group.Name)
+        """Adds a group to the quota storage, returns the old value if it already exists."""
+        try :
+            self.doModify("INSERT INTO groups (groupname, limitby, description) VALUES (%s, %s, %s)" % \
+                                  (self.doQuote(self.userCharsetToDatabase(group.Name)), \
+                                   self.doQuote(group.LimitBy or "quota"), \
+                                   self.doQuote(self.userCharsetToDatabase(group.Description))))
+        except PyKotaStorageError :    
+            # TODO : check if this is an error different from a duplicate insert
+            # return the existing entry which has to be modified
+            return self.getGroup(group.Name)
+        else :    
+            group.isDirty = False
+            return None # the entry created doesn't need further modification
 
     def addUserToGroup(self, user, group) :    
@@ -693,5 +711,8 @@
     def writeNewPayment(self, user, amount, comment="") :
         """Adds a new payment to the payments history."""
-        self.doModify("INSERT INTO payments (userid, amount, description) VALUES (%s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(amount), self.doQuote(self.userCharsetToDatabase(comment))))
+        if user.ident is not None :
+            self.doModify("INSERT INTO payments (userid, amount, description) VALUES (%s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(amount), self.doQuote(self.userCharsetToDatabase(comment))))
+        else :    
+            self.doModify("INSERT INTO payments (userid, amount, description) VALUES ((SELECT id FROM users WHERE username=%s), %s, %s)" % (self.doQuote(self.userCharsetToDatabase(user.Name)), self.doQuote(amount), self.doQuote(self.userCharsetToDatabase(comment))))
         
     def writeLastJobSize(self, lastjob, jobsize, jobprice) :        
Index: pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- pykota/trunk/pykota/storages/ldapstorage.py (revision 2768)
+++ pykota/trunk/pykota/storages/ldapstorage.py (revision 2773)
@@ -909,5 +909,8 @@
         
     def addUser(self, user) :        
-        """Adds a user to the quota storage, returns it."""
+        """Adds a user to the quota storage, returns the old value if it already exists."""
+        oldentry = self.getUser(user.Name)
+        if oldentry.Exists :
+            return oldentry # we return the existing entry
         uname = self.userCharsetToDatabase(user.Name)
         newfields = {
@@ -971,9 +974,17 @@
                 dn = "%s=%s,%s" % (self.info["balancerdn"], uname, self.info["balancebase"])
                 self.doAdd(dn, fields)
-            
-        return self.getUser(user.Name)
+        user.idbalance = dn
+        if user.PaymentsBacklog :
+            for (value, comment) in user.PaymentsBacklog :
+                self.writeNewPayment(user, value, comment)
+            user.PaymentsBacklog = []
+        user.isDirty = False
+        return None # the entry created doesn't need further modification
         
     def addGroup(self, group) :        
-        """Adds a group to the quota storage, returns it."""
+        """Adds a group to the quota storage, returns the old value if it already exists."""
+        oldentry = self.getGroup(group.Name)
+        if oldentry.Exists :
+            return oldentry # we return the existing entry
         gname = self.userCharsetToDatabase(group.Name)
         newfields = { 
@@ -1014,5 +1025,6 @@
             dn = "%s=%s,%s" % (self.info["grouprdn"], gname, self.info["groupbase"])
             self.doAdd(dn, fields)
-        return self.getGroup(group.Name)
+        group.isDirty = False
+        return None # the entry created doesn't need further modification
         
     def addUserToGroup(self, user, group) :    
Index: pykota/trunk/pykota/storages/sqlitestorage.py
===================================================================
--- pykota/trunk/pykota/storages/sqlitestorage.py (revision 2741)
+++ pykota/trunk/pykota/storages/sqlitestorage.py (revision 2773)
@@ -121,4 +121,5 @@
             self.cursor.execute(query)
         except self.database.Error, msg :    
+            self.tool.logdebug("Query failed : %s" % repr(msg))
             raise PyKotaStorageError, str(msg)
         else :    
Index: pykota/trunk/pykota/storage.py
===================================================================
--- pykota/trunk/pykota/storage.py (revision 2735)
+++ pykota/trunk/pykota/storage.py (revision 2773)
@@ -67,4 +67,5 @@
         self.OverCharge = 1.0
         self.Payments = [] # TODO : maybe handle this smartly for SQL, for now just don't retrieve them
+        self.PaymentsBacklog = []
         
     def consumeAccountBalance(self, amount) :     
@@ -78,6 +79,14 @@
         self.AccountBalance = balance
         self.LifeTimePaid = lifetimepaid
-        self.parent.writeNewPayment(self, diff, comment)
-        self.isDirty = True
+        if diff :
+            self.PaymentsBacklog.append((diff, comment))
+        self.isDirty = True
+        
+    def save(self) :    
+        """Saves an user and flush its payments backlog."""
+        for (value, comment) in self.PaymentsBacklog :
+            self.parent.writeNewPayment(self, value, comment)
+        self.PaymentsBacklog = []    
+        StorageObject.save(self)    
         
     def setLimitBy(self, limitby) :    
