aboutsummaryrefslogtreecommitdiff
path: root/internal/db/repos.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/db/repos.go')
-rw-r--r--internal/db/repos.go90
1 files changed, 82 insertions, 8 deletions
diff --git a/internal/db/repos.go b/internal/db/repos.go
index 8b4c5bce..c1480b16 100644
--- a/internal/db/repos.go
+++ b/internal/db/repos.go
@@ -10,18 +10,28 @@ import (
"strings"
"time"
+ api "github.com/gogs/go-gogs-client"
"gorm.io/gorm"
"gogs.io/gogs/internal/errutil"
+ "gogs.io/gogs/internal/repoutil"
)
// ReposStore is the persistent interface for repositories.
//
// NOTE: All methods are sorted in alphabetical order.
type ReposStore interface {
+ // Create creates a new repository record in the database. It returns
+ // ErrNameNotAllowed when the repository name is not allowed, or
+ // ErrRepoAlreadyExist when a repository with same name already exists for the
+ // owner.
+ Create(ctx context.Context, ownerID int64, opts CreateRepoOptions) (*Repository, error)
// GetByName returns the repository with given owner and name. It returns
// ErrRepoNotExist when not found.
GetByName(ctx context.Context, ownerID int64, name string) (*Repository, error)
+ // Touch updates the updated time to the current time and removes the bare state
+ // of the given repository.
+ Touch(ctx context.Context, id int64) error
}
var Repos ReposStore
@@ -47,12 +57,58 @@ func (r *Repository) AfterFind(_ *gorm.DB) error {
return nil
}
+type RepositoryAPIFormatOptions struct {
+ Permission *api.Permission
+ Parent *api.Repository
+}
+
+// APIFormat returns the API format of a repository.
+func (r *Repository) APIFormat(owner *User, opts ...RepositoryAPIFormatOptions) *api.Repository {
+ var opt RepositoryAPIFormatOptions
+ if len(opts) > 0 {
+ opt = opts[0]
+ }
+
+ cloneLink := repoutil.NewCloneLink(owner.Name, r.Name, false)
+ return &api.Repository{
+ ID: r.ID,
+ Owner: owner.APIFormat(),
+ Name: r.Name,
+ FullName: owner.Name + "/" + r.Name,
+ Description: r.Description,
+ Private: r.IsPrivate,
+ Fork: r.IsFork,
+ Parent: opt.Parent,
+ Empty: r.IsBare,
+ Mirror: r.IsMirror,
+ Size: r.Size,
+ HTMLURL: repoutil.HTMLURL(owner.Name, r.Name),
+ SSHURL: cloneLink.SSH,
+ CloneURL: cloneLink.HTTPS,
+ Website: r.Website,
+ Stars: r.NumStars,
+ Forks: r.NumForks,
+ Watchers: r.NumWatches,
+ OpenIssues: r.NumOpenIssues,
+ DefaultBranch: r.DefaultBranch,
+ Created: r.Created,
+ Updated: r.Updated,
+ Permissions: opt.Permission,
+ }
+}
+
var _ ReposStore = (*repos)(nil)
type repos struct {
*gorm.DB
}
+// NewReposStore returns a persistent interface for repositories with given
+// database connection.
+func NewReposStore(db *gorm.DB) ReposStore {
+ return &repos{DB: db}
+}
+
type ErrRepoAlreadyExist struct {
args errutil.Args
}
@@ -66,7 +122,7 @@ func (err ErrRepoAlreadyExist) Error() string {
return fmt.Sprintf("repository already exists: %v", err.args)
}
-type createRepoOpts struct {
+type CreateRepoOptions struct {
Name string
Description string
DefaultBranch string
@@ -79,10 +135,7 @@ type createRepoOpts struct {
ForkID int64
}
-// create creates a new repository record in the database. Fields of "repo" will be updated
-// in place upon insertion. It returns ErrNameNotAllowed when the repository name is not allowed,
-// or ErrRepoAlreadyExist when a repository with same name already exists for the owner.
-func (db *repos) create(ctx context.Context, ownerID int64, opts createRepoOpts) (*Repository, error) {
+func (db *repos) Create(ctx context.Context, ownerID int64, opts CreateRepoOptions) (*Repository, error) {
err := isRepoNameAllowed(opts.Name)
if err != nil {
return nil, err
@@ -90,7 +143,12 @@ func (db *repos) create(ctx context.Context, ownerID int64, opts createRepoOpts)
_, err = db.GetByName(ctx, ownerID, opts.Name)
if err == nil {
- return nil, ErrRepoAlreadyExist{args: errutil.Args{"ownerID": ownerID, "name": opts.Name}}
+ return nil, ErrRepoAlreadyExist{
+ args: errutil.Args{
+ "ownerID": ownerID,
+ "name": opts.Name,
+ },
+ }
} else if !IsErrRepoNotExist(err) {
return nil, err
}
@@ -115,7 +173,7 @@ func (db *repos) create(ctx context.Context, ownerID int64, opts createRepoOpts)
var _ errutil.NotFound = (*ErrRepoNotExist)(nil)
type ErrRepoNotExist struct {
- args map[string]interface{}
+ args errutil.Args
}
func IsErrRepoNotExist(err error) bool {
@@ -139,9 +197,25 @@ func (db *repos) GetByName(ctx context.Context, ownerID int64, name string) (*Re
Error
if err != nil {
if err == gorm.ErrRecordNotFound {
- return nil, ErrRepoNotExist{args: map[string]interface{}{"ownerID": ownerID, "name": name}}
+ return nil, ErrRepoNotExist{
+ args: errutil.Args{
+ "ownerID": ownerID,
+ "name": name,
+ },
+ }
}
return nil, err
}
return repo, nil
}
+
+func (db *repos) Touch(ctx context.Context, id int64) error {
+ return db.WithContext(ctx).
+ Model(new(Repository)).
+ Where("id = ?", id).
+ Updates(map[string]interface{}{
+ "is_bare": false,
+ "updated_unix": db.NowFunc().Unix(),
+ }).
+ Error
+}