MCPcopy
hub / github.com/tinode/chat / TopicsForUser

Method TopicsForUser

server/db/rethinkdb/adapter.go:1397–1571  ·  view source on GitHub ↗

TopicsForUser loads user's contact list: p2p and grp topics, except for 'me' & 'fnd' subscriptions. Reads and denormalizes Public value.

(uid t.Uid, keepDeleted bool, opts *t.QueryOpt)

Source from the content-addressed store, hash-verified

1395// TopicsForUser loads user's contact list: p2p and grp topics, except for 'me' & 'fnd' subscriptions.
1396// Reads and denormalizes Public value.
1397func (a *adapter) TopicsForUser(uid t.Uid, keepDeleted bool, opts *t.QueryOpt) ([]t.Subscription, error) {
1398 // Fetch ALL user's subscriptions, even those which has not been modified recently.
1399 // We are going to use these subscriptions to fetch topics and users which may have been modified recently.
1400 q := rdb.DB(a.dbName).Table("subscriptions").GetAllByIndex("User", uid.String())
1401 if !keepDeleted {
1402 // Filter out rows with defined DeletedAt
1403 q = q.Filter(rdb.Row.HasFields("DeletedAt").Not())
1404 }
1405
1406 limit := 0
1407 ims := time.Time{}
1408 if opts != nil {
1409 if opts.Topic != "" {
1410 q = q.Filter(rdb.Row.Field("Topic").Eq(opts.Topic))
1411 }
1412
1413 // Apply the limit only when the client does not manage the cache (or cold start).
1414 // Otherwise have to get all subscriptions and do a manual join with users/topics.
1415 if opts.IfModifiedSince == nil {
1416 if opts.Limit > 0 && opts.Limit < a.maxResults {
1417 limit = opts.Limit
1418 } else {
1419 limit = a.maxResults
1420 }
1421 } else {
1422 ims = *opts.IfModifiedSince
1423 }
1424 } else {
1425 limit = a.maxResults
1426 }
1427
1428 if limit > 0 {
1429 q = q.Limit(limit)
1430 }
1431
1432 cursor, err := q.Run(a.conn)
1433 if err != nil {
1434 return nil, err
1435 }
1436
1437 // Fetch subscriptions. Two queries are needed: users table (me & p2p) and topics table (p2p and grp).
1438 // Prepare a list of Separate subscriptions to users vs topics
1439 var sub t.Subscription
1440 join := make(map[string]t.Subscription) // Keeping these to make a join with table for .private and .access
1441 topq := make([]any, 0, 16)
1442 usrq := make([]any, 0, 16)
1443 for cursor.Next(&sub) {
1444 tname := sub.Topic
1445 sub.User = uid.String()
1446 tcat := t.GetTopicCat(tname)
1447
1448 if tcat == t.TopicCatMe || tcat == t.TopicCatFnd {
1449 // 'me' or 'fnd' subscription, skip. Don't skip 'sys'.
1450 continue
1451 } else if tcat == t.TopicCatP2P {
1452 // P2P subscription, find the other user to get user.Public
1453 uid1, uid2, _ := t.ParseP2P(sub.Topic)
1454 if uid1 == uid {

Callers

nothing calls this directly

Calls 15

SetWithMethod · 0.95
SetStateMethod · 0.95
SetTouchedAtMethod · 0.95
SetSeqIdMethod · 0.95
SetSubCntMethod · 0.95
SetPublicMethod · 0.95
SetTrustedMethod · 0.95
SetDefaultAccessMethod · 0.95
SetLastSeenAndUAMethod · 0.95
SelectLatestTimeFunction · 0.92
NextMethod · 0.80

Tested by

no test coverage detected