count.go raw
1 //go:build !(js && wasm)
2
3 package database
4
5 import (
6 "context"
7
8 "next.orly.dev/pkg/nostr/encoders/filter"
9 )
10
11 // CountEvents mirrors the initial selection logic of QueryEvents but stops
12 // once we have identified candidate event serials (id/pk/ts). It returns the
13 // count of those serials. The `approx` flag is always false as requested.
14 func (d *D) CountEvents(c context.Context, f *filter.F) (
15 count int, approx bool, err error,
16 ) {
17 approx = false
18 if f == nil {
19 return 0, false, nil
20 }
21
22 // If explicit Ids are provided, count how many of them resolve to serials.
23 if f.Ids != nil && f.Ids.Len() > 0 {
24 var serials map[string]interface{}
25 // Use type inference without importing extra packages by discarding the
26 // concrete value type via a two-step assignment.
27 if tmp, idErr := d.GetSerialsByIds(f.Ids); idErr != nil {
28 return 0, false, idErr
29 } else {
30 // Reassign to a map with empty interface values to avoid referencing
31 // the concrete Uint40 type here.
32 serials = make(map[string]interface{}, len(tmp))
33 for k := range tmp {
34 serials[k] = struct{}{}
35 }
36 }
37 return len(serials), false, nil
38 }
39
40 // Otherwise, query for candidate Id/Pubkey/Timestamp triplets and count them.
41 if idPkTs, qErr := d.QueryForIds(c, f); qErr != nil {
42 return 0, false, qErr
43 } else {
44 return len(idPkTs), false, nil
45 }
46 }
47