diff options
author | Wim <wim@42.be> | 2022-03-12 23:02:04 +0100 |
---|---|---|
committer | Wim <wim@42.be> | 2022-03-20 14:57:48 +0100 |
commit | aefa70891cfd489fccb8a9567b5bdafb0f863ede (patch) | |
tree | 90fe7c91d7b33b2a1ed08ea3a94840860adc6fc1 /vendor/go.mau.fi/whatsmeow/store/sqlstore | |
parent | 1b9877fda45be021ea6a5677c78648cecc19dcd5 (diff) | |
download | matterbridge-msglm-aefa70891cfd489fccb8a9567b5bdafb0f863ede.tar.gz matterbridge-msglm-aefa70891cfd489fccb8a9567b5bdafb0f863ede.tar.bz2 matterbridge-msglm-aefa70891cfd489fccb8a9567b5bdafb0f863ede.zip |
Update vendor (whatsapp)
Diffstat (limited to 'vendor/go.mau.fi/whatsmeow/store/sqlstore')
-rw-r--r-- | vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go b/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go index ad1eea7e..01ec2056 100644 --- a/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go +++ b/vendor/go.mau.fi/whatsmeow/store/sqlstore/store.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Tulir Asokan +// Copyright (c) 2022 Tulir Asokan // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -349,15 +349,15 @@ func (s *SQLStore) putAppStateMutationMACs(tx execable, name string, version uin values[0] = s.JID values[1] = name values[2] = version + placeholderSyntax := "($1, $2, $3, $%d, $%d)" + if s.dialect == "sqlite3" { + placeholderSyntax = "(?1, ?2, ?3, ?%d, ?%d)" + } for i, mutation := range mutations { baseIndex := 3 + i*2 values[baseIndex] = mutation.IndexMAC values[baseIndex+1] = mutation.ValueMAC - if s.dialect == "sqlite3" { - queryParts[i] = fmt.Sprintf("(?1, ?2, ?3, ?%d, ?%d)", baseIndex+1, baseIndex+2) - } else { - queryParts[i] = fmt.Sprintf("($1, $2, $3, $%d, $%d)", baseIndex+1, baseIndex+2) - } + queryParts[i] = fmt.Sprintf(placeholderSyntax, baseIndex+1, baseIndex+2) } _, err := tx.Exec(putAppStateMutationMACsQuery+strings.Join(queryParts, ","), values...) return err @@ -426,7 +426,12 @@ func (s *SQLStore) GetAppStateMutationMAC(name string, indexMAC []byte) (valueMA const ( putContactNameQuery = ` INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name) VALUES ($1, $2, $3, $4) - ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=$3, full_name=$4 + ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name + ` + putManyContactNamesQuery = ` + INSERT INTO whatsmeow_contacts (our_jid, their_jid, first_name, full_name) + VALUES %s + ON CONFLICT (our_jid, their_jid) DO UPDATE SET first_name=excluded.first_name, full_name=excluded.full_name ` putPushNameQuery = ` INSERT INTO whatsmeow_contacts (our_jid, their_jid, push_name) VALUES ($1, $2, $3) @@ -504,6 +509,77 @@ func (s *SQLStore) PutContactName(user types.JID, firstName, fullName string) er return nil } +const contactBatchSize = 300 + +func (s *SQLStore) putContactNamesBatch(tx execable, contacts []store.ContactEntry) error { + values := make([]interface{}, 1, 1+len(contacts)*3) + queryParts := make([]string, 0, len(contacts)) + values[0] = s.JID + placeholderSyntax := "($1, $%d, $%d, $%d)" + if s.dialect == "sqlite3" { + placeholderSyntax = "(?1, ?%d, ?%d, ?%d)" + } + i := 0 + handledContacts := make(map[types.JID]struct{}, len(contacts)) + for _, contact := range contacts { + if contact.JID.IsEmpty() { + s.log.Warnf("Empty contact info in mass insert: %+v", contact) + continue + } + // The whole query will break if there are duplicates, so make sure there aren't any duplicates + _, alreadyHandled := handledContacts[contact.JID] + if alreadyHandled { + s.log.Warnf("Duplicate contact info for %s in mass insert", contact.JID) + continue + } + handledContacts[contact.JID] = struct{}{} + baseIndex := i*3 + 1 + values = append(values, contact.JID.String(), contact.FirstName, contact.FullName) + queryParts = append(queryParts, fmt.Sprintf(placeholderSyntax, baseIndex+1, baseIndex+2, baseIndex+3)) + i++ + } + _, err := tx.Exec(fmt.Sprintf(putManyContactNamesQuery, strings.Join(queryParts, ",")), values...) + return err +} + +func (s *SQLStore) PutAllContactNames(contacts []store.ContactEntry) error { + if len(contacts) > contactBatchSize { + tx, err := s.db.Begin() + if err != nil { + return fmt.Errorf("failed to start transaction: %w", err) + } + for i := 0; i < len(contacts); i += contactBatchSize { + var contactSlice []store.ContactEntry + if len(contacts) > i+contactBatchSize { + contactSlice = contacts[i : i+contactBatchSize] + } else { + contactSlice = contacts[i:] + } + err = s.putContactNamesBatch(tx, contactSlice) + if err != nil { + _ = tx.Rollback() + return err + } + } + err = tx.Commit() + if err != nil { + return fmt.Errorf("failed to commit transaction: %w", err) + } + } else if len(contacts) > 0 { + err := s.putContactNamesBatch(s.db, contacts) + if err != nil { + return err + } + } else { + return nil + } + s.contactCacheLock.Lock() + // Just clear the cache, fetching pushnames and business names would be too much effort + s.contactCache = make(map[types.JID]*types.ContactInfo) + s.contactCacheLock.Unlock() + return nil +} + func (s *SQLStore) getContact(user types.JID) (*types.ContactInfo, error) { cached, ok := s.contactCache[user] if ok { |