aboutsummaryrefslogtreecommitdiff
path: root/internal/db/migrations/v16.go
blob: f60f9d156cd16d356cd8259832dae9de908b6ccd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2017 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package migrations

import (
	"fmt"
	"path/filepath"
	"strings"

	log "unknwon.dev/clog/v2"
	"xorm.io/xorm"

	"github.com/gogs/git-module"

	"gogs.io/gogs/internal/conf"
)

func updateRepositorySizes(x *xorm.Engine) (err error) {
	log.Info("[migrations.v16] This migration could take up to minutes, please be patient.")
	type Repository struct {
		ID      int64
		OwnerID int64
		Name    string
		Size    int64
	}
	type User struct {
		ID   int64
		Name string
	}
	if err = x.Sync2(new(Repository)); err != nil {
		return fmt.Errorf("Sync2: %v", err)
	}

	// For the sake of SQLite3, we can't use x.Iterate here.
	offset := 0
	for {
		repos := make([]*Repository, 0, 10)
		if err = x.Sql(fmt.Sprintf("SELECT * FROM `repository` ORDER BY id ASC LIMIT 10 OFFSET %d", offset)).
			Find(&repos); err != nil {
			return fmt.Errorf("select repos [offset: %d]: %v", offset, err)
		}
		log.Trace("[migrations.v16] Select [offset: %d, repos: %d]", offset, len(repos))
		if len(repos) == 0 {
			break
		}
		offset += 10

		for _, repo := range repos {
			if repo.Name == "." || repo.Name == ".." {
				continue
			}

			user := new(User)
			has, err := x.Where("id = ?", repo.OwnerID).Get(user)
			if err != nil {
				return fmt.Errorf("query owner of repository [repo_id: %d, owner_id: %d]: %v", repo.ID, repo.OwnerID, err)
			} else if !has {
				continue
			}

			repoPath := strings.ToLower(filepath.Join(conf.Repository.Root, user.Name, repo.Name)) + ".git"
			countObject, err := git.RepoCountObjects(repoPath)
			if err != nil {
				log.Warn("[migrations.v16] Count repository objects: %v", err)
				continue
			}

			repo.Size = countObject.Size + countObject.SizePack
			if _, err = x.Id(repo.ID).Cols("size").Update(repo); err != nil {
				return fmt.Errorf("update size: %v", err)
			}
		}
	}
	return nil
}