@@ -17,21 +17,66 @@ import (
1717 "zgo.at/zli"
1818)
1919
20+ type agentsT []struct {
21+ ID int64 `db:"user_agent_id"`
22+ UserAgent string `db:"ua"`
23+ }
24+
25+ func getAgents (ctx context.Context ) (agentsT , error ) {
26+ var agents agentsT
27+ err := zdb .Select (ctx , & agents , `select user_agent_id, ua from user_agents order by user_agent_id asc` )
28+ return agents , err
29+ }
30+
2031func UserAgents (ctx context.Context ) error {
21- var agents []struct {
22- ID int64 `db:"user_agent_id"`
23- UserAgent string `db:"ua"`
24- }
25- err := zdb .Select (ctx , & agents ,
26- `select user_agent_id, ua from user_agents order by user_agent_id asc` )
32+ agents , err := getAgents (ctx )
2733 if err != nil {
2834 return err
2935 }
30-
3136 if len (agents ) == 0 {
3237 return nil
3338 }
3439
40+ // Remove duplicates first.
41+ deleted := make (map [int64 ]struct {})
42+ for _ , u := range agents {
43+ if _ , ok := deleted [u .ID ]; ok {
44+ continue
45+ }
46+
47+ if strings .ContainsRune (u .UserAgent , '~' ) {
48+ u .UserAgent = gadget .Unshorten (u .UserAgent )
49+ } else {
50+ u .UserAgent = gadget .Shorten (u .UserAgent )
51+ }
52+
53+ var dupes []int64
54+ err := zdb .Select (ctx , & dupes , `select user_agent_id from user_agents where ua=? and user_agent_id != ?` ,
55+ u .UserAgent , u .ID )
56+ if err != nil {
57+ return err
58+ }
59+ if len (dupes ) > 0 {
60+ fmt .Printf ("%d → dupes: %v\n " , u .ID , dupes )
61+ err := zdb .Exec (ctx , `update hits set user_agent_id=? where user_agent_id in (?)` , u .ID , dupes )
62+ if err != nil {
63+ return err
64+ }
65+ err = zdb .Exec (ctx , `delete from user_agents where user_agent_id in (?)` , dupes )
66+ if err != nil {
67+ return err
68+ }
69+ for _ , d := range dupes {
70+ deleted [d ] = struct {}{}
71+ }
72+ }
73+ }
74+
75+ agents , err = getAgents (ctx )
76+ if err != nil {
77+ return err
78+ }
79+
3580 errs := errors .NewGroup (1000 )
3681 for i , u := range agents {
3782 if i % 100 == 0 {
@@ -61,8 +106,8 @@ func UserAgents(ctx context.Context) error {
61106 bot := isbot .UserAgent (u .UserAgent )
62107 err = zdb .Exec (ctx , `update user_agents
63108 set browser_id=$1, system_id=$2, ua=$3, isbot=$4 where user_agent_id=$5` ,
64- browser .ID , system .ID , u .UserAgent , bot , u .ID )
65- errs .Append (err )
109+ browser .ID , system .ID , gadget . Shorten ( u .UserAgent ) , bot , u .ID )
110+ errs .Append (errors . Wrapf ( err , "update user_agent %d" , u . ID ) )
66111 }
67112 if errs .Len () > 0 {
68113 return errs
0 commit comments