def editEntry(self, oData, uidAuthor, fCommit=False): """ Modifies a test group. """ # # Validate inputs and read in the old(/current) data. # assert isinstance(oData, TestGroupDataEx) dErrors = oData.validateAndConvert(self._oDb, oData.ksValidateFor_Edit) if dErrors: raise TMInvalidData('editEntry invalid input: %s' % (dErrors, )) self._assertUniq(oData, oData.idTestGroup) oOldData = TestGroupDataEx().initFromDbWithId(self._oDb, oData.idTestGroup) # # Update the data that needs updating. # if not oData.isEqualEx(oOldData, [ 'aoMembers', 'tsEffective', 'tsExpire', 'uidAuthor', ]): self._historizeTestGroup(oData.idTestGroup) self._oDb.execute( 'INSERT INTO TestGroups\n' ' (uidAuthor, idTestGroup, sName, sDescription, sComment)\n' 'VALUES (%s, %s, %s, %s, %s)\n', (uidAuthor, oData.idTestGroup, oData.sName, oData.sDescription, oData.sComment)) # Create a lookup dictionary for old entries. dOld = {} for oOld in oOldData.aoMembers: dOld[oOld.idTestCase] = oOld assert len(dOld) == len(oOldData.aoMembers) # Add new members, updated existing ones. dNew = {} for oNewMember in oData.aoMembers: oNewMember.idTestGroup = oData.idTestGroup if oNewMember.idTestCase in dNew: raise TMRowAlreadyExists( 'Duplicate test group member: idTestCase=%d (%s / %s)' % ( oNewMember.idTestCase, oNewMember, dNew[oNewMember.idTestCase], )) dNew[oNewMember.idTestCase] = oNewMember oOldMember = dOld.get(oNewMember.idTestCase, None) if oOldMember is not None: if oNewMember.isEqualEx( oOldMember, ['uidAuthor', 'tsEffective', 'tsExpire']): continue # Skip, nothing changed. self._historizeTestGroupMember(oData.idTestGroup, oNewMember.idTestCase) self._insertTestGroupMember(uidAuthor, oNewMember) # Expire members that have been removed. sQuery = self._oDb.formatBindArgs( 'UPDATE TestGroupMembers\n' 'SET tsExpire = CURRENT_TIMESTAMP\n' 'WHERE idTestGroup = %s\n' ' AND tsExpire = \'infinity\'::TIMESTAMP\n', (oData.idTestGroup, )) if dNew: sQuery += ' AND idTestCase NOT IN (%s)' % (', '.join( [str(iKey) for iKey in dNew]), ) self._oDb.execute(sQuery) self._oDb.maybeCommit(fCommit) return True