mirror of
https://github.com/versia-pub/versia-go.git
synced 2026-03-13 12:39:15 +01:00
chore: init
This commit is contained in:
commit
320715f3e7
174 changed files with 42083 additions and 0 deletions
171
internal/repository/repo_impls/follow_repository_impl.go
Normal file
171
internal/repository/repo_impls/follow_repository_impl.go
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
package repo_impls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/lysand-org/versia-go/ent"
|
||||
"github.com/lysand-org/versia-go/ent/follow"
|
||||
"github.com/lysand-org/versia-go/ent/predicate"
|
||||
"github.com/lysand-org/versia-go/ent/user"
|
||||
"github.com/lysand-org/versia-go/internal/entity"
|
||||
"github.com/lysand-org/versia-go/internal/utils"
|
||||
)
|
||||
|
||||
var ErrFollowAlreadyExists = errors.New("follow already exists")
|
||||
|
||||
var _ repository.FollowRepository = (*FollowRepositoryImpl)(nil)
|
||||
|
||||
type FollowRepositoryImpl struct {
|
||||
db *ent.Client
|
||||
log logr.Logger
|
||||
telemetry *unitel.Telemetry
|
||||
}
|
||||
|
||||
func NewFollowRepositoryImpl(db *ent.Client, log logr.Logger, telemetry *unitel.Telemetry) repository.FollowRepository {
|
||||
return &FollowRepositoryImpl{
|
||||
db: db,
|
||||
log: log,
|
||||
telemetry: telemetry,
|
||||
}
|
||||
}
|
||||
|
||||
func (i FollowRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entity.Follow, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.FollowRepositoryImpl.GetByID").
|
||||
AddAttribute("followID", id)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
f, err := i.db.Follow.Query().
|
||||
Where(follow.ID(id)).
|
||||
WithFollowee().
|
||||
WithFollower().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.AddAttribute("follower", f.Edges.Follower.URI).
|
||||
AddAttribute("followee", f.Edges.Followee.URI).
|
||||
AddAttribute("followURI", f.URI)
|
||||
|
||||
return entity.NewFollow(f)
|
||||
}
|
||||
|
||||
func (i FollowRepositoryImpl) Follow(ctx context.Context, follower, followee *entity.User) (*entity.Follow, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.FollowRepositoryImpl.Follow").
|
||||
AddAttribute("follower", follower.URI).
|
||||
AddAttribute("followee", followee.URI)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
fid := uuid.New()
|
||||
|
||||
fid, err := i.db.Follow.Create().
|
||||
SetID(fid).
|
||||
SetIsRemote(false).
|
||||
SetURI(utils.UserAPIURL(fid).String()).
|
||||
SetStatus(follow.StatusPending).
|
||||
SetFollower(follower.User).
|
||||
SetFollowee(followee.User).
|
||||
OnConflictColumns(follow.FollowerColumn, follow.FolloweeColumn).
|
||||
UpdateStatus().
|
||||
ID(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsConstraintError(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, ErrFollowAlreadyExists
|
||||
}
|
||||
|
||||
s.AddAttribute("followID", fid)
|
||||
|
||||
f, err := i.db.Follow.Query().
|
||||
Where(follow.ID(fid)).
|
||||
WithFollowee().
|
||||
WithFollower().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.AddAttribute("followURI", f.URI)
|
||||
|
||||
return entity.NewFollow(f)
|
||||
}
|
||||
|
||||
func (i FollowRepositoryImpl) Unfollow(ctx context.Context, follower, followee *entity.User) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.FollowRepositoryImpl.Unfollow").
|
||||
AddAttribute("follower", follower.URI).
|
||||
AddAttribute("followee", followee.URI)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
n, err := i.db.Follow.Delete().
|
||||
Where(matchFollowUsers(follower, followee)).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
s.CaptureError(err)
|
||||
} else {
|
||||
s.AddAttribute("deleted", n).
|
||||
CaptureMessage(fmt.Sprintf("Deleted %d follow(s)", n))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i FollowRepositoryImpl) AcceptFollow(ctx context.Context, follower, followee *entity.User) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.FollowRepositoryImpl.AcceptFollow").
|
||||
AddAttribute("follower", follower.URI).
|
||||
AddAttribute("followee", followee.URI)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
n, err := i.db.Follow.Update().
|
||||
Where(matchFollowUsers(follower, followee), follow.StatusEQ(follow.StatusPending)).
|
||||
SetStatus(follow.StatusAccepted).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
s.CaptureError(err)
|
||||
} else {
|
||||
s.CaptureMessage(fmt.Sprintf("Accepted %d follow(s)", n))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (i FollowRepositoryImpl) RejectFollow(ctx context.Context, follower, followee *entity.User) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.FollowRepositoryImpl.RejectFollow").
|
||||
AddAttribute("follower", follower.URI).
|
||||
AddAttribute("followee", followee.URI)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
n, err := i.db.Follow.Delete().
|
||||
Where(follow.And(matchFollowUsers(follower, followee), follow.StatusEQ(follow.StatusPending))).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
s.CaptureError(err)
|
||||
} else {
|
||||
s.CaptureMessage(fmt.Sprintf("Deleted %d follow(s)", n))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func matchFollowUsers(follower, followee *entity.User) predicate.Follow {
|
||||
return follow.And(
|
||||
follow.HasFollowerWith(
|
||||
user.ID(follower.ID), user.ID(followee.ID),
|
||||
),
|
||||
follow.HasFolloweeWith(
|
||||
user.ID(follower.ID), user.ID(followee.ID),
|
||||
),
|
||||
)
|
||||
}
|
||||
90
internal/repository/repo_impls/manager.go
Normal file
90
internal/repository/repo_impls/manager.go
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
package repo_impls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/lysand-org/versia-go/ent"
|
||||
"github.com/lysand-org/versia-go/internal/database"
|
||||
)
|
||||
|
||||
type Factory[T any] func(db *ent.Client, log logr.Logger, telemetry *unitel.Telemetry) T
|
||||
|
||||
var _ repository.Manager = (*ManagerImpl)(nil)
|
||||
|
||||
type ManagerImpl struct {
|
||||
users repository.UserRepository
|
||||
notes repository.NoteRepository
|
||||
follows repository.FollowRepository
|
||||
|
||||
uRFactory Factory[repository.UserRepository]
|
||||
nRFactory Factory[repository.NoteRepository]
|
||||
fRFactory Factory[repository.FollowRepository]
|
||||
|
||||
db *ent.Client
|
||||
log logr.Logger
|
||||
telemetry *unitel.Telemetry
|
||||
}
|
||||
|
||||
func NewManagerImpl(db *ent.Client, telemetry *unitel.Telemetry, log logr.Logger, userRepositoryFunc Factory[repository.UserRepository], noteRepositoryFunc Factory[repository.NoteRepository], followRepositoryFunc Factory[repository.FollowRepository]) *ManagerImpl {
|
||||
userRepository := userRepositoryFunc(db, log.WithName("users"), telemetry)
|
||||
noteRepository := noteRepositoryFunc(db, log.WithName("notes"), telemetry)
|
||||
followRepository := followRepositoryFunc(db, log.WithName("follows"), telemetry)
|
||||
|
||||
return &ManagerImpl{
|
||||
users: userRepository,
|
||||
notes: noteRepository,
|
||||
follows: followRepository,
|
||||
|
||||
uRFactory: userRepositoryFunc,
|
||||
nRFactory: noteRepositoryFunc,
|
||||
fRFactory: followRepositoryFunc,
|
||||
|
||||
db: db,
|
||||
log: log,
|
||||
telemetry: telemetry,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *ManagerImpl) withDB(db *ent.Client) *ManagerImpl {
|
||||
return NewManagerImpl(db, i.telemetry, i.log, i.uRFactory, i.nRFactory, i.fRFactory)
|
||||
}
|
||||
|
||||
func (i *ManagerImpl) Atomic(ctx context.Context, fn func(ctx context.Context, tx repository.Manager) error) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.ManagerImpl.Atomic")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
tx, err := database.BeginTx(ctx, i.db, i.telemetry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(tx *database.Tx) {
|
||||
err := tx.Finish()
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to finish transaction")
|
||||
}
|
||||
}(tx)
|
||||
|
||||
if err := fn(ctx, i.withDB(tx.Client())); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.MarkForCommit()
|
||||
|
||||
return tx.Finish()
|
||||
}
|
||||
|
||||
func (i *ManagerImpl) Users() repository.UserRepository {
|
||||
return i.users
|
||||
}
|
||||
|
||||
func (i *ManagerImpl) Notes() repository.NoteRepository {
|
||||
return i.notes
|
||||
}
|
||||
|
||||
func (i *ManagerImpl) Follows() repository.FollowRepository {
|
||||
return i.follows
|
||||
}
|
||||
117
internal/repository/repo_impls/note_repository_impl.go
Normal file
117
internal/repository/repo_impls/note_repository_impl.go
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
package repo_impls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/lysand-org/versia-go/ent"
|
||||
"github.com/lysand-org/versia-go/ent/note"
|
||||
"github.com/lysand-org/versia-go/internal/entity"
|
||||
"github.com/lysand-org/versia-go/internal/utils"
|
||||
"github.com/lysand-org/versia-go/pkg/lysand"
|
||||
)
|
||||
|
||||
var _ repository.NoteRepository = (*NoteRepositoryImpl)(nil)
|
||||
|
||||
type NoteRepositoryImpl struct {
|
||||
db *ent.Client
|
||||
log logr.Logger
|
||||
telemetry *unitel.Telemetry
|
||||
}
|
||||
|
||||
func NewNoteRepositoryImpl(db *ent.Client, log logr.Logger, telemetry *unitel.Telemetry) repository.NoteRepository {
|
||||
return &NoteRepositoryImpl{
|
||||
db: db,
|
||||
log: log,
|
||||
telemetry: telemetry,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *NoteRepositoryImpl) NewNote(ctx context.Context, author *entity.User, content string, mentions []*entity.User) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.NoteRepositoryImpl.NewNote")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
nid := uuid.New()
|
||||
|
||||
n, err := i.db.Note.Create().
|
||||
SetID(nid).
|
||||
SetIsRemote(false).
|
||||
SetURI(utils.NoteAPIURL(nid).String()).
|
||||
SetAuthor(author.User).
|
||||
SetContent(content).
|
||||
AddMentions(utils.MapSlice(mentions, func(m *entity.User) *ent.User { return m.User })...).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n, err = i.db.Note.Query().
|
||||
Where(note.ID(nid)).
|
||||
WithAuthor().
|
||||
WithMentions().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to query author", "id", nid)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entity.NewNote(n)
|
||||
}
|
||||
|
||||
func (i *NoteRepositoryImpl) ImportLysandNote(ctx context.Context, lNote *lysand.Note) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.NoteRepositoryImpl.ImportLysandNote")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
id, err := i.db.Note.Create().
|
||||
SetID(uuid.New()).
|
||||
SetIsRemote(true).
|
||||
SetURI(lNote.URI.String()).
|
||||
OnConflict().
|
||||
UpdateNewValues().
|
||||
ID(ctx)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to import note into database", "uri", lNote.URI)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n, err := i.db.Note.Get(ctx, id)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to get imported note", "id", id, "uri", lNote.URI)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("Imported note into database", "id", id, "uri", lNote.URI)
|
||||
|
||||
return entity.NewNote(n)
|
||||
}
|
||||
|
||||
func (i *NoteRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.NoteRepositoryImpl.LookupByIDOrUsername")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
n, err := i.db.Note.Query().
|
||||
Where(note.ID(id)).
|
||||
WithAuthor().
|
||||
WithMentions().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsNotFound(err) {
|
||||
i.log.Error(err, "Failed to query user", "id", id)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User not found in DB", "id", id)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User found in DB", "id", id)
|
||||
|
||||
return entity.NewNote(n)
|
||||
}
|
||||
325
internal/repository/repo_impls/user_repository_impl.go
Normal file
325
internal/repository/repo_impls/user_repository_impl.go
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
package repo_impls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"errors"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
"github.com/lysand-org/versia-go/internal/service"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/lysand-org/versia-go/ent"
|
||||
"github.com/lysand-org/versia-go/ent/predicate"
|
||||
"github.com/lysand-org/versia-go/ent/user"
|
||||
"github.com/lysand-org/versia-go/internal/entity"
|
||||
"github.com/lysand-org/versia-go/internal/utils"
|
||||
"github.com/lysand-org/versia-go/pkg/lysand"
|
||||
)
|
||||
|
||||
const bcryptCost = 12
|
||||
|
||||
var (
|
||||
ErrUsernameTaken = errors.New("username taken")
|
||||
|
||||
_ repository.UserRepository = (*UserRepositoryImpl)(nil)
|
||||
)
|
||||
|
||||
type UserRepositoryImpl struct {
|
||||
federationService service.FederationService
|
||||
|
||||
db *ent.Client
|
||||
log logr.Logger
|
||||
telemetry *unitel.Telemetry
|
||||
}
|
||||
|
||||
func NewUserRepositoryImpl(federationService service.FederationService, db *ent.Client, log logr.Logger, telemetry *unitel.Telemetry) repository.UserRepository {
|
||||
return &UserRepositoryImpl{
|
||||
federationService: federationService,
|
||||
db: db,
|
||||
log: log,
|
||||
telemetry: telemetry,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) NewUser(ctx context.Context, username, password string, priv ed25519.PrivateKey, pub ed25519.PublicKey) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.NewUser")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
pwHash, err := bcrypt.GenerateFromPassword([]byte(password), bcryptCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uid := uuid.New()
|
||||
|
||||
u, err := i.db.User.Create().
|
||||
SetID(uid).
|
||||
SetIsRemote(false).
|
||||
SetURI(utils.UserAPIURL(uid).String()).
|
||||
SetUsername(username).
|
||||
SetPasswordHash(pwHash).
|
||||
SetPublicKey(pub).
|
||||
SetPrivateKey(priv).
|
||||
SetInbox(utils.UserInboxAPIURL(uid).String()).
|
||||
SetOutbox(utils.UserOutboxAPIURL(uid).String()).
|
||||
SetFeatured(utils.UserFeaturedAPIURL(uid).String()).
|
||||
SetFollowers(utils.UserFollowersAPIURL(uid).String()).
|
||||
SetFollowing(utils.UserFollowingAPIURL(uid).String()).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
if ent.IsConstraintError(err) {
|
||||
return nil, ErrUsernameTaken
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) ImportLysandUserByURI(ctx context.Context, uri *lysand.URL) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.ImportLysandUserByURI")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
lUser, err := i.federationService.GetUser(ctx, uri)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to fetch remote user", "uri", uri)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := i.db.User.Create().
|
||||
SetID(uuid.New()).
|
||||
SetIsRemote(true).
|
||||
SetURI(lUser.URI.String()).
|
||||
SetUsername(lUser.Username).
|
||||
SetNillableDisplayName(lUser.DisplayName).
|
||||
SetBiography(lUser.Bio.String()).
|
||||
SetPublicKey(lUser.PublicKey.PublicKey.ToStd()).
|
||||
SetIndexable(lUser.Indexable).
|
||||
SetFields(lUser.Fields).
|
||||
SetExtensions(lUser.Extensions).
|
||||
SetInbox(lUser.Inbox.String()).
|
||||
SetOutbox(lUser.Outbox.String()).
|
||||
SetFeatured(lUser.Featured.String()).
|
||||
SetFollowers(lUser.Followers.String()).
|
||||
SetFollowing(lUser.Following.String()).
|
||||
OnConflict().
|
||||
UpdateNewValues().
|
||||
ID(ctx)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to import user into database", "uri", lUser.URI)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u, err := i.db.User.Get(ctx, id)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to get imported user", "id", id, "uri", lUser.URI)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("Imported user into database", "id", id, "uri", lUser.URI)
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) Resolve(ctx context.Context, uri *lysand.URL) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.Resolve")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
u, err := i.LookupByURI(ctx, uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// check if the user is already imported
|
||||
if u == nil {
|
||||
i.log.V(2).Info("User not found in DB", "uri", uri)
|
||||
|
||||
u, err := i.ImportLysandUserByURI(ctx, uri)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to import user", "uri", uri)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User found in DB", "uri", uri)
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) ResolveMultiple(ctx context.Context, uris []lysand.URL) ([]*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.ResolveMultiple")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
us, err := i.LookupByURIs(ctx, uris)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: Refactor to use async imports using a work queue
|
||||
outer:
|
||||
for _, uri := range uris {
|
||||
// check if the user is already imported
|
||||
for _, u := range us {
|
||||
if uri.String() == u.URI.String() {
|
||||
i.log.V(2).Info("User found in DB", "uri", uri)
|
||||
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User not found in DB", "uri", uri)
|
||||
|
||||
importedUser, err := i.ImportLysandUserByURI(ctx, &uri)
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to import user", "uri", uri)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
i.log.V(2).Info("Imported user", "uri", uri)
|
||||
|
||||
us = append(us, importedUser)
|
||||
}
|
||||
|
||||
return us, nil
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) GetByID(ctx context.Context, uid uuid.UUID) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.GetByID")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
u, err := i.db.User.Query().
|
||||
Where(user.IDEQ(uid)).
|
||||
WithAvatarImage().
|
||||
WithHeaderImage().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsNotFound(err) {
|
||||
i.log.Error(err, "Failed to query user", "id", uid)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User not found in DB", "id", uid)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User found in DB", "id", uid)
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) GetLocalByID(ctx context.Context, uid uuid.UUID) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.GetLocalByID")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
u, err := i.db.User.Query().
|
||||
Where(user.And(user.ID(uid), user.IsRemote(false))).
|
||||
WithAvatarImage().
|
||||
WithHeaderImage().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsNotFound(err) {
|
||||
i.log.Error(err, "Failed to query local user", "id", uid)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("Local user not found in DB", "id", uid)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("Local user found in DB", "id", uid)
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) LookupByURI(ctx context.Context, uri *lysand.URL) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.LookupByURI")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
// check if the user is already imported
|
||||
u, err := i.db.User.Query().
|
||||
Where(user.URI(uri.String())).
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsNotFound(err) {
|
||||
i.log.Error(err, "Failed to query user", "uri", uri)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User not found in DB", "uri", uri)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User found in DB", "uri", uri)
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) LookupByURIs(ctx context.Context, uris []lysand.URL) ([]*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.LookupByURIs")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
urisStrs := make([]string, 0, len(uris))
|
||||
for _, u := range uris {
|
||||
urisStrs = append(urisStrs, u.String())
|
||||
}
|
||||
|
||||
us, err := i.db.User.Query().
|
||||
Where(user.URIIn(urisStrs...)).
|
||||
All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return utils.MapErrorSlice(us, entity.NewUser)
|
||||
}
|
||||
|
||||
func (i *UserRepositoryImpl) LookupByIDOrUsername(ctx context.Context, idOrUsername string) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "repository/repo_impls.UserRepositoryImpl.LookupByIDOrUsername")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
var preds []predicate.User
|
||||
if u, err := uuid.Parse(idOrUsername); err == nil {
|
||||
preds = append(preds, user.IDEQ(u))
|
||||
} else {
|
||||
preds = append(preds, user.UsernameEQ(idOrUsername))
|
||||
}
|
||||
|
||||
u, err := i.db.User.Query().
|
||||
Where(preds...).
|
||||
WithAvatarImage().
|
||||
WithHeaderImage().
|
||||
Only(ctx)
|
||||
if err != nil {
|
||||
if !ent.IsNotFound(err) {
|
||||
i.log.Error(err, "Failed to query user", "idOrUsername", idOrUsername)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User not found in DB", "idOrUsername", idOrUsername)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
i.log.V(2).Info("User found in DB", "idOrUsername", idOrUsername, "id", u.ID)
|
||||
|
||||
return entity.NewUser(u)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue