| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | // Copyright 2020 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 dbimport (	"fmt"	"strings"	"time"	"gorm.io/gorm"	"gogs.io/gogs/internal/errutil")// ReposStore is the persistent interface for repositories.//// NOTE: All methods are sorted in alphabetical order.type ReposStore interface {	// GetByName returns the repository with given owner and name.	// It returns ErrRepoNotExist when not found.	GetByName(ownerID int64, name string) (*Repository, error)}var Repos ReposStore// NOTE: This is a GORM create hook.func (r *Repository) BeforeCreate(tx *gorm.DB) error {	if r.CreatedUnix == 0 {		r.CreatedUnix = tx.NowFunc().Unix()	}	return nil}// NOTE: This is a GORM update hook.func (r *Repository) BeforeUpdate(tx *gorm.DB) error {	r.UpdatedUnix = tx.NowFunc().Unix()	return nil}// NOTE: This is a GORM query hook.func (r *Repository) AfterFind(_ *gorm.DB) error {	r.Created = time.Unix(r.CreatedUnix, 0).Local()	r.Updated = time.Unix(r.UpdatedUnix, 0).Local()	return nil}var _ ReposStore = (*repos)(nil)type repos struct {	*gorm.DB}type ErrRepoAlreadyExist struct {	args errutil.Args}func IsErrRepoAlreadyExist(err error) bool {	_, ok := err.(ErrRepoAlreadyExist)	return ok}func (err ErrRepoAlreadyExist) Error() string {	return fmt.Sprintf("repository already exists: %v", err.args)}type createRepoOpts struct {	Name          string	Description   string	DefaultBranch string	Private       bool	Mirror        bool	EnableWiki    bool	EnableIssues  bool	EnablePulls   bool	Fork          bool	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(ownerID int64, opts createRepoOpts) (*Repository, error) {	err := isRepoNameAllowed(opts.Name)	if err != nil {		return nil, err	}	_, err = db.GetByName(ownerID, opts.Name)	if err == nil {		return nil, ErrRepoAlreadyExist{args: errutil.Args{"ownerID": ownerID, "name": opts.Name}}	} else if !IsErrRepoNotExist(err) {		return nil, err	}	repo := &Repository{		OwnerID:       ownerID,		LowerName:     strings.ToLower(opts.Name),		Name:          opts.Name,		Description:   opts.Description,		DefaultBranch: opts.DefaultBranch,		IsPrivate:     opts.Private,		IsMirror:      opts.Mirror,		EnableWiki:    opts.EnableWiki,		EnableIssues:  opts.EnableIssues,		EnablePulls:   opts.EnablePulls,		IsFork:        opts.Fork,		ForkID:        opts.ForkID,	}	return repo, db.DB.Create(repo).Error}var _ errutil.NotFound = (*ErrRepoNotExist)(nil)type ErrRepoNotExist struct {	args map[string]interface{}}func IsErrRepoNotExist(err error) bool {	_, ok := err.(ErrRepoNotExist)	return ok}func (err ErrRepoNotExist) Error() string {	return fmt.Sprintf("repository does not exist: %v", err.args)}func (ErrRepoNotExist) NotFound() bool {	return true}func (db *repos) GetByName(ownerID int64, name string) (*Repository, error) {	repo := new(Repository)	err := db.Where("owner_id = ? AND lower_name = ?", ownerID, strings.ToLower(name)).First(repo).Error	if err != nil {		if err == gorm.ErrRecordNotFound {			return nil, ErrRepoNotExist{args: map[string]interface{}{"ownerID": ownerID, "name": name}}		}		return nil, err	}	return repo, nil}
 |