···470470 id integer primary key autoincrement,
471471 name text unique
472472 );
473473+474474+ -- indexes for better star query performance
475475+ create index if not exists idx_stars_created on stars(created);
476476+ create index if not exists idx_stars_repo_at_created on stars(repo_at, created);
473477 `)
474478 if err != nil {
475479 return nil, err
+72-3
appview/db/star.go
···4747// Get a star record
4848func GetStar(e Execer, starredByDid string, repoAt syntax.ATURI) (*Star, error) {
4949 query := `
5050- select starred_by_did, repo_at, created, rkey
5050+ select starred_by_did, repo_at, created, rkey
5151 from stars
5252 where starred_by_did = ? and repo_at = ?`
5353 row := e.QueryRow(query, starredByDid, repoAt)
···119119 }
120120121121 repoQuery := fmt.Sprintf(
122122- `select starred_by_did, repo_at, created, rkey
122122+ `select starred_by_did, repo_at, created, rkey
123123 from stars
124124 %s
125125 order by created desc
···187187 var stars []Star
188188189189 rows, err := e.Query(`
190190- select
190190+ select
191191 s.starred_by_did,
192192 s.repo_at,
193193 s.rkey,
···244244245245 return stars, nil
246246}
247247+248248+// GetTopStarredReposLastWeek returns the top 8 most starred repositories from the last week
249249+func GetTopStarredReposLastWeek(e Execer) ([]Repo, error) {
250250+ // first, get the top repo URIs by star count from the last week
251251+ query := `
252252+ with recent_starred_repos as (
253253+ select distinct repo_at
254254+ from stars
255255+ where created >= datetime('now', '-7 days')
256256+ ),
257257+ repo_star_counts as (
258258+ select
259259+ s.repo_at,
260260+ count(*) as star_count
261261+ from stars s
262262+ join recent_starred_repos rsr on s.repo_at = rsr.repo_at
263263+ group by s.repo_at
264264+ )
265265+ select rsc.repo_at
266266+ from repo_star_counts rsc
267267+ order by rsc.star_count desc
268268+ limit 8
269269+ `
270270+271271+ rows, err := e.Query(query)
272272+ if err != nil {
273273+ return nil, err
274274+ }
275275+ defer rows.Close()
276276+277277+ var repoUris []string
278278+ for rows.Next() {
279279+ var repoUri string
280280+ err := rows.Scan(&repoUri)
281281+ if err != nil {
282282+ return nil, err
283283+ }
284284+ repoUris = append(repoUris, repoUri)
285285+ }
286286+287287+ if err := rows.Err(); err != nil {
288288+ return nil, err
289289+ }
290290+291291+ if len(repoUris) == 0 {
292292+ return []Repo{}, nil
293293+ }
294294+295295+ // get full repo data
296296+ repos, err := GetRepos(e, 0, FilterIn("at_uri", repoUris))
297297+ if err != nil {
298298+ return nil, err
299299+ }
300300+301301+ // sort repos by the original trending order
302302+ repoMap := make(map[string]Repo)
303303+ for _, repo := range repos {
304304+ repoMap[repo.RepoAt().String()] = repo
305305+ }
306306+307307+ orderedRepos := make([]Repo, 0, len(repoUris))
308308+ for _, uri := range repoUris {
309309+ if repo, exists := repoMap[uri]; exists {
310310+ orderedRepos = append(orderedRepos, repo)
311311+ }
312312+ }
313313+314314+ return orderedRepos, nil
315315+}