From 49f8c7fe384ae6369ee6900f821c43e35164a49d Mon Sep 17 00:00:00 2001 From: alexfca <75228224+alexfca@users.noreply.github.com> Date: Wed, 6 Oct 2021 10:07:40 +1100 Subject: [PATCH] - Add $$NULL$$ string to be used when a part of the DocId is known to be NULL (#23) - Use the $$NULL$$ for the known nullable use cases Co-authored-by: alexf@example.com --- internal/cosmosdbapi/document.go | 9 +++++++++ roomserver/storage/cosmosdb/event_state_keys_table.go | 2 +- syncapi/storage/cosmosdb/account_data_table.go | 3 ++- syncapi/storage/cosmosdb/current_room_state_table.go | 5 +++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/internal/cosmosdbapi/document.go b/internal/cosmosdbapi/document.go index 879d90cfa..f24c3a8d6 100644 --- a/internal/cosmosdbapi/document.go +++ b/internal/cosmosdbapi/document.go @@ -16,6 +16,8 @@ type CosmosDocument struct { Timestamp int64 `json:"_ts"` } +var DocumentIdPartNullString string = "$$NULL$$" + func removeSpecialChars(docId string) string { // The following characters are restricted and cannot be used in the Id property: '/', '\', '?', '#' invalidChars := [4]string{"/", "\\", "?", "#"} @@ -27,6 +29,13 @@ func removeSpecialChars(docId string) string { return result } +func EnsureIdPart(idPart string) string { + if len(idPart) == 0 { + return DocumentIdPartNullString + } + return idPart +} + func GetDocumentId(tenantName string, collectionName string, id string) string { safeId := removeSpecialChars(id) return fmt.Sprintf("%s,%s,%s", collectionName, tenantName, safeId) diff --git a/roomserver/storage/cosmosdb/event_state_keys_table.go b/roomserver/storage/cosmosdb/event_state_keys_table.go index cd63cb276..fa4d6b1e2 100644 --- a/roomserver/storage/cosmosdb/event_state_keys_table.go +++ b/roomserver/storage/cosmosdb/event_state_keys_table.go @@ -132,7 +132,7 @@ func ensureEventStateKeys(s *eventStateKeyStatements, ctx context.Context) { // ON CONFLICT DO NOTHING; // event_state_key TEXT NOT NULL UNIQUE - docId := "" + docId := cosmosdbapi.EnsureIdPart("") cosmosDocId := cosmosdbapi.GetDocumentId(s.db.cosmosConfig.TenantName, s.getCollectionName(), docId) data := eventStateKeysCosmos{ diff --git a/syncapi/storage/cosmosdb/account_data_table.go b/syncapi/storage/cosmosdb/account_data_table.go index 3637a4ce0..e6e74e09e 100644 --- a/syncapi/storage/cosmosdb/account_data_table.go +++ b/syncapi/storage/cosmosdb/account_data_table.go @@ -137,7 +137,8 @@ func (s *accountDataStatements) InsertAccountData( } // UNIQUE (user_id, room_id, type) - docId := fmt.Sprintf("%s,%s,%s", userID, roomID, dataType) + // roomId can be NULL + docId := fmt.Sprintf("%s,%s,%s", userID, cosmosdbapi.EnsureIdPart(roomID), dataType) cosmosDocId := cosmosdbapi.GetDocumentId(s.db.cosmosConfig.TenantName, s.getCollectionName(), docId) dbData, _ := getAccountDataType(s, ctx, s.getPartitionKey(), cosmosDocId) diff --git a/syncapi/storage/cosmosdb/current_room_state_table.go b/syncapi/storage/cosmosdb/current_room_state_table.go index 2b5d8c04e..55e5fd69b 100644 --- a/syncapi/storage/cosmosdb/current_room_state_table.go +++ b/syncapi/storage/cosmosdb/current_room_state_table.go @@ -391,7 +391,8 @@ func (s *currentRoomStateStatements) UpsertRoomState( // ) // " ON CONFLICT (room_id, type, state_key)" + - docId := fmt.Sprintf("%s,%s,%s", event.RoomID(), event.Type(), *event.StateKey()) + //StateKey can be NULL + docId := fmt.Sprintf("%s,%s,%s", event.RoomID(), event.Type(), cosmosdbapi.EnsureIdPart(*event.StateKey())) cosmosDocId := cosmosdbapi.GetDocumentId(s.db.cosmosConfig.TenantName, s.getCollectionName(), docId) membershipData := "" @@ -556,7 +557,7 @@ func (s *currentRoomStateStatements) SelectStateEvent( var res []byte // " ON CONFLICT (room_id, type, state_key)" + - docId := fmt.Sprintf("%s,%s,%s", roomID, evType, stateKey) + docId := fmt.Sprintf("%s,%s,%s", roomID, evType, cosmosdbapi.EnsureIdPart(stateKey)) cosmosDocId := cosmosdbapi.GetDocumentId(s.db.cosmosConfig.TenantName, s.getCollectionName(), docId) var response, err = getEvent(s, ctx, s.getPartitionKey(), cosmosDocId)