You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudreve/inventory/dav_account.go

188 lines
5.2 KiB

package inventory
import (
"context"
"entgo.io/ent/dialect/sql"
"fmt"
"github.com/cloudreve/Cloudreve/v4/ent"
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
"github.com/samber/lo"
)
type (
DavAccountClient interface {
TxOperator
// List returns a list of dav accounts with the given args.
List(ctx context.Context, args *ListDavAccountArgs) (*ListDavAccountResult, error)
// Create creates a new dav account.
Create(ctx context.Context, params *CreateDavAccountParams) (*ent.DavAccount, error)
// Update updates a dav account.
Update(ctx context.Context, id int, params *CreateDavAccountParams) (*ent.DavAccount, error)
// GetByIDAndUserID returns the dav account with given id and user id.
GetByIDAndUserID(ctx context.Context, id, userID int) (*ent.DavAccount, error)
// Delete deletes the dav account.
Delete(ctx context.Context, id int) error
}
ListDavAccountArgs struct {
*PaginationArgs
UserID int
}
ListDavAccountResult struct {
*PaginationResults
Accounts []*ent.DavAccount
}
CreateDavAccountParams struct {
UserID int
Name string
URI string
Password string
Options *boolset.BooleanSet
}
)
func NewDavAccountClient(client *ent.Client, dbType conf.DBType, hasher hashid.Encoder) DavAccountClient {
return &davAccountClient{
client: client,
hasher: hasher,
maxSQlParam: sqlParamLimit(dbType),
}
}
type davAccountClient struct {
maxSQlParam int
client *ent.Client
hasher hashid.Encoder
}
func (c *davAccountClient) SetClient(newClient *ent.Client) TxOperator {
return &davAccountClient{client: newClient, hasher: c.hasher, maxSQlParam: c.maxSQlParam}
}
func (c *davAccountClient) GetClient() *ent.Client {
return c.client
}
func (c *davAccountClient) Create(ctx context.Context, params *CreateDavAccountParams) (*ent.DavAccount, error) {
account := c.client.DavAccount.Create().
SetOwnerID(params.UserID).
SetName(params.Name).
SetURI(params.URI).
SetPassword(params.Password).
SetOptions(params.Options)
return account.Save(ctx)
}
func (c *davAccountClient) GetByIDAndUserID(ctx context.Context, id, userID int) (*ent.DavAccount, error) {
return c.client.DavAccount.Query().
Where(davaccount.ID(id), davaccount.OwnerID(userID)).
First(ctx)
}
func (c *davAccountClient) Update(ctx context.Context, id int, params *CreateDavAccountParams) (*ent.DavAccount, error) {
account := c.client.DavAccount.UpdateOneID(id).
SetName(params.Name).
SetURI(params.URI).
SetOptions(params.Options)
return account.Save(ctx)
}
func (c *davAccountClient) Delete(ctx context.Context, id int) error {
return c.client.DavAccount.DeleteOneID(id).Exec(ctx)
}
func (c *davAccountClient) List(ctx context.Context, args *ListDavAccountArgs) (*ListDavAccountResult, error) {
query := c.listQuery(args)
var (
accounts []*ent.DavAccount
err error
paginationRes *PaginationResults
)
accounts, paginationRes, err = c.cursorPagination(ctx, query, args, 10)
if err != nil {
return nil, fmt.Errorf("query failed with paginiation: %w", err)
}
return &ListDavAccountResult{
Accounts: accounts,
PaginationResults: paginationRes,
}, nil
}
func (c *davAccountClient) cursorPagination(ctx context.Context, query *ent.DavAccountQuery, args *ListDavAccountArgs, paramMargin int) ([]*ent.DavAccount, *PaginationResults, error) {
pageSize := capPageSize(c.maxSQlParam, args.PageSize, paramMargin)
query.Order(davaccount.ByID(sql.OrderDesc()))
var (
pageToken *PageToken
err error
)
if args.PageToken != "" {
pageToken, err = pageTokenFromString(args.PageToken, c.hasher, hashid.DavAccountID)
if err != nil {
return nil, nil, fmt.Errorf("invalid page token %q: %w", args.PageToken, err)
}
}
queryPaged := getDavAccountCursorQuery(pageToken, query)
// Use page size + 1 to determine if there are more items to come
queryPaged.Limit(pageSize + 1)
logs, err := queryPaged.
All(ctx)
if err != nil {
return nil, nil, err
}
// More items to come
nextTokenStr := ""
if len(logs) > pageSize {
lastItem := logs[len(logs)-2]
nextToken, err := getDavAccountNextPageToken(c.hasher, lastItem)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate next page token: %w", err)
}
nextTokenStr = nextToken
}
return lo.Subset(logs, 0, uint(pageSize)), &PaginationResults{
PageSize: pageSize,
NextPageToken: nextTokenStr,
IsCursor: true,
}, nil
}
func (c *davAccountClient) listQuery(args *ListDavAccountArgs) *ent.DavAccountQuery {
query := c.client.DavAccount.Query()
if args.UserID > 0 {
query.Where(davaccount.OwnerID(args.UserID))
}
return query
}
// getDavAccountNextPageToken returns the next page token for the given last dav account.
func getDavAccountNextPageToken(hasher hashid.Encoder, last *ent.DavAccount) (string, error) {
token := &PageToken{
ID: last.ID,
}
return token.Encode(hasher, hashid.EncodeDavAccountID)
}
func getDavAccountCursorQuery(token *PageToken, query *ent.DavAccountQuery) *ent.DavAccountQuery {
if token != nil {
query.Where(davaccount.IDLT(token.ID))
}
return query
}