update
This commit is contained in:
@@ -807,6 +807,39 @@ func (r *Repo) Count(ctx context.Context) (int64, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
// ExistingDedupeKeys returns a set of every QSO key currently in the DB,
|
||||
// used by the ADIF importer to skip records that would re-create the
|
||||
// same contact. The key is callsign|YYYY-MM-DDTHH:MM|band|mode — minute
|
||||
// precision so two loggers that wrote a few seconds apart still match.
|
||||
//
|
||||
// On a 25k-row table this returns ~25k strings (~2MB RAM) in one pass —
|
||||
// far cheaper than N exists-queries during the import loop.
|
||||
func (r *Repo) ExistingDedupeKeys(ctx context.Context) (map[string]struct{}, error) {
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT callsign, strftime('%Y-%m-%dT%H:%M', qso_date), band, mode
|
||||
FROM qso`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make(map[string]struct{}, 1024)
|
||||
for rows.Next() {
|
||||
var call, when, band, mode string
|
||||
if err := rows.Scan(&call, &when, &band, &mode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[DedupeKey(call, when, band, mode)] = struct{}{}
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// DedupeKey is the canonical dedupe identity for a QSO. Exposed so the
|
||||
// importer can compute the key from in-flight records and check against
|
||||
// the same map ExistingDedupeKeys returns.
|
||||
func DedupeKey(callsign, qsoDateMinute, band, mode string) string {
|
||||
return strings.ToUpper(callsign) + "|" + qsoDateMinute + "|" + strings.ToLower(band) + "|" + strings.ToUpper(mode)
|
||||
}
|
||||
|
||||
// scanner is what both *sql.Row and *sql.Rows satisfy for our needs.
|
||||
type scanner interface {
|
||||
Scan(dest ...any) error
|
||||
|
||||
Reference in New Issue
Block a user