feat(storage): 💥 repository v2

master
Xeronith 2022-10-01 12:36:12 +03:30
rodzic 5119952846
commit 712564dada
12 zmienionych plików z 313 dodań i 9 usunięć

Wyświetl plik

@ -2,12 +2,8 @@ package db
import (
. "contracts"
"gorm.io/gorm"
)
var Executor *gorm.DB
const (
SqliteStorage StorageType = iota
MySQLStorage

Wyświetl plik

@ -3,6 +3,7 @@ module db
go 1.19
require (
github.com/gofiber/fiber/v2 v2.38.1
gorm.io/driver/mysql v1.3.6
gorm.io/driver/postgres v1.3.9
gorm.io/driver/sqlite v1.3.6
@ -10,6 +11,7 @@ require (
)
require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
@ -21,7 +23,12 @@ require (
github.com/jackc/pgx/v4 v4.16.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.15.0 // indirect
github.com/mattn/go-sqlite3 v1.14.14 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.40.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
)

Wyświetl plik

@ -1,6 +1,8 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@ -14,6 +16,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofiber/fiber/v2 v2.38.1 h1:GEQ/Yt3Wsf2a30iTqtLXlBYJZso0JXPovt/tmj5H9jU=
github.com/gofiber/fiber/v2 v2.38.1/go.mod h1:t0NlbaXzuGH7I+7M4paE848fNWInZ7mfxI/Er1fTth8=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
@ -70,6 +74,8 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -112,6 +118,12 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc=
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -133,8 +145,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@ -143,6 +156,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -155,9 +170,14 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

Wyświetl plik

@ -2,6 +2,7 @@ package db
import (
"contracts"
"db/repos"
"log"
"time"
@ -35,7 +36,7 @@ func (storage *mysqlStorage) Connect(dsn string) {
}
storage.database = database
Executor = storage.database
repos.Default.Storage = database
log.Println("[DATABASE]::CONNECTED")
}

Wyświetl plik

@ -2,6 +2,7 @@ package db
import (
"contracts"
"db/repos"
"log"
"time"
@ -35,7 +36,7 @@ func (storage *postgresqlStorage) Connect(dsn string) {
}
storage.database = database
Executor = storage.database
repos.Default.Storage = database
log.Println("[DATABASE]::CONNECTED")
}

Wyświetl plik

@ -0,0 +1,13 @@
package repos
var (
All = []interface{}{
&User{},
&IncomingActivity{},
&OutgoingActivity{},
&Follower{},
&Following{},
}
Default = &repository{}
)

Wyświetl plik

@ -0,0 +1,86 @@
package repos
import (
"contracts"
"errors"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
type Access int64
const (
ACCESS_PUBLIC Access = iota
ACCESS_PRIVATE
)
// User struct defines the user
type User struct {
gorm.Model
Username string `gorm:"uniqueIndex;not null"`
Email string `gorm:"uniqueIndex;not null"`
Password string `gorm:"not null"`
DisplayName string
Bio string
Github string
ApiKey string
PrivateKey string
PublicKey string
Avatar string
Banner string
Access Access
}
// CreateUser create a user entry in the user's table
func (repo *repository) CreateUser(user *User) error {
if err := repo.Storage.Create(user).Error; err != nil {
return err
}
return nil
}
// FindUser searches the user's table with the condition given
func (repo *repository) FindUser(conds ...any) (*User, error) {
dest := &User{}
if err := repo.Storage.Model(dest).Take(dest, conds...).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, &fiber.Error{
Code: contracts.StatusNotFound,
Message: "user not found",
}
} else {
return nil, &fiber.Error{
Code: contracts.StatusInternalServerError,
Message: err.Error(),
}
}
}
return dest, nil
}
// FindUserById searches the user's table with the id given
func (repo *repository) FindUserById(id uint) (*User, error) {
return repo.FindUser("id = ?", id)
}
// FindUserByEmail searches the user's table with the email given
func (repo *repository) FindUserByEmail(email string) (*User, error) {
return repo.FindUser("email = ?", email)
}
// FindUserByUsername searches the user's table with the name given
func (repo *repository) FindUserByUsername(username string) (*User, error) {
return repo.FindUser("username = ?", username)
}
// UpdateProfile updates the user's profile with the info given
func (repo *repository) UpdateProfile(userId interface{}, data interface{}) error {
if err := repo.Storage.Model(&User{}).Where("id = ?", userId).Updates(data).Error; err != nil {
return err
}
return nil
}

Wyświetl plik

@ -0,0 +1,72 @@
package repos
import (
"contracts"
"errors"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
// Follower struct defines a follower
type Follower struct {
gorm.Model
Target string `gorm:"not null"`
Handle string `gorm:"not null"`
HandleInbox string
Activity string
Accepted bool
}
// CreateFollower creates a new entry in the followers's table
func (repo *repository) CreateFollower(follower *Follower) error {
if err := repo.Storage.Create(follower).Error; err != nil {
return err
}
return nil
}
// FindFollower searches the followers table with the condition given
func (repo *repository) FindFollower(conds ...any) (*Follower, error) {
dest := &Follower{}
if err := repo.Storage.Model(&Follower{}).Take(dest, conds...).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, &fiber.Error{
Code: contracts.StatusNotFound,
Message: "follower not found",
}
} else {
return nil, &fiber.Error{
Code: contracts.StatusInternalServerError,
Message: err.Error(),
}
}
}
return dest, nil
}
// FindFollowers finds the user's followers
func (repo *repository) FindFollowers(userIden interface{}) ([]Follower, error) {
result := &[]Follower{}
if err := repo.Storage.Model(&Follower{}).Find(result, "`target` = ?", userIden).Error; err != nil {
return *result, err
}
return *result, nil
}
// FindFollowerById searches the followers's table with the id given
func (repo *repository) FindFollowerById(id uint64) (*Follower, error) {
return repo.FindFollower("id = ?", id)
}
// AcceptFollower accepts a follow request
func (repo *repository) AcceptFollower(id interface{}) error {
if err := repo.Storage.Model(&Follower{}).Where("id = ?", id).Update("accepted", true).Error; err != nil {
return err
}
return nil
}

Wyświetl plik

@ -0,0 +1,31 @@
package repos
import (
"gorm.io/gorm"
)
// Following struct defines an account that the user follows
type Following struct {
gorm.Model
Target string `gorm:"not null"`
Handle string `gorm:"not null"`
}
// CreateFollowing creates a new entry in the following's table
func (repo *repository) CreateFollowing(following *Following) error {
if err := repo.Storage.Create(following).Error; err != nil {
return err
}
return nil
}
// FindFollowing finds what accounts the user is following
func (repo *repository) FindFollowing(userIden interface{}) ([]Following, error) {
followings := &[]Following{}
if err := repo.Storage.Model(&Following{}).Find(followings, "`target` = ?", userIden).Error; err != nil {
return *followings, err
}
return *followings, nil
}

Wyświetl plik

@ -0,0 +1,69 @@
package repos
import (
"contracts"
"errors"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
// IncomingActivity struct defines the activity
type IncomingActivity struct {
gorm.Model
Timestamp int64
From string `gorm:"not null"`
To string `gorm:"not null"`
Guid string `gorm:"uniqueIndex;not null"`
Content string `gorm:"not null"`
}
// CreateIncomingActivity creates an activity entry in the incoming activities table
func (repo *repository) CreateIncomingActivity(activity *IncomingActivity) error {
if err := repo.Storage.Create(activity).Error; err != nil {
return err
}
return nil
}
// FindIncomingActivity searches the incoming activities table with the condition given
// and returns a single record.
func (repo *repository) FindIncomingActivity(conds ...interface{}) (*IncomingActivity, error) {
dest := &IncomingActivity{}
if err := repo.Storage.Model(&IncomingActivity{}).Take(dest, conds...).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, &fiber.Error{
Code: contracts.StatusNotFound,
Message: "activity not found",
}
} else {
return nil, &fiber.Error{
Code: contracts.StatusInternalServerError,
Message: err.Error(),
}
}
}
return dest, nil
}
// FindIncomingActivitiesForUser finds the activities posted to user
func (repo *repository) FindIncomingActivitiesForUser(userIden interface{}) ([]IncomingActivity, error) {
result := &[]IncomingActivity{}
if err := repo.Storage.Model(&IncomingActivity{}).Find(result, "`to` = ?", userIden).Error; err != nil {
return *result, err
}
return *result, nil
}
// FindIncomingActivityById searches the incoming activities table with the id given
func (repo *repository) FindIncomingActivityById(id uint) (*IncomingActivity, error) {
return repo.FindIncomingActivity("id = ?", id)
}
// FindIncomingActivityByGuid searches the incoming activities table with the guid given
func (repo *repository) FindIncomingActivityByGuid(guid string) (*IncomingActivity, error) {
return repo.FindIncomingActivity("guid = ?", guid)
}

Wyświetl plik

@ -0,0 +1,7 @@
package repos
import "gorm.io/gorm"
type repository struct {
Storage *gorm.DB
}

Wyświetl plik

@ -2,6 +2,7 @@ package db
import (
"contracts"
"db/repos"
"log"
"time"
@ -35,7 +36,7 @@ func (storage *sqliteStorage) Connect(path string) {
}
storage.database = database
Executor = storage.database
repos.Default.Storage = database
log.Println("[DATABASE]::CONNECTED")
}