diff --git a/storage/errors.go b/storage/errors.go index ac1ee99..b0885d0 100644 --- a/storage/errors.go +++ b/storage/errors.go @@ -9,3 +9,5 @@ func (n ErrNotImplemented) Error() string { } var ErrEntryNotFound = errors.New("entry not found") +var ErrEntryAlreadyExists = errors.New("entry already exists") +var ErrNothingToChange = errors.New("nothing to change") diff --git a/storage/inboundJobs.go b/storage/inboundJobs.go index 736db97..231dd33 100644 --- a/storage/inboundJobs.go +++ b/storage/inboundJobs.go @@ -1,8 +1,6 @@ package storage import ( - "time" - "gorm.io/gorm" ) @@ -23,8 +21,7 @@ const ( // Ensures data consistency in case the server is forced to restart unexpectedly // No DeletedAt field since don't want completed jobs to linger in the db for any longer than necessary type InboundJob struct { - ID uint `gorm:"primarykey"` - CreatedAt time.Time + gorm.Model // Raw data, could be json or gob data, check source for how to interpret RawData []byte `gorm:"->;<-create"` // Where this job is coming from. Important for figuring out how to decode the raw data and what to do with it @@ -47,9 +44,9 @@ func (s *Storage) AddNewInboundJob(data []byte, source InboundJobSource, inboxOw } // Get the specified amount of jobs, sorted by age (oldest first) -func (s *Storage) GetOldestInboundJobs(amount int) ([]InboundJob, error) { +func (s *Storage) GetOldestInboundJobs(amount uint) ([]InboundJob, error) { jobs := []InboundJob{} - switch err := s.db.Order("id asc, created_at asc").Limit(amount).Find(jobs).Error; err { + switch err := s.db.Order("id asc, created_at asc").Limit(int(amount)).Find(jobs).Error; err { case gorm.ErrRecordNotFound: return nil, ErrEntryNotFound case nil: @@ -58,3 +55,8 @@ func (s *Storage) GetOldestInboundJobs(amount int) ([]InboundJob, error) { return nil, err } } + +func (s *Storage) CompleteInboundJob(id uint) error { + s.db.Delete(InboundJob{Model: gorm.Model{ID: id}}) + return nil +} diff --git a/storage/outboundJobs.go b/storage/outboundJobs.go index 27bda9e..74d7601 100644 --- a/storage/outboundJobs.go +++ b/storage/outboundJobs.go @@ -11,3 +11,44 @@ type OutboundJob struct { TargetPath string `gorm:"->;<-:create"` // The full path of api endpoint targeted Data []byte `gorm:"->;<-:create"` // The raw data to send } + +func (s *Storage) AddNewOutboundJob(data []byte, targetDomain string, targetUrl string) { + newJob := OutboundJob{ + Data: data, + TargetServer: targetDomain, + TargetPath: targetUrl, + } + s.db.Create(&newJob) +} + +// Get the specified amount of jobs, sorted by age (oldest first) +func (s *Storage) GetOldestOutboundJobs(amount uint) ([]OutboundJob, error) { + jobs := []OutboundJob{} + err := s.db.Order("id asc, created_at asc").Limit(int(amount)).Find(jobs).Error + switch err { + case gorm.ErrRecordNotFound: + return nil, ErrEntryNotFound + case nil: + return jobs, nil + default: + return nil, err + } +} + +func (s *Storage) GetOutboundJobsForDomain(domain string, amount uint) ([]OutboundJob, error) { + jobs := []OutboundJob{} + err := s.db.Where("target_server = ?", domain).Order("id asc, created_at asc").Limit(int(amount)).Find(jobs).Error + switch err { + case gorm.ErrRecordNotFound: + return nil, ErrEntryNotFound + case nil: + return jobs, nil + default: + return nil, err + } +} + +func (s *Storage) CompleteOutboundJob(id uint) error { + s.db.Delete(OutboundJob{Model: gorm.Model{ID: id}}) + return nil +} diff --git a/storage/remoteServerInfo.go b/storage/remoteServerInfo.go index 48a4005..d28812b 100644 --- a/storage/remoteServerInfo.go +++ b/storage/remoteServerInfo.go @@ -21,14 +21,32 @@ type RemoteServer struct { } func (s *Storage) FindRemoteServer(url string) (*RemoteServer, error) { - // TODO: Implement me - panic("not implemented") + server := RemoteServer{ + ID: url, + } + err := s.db.First(&server).Error + switch err { + case nil: + return &server, nil + case gorm.ErrRecordNotFound: + return nil, ErrEntryNotFound + default: + return nil, err + } } // Find a remote server with a given display name func (s *Storage) FindRemoteServerByDisplayName(displayName string) (*RemoteServer, error) { - // TODO: Implement me - panic("not implemented") + server := RemoteServer{} + err := s.db.Where("name = ?", displayName).First(&server).Error + switch err { + case nil: + return &server, nil + case gorm.ErrRecordNotFound: + return nil, ErrEntryNotFound + default: + return nil, err + } } // Create a new remote server @@ -36,8 +54,25 @@ func (s *Storage) NewRemoteServer( url, displayName, icon string, serverType RemoteServerType, ) (*RemoteServer, error) { - // TODO: Implement me - panic("not implemented") + _, err := s.FindRemoteServer(url) + switch err { + case nil: + return nil, ErrEntryAlreadyExists + case ErrEntryNotFound: // Empty case, not found is what we want + default: + return nil, err + } + server := RemoteServer{ + ID: url, + Name: displayName, + Icon: icon, + ServerType: serverType, + } + err = s.db.Create(&server).Error + if err != nil { + return nil, err + } + return &server, nil } // Update a remote server with the given url @@ -45,6 +80,22 @@ func (s *Storage) NewRemoteServer( // If icon is set, update that // Returns the updated version func (s *Storage) UpdateRemoteServer(url string, displayName, icon *string) (*RemoteServer, error) { - // TODO: Implement me - panic("not implemented") + if displayName == nil && icon == nil { + return nil, ErrNothingToChange + } + server, err := s.FindRemoteServer(url) + if err != nil { + return nil, err + } + if displayName != nil { + server.Name = *displayName + } + if icon != nil { + server.Icon = *icon + } + err = s.db.Save(server).Error + if err != nil { + return nil, err + } + return server, nil }