Drop calls from migration with the same callId and peerId

This commit is contained in:
Jamie Kyle 2023-08-09 09:32:43 -07:00 committed by GitHub
parent 1eaabb6734
commit e20fa41fd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 0 deletions

View file

@ -77,6 +77,8 @@ export default function updateToSchemaVersion87(
const rows = db.prepare(selectQuery).all();
const uniqueConstraint = new Set();
for (const row of rows) {
const json = JSON.parse(row.json);
const details = json.callHistoryDetails;
@ -153,6 +155,17 @@ export default function updateToSchemaVersion87(
continue;
}
// We need to ensure a call with the same callId and peerId doesn't get
// inserted twice because of the unique constraint on the table.
const uniqueKey = `${callId} -> ${peerId}`;
if (uniqueConstraint.has(uniqueKey)) {
logger.error(
`updateToSchemaVersion87: duplicate callId/peerId pair (${uniqueKey})`
);
continue;
}
uniqueConstraint.add(uniqueKey);
const [insertQuery, insertParams] = sql`
INSERT INTO callsHistory (
callId,

View file

@ -3658,5 +3658,81 @@ describe('SQL migrations test', () => {
callHistoryDetailsSchema.parse(row);
}
});
it('handles unique constraint violations', () => {
updateToVersion(86);
const message1Id = generateGuid();
const message2Id = generateGuid();
const conversationId = generateGuid();
const callHistoryDetails = {
callId: '123',
callMode: CallMode.Direct,
wasDeclined: false,
wasDeleted: false,
wasIncoming: false,
wasVideoCall: false,
acceptedTime: Date.now(),
endedTime: undefined,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- using old types
const message1: MessageAttributesType & { callHistoryDetails: any } = {
id: message1Id,
type: 'call-history',
conversationId,
sent_at: Date.now() - 10,
received_at: Date.now() - 10,
timestamp: Date.now() - 10,
callHistoryDetails,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- using old types
const message2: MessageAttributesType & { callHistoryDetails: any } = {
id: message2Id,
type: 'call-history',
conversationId,
sent_at: Date.now(),
received_at: Date.now(),
timestamp: Date.now(),
callHistoryDetails,
};
const [insertQuery, insertParams] = sql`
INSERT INTO messages (
id,
conversationId,
type,
json
)
VALUES
(
${message1Id},
${conversationId},
${message1.type},
${JSON.stringify(message1)}
),
(
${message2Id},
${conversationId},
${message2.type},
${JSON.stringify(message2)}
);
`;
db.prepare(insertQuery).run(insertParams);
updateToVersion(87);
const [selectHistoryQuery] = sql`
SELECT * FROM callsHistory;
`;
const rows = db.prepare(selectHistoryQuery).all();
for (const row of rows) {
callHistoryDetailsSchema.parse(row);
}
assert.strictEqual(rows.length, 1);
});
});
});