diff options
Diffstat (limited to 'internal/db/repos.go')
-rw-r--r-- | internal/db/repos.go | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/internal/db/repos.go b/internal/db/repos.go index cac50b76..f97cf28d 100644 --- a/internal/db/repos.go +++ b/internal/db/repos.go @@ -5,9 +5,13 @@ package db import ( + "fmt" "strings" + "time" "github.com/jinzhu/gorm" + + "gogs.io/gogs/internal/errutil" ) // ReposStore is the persistent interface for repositories. @@ -21,10 +25,106 @@ type ReposStore interface { var Repos ReposStore +// NOTE: This is a GORM create hook. +func (r *Repository) BeforeCreate() { + r.CreatedUnix = gorm.NowFunc().Unix() +} + +// NOTE: This is a GORM update hook. +func (r *Repository) BeforeUpdate() { + r.UpdatedUnix = gorm.NowFunc().Unix() +} + +// NOTE: This is a GORM query hook. +func (r *Repository) AfterFind() { + r.Created = time.Unix(r.CreatedUnix, 0).Local() + r.Updated = time.Unix(r.UpdatedUnix, 0).Local() +} + +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 returns 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 |