mirror of
https://github.com/cloudreve/Cloudreve.git
synced 2025-12-25 15:42:47 +00:00
feat(fs): fs change event notification via SSE / show panic stack trace in task queue
This commit is contained in:
parent
05c68b4062
commit
c01b748dfc
|
|
@ -178,6 +178,8 @@ func (s *server) Close() {
|
|||
defer cancel()
|
||||
}
|
||||
|
||||
s.dep.EventHub().Close()
|
||||
|
||||
// Shutdown http server
|
||||
if s.server != nil {
|
||||
err := s.server.Shutdown(ctx)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/pkg/credmanager"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/email"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/encrypt"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/eventhub"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs/mime"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/lock"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
|
|
@ -134,6 +135,8 @@ type Dep interface {
|
|||
MasterEncryptKeyVault(ctx context.Context) encrypt.MasterEncryptKeyVault
|
||||
// EncryptorFactory Get a new encrypt.CryptorFactory instance.
|
||||
EncryptorFactory(ctx context.Context) encrypt.CryptorFactory
|
||||
// EventHub Get a singleton eventhub.EventHub instance for event publishing.
|
||||
EventHub() eventhub.EventHub
|
||||
}
|
||||
|
||||
type dependency struct {
|
||||
|
|
@ -156,6 +159,7 @@ type dependency struct {
|
|||
nodeClient inventory.NodeClient
|
||||
davAccountClient inventory.DavAccountClient
|
||||
directLinkClient inventory.DirectLinkClient
|
||||
fsEventClient inventory.FsEventClient
|
||||
emailClient email.Driver
|
||||
generalAuth auth.Auth
|
||||
hashidEncoder hashid.Encoder
|
||||
|
|
@ -179,6 +183,7 @@ type dependency struct {
|
|||
parser *uaparser.Parser
|
||||
cron *cron.Cron
|
||||
masterEncryptKeyVault encrypt.MasterEncryptKeyVault
|
||||
eventHub eventhub.EventHub
|
||||
|
||||
configPath string
|
||||
isPro bool
|
||||
|
|
@ -364,6 +369,21 @@ func (d *dependency) NavigatorStateKV() cache.Driver {
|
|||
return d.navigatorStateKv
|
||||
}
|
||||
|
||||
func (d *dependency) EventHub() eventhub.EventHub {
|
||||
if d.eventHub != nil {
|
||||
return d.eventHub
|
||||
}
|
||||
d.eventHub = eventhub.NewEventHub(d.UserClient(), d.FsEventClient())
|
||||
return d.eventHub
|
||||
}
|
||||
|
||||
func (d *dependency) FsEventClient() inventory.FsEventClient {
|
||||
if d.fsEventClient != nil {
|
||||
return d.fsEventClient
|
||||
}
|
||||
return inventory.NewFsEventClient(d.DBClient(), d.ConfigProvider().Database().Type)
|
||||
}
|
||||
|
||||
func (d *dependency) SettingClient() inventory.SettingClient {
|
||||
if d.settingClient != nil {
|
||||
return d.settingClient
|
||||
|
|
@ -861,6 +881,14 @@ func (d *dependency) Shutdown(ctx context.Context) error {
|
|||
}()
|
||||
}
|
||||
|
||||
if d.eventHub != nil {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
d.eventHub.Close()
|
||||
defer wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
d.mu.Unlock()
|
||||
wg.Wait()
|
||||
|
||||
|
|
|
|||
191
ent/client.go
191
ent/client.go
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
|
|
@ -45,6 +46,8 @@ type Client struct {
|
|||
Entity *EntityClient
|
||||
// File is the client for interacting with the File builders.
|
||||
File *FileClient
|
||||
// FsEvent is the client for interacting with the FsEvent builders.
|
||||
FsEvent *FsEventClient
|
||||
// Group is the client for interacting with the Group builders.
|
||||
Group *GroupClient
|
||||
// Metadata is the client for interacting with the Metadata builders.
|
||||
|
|
@ -78,6 +81,7 @@ func (c *Client) init() {
|
|||
c.DirectLink = NewDirectLinkClient(c.config)
|
||||
c.Entity = NewEntityClient(c.config)
|
||||
c.File = NewFileClient(c.config)
|
||||
c.FsEvent = NewFsEventClient(c.config)
|
||||
c.Group = NewGroupClient(c.config)
|
||||
c.Metadata = NewMetadataClient(c.config)
|
||||
c.Node = NewNodeClient(c.config)
|
||||
|
|
@ -183,6 +187,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
|||
DirectLink: NewDirectLinkClient(cfg),
|
||||
Entity: NewEntityClient(cfg),
|
||||
File: NewFileClient(cfg),
|
||||
FsEvent: NewFsEventClient(cfg),
|
||||
Group: NewGroupClient(cfg),
|
||||
Metadata: NewMetadataClient(cfg),
|
||||
Node: NewNodeClient(cfg),
|
||||
|
|
@ -215,6 +220,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
|||
DirectLink: NewDirectLinkClient(cfg),
|
||||
Entity: NewEntityClient(cfg),
|
||||
File: NewFileClient(cfg),
|
||||
FsEvent: NewFsEventClient(cfg),
|
||||
Group: NewGroupClient(cfg),
|
||||
Metadata: NewMetadataClient(cfg),
|
||||
Node: NewNodeClient(cfg),
|
||||
|
|
@ -253,8 +259,8 @@ func (c *Client) Close() error {
|
|||
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
||||
func (c *Client) Use(hooks ...Hook) {
|
||||
for _, n := range []interface{ Use(...Hook) }{
|
||||
c.DavAccount, c.DirectLink, c.Entity, c.File, c.Group, c.Metadata, c.Node,
|
||||
c.Passkey, c.Setting, c.Share, c.StoragePolicy, c.Task, c.User,
|
||||
c.DavAccount, c.DirectLink, c.Entity, c.File, c.FsEvent, c.Group, c.Metadata,
|
||||
c.Node, c.Passkey, c.Setting, c.Share, c.StoragePolicy, c.Task, c.User,
|
||||
} {
|
||||
n.Use(hooks...)
|
||||
}
|
||||
|
|
@ -264,8 +270,8 @@ func (c *Client) Use(hooks ...Hook) {
|
|||
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
|
||||
func (c *Client) Intercept(interceptors ...Interceptor) {
|
||||
for _, n := range []interface{ Intercept(...Interceptor) }{
|
||||
c.DavAccount, c.DirectLink, c.Entity, c.File, c.Group, c.Metadata, c.Node,
|
||||
c.Passkey, c.Setting, c.Share, c.StoragePolicy, c.Task, c.User,
|
||||
c.DavAccount, c.DirectLink, c.Entity, c.File, c.FsEvent, c.Group, c.Metadata,
|
||||
c.Node, c.Passkey, c.Setting, c.Share, c.StoragePolicy, c.Task, c.User,
|
||||
} {
|
||||
n.Intercept(interceptors...)
|
||||
}
|
||||
|
|
@ -282,6 +288,8 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
|||
return c.Entity.mutate(ctx, m)
|
||||
case *FileMutation:
|
||||
return c.File.mutate(ctx, m)
|
||||
case *FsEventMutation:
|
||||
return c.FsEvent.mutate(ctx, m)
|
||||
case *GroupMutation:
|
||||
return c.Group.mutate(ctx, m)
|
||||
case *MetadataMutation:
|
||||
|
|
@ -1052,6 +1060,157 @@ func (c *FileClient) mutate(ctx context.Context, m *FileMutation) (Value, error)
|
|||
}
|
||||
}
|
||||
|
||||
// FsEventClient is a client for the FsEvent schema.
|
||||
type FsEventClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewFsEventClient returns a client for the FsEvent from the given config.
|
||||
func NewFsEventClient(c config) *FsEventClient {
|
||||
return &FsEventClient{config: c}
|
||||
}
|
||||
|
||||
// Use adds a list of mutation hooks to the hooks stack.
|
||||
// A call to `Use(f, g, h)` equals to `fsevent.Hooks(f(g(h())))`.
|
||||
func (c *FsEventClient) Use(hooks ...Hook) {
|
||||
c.hooks.FsEvent = append(c.hooks.FsEvent, hooks...)
|
||||
}
|
||||
|
||||
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||
// A call to `Intercept(f, g, h)` equals to `fsevent.Intercept(f(g(h())))`.
|
||||
func (c *FsEventClient) Intercept(interceptors ...Interceptor) {
|
||||
c.inters.FsEvent = append(c.inters.FsEvent, interceptors...)
|
||||
}
|
||||
|
||||
// Create returns a builder for creating a FsEvent entity.
|
||||
func (c *FsEventClient) Create() *FsEventCreate {
|
||||
mutation := newFsEventMutation(c.config, OpCreate)
|
||||
return &FsEventCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// CreateBulk returns a builder for creating a bulk of FsEvent entities.
|
||||
func (c *FsEventClient) CreateBulk(builders ...*FsEventCreate) *FsEventCreateBulk {
|
||||
return &FsEventCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
|
||||
// a builder and applies setFunc on it.
|
||||
func (c *FsEventClient) MapCreateBulk(slice any, setFunc func(*FsEventCreate, int)) *FsEventCreateBulk {
|
||||
rv := reflect.ValueOf(slice)
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return &FsEventCreateBulk{err: fmt.Errorf("calling to FsEventClient.MapCreateBulk with wrong type %T, need slice", slice)}
|
||||
}
|
||||
builders := make([]*FsEventCreate, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
builders[i] = c.Create()
|
||||
setFunc(builders[i], i)
|
||||
}
|
||||
return &FsEventCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// Update returns an update builder for FsEvent.
|
||||
func (c *FsEventClient) Update() *FsEventUpdate {
|
||||
mutation := newFsEventMutation(c.config, OpUpdate)
|
||||
return &FsEventUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *FsEventClient) UpdateOne(fe *FsEvent) *FsEventUpdateOne {
|
||||
mutation := newFsEventMutation(c.config, OpUpdateOne, withFsEvent(fe))
|
||||
return &FsEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *FsEventClient) UpdateOneID(id int) *FsEventUpdateOne {
|
||||
mutation := newFsEventMutation(c.config, OpUpdateOne, withFsEventID(id))
|
||||
return &FsEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for FsEvent.
|
||||
func (c *FsEventClient) Delete() *FsEventDelete {
|
||||
mutation := newFsEventMutation(c.config, OpDelete)
|
||||
return &FsEventDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// DeleteOne returns a builder for deleting the given entity.
|
||||
func (c *FsEventClient) DeleteOne(fe *FsEvent) *FsEventDeleteOne {
|
||||
return c.DeleteOneID(fe.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||
func (c *FsEventClient) DeleteOneID(id int) *FsEventDeleteOne {
|
||||
builder := c.Delete().Where(fsevent.ID(id))
|
||||
builder.mutation.id = &id
|
||||
builder.mutation.op = OpDeleteOne
|
||||
return &FsEventDeleteOne{builder}
|
||||
}
|
||||
|
||||
// Query returns a query builder for FsEvent.
|
||||
func (c *FsEventClient) Query() *FsEventQuery {
|
||||
return &FsEventQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeFsEvent},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a FsEvent entity by its id.
|
||||
func (c *FsEventClient) Get(ctx context.Context, id int) (*FsEvent, error) {
|
||||
return c.Query().Where(fsevent.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (c *FsEventClient) GetX(ctx context.Context, id int) *FsEvent {
|
||||
obj, err := c.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// QueryUser queries the user edge of a FsEvent.
|
||||
func (c *FsEventClient) QueryUser(fe *FsEvent) *UserQuery {
|
||||
query := (&UserClient{config: c.config}).Query()
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := fe.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(fsevent.Table, fsevent.FieldID, id),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, fsevent.UserTable, fsevent.UserColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(fe.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *FsEventClient) Hooks() []Hook {
|
||||
hooks := c.hooks.FsEvent
|
||||
return append(hooks[:len(hooks):len(hooks)], fsevent.Hooks[:]...)
|
||||
}
|
||||
|
||||
// Interceptors returns the client interceptors.
|
||||
func (c *FsEventClient) Interceptors() []Interceptor {
|
||||
inters := c.inters.FsEvent
|
||||
return append(inters[:len(inters):len(inters)], fsevent.Interceptors[:]...)
|
||||
}
|
||||
|
||||
func (c *FsEventClient) mutate(ctx context.Context, m *FsEventMutation) (Value, error) {
|
||||
switch m.Op() {
|
||||
case OpCreate:
|
||||
return (&FsEventCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdate:
|
||||
return (&FsEventUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdateOne:
|
||||
return (&FsEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpDelete, OpDeleteOne:
|
||||
return (&FsEventDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("ent: unknown FsEvent mutation op: %q", m.Op())
|
||||
}
|
||||
}
|
||||
|
||||
// GroupClient is a client for the Group schema.
|
||||
type GroupClient struct {
|
||||
config
|
||||
|
|
@ -2528,6 +2687,22 @@ func (c *UserClient) QueryTasks(u *User) *TaskQuery {
|
|||
return query
|
||||
}
|
||||
|
||||
// QueryFsevents queries the fsevents edge of a User.
|
||||
func (c *UserClient) QueryFsevents(u *User) *FsEventQuery {
|
||||
query := (&FsEventClient{config: c.config}).Query()
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := u.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(user.Table, user.FieldID, id),
|
||||
sqlgraph.To(fsevent.Table, fsevent.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, user.FseventsTable, user.FseventsColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(u.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryEntities queries the entities edge of a User.
|
||||
func (c *UserClient) QueryEntities(u *User) *EntityQuery {
|
||||
query := (&EntityClient{config: c.config}).Query()
|
||||
|
|
@ -2574,12 +2749,12 @@ func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error)
|
|||
// hooks and interceptors per client, for fast access.
|
||||
type (
|
||||
hooks struct {
|
||||
DavAccount, DirectLink, Entity, File, Group, Metadata, Node, Passkey, Setting,
|
||||
Share, StoragePolicy, Task, User []ent.Hook
|
||||
DavAccount, DirectLink, Entity, File, FsEvent, Group, Metadata, Node, Passkey,
|
||||
Setting, Share, StoragePolicy, Task, User []ent.Hook
|
||||
}
|
||||
inters struct {
|
||||
DavAccount, DirectLink, Entity, File, Group, Metadata, Node, Passkey, Setting,
|
||||
Share, StoragePolicy, Task, User []ent.Interceptor
|
||||
DavAccount, DirectLink, Entity, File, FsEvent, Group, Metadata, Node, Passkey,
|
||||
Setting, Share, StoragePolicy, Task, User []ent.Interceptor
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
|
|
@ -89,6 +90,7 @@ func checkColumn(table, column string) error {
|
|||
directlink.Table: directlink.ValidColumn,
|
||||
entity.Table: entity.ValidColumn,
|
||||
file.Table: file.ValidColumn,
|
||||
fsevent.Table: fsevent.ValidColumn,
|
||||
group.Table: group.ValidColumn,
|
||||
metadata.Table: metadata.ValidColumn,
|
||||
node.Table: node.ValidColumn,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,204 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// FsEvent is the model entity for the FsEvent schema.
|
||||
type FsEvent struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `json:"id,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// UpdatedAt holds the value of the "updated_at" field.
|
||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||
// DeletedAt holds the value of the "deleted_at" field.
|
||||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||
// Event holds the value of the "event" field.
|
||||
Event string `json:"event,omitempty"`
|
||||
// Subscriber holds the value of the "subscriber" field.
|
||||
Subscriber uuid.UUID `json:"subscriber,omitempty"`
|
||||
// UserFsevent holds the value of the "user_fsevent" field.
|
||||
UserFsevent int `json:"user_fsevent,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the FsEventQuery when eager-loading is set.
|
||||
Edges FsEventEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// FsEventEdges holds the relations/edges for other nodes in the graph.
|
||||
type FsEventEdges struct {
|
||||
// User holds the value of the user edge.
|
||||
User *User `json:"user,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e FsEventEdges) UserOrErr() (*User, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.User == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return e.User, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*FsEvent) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case fsevent.FieldID, fsevent.FieldUserFsevent:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case fsevent.FieldEvent:
|
||||
values[i] = new(sql.NullString)
|
||||
case fsevent.FieldCreatedAt, fsevent.FieldUpdatedAt, fsevent.FieldDeletedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
case fsevent.FieldSubscriber:
|
||||
values[i] = new(uuid.UUID)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the FsEvent fields.
|
||||
func (fe *FsEvent) assignValues(columns []string, values []any) error {
|
||||
if m, n := len(values), len(columns); m < n {
|
||||
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||
}
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case fsevent.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
fe.ID = int(value.Int64)
|
||||
case fsevent.FieldCreatedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||
} else if value.Valid {
|
||||
fe.CreatedAt = value.Time
|
||||
}
|
||||
case fsevent.FieldUpdatedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
|
||||
} else if value.Valid {
|
||||
fe.UpdatedAt = value.Time
|
||||
}
|
||||
case fsevent.FieldDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
fe.DeletedAt = new(time.Time)
|
||||
*fe.DeletedAt = value.Time
|
||||
}
|
||||
case fsevent.FieldEvent:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field event", values[i])
|
||||
} else if value.Valid {
|
||||
fe.Event = value.String
|
||||
}
|
||||
case fsevent.FieldSubscriber:
|
||||
if value, ok := values[i].(*uuid.UUID); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field subscriber", values[i])
|
||||
} else if value != nil {
|
||||
fe.Subscriber = *value
|
||||
}
|
||||
case fsevent.FieldUserFsevent:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field user_fsevent", values[i])
|
||||
} else if value.Valid {
|
||||
fe.UserFsevent = int(value.Int64)
|
||||
}
|
||||
default:
|
||||
fe.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the FsEvent.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (fe *FsEvent) Value(name string) (ent.Value, error) {
|
||||
return fe.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryUser queries the "user" edge of the FsEvent entity.
|
||||
func (fe *FsEvent) QueryUser() *UserQuery {
|
||||
return NewFsEventClient(fe.config).QueryUser(fe)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this FsEvent.
|
||||
// Note that you need to call FsEvent.Unwrap() before calling this method if this FsEvent
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (fe *FsEvent) Update() *FsEventUpdateOne {
|
||||
return NewFsEventClient(fe.config).UpdateOne(fe)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the FsEvent entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (fe *FsEvent) Unwrap() *FsEvent {
|
||||
_tx, ok := fe.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: FsEvent is not a transactional entity")
|
||||
}
|
||||
fe.config.driver = _tx.drv
|
||||
return fe
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (fe *FsEvent) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("FsEvent(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", fe.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(fe.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(fe.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := fe.DeletedAt; v != nil {
|
||||
builder.WriteString("deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("event=")
|
||||
builder.WriteString(fe.Event)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("subscriber=")
|
||||
builder.WriteString(fmt.Sprintf("%v", fe.Subscriber))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("user_fsevent=")
|
||||
builder.WriteString(fmt.Sprintf("%v", fe.UserFsevent))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// SetUser manually set the edge as loaded state.
|
||||
func (e *FsEvent) SetUser(v *User) {
|
||||
e.Edges.User = v
|
||||
e.Edges.loadedTypes[0] = true
|
||||
}
|
||||
|
||||
// FsEvents is a parsable slice of FsEvent.
|
||||
type FsEvents []*FsEvent
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package fsevent
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the fsevent type in the database.
|
||||
Label = "fs_event"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
FieldCreatedAt = "created_at"
|
||||
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
|
||||
FieldUpdatedAt = "updated_at"
|
||||
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
|
||||
FieldDeletedAt = "deleted_at"
|
||||
// FieldEvent holds the string denoting the event field in the database.
|
||||
FieldEvent = "event"
|
||||
// FieldSubscriber holds the string denoting the subscriber field in the database.
|
||||
FieldSubscriber = "subscriber"
|
||||
// FieldUserFsevent holds the string denoting the user_fsevent field in the database.
|
||||
FieldUserFsevent = "user_fsevent"
|
||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||
EdgeUser = "user"
|
||||
// Table holds the table name of the fsevent in the database.
|
||||
Table = "fs_events"
|
||||
// UserTable is the table that holds the user relation/edge.
|
||||
UserTable = "fs_events"
|
||||
// UserInverseTable is the table name for the User entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "user" package.
|
||||
UserInverseTable = "users"
|
||||
// UserColumn is the table column denoting the user relation/edge.
|
||||
UserColumn = "user_fsevent"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for fsevent fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldDeletedAt,
|
||||
FieldEvent,
|
||||
FieldSubscriber,
|
||||
FieldUserFsevent,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
Interceptors [1]ent.Interceptor
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the FsEvent queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
// ByID orders the results by the id field.
|
||||
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUpdatedAt orders the results by the updated_at field.
|
||||
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDeletedAt orders the results by the deleted_at field.
|
||||
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByEvent orders the results by the event field.
|
||||
func ByEvent(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldEvent, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySubscriber orders the results by the subscriber field.
|
||||
func BySubscriber(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSubscriber, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUserFsevent orders the results by the user_fsevent field.
|
||||
func ByUserFsevent(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUserFsevent, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUserField orders the results by user field.
|
||||
func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
func newUserStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(UserInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package fsevent
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
|
||||
func DeletedAt(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// Event applies equality check predicate on the "event" field. It's identical to EventEQ.
|
||||
func Event(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldEvent, v))
|
||||
}
|
||||
|
||||
// Subscriber applies equality check predicate on the "subscriber" field. It's identical to SubscriberEQ.
|
||||
func Subscriber(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// UserFsevent applies equality check predicate on the "user_fsevent" field. It's identical to UserFseventEQ.
|
||||
func UserFsevent(v int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldUserFsevent, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
|
||||
func DeletedAtEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
|
||||
func DeletedAtNEQ(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIn applies the In predicate on the "deleted_at" field.
|
||||
func DeletedAtIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
|
||||
func DeletedAtNotIn(vs ...time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
|
||||
func DeletedAtGT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
|
||||
func DeletedAtGTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
|
||||
func DeletedAtLT(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
|
||||
func DeletedAtLTE(v time.Time) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
|
||||
func DeletedAtIsNil() predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIsNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
|
||||
func DeletedAtNotNil() predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// EventEQ applies the EQ predicate on the "event" field.
|
||||
func EventEQ(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventNEQ applies the NEQ predicate on the "event" field.
|
||||
func EventNEQ(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventIn applies the In predicate on the "event" field.
|
||||
func EventIn(vs ...string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldEvent, vs...))
|
||||
}
|
||||
|
||||
// EventNotIn applies the NotIn predicate on the "event" field.
|
||||
func EventNotIn(vs ...string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldEvent, vs...))
|
||||
}
|
||||
|
||||
// EventGT applies the GT predicate on the "event" field.
|
||||
func EventGT(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventGTE applies the GTE predicate on the "event" field.
|
||||
func EventGTE(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventLT applies the LT predicate on the "event" field.
|
||||
func EventLT(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventLTE applies the LTE predicate on the "event" field.
|
||||
func EventLTE(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventContains applies the Contains predicate on the "event" field.
|
||||
func EventContains(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldContains(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventHasPrefix applies the HasPrefix predicate on the "event" field.
|
||||
func EventHasPrefix(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldHasPrefix(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventHasSuffix applies the HasSuffix predicate on the "event" field.
|
||||
func EventHasSuffix(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldHasSuffix(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventEqualFold applies the EqualFold predicate on the "event" field.
|
||||
func EventEqualFold(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEqualFold(FieldEvent, v))
|
||||
}
|
||||
|
||||
// EventContainsFold applies the ContainsFold predicate on the "event" field.
|
||||
func EventContainsFold(v string) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldContainsFold(FieldEvent, v))
|
||||
}
|
||||
|
||||
// SubscriberEQ applies the EQ predicate on the "subscriber" field.
|
||||
func SubscriberEQ(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// SubscriberNEQ applies the NEQ predicate on the "subscriber" field.
|
||||
func SubscriberNEQ(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// SubscriberIn applies the In predicate on the "subscriber" field.
|
||||
func SubscriberIn(vs ...uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldSubscriber, vs...))
|
||||
}
|
||||
|
||||
// SubscriberNotIn applies the NotIn predicate on the "subscriber" field.
|
||||
func SubscriberNotIn(vs ...uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldSubscriber, vs...))
|
||||
}
|
||||
|
||||
// SubscriberGT applies the GT predicate on the "subscriber" field.
|
||||
func SubscriberGT(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGT(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// SubscriberGTE applies the GTE predicate on the "subscriber" field.
|
||||
func SubscriberGTE(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldGTE(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// SubscriberLT applies the LT predicate on the "subscriber" field.
|
||||
func SubscriberLT(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLT(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// SubscriberLTE applies the LTE predicate on the "subscriber" field.
|
||||
func SubscriberLTE(v uuid.UUID) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldLTE(FieldSubscriber, v))
|
||||
}
|
||||
|
||||
// UserFseventEQ applies the EQ predicate on the "user_fsevent" field.
|
||||
func UserFseventEQ(v int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldEQ(FieldUserFsevent, v))
|
||||
}
|
||||
|
||||
// UserFseventNEQ applies the NEQ predicate on the "user_fsevent" field.
|
||||
func UserFseventNEQ(v int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNEQ(FieldUserFsevent, v))
|
||||
}
|
||||
|
||||
// UserFseventIn applies the In predicate on the "user_fsevent" field.
|
||||
func UserFseventIn(vs ...int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIn(FieldUserFsevent, vs...))
|
||||
}
|
||||
|
||||
// UserFseventNotIn applies the NotIn predicate on the "user_fsevent" field.
|
||||
func UserFseventNotIn(vs ...int) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotIn(FieldUserFsevent, vs...))
|
||||
}
|
||||
|
||||
// UserFseventIsNil applies the IsNil predicate on the "user_fsevent" field.
|
||||
func UserFseventIsNil() predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldIsNull(FieldUserFsevent))
|
||||
}
|
||||
|
||||
// UserFseventNotNil applies the NotNil predicate on the "user_fsevent" field.
|
||||
func UserFseventNotNil() predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.FieldNotNull(FieldUserFsevent))
|
||||
}
|
||||
|
||||
// HasUser applies the HasEdge predicate on the "user" edge.
|
||||
func HasUser() predicate.FsEvent {
|
||||
return predicate.FsEvent(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
|
||||
func HasUserWith(preds ...predicate.User) predicate.FsEvent {
|
||||
return predicate.FsEvent(func(s *sql.Selector) {
|
||||
step := newUserStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.FsEvent) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.FsEvent) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.FsEvent) predicate.FsEvent {
|
||||
return predicate.FsEvent(sql.NotPredicates(p))
|
||||
}
|
||||
|
|
@ -0,0 +1,827 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// FsEventCreate is the builder for creating a FsEvent entity.
|
||||
type FsEventCreate struct {
|
||||
config
|
||||
mutation *FsEventMutation
|
||||
hooks []Hook
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (fec *FsEventCreate) SetCreatedAt(t time.Time) *FsEventCreate {
|
||||
fec.mutation.SetCreatedAt(t)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||
func (fec *FsEventCreate) SetNillableCreatedAt(t *time.Time) *FsEventCreate {
|
||||
if t != nil {
|
||||
fec.SetCreatedAt(*t)
|
||||
}
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (fec *FsEventCreate) SetUpdatedAt(t time.Time) *FsEventCreate {
|
||||
fec.mutation.SetUpdatedAt(t)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
|
||||
func (fec *FsEventCreate) SetNillableUpdatedAt(t *time.Time) *FsEventCreate {
|
||||
if t != nil {
|
||||
fec.SetUpdatedAt(*t)
|
||||
}
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (fec *FsEventCreate) SetDeletedAt(t time.Time) *FsEventCreate {
|
||||
fec.mutation.SetDeletedAt(t)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (fec *FsEventCreate) SetNillableDeletedAt(t *time.Time) *FsEventCreate {
|
||||
if t != nil {
|
||||
fec.SetDeletedAt(*t)
|
||||
}
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (fec *FsEventCreate) SetEvent(s string) *FsEventCreate {
|
||||
fec.mutation.SetEvent(s)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (fec *FsEventCreate) SetSubscriber(u uuid.UUID) *FsEventCreate {
|
||||
fec.mutation.SetSubscriber(u)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (fec *FsEventCreate) SetUserFsevent(i int) *FsEventCreate {
|
||||
fec.mutation.SetUserFsevent(i)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetNillableUserFsevent sets the "user_fsevent" field if the given value is not nil.
|
||||
func (fec *FsEventCreate) SetNillableUserFsevent(i *int) *FsEventCreate {
|
||||
if i != nil {
|
||||
fec.SetUserFsevent(*i)
|
||||
}
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (fec *FsEventCreate) SetUserID(id int) *FsEventCreate {
|
||||
fec.mutation.SetUserID(id)
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil.
|
||||
func (fec *FsEventCreate) SetNillableUserID(id *int) *FsEventCreate {
|
||||
if id != nil {
|
||||
fec = fec.SetUserID(*id)
|
||||
}
|
||||
return fec
|
||||
}
|
||||
|
||||
// SetUser sets the "user" edge to the User entity.
|
||||
func (fec *FsEventCreate) SetUser(u *User) *FsEventCreate {
|
||||
return fec.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the FsEventMutation object of the builder.
|
||||
func (fec *FsEventCreate) Mutation() *FsEventMutation {
|
||||
return fec.mutation
|
||||
}
|
||||
|
||||
// Save creates the FsEvent in the database.
|
||||
func (fec *FsEventCreate) Save(ctx context.Context) (*FsEvent, error) {
|
||||
if err := fec.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, fec.sqlSave, fec.mutation, fec.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (fec *FsEventCreate) SaveX(ctx context.Context) *FsEvent {
|
||||
v, err := fec.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (fec *FsEventCreate) Exec(ctx context.Context) error {
|
||||
_, err := fec.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fec *FsEventCreate) ExecX(ctx context.Context) {
|
||||
if err := fec.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (fec *FsEventCreate) defaults() error {
|
||||
if _, ok := fec.mutation.CreatedAt(); !ok {
|
||||
if fsevent.DefaultCreatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized fsevent.DefaultCreatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := fsevent.DefaultCreatedAt()
|
||||
fec.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := fec.mutation.UpdatedAt(); !ok {
|
||||
if fsevent.DefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized fsevent.DefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := fsevent.DefaultUpdatedAt()
|
||||
fec.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (fec *FsEventCreate) check() error {
|
||||
if _, ok := fec.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "FsEvent.created_at"`)}
|
||||
}
|
||||
if _, ok := fec.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "FsEvent.updated_at"`)}
|
||||
}
|
||||
if _, ok := fec.mutation.Event(); !ok {
|
||||
return &ValidationError{Name: "event", err: errors.New(`ent: missing required field "FsEvent.event"`)}
|
||||
}
|
||||
if _, ok := fec.mutation.Subscriber(); !ok {
|
||||
return &ValidationError{Name: "subscriber", err: errors.New(`ent: missing required field "FsEvent.subscriber"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fec *FsEventCreate) sqlSave(ctx context.Context) (*FsEvent, error) {
|
||||
if err := fec.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := fec.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, fec.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
id := _spec.ID.Value.(int64)
|
||||
_node.ID = int(id)
|
||||
fec.mutation.id = &_node.ID
|
||||
fec.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (fec *FsEventCreate) createSpec() (*FsEvent, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &FsEvent{config: fec.config}
|
||||
_spec = sqlgraph.NewCreateSpec(fsevent.Table, sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt))
|
||||
)
|
||||
|
||||
if id, ok := fec.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
id64 := int64(id)
|
||||
_spec.ID.Value = id64
|
||||
}
|
||||
|
||||
_spec.OnConflict = fec.conflict
|
||||
if value, ok := fec.mutation.CreatedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := fec.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := fec.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldDeletedAt, field.TypeTime, value)
|
||||
_node.DeletedAt = &value
|
||||
}
|
||||
if value, ok := fec.mutation.Event(); ok {
|
||||
_spec.SetField(fsevent.FieldEvent, field.TypeString, value)
|
||||
_node.Event = value
|
||||
}
|
||||
if value, ok := fec.mutation.Subscriber(); ok {
|
||||
_spec.SetField(fsevent.FieldSubscriber, field.TypeUUID, value)
|
||||
_node.Subscriber = value
|
||||
}
|
||||
if nodes := fec.mutation.UserIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: fsevent.UserTable,
|
||||
Columns: []string{fsevent.UserColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.UserFsevent = nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// SetCreatedAt(v).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.FsEventUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (fec *FsEventCreate) OnConflict(opts ...sql.ConflictOption) *FsEventUpsertOne {
|
||||
fec.conflict = opts
|
||||
return &FsEventUpsertOne{
|
||||
create: fec,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (fec *FsEventCreate) OnConflictColumns(columns ...string) *FsEventUpsertOne {
|
||||
fec.conflict = append(fec.conflict, sql.ConflictColumns(columns...))
|
||||
return &FsEventUpsertOne{
|
||||
create: fec,
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// FsEventUpsertOne is the builder for "upsert"-ing
|
||||
// one FsEvent node.
|
||||
FsEventUpsertOne struct {
|
||||
create *FsEventCreate
|
||||
}
|
||||
|
||||
// FsEventUpsert is the "OnConflict" setter.
|
||||
FsEventUpsert struct {
|
||||
*sql.UpdateSet
|
||||
}
|
||||
)
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *FsEventUpsert) SetUpdatedAt(v time.Time) *FsEventUpsert {
|
||||
u.Set(fsevent.FieldUpdatedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsert) UpdateUpdatedAt() *FsEventUpsert {
|
||||
u.SetExcluded(fsevent.FieldUpdatedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *FsEventUpsert) SetDeletedAt(v time.Time) *FsEventUpsert {
|
||||
u.Set(fsevent.FieldDeletedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsert) UpdateDeletedAt() *FsEventUpsert {
|
||||
u.SetExcluded(fsevent.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *FsEventUpsert) ClearDeletedAt() *FsEventUpsert {
|
||||
u.SetNull(fsevent.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (u *FsEventUpsert) SetEvent(v string) *FsEventUpsert {
|
||||
u.Set(fsevent.FieldEvent, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateEvent sets the "event" field to the value that was provided on create.
|
||||
func (u *FsEventUpsert) UpdateEvent() *FsEventUpsert {
|
||||
u.SetExcluded(fsevent.FieldEvent)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (u *FsEventUpsert) SetSubscriber(v uuid.UUID) *FsEventUpsert {
|
||||
u.Set(fsevent.FieldSubscriber, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateSubscriber sets the "subscriber" field to the value that was provided on create.
|
||||
func (u *FsEventUpsert) UpdateSubscriber() *FsEventUpsert {
|
||||
u.SetExcluded(fsevent.FieldSubscriber)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (u *FsEventUpsert) SetUserFsevent(v int) *FsEventUpsert {
|
||||
u.Set(fsevent.FieldUserFsevent, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateUserFsevent sets the "user_fsevent" field to the value that was provided on create.
|
||||
func (u *FsEventUpsert) UpdateUserFsevent() *FsEventUpsert {
|
||||
u.SetExcluded(fsevent.FieldUserFsevent)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (u *FsEventUpsert) ClearUserFsevent() *FsEventUpsert {
|
||||
u.SetNull(fsevent.FieldUserFsevent)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *FsEventUpsertOne) UpdateNewValues() *FsEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
if _, exists := u.create.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(fsevent.FieldCreatedAt)
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *FsEventUpsertOne) Ignore() *FsEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *FsEventUpsertOne) DoNothing() *FsEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the FsEventCreate.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *FsEventUpsertOne) Update(set func(*FsEventUpsert)) *FsEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&FsEventUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *FsEventUpsertOne) SetUpdatedAt(v time.Time) *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertOne) UpdateUpdatedAt() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *FsEventUpsertOne) SetDeletedAt(v time.Time) *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertOne) UpdateDeletedAt() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *FsEventUpsertOne) ClearDeletedAt() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (u *FsEventUpsertOne) SetEvent(v string) *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetEvent(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEvent sets the "event" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertOne) UpdateEvent() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateEvent()
|
||||
})
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (u *FsEventUpsertOne) SetSubscriber(v uuid.UUID) *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetSubscriber(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSubscriber sets the "subscriber" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertOne) UpdateSubscriber() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateSubscriber()
|
||||
})
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (u *FsEventUpsertOne) SetUserFsevent(v int) *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetUserFsevent(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUserFsevent sets the "user_fsevent" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertOne) UpdateUserFsevent() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateUserFsevent()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (u *FsEventUpsertOne) ClearUserFsevent() *FsEventUpsertOne {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.ClearUserFsevent()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *FsEventUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for FsEventCreate.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *FsEventUpsertOne) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Exec executes the UPSERT query and returns the inserted/updated ID.
|
||||
func (u *FsEventUpsertOne) ID(ctx context.Context) (id int, err error) {
|
||||
node, err := u.create.Save(ctx)
|
||||
if err != nil {
|
||||
return id, err
|
||||
}
|
||||
return node.ID, nil
|
||||
}
|
||||
|
||||
// IDX is like ID, but panics if an error occurs.
|
||||
func (u *FsEventUpsertOne) IDX(ctx context.Context) int {
|
||||
id, err := u.ID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (m *FsEventCreate) SetRawID(t int) *FsEventCreate {
|
||||
m.mutation.SetRawID(t)
|
||||
return m
|
||||
}
|
||||
|
||||
// FsEventCreateBulk is the builder for creating many FsEvent entities in bulk.
|
||||
type FsEventCreateBulk struct {
|
||||
config
|
||||
err error
|
||||
builders []*FsEventCreate
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// Save creates the FsEvent entities in the database.
|
||||
func (fecb *FsEventCreateBulk) Save(ctx context.Context) ([]*FsEvent, error) {
|
||||
if fecb.err != nil {
|
||||
return nil, fecb.err
|
||||
}
|
||||
specs := make([]*sqlgraph.CreateSpec, len(fecb.builders))
|
||||
nodes := make([]*FsEvent, len(fecb.builders))
|
||||
mutators := make([]Mutator, len(fecb.builders))
|
||||
for i := range fecb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := fecb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*FsEventMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
var err error
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, fecb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
spec.OnConflict = fecb.conflict
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, fecb.driver, spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &nodes[i].ID
|
||||
if specs[i].ID.Value != nil {
|
||||
id := specs[i].ID.Value.(int64)
|
||||
nodes[i].ID = int(id)
|
||||
}
|
||||
mutation.done = true
|
||||
return nodes[i], nil
|
||||
})
|
||||
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||
mut = builder.hooks[i](mut)
|
||||
}
|
||||
mutators[i] = mut
|
||||
}(i, ctx)
|
||||
}
|
||||
if len(mutators) > 0 {
|
||||
if _, err := mutators[0].Mutate(ctx, fecb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (fecb *FsEventCreateBulk) SaveX(ctx context.Context) []*FsEvent {
|
||||
v, err := fecb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (fecb *FsEventCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := fecb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fecb *FsEventCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := fecb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.FsEvent.CreateBulk(builders...).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.FsEventUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (fecb *FsEventCreateBulk) OnConflict(opts ...sql.ConflictOption) *FsEventUpsertBulk {
|
||||
fecb.conflict = opts
|
||||
return &FsEventUpsertBulk{
|
||||
create: fecb,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (fecb *FsEventCreateBulk) OnConflictColumns(columns ...string) *FsEventUpsertBulk {
|
||||
fecb.conflict = append(fecb.conflict, sql.ConflictColumns(columns...))
|
||||
return &FsEventUpsertBulk{
|
||||
create: fecb,
|
||||
}
|
||||
}
|
||||
|
||||
// FsEventUpsertBulk is the builder for "upsert"-ing
|
||||
// a bulk of FsEvent nodes.
|
||||
type FsEventUpsertBulk struct {
|
||||
create *FsEventCreateBulk
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that
|
||||
// were set on create. Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *FsEventUpsertBulk) UpdateNewValues() *FsEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
for _, b := range u.create.builders {
|
||||
if _, exists := b.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(fsevent.FieldCreatedAt)
|
||||
}
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.FsEvent.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *FsEventUpsertBulk) Ignore() *FsEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *FsEventUpsertBulk) DoNothing() *FsEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the FsEventCreateBulk.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *FsEventUpsertBulk) Update(set func(*FsEventUpsert)) *FsEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&FsEventUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *FsEventUpsertBulk) SetUpdatedAt(v time.Time) *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertBulk) UpdateUpdatedAt() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *FsEventUpsertBulk) SetDeletedAt(v time.Time) *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertBulk) UpdateDeletedAt() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *FsEventUpsertBulk) ClearDeletedAt() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (u *FsEventUpsertBulk) SetEvent(v string) *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetEvent(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEvent sets the "event" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertBulk) UpdateEvent() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateEvent()
|
||||
})
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (u *FsEventUpsertBulk) SetSubscriber(v uuid.UUID) *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetSubscriber(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSubscriber sets the "subscriber" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertBulk) UpdateSubscriber() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateSubscriber()
|
||||
})
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (u *FsEventUpsertBulk) SetUserFsevent(v int) *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.SetUserFsevent(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUserFsevent sets the "user_fsevent" field to the value that was provided on create.
|
||||
func (u *FsEventUpsertBulk) UpdateUserFsevent() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.UpdateUserFsevent()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (u *FsEventUpsertBulk) ClearUserFsevent() *FsEventUpsertBulk {
|
||||
return u.Update(func(s *FsEventUpsert) {
|
||||
s.ClearUserFsevent()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *FsEventUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
return u.create.err
|
||||
}
|
||||
for i, b := range u.create.builders {
|
||||
if len(b.conflict) != 0 {
|
||||
return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the FsEventCreateBulk instead", i)
|
||||
}
|
||||
}
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for FsEventCreateBulk.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *FsEventUpsertBulk) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// FsEventDelete is the builder for deleting a FsEvent entity.
|
||||
type FsEventDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *FsEventMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FsEventDelete builder.
|
||||
func (fed *FsEventDelete) Where(ps ...predicate.FsEvent) *FsEventDelete {
|
||||
fed.mutation.Where(ps...)
|
||||
return fed
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (fed *FsEventDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, fed.sqlExec, fed.mutation, fed.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fed *FsEventDelete) ExecX(ctx context.Context) int {
|
||||
n, err := fed.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (fed *FsEventDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(fsevent.Table, sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt))
|
||||
if ps := fed.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, fed.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
fed.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// FsEventDeleteOne is the builder for deleting a single FsEvent entity.
|
||||
type FsEventDeleteOne struct {
|
||||
fed *FsEventDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FsEventDelete builder.
|
||||
func (fedo *FsEventDeleteOne) Where(ps ...predicate.FsEvent) *FsEventDeleteOne {
|
||||
fedo.fed.mutation.Where(ps...)
|
||||
return fedo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (fedo *FsEventDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := fedo.fed.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{fsevent.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fedo *FsEventDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := fedo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,605 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
)
|
||||
|
||||
// FsEventQuery is the builder for querying FsEvent entities.
|
||||
type FsEventQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []fsevent.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.FsEvent
|
||||
withUser *UserQuery
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the FsEventQuery builder.
|
||||
func (feq *FsEventQuery) Where(ps ...predicate.FsEvent) *FsEventQuery {
|
||||
feq.predicates = append(feq.predicates, ps...)
|
||||
return feq
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (feq *FsEventQuery) Limit(limit int) *FsEventQuery {
|
||||
feq.ctx.Limit = &limit
|
||||
return feq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (feq *FsEventQuery) Offset(offset int) *FsEventQuery {
|
||||
feq.ctx.Offset = &offset
|
||||
return feq
|
||||
}
|
||||
|
||||
// Unique configures the query builder to filter duplicate records on query.
|
||||
// By default, unique is set to true, and can be disabled using this method.
|
||||
func (feq *FsEventQuery) Unique(unique bool) *FsEventQuery {
|
||||
feq.ctx.Unique = &unique
|
||||
return feq
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (feq *FsEventQuery) Order(o ...fsevent.OrderOption) *FsEventQuery {
|
||||
feq.order = append(feq.order, o...)
|
||||
return feq
|
||||
}
|
||||
|
||||
// QueryUser chains the current query on the "user" edge.
|
||||
func (feq *FsEventQuery) QueryUser() *UserQuery {
|
||||
query := (&UserClient{config: feq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := feq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := feq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(fsevent.Table, fsevent.FieldID, selector),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, fsevent.UserTable, fsevent.UserColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(feq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first FsEvent entity from the query.
|
||||
// Returns a *NotFoundError when no FsEvent was found.
|
||||
func (feq *FsEventQuery) First(ctx context.Context) (*FsEvent, error) {
|
||||
nodes, err := feq.Limit(1).All(setContextOp(ctx, feq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{fsevent.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) FirstX(ctx context.Context) *FsEvent {
|
||||
node, err := feq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first FsEvent ID from the query.
|
||||
// Returns a *NotFoundError when no FsEvent ID was found.
|
||||
func (feq *FsEventQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = feq.Limit(1).IDs(setContextOp(ctx, feq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{fsevent.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := feq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single FsEvent entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one FsEvent entity is found.
|
||||
// Returns a *NotFoundError when no FsEvent entities are found.
|
||||
func (feq *FsEventQuery) Only(ctx context.Context) (*FsEvent, error) {
|
||||
nodes, err := feq.Limit(2).All(setContextOp(ctx, feq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{fsevent.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{fsevent.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) OnlyX(ctx context.Context) *FsEvent {
|
||||
node, err := feq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only FsEvent ID in the query.
|
||||
// Returns a *NotSingularError when more than one FsEvent ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (feq *FsEventQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = feq.Limit(2).IDs(setContextOp(ctx, feq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{fsevent.Label}
|
||||
default:
|
||||
err = &NotSingularError{fsevent.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := feq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of FsEvents.
|
||||
func (feq *FsEventQuery) All(ctx context.Context) ([]*FsEvent, error) {
|
||||
ctx = setContextOp(ctx, feq.ctx, "All")
|
||||
if err := feq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*FsEvent, *FsEventQuery]()
|
||||
return withInterceptors[[]*FsEvent](ctx, feq, qr, feq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) AllX(ctx context.Context) []*FsEvent {
|
||||
nodes, err := feq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of FsEvent IDs.
|
||||
func (feq *FsEventQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if feq.ctx.Unique == nil && feq.path != nil {
|
||||
feq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, feq.ctx, "IDs")
|
||||
if err = feq.Select(fsevent.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := feq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (feq *FsEventQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, feq.ctx, "Count")
|
||||
if err := feq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, feq, querierCount[*FsEventQuery](), feq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) CountX(ctx context.Context) int {
|
||||
count, err := feq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (feq *FsEventQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, feq.ctx, "Exist")
|
||||
switch _, err := feq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (feq *FsEventQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := feq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the FsEventQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (feq *FsEventQuery) Clone() *FsEventQuery {
|
||||
if feq == nil {
|
||||
return nil
|
||||
}
|
||||
return &FsEventQuery{
|
||||
config: feq.config,
|
||||
ctx: feq.ctx.Clone(),
|
||||
order: append([]fsevent.OrderOption{}, feq.order...),
|
||||
inters: append([]Interceptor{}, feq.inters...),
|
||||
predicates: append([]predicate.FsEvent{}, feq.predicates...),
|
||||
withUser: feq.withUser.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: feq.sql.Clone(),
|
||||
path: feq.path,
|
||||
}
|
||||
}
|
||||
|
||||
// WithUser tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "user" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (feq *FsEventQuery) WithUser(opts ...func(*UserQuery)) *FsEventQuery {
|
||||
query := (&UserClient{config: feq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
feq.withUser = query
|
||||
return feq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.FsEvent.Query().
|
||||
// GroupBy(fsevent.FieldCreatedAt).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (feq *FsEventQuery) GroupBy(field string, fields ...string) *FsEventGroupBy {
|
||||
feq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &FsEventGroupBy{build: feq}
|
||||
grbuild.flds = &feq.ctx.Fields
|
||||
grbuild.label = fsevent.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
// Select allows the selection one or more fields/columns for the given query,
|
||||
// instead of selecting all fields in the entity.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.FsEvent.Query().
|
||||
// Select(fsevent.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (feq *FsEventQuery) Select(fields ...string) *FsEventSelect {
|
||||
feq.ctx.Fields = append(feq.ctx.Fields, fields...)
|
||||
sbuild := &FsEventSelect{FsEventQuery: feq}
|
||||
sbuild.label = fsevent.Label
|
||||
sbuild.flds, sbuild.scan = &feq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a FsEventSelect configured with the given aggregations.
|
||||
func (feq *FsEventQuery) Aggregate(fns ...AggregateFunc) *FsEventSelect {
|
||||
return feq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range feq.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, feq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range feq.ctx.Fields {
|
||||
if !fsevent.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if feq.path != nil {
|
||||
prev, err := feq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
feq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*FsEvent, error) {
|
||||
var (
|
||||
nodes = []*FsEvent{}
|
||||
_spec = feq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
feq.withUser != nil,
|
||||
}
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*FsEvent).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &FsEvent{config: feq.config}
|
||||
nodes = append(nodes, node)
|
||||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, feq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := feq.withUser; query != nil {
|
||||
if err := feq.loadUser(ctx, query, nodes, nil,
|
||||
func(n *FsEvent, e *User) { n.Edges.User = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*FsEvent, init func(*FsEvent), assign func(*FsEvent, *User)) error {
|
||||
ids := make([]int, 0, len(nodes))
|
||||
nodeids := make(map[int][]*FsEvent)
|
||||
for i := range nodes {
|
||||
fk := nodes[i].UserFsevent
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(user.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "user_fsevent" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := feq.querySpec()
|
||||
_spec.Node.Columns = feq.ctx.Fields
|
||||
if len(feq.ctx.Fields) > 0 {
|
||||
_spec.Unique = feq.ctx.Unique != nil && *feq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, feq.driver, _spec)
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(fsevent.Table, fsevent.Columns, sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt))
|
||||
_spec.From = feq.sql
|
||||
if unique := feq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if feq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := feq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fsevent.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != fsevent.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if feq.withUser != nil {
|
||||
_spec.Node.AddColumnOnce(fsevent.FieldUserFsevent)
|
||||
}
|
||||
}
|
||||
if ps := feq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := feq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := feq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := feq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (feq *FsEventQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(feq.driver.Dialect())
|
||||
t1 := builder.Table(fsevent.Table)
|
||||
columns := feq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = fsevent.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if feq.sql != nil {
|
||||
selector = feq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if feq.ctx.Unique != nil && *feq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range feq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range feq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := feq.ctx.Offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||
}
|
||||
if limit := feq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// FsEventGroupBy is the group-by builder for FsEvent entities.
|
||||
type FsEventGroupBy struct {
|
||||
selector
|
||||
build *FsEventQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (fegb *FsEventGroupBy) Aggregate(fns ...AggregateFunc) *FsEventGroupBy {
|
||||
fegb.fns = append(fegb.fns, fns...)
|
||||
return fegb
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (fegb *FsEventGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, fegb.build.ctx, "GroupBy")
|
||||
if err := fegb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*FsEventQuery, *FsEventGroupBy](ctx, fegb.build, fegb, fegb.build.inters, v)
|
||||
}
|
||||
|
||||
func (fegb *FsEventGroupBy) sqlScan(ctx context.Context, root *FsEventQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(fegb.fns))
|
||||
for _, fn := range fegb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*fegb.flds)+len(fegb.fns))
|
||||
for _, f := range *fegb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*fegb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := fegb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// FsEventSelect is the builder for selecting fields of FsEvent entities.
|
||||
type FsEventSelect struct {
|
||||
*FsEventQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (fes *FsEventSelect) Aggregate(fns ...AggregateFunc) *FsEventSelect {
|
||||
fes.fns = append(fes.fns, fns...)
|
||||
return fes
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (fes *FsEventSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, fes.ctx, "Select")
|
||||
if err := fes.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*FsEventQuery, *FsEventSelect](ctx, fes.FsEventQuery, fes, fes.inters, v)
|
||||
}
|
||||
|
||||
func (fes *FsEventSelect) sqlScan(ctx context.Context, root *FsEventQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(fes.fns))
|
||||
for _, fn := range fes.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*fes.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := fes.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// FsEventUpdate is the builder for updating FsEvent entities.
|
||||
type FsEventUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *FsEventMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FsEventUpdate builder.
|
||||
func (feu *FsEventUpdate) Where(ps ...predicate.FsEvent) *FsEventUpdate {
|
||||
feu.mutation.Where(ps...)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (feu *FsEventUpdate) SetUpdatedAt(t time.Time) *FsEventUpdate {
|
||||
feu.mutation.SetUpdatedAt(t)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (feu *FsEventUpdate) SetDeletedAt(t time.Time) *FsEventUpdate {
|
||||
feu.mutation.SetDeletedAt(t)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (feu *FsEventUpdate) SetNillableDeletedAt(t *time.Time) *FsEventUpdate {
|
||||
if t != nil {
|
||||
feu.SetDeletedAt(*t)
|
||||
}
|
||||
return feu
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (feu *FsEventUpdate) ClearDeletedAt() *FsEventUpdate {
|
||||
feu.mutation.ClearDeletedAt()
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (feu *FsEventUpdate) SetEvent(s string) *FsEventUpdate {
|
||||
feu.mutation.SetEvent(s)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetNillableEvent sets the "event" field if the given value is not nil.
|
||||
func (feu *FsEventUpdate) SetNillableEvent(s *string) *FsEventUpdate {
|
||||
if s != nil {
|
||||
feu.SetEvent(*s)
|
||||
}
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (feu *FsEventUpdate) SetSubscriber(u uuid.UUID) *FsEventUpdate {
|
||||
feu.mutation.SetSubscriber(u)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetNillableSubscriber sets the "subscriber" field if the given value is not nil.
|
||||
func (feu *FsEventUpdate) SetNillableSubscriber(u *uuid.UUID) *FsEventUpdate {
|
||||
if u != nil {
|
||||
feu.SetSubscriber(*u)
|
||||
}
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (feu *FsEventUpdate) SetUserFsevent(i int) *FsEventUpdate {
|
||||
feu.mutation.SetUserFsevent(i)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetNillableUserFsevent sets the "user_fsevent" field if the given value is not nil.
|
||||
func (feu *FsEventUpdate) SetNillableUserFsevent(i *int) *FsEventUpdate {
|
||||
if i != nil {
|
||||
feu.SetUserFsevent(*i)
|
||||
}
|
||||
return feu
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (feu *FsEventUpdate) ClearUserFsevent() *FsEventUpdate {
|
||||
feu.mutation.ClearUserFsevent()
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (feu *FsEventUpdate) SetUserID(id int) *FsEventUpdate {
|
||||
feu.mutation.SetUserID(id)
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil.
|
||||
func (feu *FsEventUpdate) SetNillableUserID(id *int) *FsEventUpdate {
|
||||
if id != nil {
|
||||
feu = feu.SetUserID(*id)
|
||||
}
|
||||
return feu
|
||||
}
|
||||
|
||||
// SetUser sets the "user" edge to the User entity.
|
||||
func (feu *FsEventUpdate) SetUser(u *User) *FsEventUpdate {
|
||||
return feu.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the FsEventMutation object of the builder.
|
||||
func (feu *FsEventUpdate) Mutation() *FsEventMutation {
|
||||
return feu.mutation
|
||||
}
|
||||
|
||||
// ClearUser clears the "user" edge to the User entity.
|
||||
func (feu *FsEventUpdate) ClearUser() *FsEventUpdate {
|
||||
feu.mutation.ClearUser()
|
||||
return feu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (feu *FsEventUpdate) Save(ctx context.Context) (int, error) {
|
||||
if err := feu.defaults(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withHooks(ctx, feu.sqlSave, feu.mutation, feu.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (feu *FsEventUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := feu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (feu *FsEventUpdate) Exec(ctx context.Context) error {
|
||||
_, err := feu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (feu *FsEventUpdate) ExecX(ctx context.Context) {
|
||||
if err := feu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (feu *FsEventUpdate) defaults() error {
|
||||
if _, ok := feu.mutation.UpdatedAt(); !ok {
|
||||
if fsevent.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized fsevent.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := fsevent.UpdateDefaultUpdatedAt()
|
||||
feu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (feu *FsEventUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := sqlgraph.NewUpdateSpec(fsevent.Table, fsevent.Columns, sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt))
|
||||
if ps := feu.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := feu.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := feu.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if feu.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(fsevent.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := feu.mutation.Event(); ok {
|
||||
_spec.SetField(fsevent.FieldEvent, field.TypeString, value)
|
||||
}
|
||||
if value, ok := feu.mutation.Subscriber(); ok {
|
||||
_spec.SetField(fsevent.FieldSubscriber, field.TypeUUID, value)
|
||||
}
|
||||
if feu.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: fsevent.UserTable,
|
||||
Columns: []string{fsevent.UserColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := feu.mutation.UserIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: fsevent.UserTable,
|
||||
Columns: []string{fsevent.UserColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, feu.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{fsevent.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
feu.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// FsEventUpdateOne is the builder for updating a single FsEvent entity.
|
||||
type FsEventUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *FsEventMutation
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (feuo *FsEventUpdateOne) SetUpdatedAt(t time.Time) *FsEventUpdateOne {
|
||||
feuo.mutation.SetUpdatedAt(t)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (feuo *FsEventUpdateOne) SetDeletedAt(t time.Time) *FsEventUpdateOne {
|
||||
feuo.mutation.SetDeletedAt(t)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (feuo *FsEventUpdateOne) SetNillableDeletedAt(t *time.Time) *FsEventUpdateOne {
|
||||
if t != nil {
|
||||
feuo.SetDeletedAt(*t)
|
||||
}
|
||||
return feuo
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (feuo *FsEventUpdateOne) ClearDeletedAt() *FsEventUpdateOne {
|
||||
feuo.mutation.ClearDeletedAt()
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (feuo *FsEventUpdateOne) SetEvent(s string) *FsEventUpdateOne {
|
||||
feuo.mutation.SetEvent(s)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetNillableEvent sets the "event" field if the given value is not nil.
|
||||
func (feuo *FsEventUpdateOne) SetNillableEvent(s *string) *FsEventUpdateOne {
|
||||
if s != nil {
|
||||
feuo.SetEvent(*s)
|
||||
}
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (feuo *FsEventUpdateOne) SetSubscriber(u uuid.UUID) *FsEventUpdateOne {
|
||||
feuo.mutation.SetSubscriber(u)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetNillableSubscriber sets the "subscriber" field if the given value is not nil.
|
||||
func (feuo *FsEventUpdateOne) SetNillableSubscriber(u *uuid.UUID) *FsEventUpdateOne {
|
||||
if u != nil {
|
||||
feuo.SetSubscriber(*u)
|
||||
}
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (feuo *FsEventUpdateOne) SetUserFsevent(i int) *FsEventUpdateOne {
|
||||
feuo.mutation.SetUserFsevent(i)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetNillableUserFsevent sets the "user_fsevent" field if the given value is not nil.
|
||||
func (feuo *FsEventUpdateOne) SetNillableUserFsevent(i *int) *FsEventUpdateOne {
|
||||
if i != nil {
|
||||
feuo.SetUserFsevent(*i)
|
||||
}
|
||||
return feuo
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (feuo *FsEventUpdateOne) ClearUserFsevent() *FsEventUpdateOne {
|
||||
feuo.mutation.ClearUserFsevent()
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by ID.
|
||||
func (feuo *FsEventUpdateOne) SetUserID(id int) *FsEventUpdateOne {
|
||||
feuo.mutation.SetUserID(id)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetNillableUserID sets the "user" edge to the User entity by ID if the given value is not nil.
|
||||
func (feuo *FsEventUpdateOne) SetNillableUserID(id *int) *FsEventUpdateOne {
|
||||
if id != nil {
|
||||
feuo = feuo.SetUserID(*id)
|
||||
}
|
||||
return feuo
|
||||
}
|
||||
|
||||
// SetUser sets the "user" edge to the User entity.
|
||||
func (feuo *FsEventUpdateOne) SetUser(u *User) *FsEventUpdateOne {
|
||||
return feuo.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the FsEventMutation object of the builder.
|
||||
func (feuo *FsEventUpdateOne) Mutation() *FsEventMutation {
|
||||
return feuo.mutation
|
||||
}
|
||||
|
||||
// ClearUser clears the "user" edge to the User entity.
|
||||
func (feuo *FsEventUpdateOne) ClearUser() *FsEventUpdateOne {
|
||||
feuo.mutation.ClearUser()
|
||||
return feuo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FsEventUpdate builder.
|
||||
func (feuo *FsEventUpdateOne) Where(ps ...predicate.FsEvent) *FsEventUpdateOne {
|
||||
feuo.mutation.Where(ps...)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (feuo *FsEventUpdateOne) Select(field string, fields ...string) *FsEventUpdateOne {
|
||||
feuo.fields = append([]string{field}, fields...)
|
||||
return feuo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated FsEvent entity.
|
||||
func (feuo *FsEventUpdateOne) Save(ctx context.Context) (*FsEvent, error) {
|
||||
if err := feuo.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, feuo.sqlSave, feuo.mutation, feuo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (feuo *FsEventUpdateOne) SaveX(ctx context.Context) *FsEvent {
|
||||
node, err := feuo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (feuo *FsEventUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := feuo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (feuo *FsEventUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := feuo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (feuo *FsEventUpdateOne) defaults() error {
|
||||
if _, ok := feuo.mutation.UpdatedAt(); !ok {
|
||||
if fsevent.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized fsevent.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := fsevent.UpdateDefaultUpdatedAt()
|
||||
feuo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (feuo *FsEventUpdateOne) sqlSave(ctx context.Context) (_node *FsEvent, err error) {
|
||||
_spec := sqlgraph.NewUpdateSpec(fsevent.Table, fsevent.Columns, sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt))
|
||||
id, ok := feuo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "FsEvent.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := feuo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fsevent.FieldID)
|
||||
for _, f := range fields {
|
||||
if !fsevent.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != fsevent.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := feuo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := feuo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := feuo.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(fsevent.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if feuo.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(fsevent.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := feuo.mutation.Event(); ok {
|
||||
_spec.SetField(fsevent.FieldEvent, field.TypeString, value)
|
||||
}
|
||||
if value, ok := feuo.mutation.Subscriber(); ok {
|
||||
_spec.SetField(fsevent.FieldSubscriber, field.TypeUUID, value)
|
||||
}
|
||||
if feuo.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: fsevent.UserTable,
|
||||
Columns: []string{fsevent.UserColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := feuo.mutation.UserIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: fsevent.UserTable,
|
||||
Columns: []string{fsevent.UserColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &FsEvent{config: feuo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, feuo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{fsevent.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
feuo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
|
@ -57,6 +57,18 @@ func (f FileFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error)
|
|||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FileMutation", m)
|
||||
}
|
||||
|
||||
// The FsEventFunc type is an adapter to allow the use of ordinary
|
||||
// function as FsEvent mutator.
|
||||
type FsEventFunc func(context.Context, *ent.FsEventMutation) (ent.Value, error)
|
||||
|
||||
// Mutate calls f(ctx, m).
|
||||
func (f FsEventFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
if mv, ok := m.(*ent.FsEventMutation); ok {
|
||||
return f(ctx, mv)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.FsEventMutation", m)
|
||||
}
|
||||
|
||||
// The GroupFunc type is an adapter to allow the use of ordinary
|
||||
// function as Group mutator.
|
||||
type GroupFunc func(context.Context, *ent.GroupMutation) (ent.Value, error)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
|
|
@ -188,6 +189,33 @@ func (f TraverseFile) Traverse(ctx context.Context, q ent.Query) error {
|
|||
return fmt.Errorf("unexpected query type %T. expect *ent.FileQuery", q)
|
||||
}
|
||||
|
||||
// The FsEventFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type FsEventFunc func(context.Context, *ent.FsEventQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f FsEventFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.FsEventQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.FsEventQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseFsEvent type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseFsEvent func(context.Context, *ent.FsEventQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseFsEvent) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseFsEvent) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.FsEventQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.FsEventQuery", q)
|
||||
}
|
||||
|
||||
// The GroupFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type GroupFunc func(context.Context, *ent.GroupQuery) (ent.Value, error)
|
||||
|
||||
|
|
@ -442,6 +470,8 @@ func NewQuery(q ent.Query) (Query, error) {
|
|||
return &query[*ent.EntityQuery, predicate.Entity, entity.OrderOption]{typ: ent.TypeEntity, tq: q}, nil
|
||||
case *ent.FileQuery:
|
||||
return &query[*ent.FileQuery, predicate.File, file.OrderOption]{typ: ent.TypeFile, tq: q}, nil
|
||||
case *ent.FsEventQuery:
|
||||
return &query[*ent.FsEventQuery, predicate.FsEvent, fsevent.OrderOption]{typ: ent.TypeFsEvent, tq: q}, nil
|
||||
case *ent.GroupQuery:
|
||||
return &query[*ent.GroupQuery, predicate.Group, group.OrderOption]{typ: ent.TypeGroup, tq: q}, nil
|
||||
case *ent.MetadataQuery:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -160,6 +160,30 @@ var (
|
|||
},
|
||||
},
|
||||
}
|
||||
// FsEventsColumns holds the columns for the "fs_events" table.
|
||||
FsEventsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime"}},
|
||||
{Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"mysql": "datetime"}},
|
||||
{Name: "event", Type: field.TypeString, Size: 2147483647},
|
||||
{Name: "subscriber", Type: field.TypeUUID},
|
||||
{Name: "user_fsevent", Type: field.TypeInt, Nullable: true},
|
||||
}
|
||||
// FsEventsTable holds the schema information for the "fs_events" table.
|
||||
FsEventsTable = &schema.Table{
|
||||
Name: "fs_events",
|
||||
Columns: FsEventsColumns,
|
||||
PrimaryKey: []*schema.Column{FsEventsColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "fs_events_users_fsevents",
|
||||
Columns: []*schema.Column{FsEventsColumns[6]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
},
|
||||
}
|
||||
// GroupsColumns holds the columns for the "groups" table.
|
||||
GroupsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
|
|
@ -444,6 +468,7 @@ var (
|
|||
DirectLinksTable,
|
||||
EntitiesTable,
|
||||
FilesTable,
|
||||
FsEventsTable,
|
||||
GroupsTable,
|
||||
MetadataTable,
|
||||
NodesTable,
|
||||
|
|
@ -465,6 +490,7 @@ func init() {
|
|||
FilesTable.ForeignKeys[0].RefTable = FilesTable
|
||||
FilesTable.ForeignKeys[1].RefTable = StoragePoliciesTable
|
||||
FilesTable.ForeignKeys[2].RefTable = UsersTable
|
||||
FsEventsTable.ForeignKeys[0].RefTable = UsersTable
|
||||
GroupsTable.ForeignKeys[0].RefTable = StoragePoliciesTable
|
||||
MetadataTable.ForeignKeys[0].RefTable = FilesTable
|
||||
PasskeysTable.ForeignKeys[0].RefTable = UsersTable
|
||||
|
|
|
|||
798
ent/mutation.go
798
ent/mutation.go
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
|
|
@ -44,6 +45,7 @@ const (
|
|||
TypeDirectLink = "DirectLink"
|
||||
TypeEntity = "Entity"
|
||||
TypeFile = "File"
|
||||
TypeFsEvent = "FsEvent"
|
||||
TypeGroup = "Group"
|
||||
TypeMetadata = "Metadata"
|
||||
TypeNode = "Node"
|
||||
|
|
@ -4601,6 +4603,713 @@ func (m *FileMutation) ResetEdge(name string) error {
|
|||
return fmt.Errorf("unknown File edge %s", name)
|
||||
}
|
||||
|
||||
// FsEventMutation represents an operation that mutates the FsEvent nodes in the graph.
|
||||
type FsEventMutation struct {
|
||||
config
|
||||
op Op
|
||||
typ string
|
||||
id *int
|
||||
created_at *time.Time
|
||||
updated_at *time.Time
|
||||
deleted_at *time.Time
|
||||
event *string
|
||||
subscriber *uuid.UUID
|
||||
clearedFields map[string]struct{}
|
||||
user *int
|
||||
cleareduser bool
|
||||
done bool
|
||||
oldValue func(context.Context) (*FsEvent, error)
|
||||
predicates []predicate.FsEvent
|
||||
}
|
||||
|
||||
var _ ent.Mutation = (*FsEventMutation)(nil)
|
||||
|
||||
// fseventOption allows management of the mutation configuration using functional options.
|
||||
type fseventOption func(*FsEventMutation)
|
||||
|
||||
// newFsEventMutation creates new mutation for the FsEvent entity.
|
||||
func newFsEventMutation(c config, op Op, opts ...fseventOption) *FsEventMutation {
|
||||
m := &FsEventMutation{
|
||||
config: c,
|
||||
op: op,
|
||||
typ: TypeFsEvent,
|
||||
clearedFields: make(map[string]struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// withFsEventID sets the ID field of the mutation.
|
||||
func withFsEventID(id int) fseventOption {
|
||||
return func(m *FsEventMutation) {
|
||||
var (
|
||||
err error
|
||||
once sync.Once
|
||||
value *FsEvent
|
||||
)
|
||||
m.oldValue = func(ctx context.Context) (*FsEvent, error) {
|
||||
once.Do(func() {
|
||||
if m.done {
|
||||
err = errors.New("querying old values post mutation is not allowed")
|
||||
} else {
|
||||
value, err = m.Client().FsEvent.Get(ctx, id)
|
||||
}
|
||||
})
|
||||
return value, err
|
||||
}
|
||||
m.id = &id
|
||||
}
|
||||
}
|
||||
|
||||
// withFsEvent sets the old FsEvent of the mutation.
|
||||
func withFsEvent(node *FsEvent) fseventOption {
|
||||
return func(m *FsEventMutation) {
|
||||
m.oldValue = func(context.Context) (*FsEvent, error) {
|
||||
return node, nil
|
||||
}
|
||||
m.id = &node.ID
|
||||
}
|
||||
}
|
||||
|
||||
// Client returns a new `ent.Client` from the mutation. If the mutation was
|
||||
// executed in a transaction (ent.Tx), a transactional client is returned.
|
||||
func (m FsEventMutation) Client() *Client {
|
||||
client := &Client{config: m.config}
|
||||
client.init()
|
||||
return client
|
||||
}
|
||||
|
||||
// Tx returns an `ent.Tx` for mutations that were executed in transactions;
|
||||
// it returns an error otherwise.
|
||||
func (m FsEventMutation) Tx() (*Tx, error) {
|
||||
if _, ok := m.driver.(*txDriver); !ok {
|
||||
return nil, errors.New("ent: mutation is not running in a transaction")
|
||||
}
|
||||
tx := &Tx{config: m.config}
|
||||
tx.init()
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// ID returns the ID value in the mutation. Note that the ID is only available
|
||||
// if it was provided to the builder or after it was returned from the database.
|
||||
func (m *FsEventMutation) ID() (id int, exists bool) {
|
||||
if m.id == nil {
|
||||
return
|
||||
}
|
||||
return *m.id, true
|
||||
}
|
||||
|
||||
// IDs queries the database and returns the entity ids that match the mutation's predicate.
|
||||
// That means, if the mutation is applied within a transaction with an isolation level such
|
||||
// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
|
||||
// or updated by the mutation.
|
||||
func (m *FsEventMutation) IDs(ctx context.Context) ([]int, error) {
|
||||
switch {
|
||||
case m.op.Is(OpUpdateOne | OpDeleteOne):
|
||||
id, exists := m.ID()
|
||||
if exists {
|
||||
return []int{id}, nil
|
||||
}
|
||||
fallthrough
|
||||
case m.op.Is(OpUpdate | OpDelete):
|
||||
return m.Client().FsEvent.Query().Where(m.predicates...).IDs(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
|
||||
}
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (m *FsEventMutation) SetCreatedAt(t time.Time) {
|
||||
m.created_at = &t
|
||||
}
|
||||
|
||||
// CreatedAt returns the value of the "created_at" field in the mutation.
|
||||
func (m *FsEventMutation) CreatedAt() (r time.Time, exists bool) {
|
||||
v := m.created_at
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldCreatedAt returns the old "created_at" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldCreatedAt requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
|
||||
}
|
||||
return oldValue.CreatedAt, nil
|
||||
}
|
||||
|
||||
// ResetCreatedAt resets all changes to the "created_at" field.
|
||||
func (m *FsEventMutation) ResetCreatedAt() {
|
||||
m.created_at = nil
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (m *FsEventMutation) SetUpdatedAt(t time.Time) {
|
||||
m.updated_at = &t
|
||||
}
|
||||
|
||||
// UpdatedAt returns the value of the "updated_at" field in the mutation.
|
||||
func (m *FsEventMutation) UpdatedAt() (r time.Time, exists bool) {
|
||||
v := m.updated_at
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldUpdatedAt returns the old "updated_at" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldUpdatedAt requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err)
|
||||
}
|
||||
return oldValue.UpdatedAt, nil
|
||||
}
|
||||
|
||||
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||
func (m *FsEventMutation) ResetUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (m *FsEventMutation) SetDeletedAt(t time.Time) {
|
||||
m.deleted_at = &t
|
||||
}
|
||||
|
||||
// DeletedAt returns the value of the "deleted_at" field in the mutation.
|
||||
func (m *FsEventMutation) DeletedAt() (r time.Time, exists bool) {
|
||||
v := m.deleted_at
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldDeletedAt returns the old "deleted_at" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldDeletedAt(ctx context.Context) (v *time.Time, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldDeletedAt is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldDeletedAt requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldDeletedAt: %w", err)
|
||||
}
|
||||
return oldValue.DeletedAt, nil
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (m *FsEventMutation) ClearDeletedAt() {
|
||||
m.deleted_at = nil
|
||||
m.clearedFields[fsevent.FieldDeletedAt] = struct{}{}
|
||||
}
|
||||
|
||||
// DeletedAtCleared returns if the "deleted_at" field was cleared in this mutation.
|
||||
func (m *FsEventMutation) DeletedAtCleared() bool {
|
||||
_, ok := m.clearedFields[fsevent.FieldDeletedAt]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetDeletedAt resets all changes to the "deleted_at" field.
|
||||
func (m *FsEventMutation) ResetDeletedAt() {
|
||||
m.deleted_at = nil
|
||||
delete(m.clearedFields, fsevent.FieldDeletedAt)
|
||||
}
|
||||
|
||||
// SetEvent sets the "event" field.
|
||||
func (m *FsEventMutation) SetEvent(s string) {
|
||||
m.event = &s
|
||||
}
|
||||
|
||||
// Event returns the value of the "event" field in the mutation.
|
||||
func (m *FsEventMutation) Event() (r string, exists bool) {
|
||||
v := m.event
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldEvent returns the old "event" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldEvent(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldEvent is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldEvent requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldEvent: %w", err)
|
||||
}
|
||||
return oldValue.Event, nil
|
||||
}
|
||||
|
||||
// ResetEvent resets all changes to the "event" field.
|
||||
func (m *FsEventMutation) ResetEvent() {
|
||||
m.event = nil
|
||||
}
|
||||
|
||||
// SetSubscriber sets the "subscriber" field.
|
||||
func (m *FsEventMutation) SetSubscriber(u uuid.UUID) {
|
||||
m.subscriber = &u
|
||||
}
|
||||
|
||||
// Subscriber returns the value of the "subscriber" field in the mutation.
|
||||
func (m *FsEventMutation) Subscriber() (r uuid.UUID, exists bool) {
|
||||
v := m.subscriber
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldSubscriber returns the old "subscriber" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldSubscriber(ctx context.Context) (v uuid.UUID, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldSubscriber is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldSubscriber requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldSubscriber: %w", err)
|
||||
}
|
||||
return oldValue.Subscriber, nil
|
||||
}
|
||||
|
||||
// ResetSubscriber resets all changes to the "subscriber" field.
|
||||
func (m *FsEventMutation) ResetSubscriber() {
|
||||
m.subscriber = nil
|
||||
}
|
||||
|
||||
// SetUserFsevent sets the "user_fsevent" field.
|
||||
func (m *FsEventMutation) SetUserFsevent(i int) {
|
||||
m.user = &i
|
||||
}
|
||||
|
||||
// UserFsevent returns the value of the "user_fsevent" field in the mutation.
|
||||
func (m *FsEventMutation) UserFsevent() (r int, exists bool) {
|
||||
v := m.user
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldUserFsevent returns the old "user_fsevent" field's value of the FsEvent entity.
|
||||
// If the FsEvent object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *FsEventMutation) OldUserFsevent(ctx context.Context) (v int, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldUserFsevent is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldUserFsevent requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldUserFsevent: %w", err)
|
||||
}
|
||||
return oldValue.UserFsevent, nil
|
||||
}
|
||||
|
||||
// ClearUserFsevent clears the value of the "user_fsevent" field.
|
||||
func (m *FsEventMutation) ClearUserFsevent() {
|
||||
m.user = nil
|
||||
m.clearedFields[fsevent.FieldUserFsevent] = struct{}{}
|
||||
}
|
||||
|
||||
// UserFseventCleared returns if the "user_fsevent" field was cleared in this mutation.
|
||||
func (m *FsEventMutation) UserFseventCleared() bool {
|
||||
_, ok := m.clearedFields[fsevent.FieldUserFsevent]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetUserFsevent resets all changes to the "user_fsevent" field.
|
||||
func (m *FsEventMutation) ResetUserFsevent() {
|
||||
m.user = nil
|
||||
delete(m.clearedFields, fsevent.FieldUserFsevent)
|
||||
}
|
||||
|
||||
// SetUserID sets the "user" edge to the User entity by id.
|
||||
func (m *FsEventMutation) SetUserID(id int) {
|
||||
m.user = &id
|
||||
}
|
||||
|
||||
// ClearUser clears the "user" edge to the User entity.
|
||||
func (m *FsEventMutation) ClearUser() {
|
||||
m.cleareduser = true
|
||||
m.clearedFields[fsevent.FieldUserFsevent] = struct{}{}
|
||||
}
|
||||
|
||||
// UserCleared reports if the "user" edge to the User entity was cleared.
|
||||
func (m *FsEventMutation) UserCleared() bool {
|
||||
return m.UserFseventCleared() || m.cleareduser
|
||||
}
|
||||
|
||||
// UserID returns the "user" edge ID in the mutation.
|
||||
func (m *FsEventMutation) UserID() (id int, exists bool) {
|
||||
if m.user != nil {
|
||||
return *m.user, true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UserIDs returns the "user" edge IDs in the mutation.
|
||||
// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
|
||||
// UserID instead. It exists only for internal usage by the builders.
|
||||
func (m *FsEventMutation) UserIDs() (ids []int) {
|
||||
if id := m.user; id != nil {
|
||||
ids = append(ids, *id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ResetUser resets all changes to the "user" edge.
|
||||
func (m *FsEventMutation) ResetUser() {
|
||||
m.user = nil
|
||||
m.cleareduser = false
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FsEventMutation builder.
|
||||
func (m *FsEventMutation) Where(ps ...predicate.FsEvent) {
|
||||
m.predicates = append(m.predicates, ps...)
|
||||
}
|
||||
|
||||
// WhereP appends storage-level predicates to the FsEventMutation builder. Using this method,
|
||||
// users can use type-assertion to append predicates that do not depend on any generated package.
|
||||
func (m *FsEventMutation) WhereP(ps ...func(*sql.Selector)) {
|
||||
p := make([]predicate.FsEvent, len(ps))
|
||||
for i := range ps {
|
||||
p[i] = ps[i]
|
||||
}
|
||||
m.Where(p...)
|
||||
}
|
||||
|
||||
// Op returns the operation name.
|
||||
func (m *FsEventMutation) Op() Op {
|
||||
return m.op
|
||||
}
|
||||
|
||||
// SetOp allows setting the mutation operation.
|
||||
func (m *FsEventMutation) SetOp(op Op) {
|
||||
m.op = op
|
||||
}
|
||||
|
||||
// Type returns the node type of this mutation (FsEvent).
|
||||
func (m *FsEventMutation) Type() string {
|
||||
return m.typ
|
||||
}
|
||||
|
||||
// Fields returns all fields that were changed during this mutation. Note that in
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *FsEventMutation) Fields() []string {
|
||||
fields := make([]string, 0, 6)
|
||||
if m.created_at != nil {
|
||||
fields = append(fields, fsevent.FieldCreatedAt)
|
||||
}
|
||||
if m.updated_at != nil {
|
||||
fields = append(fields, fsevent.FieldUpdatedAt)
|
||||
}
|
||||
if m.deleted_at != nil {
|
||||
fields = append(fields, fsevent.FieldDeletedAt)
|
||||
}
|
||||
if m.event != nil {
|
||||
fields = append(fields, fsevent.FieldEvent)
|
||||
}
|
||||
if m.subscriber != nil {
|
||||
fields = append(fields, fsevent.FieldSubscriber)
|
||||
}
|
||||
if m.user != nil {
|
||||
fields = append(fields, fsevent.FieldUserFsevent)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// Field returns the value of a field with the given name. The second boolean
|
||||
// return value indicates that this field was not set, or was not defined in the
|
||||
// schema.
|
||||
func (m *FsEventMutation) Field(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
case fsevent.FieldCreatedAt:
|
||||
return m.CreatedAt()
|
||||
case fsevent.FieldUpdatedAt:
|
||||
return m.UpdatedAt()
|
||||
case fsevent.FieldDeletedAt:
|
||||
return m.DeletedAt()
|
||||
case fsevent.FieldEvent:
|
||||
return m.Event()
|
||||
case fsevent.FieldSubscriber:
|
||||
return m.Subscriber()
|
||||
case fsevent.FieldUserFsevent:
|
||||
return m.UserFsevent()
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// OldField returns the old value of the field from the database. An error is
|
||||
// returned if the mutation operation is not UpdateOne, or the query to the
|
||||
// database failed.
|
||||
func (m *FsEventMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
||||
switch name {
|
||||
case fsevent.FieldCreatedAt:
|
||||
return m.OldCreatedAt(ctx)
|
||||
case fsevent.FieldUpdatedAt:
|
||||
return m.OldUpdatedAt(ctx)
|
||||
case fsevent.FieldDeletedAt:
|
||||
return m.OldDeletedAt(ctx)
|
||||
case fsevent.FieldEvent:
|
||||
return m.OldEvent(ctx)
|
||||
case fsevent.FieldSubscriber:
|
||||
return m.OldSubscriber(ctx)
|
||||
case fsevent.FieldUserFsevent:
|
||||
return m.OldUserFsevent(ctx)
|
||||
}
|
||||
return nil, fmt.Errorf("unknown FsEvent field %s", name)
|
||||
}
|
||||
|
||||
// SetField sets the value of a field with the given name. It returns an error if
|
||||
// the field is not defined in the schema, or if the type mismatched the field
|
||||
// type.
|
||||
func (m *FsEventMutation) SetField(name string, value ent.Value) error {
|
||||
switch name {
|
||||
case fsevent.FieldCreatedAt:
|
||||
v, ok := value.(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetCreatedAt(v)
|
||||
return nil
|
||||
case fsevent.FieldUpdatedAt:
|
||||
v, ok := value.(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetUpdatedAt(v)
|
||||
return nil
|
||||
case fsevent.FieldDeletedAt:
|
||||
v, ok := value.(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetDeletedAt(v)
|
||||
return nil
|
||||
case fsevent.FieldEvent:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetEvent(v)
|
||||
return nil
|
||||
case fsevent.FieldSubscriber:
|
||||
v, ok := value.(uuid.UUID)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetSubscriber(v)
|
||||
return nil
|
||||
case fsevent.FieldUserFsevent:
|
||||
v, ok := value.(int)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetUserFsevent(v)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent field %s", name)
|
||||
}
|
||||
|
||||
// AddedFields returns all numeric fields that were incremented/decremented during
|
||||
// this mutation.
|
||||
func (m *FsEventMutation) AddedFields() []string {
|
||||
var fields []string
|
||||
return fields
|
||||
}
|
||||
|
||||
// AddedField returns the numeric value that was incremented/decremented on a field
|
||||
// with the given name. The second boolean return value indicates that this field
|
||||
// was not set, or was not defined in the schema.
|
||||
func (m *FsEventMutation) AddedField(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// AddField adds the value to the field with the given name. It returns an error if
|
||||
// the field is not defined in the schema, or if the type mismatched the field
|
||||
// type.
|
||||
func (m *FsEventMutation) AddField(name string, value ent.Value) error {
|
||||
switch name {
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent numeric field %s", name)
|
||||
}
|
||||
|
||||
// ClearedFields returns all nullable fields that were cleared during this
|
||||
// mutation.
|
||||
func (m *FsEventMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(fsevent.FieldDeletedAt) {
|
||||
fields = append(fields, fsevent.FieldDeletedAt)
|
||||
}
|
||||
if m.FieldCleared(fsevent.FieldUserFsevent) {
|
||||
fields = append(fields, fsevent.FieldUserFsevent)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
// FieldCleared returns a boolean indicating if a field with the given name was
|
||||
// cleared in this mutation.
|
||||
func (m *FsEventMutation) FieldCleared(name string) bool {
|
||||
_, ok := m.clearedFields[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ClearField clears the value of the field with the given name. It returns an
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *FsEventMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case fsevent.FieldDeletedAt:
|
||||
m.ClearDeletedAt()
|
||||
return nil
|
||||
case fsevent.FieldUserFsevent:
|
||||
m.ClearUserFsevent()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent nullable field %s", name)
|
||||
}
|
||||
|
||||
// ResetField resets all changes in the mutation for the field with the given name.
|
||||
// It returns an error if the field is not defined in the schema.
|
||||
func (m *FsEventMutation) ResetField(name string) error {
|
||||
switch name {
|
||||
case fsevent.FieldCreatedAt:
|
||||
m.ResetCreatedAt()
|
||||
return nil
|
||||
case fsevent.FieldUpdatedAt:
|
||||
m.ResetUpdatedAt()
|
||||
return nil
|
||||
case fsevent.FieldDeletedAt:
|
||||
m.ResetDeletedAt()
|
||||
return nil
|
||||
case fsevent.FieldEvent:
|
||||
m.ResetEvent()
|
||||
return nil
|
||||
case fsevent.FieldSubscriber:
|
||||
m.ResetSubscriber()
|
||||
return nil
|
||||
case fsevent.FieldUserFsevent:
|
||||
m.ResetUserFsevent()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent field %s", name)
|
||||
}
|
||||
|
||||
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||
func (m *FsEventMutation) AddedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
if m.user != nil {
|
||||
edges = append(edges, fsevent.EdgeUser)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// AddedIDs returns all IDs (to other nodes) that were added for the given edge
|
||||
// name in this mutation.
|
||||
func (m *FsEventMutation) AddedIDs(name string) []ent.Value {
|
||||
switch name {
|
||||
case fsevent.EdgeUser:
|
||||
if id := m.user; id != nil {
|
||||
return []ent.Value{*id}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||
func (m *FsEventMutation) RemovedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
return edges
|
||||
}
|
||||
|
||||
// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
|
||||
// the given name in this mutation.
|
||||
func (m *FsEventMutation) RemovedIDs(name string) []ent.Value {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||
func (m *FsEventMutation) ClearedEdges() []string {
|
||||
edges := make([]string, 0, 1)
|
||||
if m.cleareduser {
|
||||
edges = append(edges, fsevent.EdgeUser)
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// EdgeCleared returns a boolean which indicates if the edge with the given name
|
||||
// was cleared in this mutation.
|
||||
func (m *FsEventMutation) EdgeCleared(name string) bool {
|
||||
switch name {
|
||||
case fsevent.EdgeUser:
|
||||
return m.cleareduser
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ClearEdge clears the value of the edge with the given name. It returns an error
|
||||
// if that edge is not defined in the schema.
|
||||
func (m *FsEventMutation) ClearEdge(name string) error {
|
||||
switch name {
|
||||
case fsevent.EdgeUser:
|
||||
m.ClearUser()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent unique edge %s", name)
|
||||
}
|
||||
|
||||
// ResetEdge resets all changes to the edge with the given name in this mutation.
|
||||
// It returns an error if the edge is not defined in the schema.
|
||||
func (m *FsEventMutation) ResetEdge(name string) error {
|
||||
switch name {
|
||||
case fsevent.EdgeUser:
|
||||
m.ResetUser()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown FsEvent edge %s", name)
|
||||
}
|
||||
|
||||
// GroupMutation represents an operation that mutates the Group nodes in the graph.
|
||||
type GroupMutation struct {
|
||||
config
|
||||
|
|
@ -12532,6 +13241,9 @@ type UserMutation struct {
|
|||
tasks map[int]struct{}
|
||||
removedtasks map[int]struct{}
|
||||
clearedtasks bool
|
||||
fsevents map[int]struct{}
|
||||
removedfsevents map[int]struct{}
|
||||
clearedfsevents bool
|
||||
entities map[int]struct{}
|
||||
removedentities map[int]struct{}
|
||||
clearedentities bool
|
||||
|
|
@ -13465,6 +14177,60 @@ func (m *UserMutation) ResetTasks() {
|
|||
m.removedtasks = nil
|
||||
}
|
||||
|
||||
// AddFseventIDs adds the "fsevents" edge to the FsEvent entity by ids.
|
||||
func (m *UserMutation) AddFseventIDs(ids ...int) {
|
||||
if m.fsevents == nil {
|
||||
m.fsevents = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
m.fsevents[ids[i]] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// ClearFsevents clears the "fsevents" edge to the FsEvent entity.
|
||||
func (m *UserMutation) ClearFsevents() {
|
||||
m.clearedfsevents = true
|
||||
}
|
||||
|
||||
// FseventsCleared reports if the "fsevents" edge to the FsEvent entity was cleared.
|
||||
func (m *UserMutation) FseventsCleared() bool {
|
||||
return m.clearedfsevents
|
||||
}
|
||||
|
||||
// RemoveFseventIDs removes the "fsevents" edge to the FsEvent entity by IDs.
|
||||
func (m *UserMutation) RemoveFseventIDs(ids ...int) {
|
||||
if m.removedfsevents == nil {
|
||||
m.removedfsevents = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
delete(m.fsevents, ids[i])
|
||||
m.removedfsevents[ids[i]] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// RemovedFsevents returns the removed IDs of the "fsevents" edge to the FsEvent entity.
|
||||
func (m *UserMutation) RemovedFseventsIDs() (ids []int) {
|
||||
for id := range m.removedfsevents {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FseventsIDs returns the "fsevents" edge IDs in the mutation.
|
||||
func (m *UserMutation) FseventsIDs() (ids []int) {
|
||||
for id := range m.fsevents {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ResetFsevents resets all changes to the "fsevents" edge.
|
||||
func (m *UserMutation) ResetFsevents() {
|
||||
m.fsevents = nil
|
||||
m.clearedfsevents = false
|
||||
m.removedfsevents = nil
|
||||
}
|
||||
|
||||
// AddEntityIDs adds the "entities" edge to the Entity entity by ids.
|
||||
func (m *UserMutation) AddEntityIDs(ids ...int) {
|
||||
if m.entities == nil {
|
||||
|
|
@ -13887,7 +14653,7 @@ func (m *UserMutation) ResetField(name string) error {
|
|||
|
||||
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||
func (m *UserMutation) AddedEdges() []string {
|
||||
edges := make([]string, 0, 7)
|
||||
edges := make([]string, 0, 8)
|
||||
if m.group != nil {
|
||||
edges = append(edges, user.EdgeGroup)
|
||||
}
|
||||
|
|
@ -13906,6 +14672,9 @@ func (m *UserMutation) AddedEdges() []string {
|
|||
if m.tasks != nil {
|
||||
edges = append(edges, user.EdgeTasks)
|
||||
}
|
||||
if m.fsevents != nil {
|
||||
edges = append(edges, user.EdgeFsevents)
|
||||
}
|
||||
if m.entities != nil {
|
||||
edges = append(edges, user.EdgeEntities)
|
||||
}
|
||||
|
|
@ -13950,6 +14719,12 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value {
|
|||
ids = append(ids, id)
|
||||
}
|
||||
return ids
|
||||
case user.EdgeFsevents:
|
||||
ids := make([]ent.Value, 0, len(m.fsevents))
|
||||
for id := range m.fsevents {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return ids
|
||||
case user.EdgeEntities:
|
||||
ids := make([]ent.Value, 0, len(m.entities))
|
||||
for id := range m.entities {
|
||||
|
|
@ -13962,7 +14737,7 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value {
|
|||
|
||||
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||
func (m *UserMutation) RemovedEdges() []string {
|
||||
edges := make([]string, 0, 7)
|
||||
edges := make([]string, 0, 8)
|
||||
if m.removedfiles != nil {
|
||||
edges = append(edges, user.EdgeFiles)
|
||||
}
|
||||
|
|
@ -13978,6 +14753,9 @@ func (m *UserMutation) RemovedEdges() []string {
|
|||
if m.removedtasks != nil {
|
||||
edges = append(edges, user.EdgeTasks)
|
||||
}
|
||||
if m.removedfsevents != nil {
|
||||
edges = append(edges, user.EdgeFsevents)
|
||||
}
|
||||
if m.removedentities != nil {
|
||||
edges = append(edges, user.EdgeEntities)
|
||||
}
|
||||
|
|
@ -14018,6 +14796,12 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value {
|
|||
ids = append(ids, id)
|
||||
}
|
||||
return ids
|
||||
case user.EdgeFsevents:
|
||||
ids := make([]ent.Value, 0, len(m.removedfsevents))
|
||||
for id := range m.removedfsevents {
|
||||
ids = append(ids, id)
|
||||
}
|
||||
return ids
|
||||
case user.EdgeEntities:
|
||||
ids := make([]ent.Value, 0, len(m.removedentities))
|
||||
for id := range m.removedentities {
|
||||
|
|
@ -14030,7 +14814,7 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value {
|
|||
|
||||
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||
func (m *UserMutation) ClearedEdges() []string {
|
||||
edges := make([]string, 0, 7)
|
||||
edges := make([]string, 0, 8)
|
||||
if m.clearedgroup {
|
||||
edges = append(edges, user.EdgeGroup)
|
||||
}
|
||||
|
|
@ -14049,6 +14833,9 @@ func (m *UserMutation) ClearedEdges() []string {
|
|||
if m.clearedtasks {
|
||||
edges = append(edges, user.EdgeTasks)
|
||||
}
|
||||
if m.clearedfsevents {
|
||||
edges = append(edges, user.EdgeFsevents)
|
||||
}
|
||||
if m.clearedentities {
|
||||
edges = append(edges, user.EdgeEntities)
|
||||
}
|
||||
|
|
@ -14071,6 +14858,8 @@ func (m *UserMutation) EdgeCleared(name string) bool {
|
|||
return m.clearedpasskey
|
||||
case user.EdgeTasks:
|
||||
return m.clearedtasks
|
||||
case user.EdgeFsevents:
|
||||
return m.clearedfsevents
|
||||
case user.EdgeEntities:
|
||||
return m.clearedentities
|
||||
}
|
||||
|
|
@ -14110,6 +14899,9 @@ func (m *UserMutation) ResetEdge(name string) error {
|
|||
case user.EdgeTasks:
|
||||
m.ResetTasks()
|
||||
return nil
|
||||
case user.EdgeFsevents:
|
||||
m.ResetFsevents()
|
||||
return nil
|
||||
case user.EdgeEntities:
|
||||
m.ResetEntities()
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ func (m *FileMutation) SetRawID(t int) {
|
|||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
|
||||
func (m *FsEventMutation) SetRawID(t int) {
|
||||
m.id = &t
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
|
||||
func (m *GroupMutation) SetRawID(t int) {
|
||||
m.id = &t
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ type Entity func(*sql.Selector)
|
|||
// File is the predicate function for file builders.
|
||||
type File func(*sql.Selector)
|
||||
|
||||
// FsEvent is the predicate function for fsevent builders.
|
||||
type FsEvent func(*sql.Selector)
|
||||
|
||||
// Group is the predicate function for group builders.
|
||||
type Group func(*sql.Selector)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
|
|
@ -107,6 +108,25 @@ func init() {
|
|||
fileDescIsSymbolic := fileFields[8].Descriptor()
|
||||
// file.DefaultIsSymbolic holds the default value on creation for the is_symbolic field.
|
||||
file.DefaultIsSymbolic = fileDescIsSymbolic.Default.(bool)
|
||||
fseventMixin := schema.FsEvent{}.Mixin()
|
||||
fseventMixinHooks0 := fseventMixin[0].Hooks()
|
||||
fsevent.Hooks[0] = fseventMixinHooks0[0]
|
||||
fseventMixinInters0 := fseventMixin[0].Interceptors()
|
||||
fsevent.Interceptors[0] = fseventMixinInters0[0]
|
||||
fseventMixinFields0 := fseventMixin[0].Fields()
|
||||
_ = fseventMixinFields0
|
||||
fseventFields := schema.FsEvent{}.Fields()
|
||||
_ = fseventFields
|
||||
// fseventDescCreatedAt is the schema descriptor for created_at field.
|
||||
fseventDescCreatedAt := fseventMixinFields0[0].Descriptor()
|
||||
// fsevent.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
fsevent.DefaultCreatedAt = fseventDescCreatedAt.Default.(func() time.Time)
|
||||
// fseventDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
fseventDescUpdatedAt := fseventMixinFields0[1].Descriptor()
|
||||
// fsevent.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
fsevent.DefaultUpdatedAt = fseventDescUpdatedAt.Default.(func() time.Time)
|
||||
// fsevent.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
fsevent.UpdateDefaultUpdatedAt = fseventDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
groupMixin := schema.Group{}.Mixin()
|
||||
groupMixinHooks0 := groupMixin[0].Hooks()
|
||||
group.Hooks[0] = groupMixinHooks0[0]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/schema/edge"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// FsEvent holds the schema definition for the FsEvent entity.
|
||||
type FsEvent struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
// Fields of the FsEvent.
|
||||
func (FsEvent) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.Text("event"),
|
||||
field.UUID("subscriber", uuid.Must(uuid.NewV4())),
|
||||
field.Int("user_fsevent").Optional(),
|
||||
}
|
||||
}
|
||||
|
||||
// Edges of the Task.
|
||||
func (FsEvent) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("user", User.Type).
|
||||
Ref("fsevents").
|
||||
Field("user_fsevent").
|
||||
Unique(),
|
||||
}
|
||||
}
|
||||
|
||||
func (FsEvent) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
CommonMixin{},
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ func (User) Edges() []ent.Edge {
|
|||
edge.To("shares", Share.Type),
|
||||
edge.To("passkey", Passkey.Type),
|
||||
edge.To("tasks", Task.Type),
|
||||
edge.To("fsevents", FsEvent.Type),
|
||||
edge.To("entities", Entity.Type),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ type Tx struct {
|
|||
Entity *EntityClient
|
||||
// File is the client for interacting with the File builders.
|
||||
File *FileClient
|
||||
// FsEvent is the client for interacting with the FsEvent builders.
|
||||
FsEvent *FsEventClient
|
||||
// Group is the client for interacting with the Group builders.
|
||||
Group *GroupClient
|
||||
// Metadata is the client for interacting with the Metadata builders.
|
||||
|
|
@ -175,6 +177,7 @@ func (tx *Tx) init() {
|
|||
tx.DirectLink = NewDirectLinkClient(tx.config)
|
||||
tx.Entity = NewEntityClient(tx.config)
|
||||
tx.File = NewFileClient(tx.config)
|
||||
tx.FsEvent = NewFsEventClient(tx.config)
|
||||
tx.Group = NewGroupClient(tx.config)
|
||||
tx.Metadata = NewMetadataClient(tx.config)
|
||||
tx.Node = NewNodeClient(tx.config)
|
||||
|
|
|
|||
28
ent/user.go
28
ent/user.go
|
|
@ -64,11 +64,13 @@ type UserEdges struct {
|
|||
Passkey []*Passkey `json:"passkey,omitempty"`
|
||||
// Tasks holds the value of the tasks edge.
|
||||
Tasks []*Task `json:"tasks,omitempty"`
|
||||
// Fsevents holds the value of the fsevents edge.
|
||||
Fsevents []*FsEvent `json:"fsevents,omitempty"`
|
||||
// Entities holds the value of the entities edge.
|
||||
Entities []*Entity `json:"entities,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [7]bool
|
||||
loadedTypes [8]bool
|
||||
}
|
||||
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
|
|
@ -129,10 +131,19 @@ func (e UserEdges) TasksOrErr() ([]*Task, error) {
|
|||
return nil, &NotLoadedError{edge: "tasks"}
|
||||
}
|
||||
|
||||
// FseventsOrErr returns the Fsevents value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e UserEdges) FseventsOrErr() ([]*FsEvent, error) {
|
||||
if e.loadedTypes[6] {
|
||||
return e.Fsevents, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "fsevents"}
|
||||
}
|
||||
|
||||
// EntitiesOrErr returns the Entities value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e UserEdges) EntitiesOrErr() ([]*Entity, error) {
|
||||
if e.loadedTypes[6] {
|
||||
if e.loadedTypes[7] {
|
||||
return e.Entities, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "entities"}
|
||||
|
|
@ -290,6 +301,11 @@ func (u *User) QueryTasks() *TaskQuery {
|
|||
return NewUserClient(u.config).QueryTasks(u)
|
||||
}
|
||||
|
||||
// QueryFsevents queries the "fsevents" edge of the User entity.
|
||||
func (u *User) QueryFsevents() *FsEventQuery {
|
||||
return NewUserClient(u.config).QueryFsevents(u)
|
||||
}
|
||||
|
||||
// QueryEntities queries the "entities" edge of the User entity.
|
||||
func (u *User) QueryEntities() *EntityQuery {
|
||||
return NewUserClient(u.config).QueryEntities(u)
|
||||
|
|
@ -393,10 +409,16 @@ func (e *User) SetTasks(v []*Task) {
|
|||
e.Edges.loadedTypes[5] = true
|
||||
}
|
||||
|
||||
// SetFsevents manually set the edge as loaded state.
|
||||
func (e *User) SetFsevents(v []*FsEvent) {
|
||||
e.Edges.Fsevents = v
|
||||
e.Edges.loadedTypes[6] = true
|
||||
}
|
||||
|
||||
// SetEntities manually set the edge as loaded state.
|
||||
func (e *User) SetEntities(v []*Entity) {
|
||||
e.Edges.Entities = v
|
||||
e.Edges.loadedTypes[6] = true
|
||||
e.Edges.loadedTypes[7] = true
|
||||
}
|
||||
|
||||
// Users is a parsable slice of User.
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ const (
|
|||
EdgePasskey = "passkey"
|
||||
// EdgeTasks holds the string denoting the tasks edge name in mutations.
|
||||
EdgeTasks = "tasks"
|
||||
// EdgeFsevents holds the string denoting the fsevents edge name in mutations.
|
||||
EdgeFsevents = "fsevents"
|
||||
// EdgeEntities holds the string denoting the entities edge name in mutations.
|
||||
EdgeEntities = "entities"
|
||||
// Table holds the table name of the user in the database.
|
||||
|
|
@ -99,6 +101,13 @@ const (
|
|||
TasksInverseTable = "tasks"
|
||||
// TasksColumn is the table column denoting the tasks relation/edge.
|
||||
TasksColumn = "user_tasks"
|
||||
// FseventsTable is the table that holds the fsevents relation/edge.
|
||||
FseventsTable = "fs_events"
|
||||
// FseventsInverseTable is the table name for the FsEvent entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "fsevent" package.
|
||||
FseventsInverseTable = "fs_events"
|
||||
// FseventsColumn is the table column denoting the fsevents relation/edge.
|
||||
FseventsColumn = "user_fsevent"
|
||||
// EntitiesTable is the table that holds the entities relation/edge.
|
||||
EntitiesTable = "entities"
|
||||
// EntitiesInverseTable is the table name for the Entity entity.
|
||||
|
|
@ -327,6 +336,20 @@ func ByTasks(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
|||
}
|
||||
}
|
||||
|
||||
// ByFseventsCount orders the results by fsevents count.
|
||||
func ByFseventsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newFseventsStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByFsevents orders the results by fsevents terms.
|
||||
func ByFsevents(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newFseventsStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByEntitiesCount orders the results by entities count.
|
||||
func ByEntitiesCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
|
|
@ -382,6 +405,13 @@ func newTasksStep() *sqlgraph.Step {
|
|||
sqlgraph.Edge(sqlgraph.O2M, false, TasksTable, TasksColumn),
|
||||
)
|
||||
}
|
||||
func newFseventsStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(FseventsInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, FseventsTable, FseventsColumn),
|
||||
)
|
||||
}
|
||||
func newEntitiesStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
|
|
|
|||
|
|
@ -818,6 +818,29 @@ func HasTasksWith(preds ...predicate.Task) predicate.User {
|
|||
})
|
||||
}
|
||||
|
||||
// HasFsevents applies the HasEdge predicate on the "fsevents" edge.
|
||||
func HasFsevents() predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, FseventsTable, FseventsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasFseventsWith applies the HasEdge predicate on the "fsevents" edge with a given conditions (other predicates).
|
||||
func HasFseventsWith(preds ...predicate.FsEvent) predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := newFseventsStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasEntities applies the HasEdge predicate on the "entities" edge.
|
||||
func HasEntities() predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/passkey"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/share"
|
||||
|
|
@ -252,6 +253,21 @@ func (uc *UserCreate) AddTasks(t ...*Task) *UserCreate {
|
|||
return uc.AddTaskIDs(ids...)
|
||||
}
|
||||
|
||||
// AddFseventIDs adds the "fsevents" edge to the FsEvent entity by IDs.
|
||||
func (uc *UserCreate) AddFseventIDs(ids ...int) *UserCreate {
|
||||
uc.mutation.AddFseventIDs(ids...)
|
||||
return uc
|
||||
}
|
||||
|
||||
// AddFsevents adds the "fsevents" edges to the FsEvent entity.
|
||||
func (uc *UserCreate) AddFsevents(f ...*FsEvent) *UserCreate {
|
||||
ids := make([]int, len(f))
|
||||
for i := range f {
|
||||
ids[i] = f[i].ID
|
||||
}
|
||||
return uc.AddFseventIDs(ids...)
|
||||
}
|
||||
|
||||
// AddEntityIDs adds the "entities" edge to the Entity entity by IDs.
|
||||
func (uc *UserCreate) AddEntityIDs(ids ...int) *UserCreate {
|
||||
uc.mutation.AddEntityIDs(ids...)
|
||||
|
|
@ -549,6 +565,22 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
|||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := uc.mutation.FseventsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := uc.mutation.EntitiesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/passkey"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
|
|
@ -35,6 +36,7 @@ type UserQuery struct {
|
|||
withShares *ShareQuery
|
||||
withPasskey *PasskeyQuery
|
||||
withTasks *TaskQuery
|
||||
withFsevents *FsEventQuery
|
||||
withEntities *EntityQuery
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
|
|
@ -204,6 +206,28 @@ func (uq *UserQuery) QueryTasks() *TaskQuery {
|
|||
return query
|
||||
}
|
||||
|
||||
// QueryFsevents chains the current query on the "fsevents" edge.
|
||||
func (uq *UserQuery) QueryFsevents() *FsEventQuery {
|
||||
query := (&FsEventClient{config: uq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := uq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(user.Table, user.FieldID, selector),
|
||||
sqlgraph.To(fsevent.Table, fsevent.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, user.FseventsTable, user.FseventsColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryEntities chains the current query on the "entities" edge.
|
||||
func (uq *UserQuery) QueryEntities() *EntityQuery {
|
||||
query := (&EntityClient{config: uq.config}).Query()
|
||||
|
|
@ -424,6 +448,7 @@ func (uq *UserQuery) Clone() *UserQuery {
|
|||
withShares: uq.withShares.Clone(),
|
||||
withPasskey: uq.withPasskey.Clone(),
|
||||
withTasks: uq.withTasks.Clone(),
|
||||
withFsevents: uq.withFsevents.Clone(),
|
||||
withEntities: uq.withEntities.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: uq.sql.Clone(),
|
||||
|
|
@ -497,6 +522,17 @@ func (uq *UserQuery) WithTasks(opts ...func(*TaskQuery)) *UserQuery {
|
|||
return uq
|
||||
}
|
||||
|
||||
// WithFsevents tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "fsevents" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (uq *UserQuery) WithFsevents(opts ...func(*FsEventQuery)) *UserQuery {
|
||||
query := (&FsEventClient{config: uq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
uq.withFsevents = query
|
||||
return uq
|
||||
}
|
||||
|
||||
// WithEntities tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "entities" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (uq *UserQuery) WithEntities(opts ...func(*EntityQuery)) *UserQuery {
|
||||
|
|
@ -586,13 +622,14 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
|
|||
var (
|
||||
nodes = []*User{}
|
||||
_spec = uq.querySpec()
|
||||
loadedTypes = [7]bool{
|
||||
loadedTypes = [8]bool{
|
||||
uq.withGroup != nil,
|
||||
uq.withFiles != nil,
|
||||
uq.withDavAccounts != nil,
|
||||
uq.withShares != nil,
|
||||
uq.withPasskey != nil,
|
||||
uq.withTasks != nil,
|
||||
uq.withFsevents != nil,
|
||||
uq.withEntities != nil,
|
||||
}
|
||||
)
|
||||
|
|
@ -655,6 +692,13 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := uq.withFsevents; query != nil {
|
||||
if err := uq.loadFsevents(ctx, query, nodes,
|
||||
func(n *User) { n.Edges.Fsevents = []*FsEvent{} },
|
||||
func(n *User, e *FsEvent) { n.Edges.Fsevents = append(n.Edges.Fsevents, e) }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := uq.withEntities; query != nil {
|
||||
if err := uq.loadEntities(ctx, query, nodes,
|
||||
func(n *User) { n.Edges.Entities = []*Entity{} },
|
||||
|
|
@ -845,6 +889,36 @@ func (uq *UserQuery) loadTasks(ctx context.Context, query *TaskQuery, nodes []*U
|
|||
}
|
||||
return nil
|
||||
}
|
||||
func (uq *UserQuery) loadFsevents(ctx context.Context, query *FsEventQuery, nodes []*User, init func(*User), assign func(*User, *FsEvent)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[int]*User)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
if init != nil {
|
||||
init(nodes[i])
|
||||
}
|
||||
}
|
||||
if len(query.ctx.Fields) > 0 {
|
||||
query.ctx.AppendFieldOnce(fsevent.FieldUserFsevent)
|
||||
}
|
||||
query.Where(predicate.FsEvent(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(s.C(user.FseventsColumn), fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.UserFsevent
|
||||
node, ok := nodeids[fk]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected referenced foreign-key "user_fsevent" returned %v for node %v`, fk, n.ID)
|
||||
}
|
||||
assign(node, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (uq *UserQuery) loadEntities(ctx context.Context, query *EntityQuery, nodes []*User, init func(*User), assign func(*User, *Entity)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[int]*User)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/passkey"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
|
|
@ -297,6 +298,21 @@ func (uu *UserUpdate) AddTasks(t ...*Task) *UserUpdate {
|
|||
return uu.AddTaskIDs(ids...)
|
||||
}
|
||||
|
||||
// AddFseventIDs adds the "fsevents" edge to the FsEvent entity by IDs.
|
||||
func (uu *UserUpdate) AddFseventIDs(ids ...int) *UserUpdate {
|
||||
uu.mutation.AddFseventIDs(ids...)
|
||||
return uu
|
||||
}
|
||||
|
||||
// AddFsevents adds the "fsevents" edges to the FsEvent entity.
|
||||
func (uu *UserUpdate) AddFsevents(f ...*FsEvent) *UserUpdate {
|
||||
ids := make([]int, len(f))
|
||||
for i := range f {
|
||||
ids[i] = f[i].ID
|
||||
}
|
||||
return uu.AddFseventIDs(ids...)
|
||||
}
|
||||
|
||||
// AddEntityIDs adds the "entities" edge to the Entity entity by IDs.
|
||||
func (uu *UserUpdate) AddEntityIDs(ids ...int) *UserUpdate {
|
||||
uu.mutation.AddEntityIDs(ids...)
|
||||
|
|
@ -428,6 +444,27 @@ func (uu *UserUpdate) RemoveTasks(t ...*Task) *UserUpdate {
|
|||
return uu.RemoveTaskIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearFsevents clears all "fsevents" edges to the FsEvent entity.
|
||||
func (uu *UserUpdate) ClearFsevents() *UserUpdate {
|
||||
uu.mutation.ClearFsevents()
|
||||
return uu
|
||||
}
|
||||
|
||||
// RemoveFseventIDs removes the "fsevents" edge to FsEvent entities by IDs.
|
||||
func (uu *UserUpdate) RemoveFseventIDs(ids ...int) *UserUpdate {
|
||||
uu.mutation.RemoveFseventIDs(ids...)
|
||||
return uu
|
||||
}
|
||||
|
||||
// RemoveFsevents removes "fsevents" edges to FsEvent entities.
|
||||
func (uu *UserUpdate) RemoveFsevents(f ...*FsEvent) *UserUpdate {
|
||||
ids := make([]int, len(f))
|
||||
for i := range f {
|
||||
ids[i] = f[i].ID
|
||||
}
|
||||
return uu.RemoveFseventIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearEntities clears all "entities" edges to the Entity entity.
|
||||
func (uu *UserUpdate) ClearEntities() *UserUpdate {
|
||||
uu.mutation.ClearEntities()
|
||||
|
|
@ -828,6 +865,51 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
|||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if uu.mutation.FseventsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := uu.mutation.RemovedFseventsIDs(); len(nodes) > 0 && !uu.mutation.FseventsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := uu.mutation.FseventsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if uu.mutation.EntitiesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
|
|
@ -1154,6 +1236,21 @@ func (uuo *UserUpdateOne) AddTasks(t ...*Task) *UserUpdateOne {
|
|||
return uuo.AddTaskIDs(ids...)
|
||||
}
|
||||
|
||||
// AddFseventIDs adds the "fsevents" edge to the FsEvent entity by IDs.
|
||||
func (uuo *UserUpdateOne) AddFseventIDs(ids ...int) *UserUpdateOne {
|
||||
uuo.mutation.AddFseventIDs(ids...)
|
||||
return uuo
|
||||
}
|
||||
|
||||
// AddFsevents adds the "fsevents" edges to the FsEvent entity.
|
||||
func (uuo *UserUpdateOne) AddFsevents(f ...*FsEvent) *UserUpdateOne {
|
||||
ids := make([]int, len(f))
|
||||
for i := range f {
|
||||
ids[i] = f[i].ID
|
||||
}
|
||||
return uuo.AddFseventIDs(ids...)
|
||||
}
|
||||
|
||||
// AddEntityIDs adds the "entities" edge to the Entity entity by IDs.
|
||||
func (uuo *UserUpdateOne) AddEntityIDs(ids ...int) *UserUpdateOne {
|
||||
uuo.mutation.AddEntityIDs(ids...)
|
||||
|
|
@ -1285,6 +1382,27 @@ func (uuo *UserUpdateOne) RemoveTasks(t ...*Task) *UserUpdateOne {
|
|||
return uuo.RemoveTaskIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearFsevents clears all "fsevents" edges to the FsEvent entity.
|
||||
func (uuo *UserUpdateOne) ClearFsevents() *UserUpdateOne {
|
||||
uuo.mutation.ClearFsevents()
|
||||
return uuo
|
||||
}
|
||||
|
||||
// RemoveFseventIDs removes the "fsevents" edge to FsEvent entities by IDs.
|
||||
func (uuo *UserUpdateOne) RemoveFseventIDs(ids ...int) *UserUpdateOne {
|
||||
uuo.mutation.RemoveFseventIDs(ids...)
|
||||
return uuo
|
||||
}
|
||||
|
||||
// RemoveFsevents removes "fsevents" edges to FsEvent entities.
|
||||
func (uuo *UserUpdateOne) RemoveFsevents(f ...*FsEvent) *UserUpdateOne {
|
||||
ids := make([]int, len(f))
|
||||
for i := range f {
|
||||
ids[i] = f[i].ID
|
||||
}
|
||||
return uuo.RemoveFseventIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearEntities clears all "entities" edges to the Entity entity.
|
||||
func (uuo *UserUpdateOne) ClearEntities() *UserUpdateOne {
|
||||
uuo.mutation.ClearEntities()
|
||||
|
|
@ -1715,6 +1833,51 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
|
|||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if uuo.mutation.FseventsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := uuo.mutation.RemovedFseventsIDs(); len(nodes) > 0 && !uuo.mutation.FseventsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := uuo.mutation.FseventsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: user.FseventsTable,
|
||||
Columns: []string{user.FseventsColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(fsevent.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if uuo.mutation.EntitiesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/schema"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type FsEventClient interface {
|
||||
TxOperator
|
||||
// Create a new FsEvent
|
||||
Create(ctx context.Context, uid int, subscriberId uuid.UUID, events ...string) error
|
||||
// Delete all FsEvents by subscriber
|
||||
DeleteBySubscriber(ctx context.Context, subscriberId uuid.UUID) error
|
||||
// Delete all FsEvents
|
||||
DeleteAll(ctx context.Context) error
|
||||
// Get all FsEvents by subscriber and user
|
||||
TakeBySubscriber(ctx context.Context, subscriberId uuid.UUID, userId int) ([]*ent.FsEvent, error)
|
||||
}
|
||||
|
||||
func NewFsEventClient(client *ent.Client, dbType conf.DBType) FsEventClient {
|
||||
return &fsEventClient{client: client, maxSQlParam: sqlParamLimit(dbType)}
|
||||
}
|
||||
|
||||
type fsEventClient struct {
|
||||
maxSQlParam int
|
||||
client *ent.Client
|
||||
}
|
||||
|
||||
func (c *fsEventClient) SetClient(newClient *ent.Client) TxOperator {
|
||||
return &fsEventClient{client: newClient, maxSQlParam: c.maxSQlParam}
|
||||
}
|
||||
|
||||
func (c *fsEventClient) GetClient() *ent.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
func (c *fsEventClient) Create(ctx context.Context, uid int, subscriberId uuid.UUID, events ...string) error {
|
||||
stms := lo.Map(events, func(event string, index int) *ent.FsEventCreate {
|
||||
res := c.client.FsEvent.
|
||||
Create().
|
||||
SetUserFsevent(uid).
|
||||
SetEvent(event).
|
||||
SetSubscriber(subscriberId).SetEvent(event)
|
||||
|
||||
return res
|
||||
})
|
||||
|
||||
_, err := c.client.FsEvent.CreateBulk(stms...).Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *fsEventClient) DeleteBySubscriber(ctx context.Context, subscriberId uuid.UUID) error {
|
||||
_, err := c.client.FsEvent.Delete().Where(fsevent.Subscriber(subscriberId)).Exec(schema.SkipSoftDelete(ctx))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *fsEventClient) DeleteAll(ctx context.Context) error {
|
||||
_, err := c.client.FsEvent.Delete().Exec(schema.SkipSoftDelete(ctx))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *fsEventClient) TakeBySubscriber(ctx context.Context, subscriberId uuid.UUID, userId int) ([]*ent.FsEvent, error) {
|
||||
res, err := c.client.FsEvent.Query().Where(fsevent.Subscriber(subscriberId), fsevent.UserFsevent(userId)).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Delete the FsEvents
|
||||
_, err = c.client.FsEvent.Delete().Where(fsevent.Subscriber(subscriberId), fsevent.UserFsevent(userId)).Exec(schema.SkipSoftDelete(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
@ -103,6 +103,7 @@ func InitializeHandling(dep dependency.Dep) gin.HandlerFunc {
|
|||
IP: clientIp,
|
||||
Host: c.Request.Host,
|
||||
UserAgent: c.Request.UserAgent(),
|
||||
ClientID: c.GetHeader(request.ClientIDHeader),
|
||||
}
|
||||
cid := uuid.FromStringOrNil(c.GetHeader(request.CorrelationHeader))
|
||||
if cid == uuid.Nil {
|
||||
|
|
|
|||
|
|
@ -22,4 +22,6 @@ type RequestInfo struct {
|
|||
Host string
|
||||
IP string
|
||||
UserAgent string
|
||||
// ID of sync client
|
||||
ClientID string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package eventhub
|
||||
|
||||
import "errors"
|
||||
|
||||
type (
|
||||
Event struct {
|
||||
Type EventType `json:"type"`
|
||||
FileID string `json:"file_id"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
}
|
||||
|
||||
EventType string
|
||||
)
|
||||
|
||||
const (
|
||||
EventTypeCreate = "create"
|
||||
EventTypeModify = "modify"
|
||||
EventTypeRename = "rename"
|
||||
EventTypeDelete = "delete"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEventHubClosed is returned when operations are attempted on a closed EventHub.
|
||||
ErrEventHubClosed = errors.New("event hub is closed")
|
||||
)
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
package eventhub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
)
|
||||
|
||||
type (
|
||||
EventHub interface {
|
||||
// Subscribe to a topic and return a channel to receive events.
|
||||
// If a subscriber with the same ID already exists and is offline,
|
||||
// it will be reactivated and any buffered events will be flushed.
|
||||
Subscribe(ctx context.Context, topic int, id string) (chan *Event, bool, error)
|
||||
// Unsubscribe marks the subscriber as offline instead of removing it.
|
||||
// Buffered events will be kept for when the subscriber reconnects.
|
||||
// Subscribers that remain offline for more than 14 days will be permanently removed.
|
||||
Unsubscribe(ctx context.Context, topic int, id string)
|
||||
// Get subscribers of a topic.
|
||||
GetSubscribers(ctx context.Context, topic int) []Subscriber
|
||||
// Close shuts down the event hub and disconnects all subscribers.
|
||||
Close()
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
bufSize = 16
|
||||
cleanupPeriod = 1 * time.Hour
|
||||
)
|
||||
|
||||
type eventHub struct {
|
||||
mu sync.RWMutex
|
||||
topics map[int]map[string]*subscriber
|
||||
userClient inventory.UserClient
|
||||
fsEventClient inventory.FsEventClient
|
||||
closed bool
|
||||
closeCh chan struct{}
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewEventHub(userClient inventory.UserClient, fsEventClient inventory.FsEventClient) EventHub {
|
||||
e := &eventHub{
|
||||
topics: make(map[int]map[string]*subscriber),
|
||||
userClient: userClient,
|
||||
fsEventClient: fsEventClient,
|
||||
closeCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Remove all existing FsEvents
|
||||
fsEventClient.DeleteAll(context.Background())
|
||||
|
||||
// Start background cleanup goroutine
|
||||
e.wg.Add(1)
|
||||
go e.cleanupLoop()
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
// cleanupLoop periodically removes subscribers that have been offline for too long.
|
||||
func (e *eventHub) cleanupLoop() {
|
||||
defer e.wg.Done()
|
||||
|
||||
ticker := time.NewTicker(cleanupPeriod)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-e.closeCh:
|
||||
return
|
||||
case <-ticker.C:
|
||||
e.cleanupExpiredSubscribers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleanupExpiredSubscribers removes subscribers that have been offline for more than 14 days.
|
||||
func (e *eventHub) cleanupExpiredSubscribers() {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if e.closed {
|
||||
return
|
||||
}
|
||||
|
||||
for topic, subs := range e.topics {
|
||||
for id, sub := range subs {
|
||||
if sub.shouldExpire() {
|
||||
sub.close()
|
||||
delete(subs, id)
|
||||
}
|
||||
}
|
||||
if len(subs) == 0 {
|
||||
delete(e.topics, topic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *eventHub) GetSubscribers(ctx context.Context, topic int) []Subscriber {
|
||||
e.mu.RLock()
|
||||
defer e.mu.RUnlock()
|
||||
|
||||
subs := make([]Subscriber, 0, len(e.topics[topic]))
|
||||
for _, v := range e.topics[topic] {
|
||||
subs = append(subs, v)
|
||||
}
|
||||
return subs
|
||||
}
|
||||
|
||||
func (e *eventHub) Subscribe(ctx context.Context, topic int, id string) (chan *Event, bool, error) {
|
||||
l := logging.FromContext(ctx)
|
||||
l.Info("Subscribing to event hub for topic %d with id %s", topic, id)
|
||||
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if e.closed {
|
||||
return nil, false, ErrEventHubClosed
|
||||
}
|
||||
|
||||
subs, ok := e.topics[topic]
|
||||
if !ok {
|
||||
subs = make(map[string]*subscriber)
|
||||
e.topics[topic] = subs
|
||||
}
|
||||
|
||||
// Check if subscriber already exists
|
||||
if existingSub, ok := subs[id]; ok {
|
||||
if existingSub.isClosed() {
|
||||
// Subscriber was closed, create a new one
|
||||
delete(subs, id)
|
||||
} else {
|
||||
// Reactivate the offline subscriber
|
||||
l.Info("Reactivating offline subscriber %s for topic %d", id, topic)
|
||||
existingSub.setOnline(ctx)
|
||||
return existingSub.ch, true, nil
|
||||
}
|
||||
}
|
||||
|
||||
sub, err := newSubscriber(ctx, id, e.userClient, e.fsEventClient)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
e.topics[topic][id] = sub
|
||||
return sub.ch, false, nil
|
||||
}
|
||||
|
||||
func (e *eventHub) Unsubscribe(ctx context.Context, topic int, id string) {
|
||||
l := logging.FromContext(ctx)
|
||||
l.Info("Marking subscriber offline for topic %d with id %s", topic, id)
|
||||
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if e.closed {
|
||||
return
|
||||
}
|
||||
|
||||
subs, ok := e.topics[topic]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if sub, ok := subs[id]; ok {
|
||||
// Stop debounce timer but keep events in buffer
|
||||
sub.Stop()
|
||||
// Mark as offline instead of deleting
|
||||
sub.setOffline()
|
||||
}
|
||||
}
|
||||
|
||||
// Close shuts down the event hub and disconnects all subscribers.
|
||||
func (e *eventHub) Close() {
|
||||
e.mu.Lock()
|
||||
|
||||
if e.closed {
|
||||
e.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
e.closed = true
|
||||
close(e.closeCh)
|
||||
|
||||
// Close all subscribers
|
||||
for _, subs := range e.topics {
|
||||
for _, sub := range subs {
|
||||
sub.close()
|
||||
}
|
||||
}
|
||||
e.topics = nil
|
||||
|
||||
e.mu.Unlock()
|
||||
|
||||
// Wait for cleanup goroutine to finish
|
||||
e.wg.Wait()
|
||||
}
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
package eventhub
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type Subscriber interface {
|
||||
ID() string
|
||||
Ch() chan *Event
|
||||
Publish(evt Event)
|
||||
Stop()
|
||||
Buffer() []*Event
|
||||
// Owner returns the owner of the subscriber.
|
||||
Owner() (*ent.User, error)
|
||||
// Online returns whether the subscriber is online.
|
||||
Online() bool
|
||||
// OfflineSince returns when the subscriber went offline.
|
||||
// Returns zero time if the subscriber is online.
|
||||
OfflineSince() time.Time
|
||||
}
|
||||
|
||||
const (
|
||||
debounceDelay = 5 * time.Second
|
||||
userCacheTTL = 1 * time.Hour
|
||||
offlineMaxAge = 14 * 24 * time.Hour // 14 days
|
||||
)
|
||||
|
||||
type subscriber struct {
|
||||
mu sync.Mutex
|
||||
userClient inventory.UserClient
|
||||
fsEventClient inventory.FsEventClient
|
||||
|
||||
id string
|
||||
uid int
|
||||
ch chan *Event
|
||||
|
||||
// Online status
|
||||
online bool
|
||||
offlineSince time.Time
|
||||
|
||||
// Debounce buffer for pending events
|
||||
buffer []*Event
|
||||
timer *time.Timer
|
||||
|
||||
// Owner info
|
||||
ownerCached *ent.User
|
||||
cachedAt time.Time
|
||||
|
||||
// Close signal
|
||||
closed bool
|
||||
closedCh chan struct{}
|
||||
}
|
||||
|
||||
func newSubscriber(ctx context.Context, id string, userClient inventory.UserClient, fsEventClient inventory.FsEventClient) (*subscriber, error) {
|
||||
user := inventory.UserFromContext(ctx)
|
||||
if user == nil || inventory.IsAnonymousUser(user) {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
|
||||
return &subscriber{
|
||||
id: id,
|
||||
ch: make(chan *Event, bufSize),
|
||||
userClient: userClient,
|
||||
fsEventClient: fsEventClient,
|
||||
ownerCached: user,
|
||||
uid: user.ID,
|
||||
cachedAt: time.Now(),
|
||||
online: true,
|
||||
closedCh: make(chan struct{}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *subscriber) ID() string {
|
||||
return s.id
|
||||
}
|
||||
|
||||
func (s *subscriber) Ch() chan *Event {
|
||||
return s.ch
|
||||
}
|
||||
|
||||
func (s *subscriber) Online() bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.online
|
||||
}
|
||||
|
||||
func (s *subscriber) OfflineSince() time.Time {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.offlineSince
|
||||
}
|
||||
|
||||
func (s *subscriber) Owner() (*ent.User, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if time.Since(s.cachedAt) > userCacheTTL || s.ownerCached == nil {
|
||||
user, err := s.userClient.GetLoginUserByID(context.Background(), s.uid)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get login user: %w", err)
|
||||
}
|
||||
|
||||
s.ownerCached = user
|
||||
s.cachedAt = time.Now()
|
||||
}
|
||||
|
||||
return s.ownerCached, nil
|
||||
}
|
||||
|
||||
// Publish adds an event to the buffer and starts/resets the debounce timer.
|
||||
// Events will be flushed to the channel after the debounce delay.
|
||||
// If the subscriber is offline, events are kept in the buffer only.
|
||||
func (s *subscriber) Publish(evt Event) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
|
||||
s.publishLocked(evt)
|
||||
}
|
||||
|
||||
// publishLocked adds an event to the buffer and manages the debounce timer.
|
||||
// Caller must hold s.mu.
|
||||
func (s *subscriber) publishLocked(evt Event) {
|
||||
// Add event to buffer
|
||||
s.buffer = append(s.buffer, &evt)
|
||||
|
||||
// Reset or start the debounce timer
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
}
|
||||
s.timer = time.AfterFunc(debounceDelay, s.flush)
|
||||
}
|
||||
|
||||
// flush sends all buffered events to the channel.
|
||||
// Called by the debounce timer.
|
||||
func (s *subscriber) flush() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
s.flushLocked(context.Background())
|
||||
}
|
||||
|
||||
// flushLocked sends all buffered events to the channel.
|
||||
// Caller must hold s.mu.
|
||||
func (s *subscriber) flushLocked(ctx context.Context) {
|
||||
if len(s.buffer) == 0 || s.closed {
|
||||
return
|
||||
}
|
||||
|
||||
if !s.online {
|
||||
_ = s.fsEventClient.Create(ctx, s.ownerCached.ID, uuid.FromStringOrNil(s.id), lo.Map(s.buffer, func(item *Event, index int) string {
|
||||
res, _ := json.Marshal(item)
|
||||
return string(res)
|
||||
})...)
|
||||
} else {
|
||||
// TODO: implement event merging logic here
|
||||
// For now, send all buffered events individually
|
||||
for _, evt := range s.buffer {
|
||||
select {
|
||||
case s.ch <- evt:
|
||||
default:
|
||||
// Non-blocking send; drop if subscriber is slow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the buffer
|
||||
s.buffer = nil
|
||||
s.timer = nil
|
||||
}
|
||||
|
||||
// Stop cancels any pending debounce timer and flushes remaining events.
|
||||
// Should be called before closing the subscriber.
|
||||
func (s *subscriber) Stop() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
s.timer = nil
|
||||
}
|
||||
|
||||
// Flush any remaining events before stopping
|
||||
s.flushLocked(context.Background())
|
||||
}
|
||||
|
||||
// setOnline marks the subscriber as online and flushes any buffered events.
|
||||
func (s *subscriber) setOnline(ctx context.Context) {
|
||||
l := logging.FromContext(ctx)
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
|
||||
s.online = true
|
||||
s.ownerCached = nil
|
||||
s.offlineSince = time.Time{}
|
||||
|
||||
// Retrieve events from inventory
|
||||
events, err := s.fsEventClient.TakeBySubscriber(ctx, uuid.FromStringOrNil(s.id), s.uid)
|
||||
if err != nil {
|
||||
l.Error("Failed to get events from inventory: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Append events to buffer
|
||||
for _, event := range events {
|
||||
var eventParsed Event
|
||||
err := json.Unmarshal([]byte(event.Event), &eventParsed)
|
||||
if err != nil {
|
||||
l.Error("Failed to unmarshal event: %s", err)
|
||||
continue
|
||||
}
|
||||
s.buffer = append(s.buffer, &eventParsed)
|
||||
}
|
||||
|
||||
// Flush buffered events if any
|
||||
if len(s.buffer) > 0 {
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
}
|
||||
s.timer = time.AfterFunc(debounceDelay, s.flush)
|
||||
}
|
||||
}
|
||||
|
||||
// setOffline marks the subscriber as offline.
|
||||
func (s *subscriber) setOffline() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
|
||||
s.online = false
|
||||
s.offlineSince = time.Now()
|
||||
|
||||
// Stop the timer, events will be kept in buffer
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
s.timer = nil
|
||||
}
|
||||
|
||||
// flush the buffer
|
||||
s.flushLocked(context.Background())
|
||||
}
|
||||
|
||||
// close permanently closes the subscriber.
|
||||
func (s *subscriber) close() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
|
||||
s.closed = true
|
||||
if s.timer != nil {
|
||||
s.timer.Stop()
|
||||
s.timer = nil
|
||||
}
|
||||
|
||||
// Delete the FsEvent
|
||||
s.fsEventClient.DeleteBySubscriber(context.Background(), uuid.FromStringOrNil(s.id))
|
||||
|
||||
// Signal close and close the channel
|
||||
close(s.closedCh)
|
||||
close(s.ch)
|
||||
s.buffer = nil
|
||||
}
|
||||
|
||||
// isClosed returns whether the subscriber is closed.
|
||||
func (s *subscriber) isClosed() bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.closed
|
||||
}
|
||||
|
||||
// shouldExpire returns whether the subscriber should be expired (offline for too long).
|
||||
func (s *subscriber) shouldExpire() bool {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return !s.online && !s.offlineSince.IsZero() && time.Since(s.offlineSince) > offlineMaxAge
|
||||
}
|
||||
|
||||
// Buffer returns a copy of the current buffered events.
|
||||
// Useful for debugging or implementing custom merging logic.
|
||||
func (s *subscriber) Buffer() []*Event {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if len(s.buffer) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return a copy to avoid data races
|
||||
buf := make([]*Event, len(s.buffer))
|
||||
copy(buf, s.buffer)
|
||||
return buf
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/cache"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/encrypt"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/eventhub"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/lock"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
|
|
@ -44,7 +45,7 @@ type (
|
|||
func NewDatabaseFS(u *ent.User, fileClient inventory.FileClient, shareClient inventory.ShareClient,
|
||||
l logging.Logger, ls lock.LockSystem, settingClient setting.Provider,
|
||||
storagePolicyClient inventory.StoragePolicyClient, hasher hashid.Encoder, userClient inventory.UserClient,
|
||||
cache, stateKv cache.Driver, directLinkClient inventory.DirectLinkClient, encryptorFactory encrypt.CryptorFactory) fs.FileSystem {
|
||||
cache, stateKv cache.Driver, directLinkClient inventory.DirectLinkClient, encryptorFactory encrypt.CryptorFactory, eventHub eventhub.EventHub) fs.FileSystem {
|
||||
return &DBFS{
|
||||
user: u,
|
||||
navigators: make(map[string]Navigator),
|
||||
|
|
@ -60,6 +61,7 @@ func NewDatabaseFS(u *ent.User, fileClient inventory.FileClient, shareClient inv
|
|||
stateKv: stateKv,
|
||||
directLinkClient: directLinkClient,
|
||||
encryptorFactory: encryptorFactory,
|
||||
eventHub: eventHub,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +81,7 @@ type DBFS struct {
|
|||
stateKv cache.Driver
|
||||
mu sync.Mutex
|
||||
encryptorFactory encrypt.CryptorFactory
|
||||
eventHub eventhub.EventHub
|
||||
}
|
||||
|
||||
func (f *DBFS) Recycle() {
|
||||
|
|
@ -643,7 +646,9 @@ func (f *DBFS) createFile(ctx context.Context, parent *File, name string, fileTy
|
|||
}
|
||||
|
||||
file.SetEntities([]*ent.Entity{entity})
|
||||
return newFile(parent, file), nil
|
||||
newFile := newFile(parent, file)
|
||||
f.emitFileCreated(ctx, newFile)
|
||||
return newFile, nil
|
||||
}
|
||||
|
||||
func (f *DBFS) generateEncryptMetadata(ctx context.Context, uploadRequest *fs.UploadRequest, policy *ent.StoragePolicy) (*types.EncryptMetadata, error) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
package dbfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/auth/requestinfo"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/eventhub"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (f *DBFS) emitFileCreated(ctx context.Context, file *File) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeCreate,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileModified(ctx context.Context, file *File) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeModify,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileRenamed(ctx context.Context, file *File, newName string) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
from := subscriber.relativePath(file)
|
||||
to := strings.TrimSuffix(from, file.Name()) + newName
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeRename,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
To: to,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileDeleted(ctx context.Context, files ...*File) {
|
||||
for _, file := range files {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeDelete,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileMoved(ctx context.Context, src, dst *File) {
|
||||
srcSubMap := lo.SliceToMap(f.getEligibleSubscriber(ctx, src, true), func(subscriber foundSubscriber) (string, *foundSubscriber) {
|
||||
return subscriber.ID(), &subscriber
|
||||
})
|
||||
dstSubMap := lo.SliceToMap(f.getEligibleSubscriber(ctx, dst, false), func(subscriber foundSubscriber) (string, *foundSubscriber) {
|
||||
return subscriber.ID(), &subscriber
|
||||
})
|
||||
|
||||
for _, subscriber := range srcSubMap {
|
||||
subId := subscriber.ID()
|
||||
if dstSub, ok := dstSubMap[subId]; ok {
|
||||
// Src and Dst subscribed by the same subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeRename,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: subscriber.relativePath(src),
|
||||
To: path.Join(dstSub.relativePath(dst), src.Name()),
|
||||
})
|
||||
delete(dstSubMap, subId)
|
||||
} else {
|
||||
// Only Src is subscribed by the subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeDelete,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: subscriber.relativePath(src),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, subscriber := range dstSubMap {
|
||||
// Only Dst is subscribed by the subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeCreate,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: path.Join(subscriber.relativePath(dst), src.Name()),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (f *DBFS) getEligibleSubscriber(ctx context.Context, file *File, checkParentPerm bool) []foundSubscriber {
|
||||
roots := file.Ancestors()
|
||||
if !checkParentPerm {
|
||||
// Include file itself
|
||||
roots = file.AncestorsChain()
|
||||
}
|
||||
requestInfo := requestinfo.RequestInfoFromContext(ctx)
|
||||
eligibleSubscribers := make([]foundSubscriber, 0)
|
||||
|
||||
for _, root := range roots {
|
||||
subscribers := f.eventHub.GetSubscribers(ctx, root.Model.ID)
|
||||
subscribers = lo.Filter(subscribers, func(subscriber eventhub.Subscriber, index int) bool {
|
||||
// Exlucde self from subscribers
|
||||
if requestInfo != nil && subscriber.ID() == requestInfo.ClientID {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
eligibleSubscribers = append(eligibleSubscribers, lo.Map(subscribers, func(subscriber eventhub.Subscriber, index int) foundSubscriber {
|
||||
return foundSubscriber{
|
||||
Subscriber: subscriber,
|
||||
root: root,
|
||||
}
|
||||
})...)
|
||||
}
|
||||
|
||||
return eligibleSubscribers
|
||||
|
||||
}
|
||||
|
||||
type foundSubscriber struct {
|
||||
eventhub.Subscriber
|
||||
root *File
|
||||
}
|
||||
|
||||
func (s *foundSubscriber) relativePath(file *File) string {
|
||||
res := strings.TrimPrefix(file.Uri(true).Path(), s.root.Uri(true).Path())
|
||||
if res == "" {
|
||||
res = fs.Separator
|
||||
}
|
||||
|
||||
if res[0] != fs.Separator[0] {
|
||||
res = fs.Separator + res
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
|
@ -119,6 +119,7 @@ func (f *DBFS) Create(ctx context.Context, path *fs.URI, fileType types.FileType
|
|||
}
|
||||
|
||||
ancestor = newFile(ancestor, newFolder)
|
||||
f.emitFileCreated(ctx, ancestor)
|
||||
} else {
|
||||
// valide file name
|
||||
policy, err := f.getPreferredPolicy(ctx, ancestor)
|
||||
|
|
@ -225,6 +226,8 @@ func (f *DBFS) Rename(ctx context.Context, path *fs.URI, newName string) (fs.Fil
|
|||
return nil, serializer.NewError(serializer.CodeDBError, "Failed to commit rename change", err)
|
||||
}
|
||||
|
||||
f.emitFileRenamed(ctx, target, newName)
|
||||
|
||||
return target.Replace(updated), nil
|
||||
}
|
||||
|
||||
|
|
@ -303,6 +306,8 @@ func (f *DBFS) SoftDelete(ctx context.Context, path ...*fs.URI) error {
|
|||
return serializer.NewError(serializer.CodeDBError, "Failed to commit soft-delete change", err)
|
||||
}
|
||||
|
||||
f.emitFileDeleted(ctx, targets...)
|
||||
|
||||
return ae.Aggregate()
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +390,7 @@ func (f *DBFS) Delete(ctx context.Context, path []*fs.URI, opts ...fs.Option) ([
|
|||
if err := inventory.CommitWithStorageDiff(ctx, tx, f.l, f.userClient); err != nil {
|
||||
return nil, serializer.NewError(serializer.CodeDBError, "Failed to commit delete change", err)
|
||||
}
|
||||
|
||||
f.emitFileDeleted(ctx, targets...)
|
||||
return newStaleEntities, ae.Aggregate()
|
||||
}
|
||||
|
||||
|
|
@ -603,10 +608,11 @@ func (f *DBFS) MoveOrCopy(ctx context.Context, path []*fs.URI, dst *fs.URI, isCo
|
|||
}
|
||||
|
||||
var (
|
||||
copiedNewTargetsMap map[int]*ent.File
|
||||
storageDiff inventory.StorageDiff
|
||||
)
|
||||
if isCopy {
|
||||
_, storageDiff, err = f.copyFiles(ctx, fileNavGroup, destination, fc)
|
||||
copiedNewTargetsMap, storageDiff, err = f.copyFiles(ctx, fileNavGroup, destination, fc)
|
||||
} else {
|
||||
storageDiff, err = f.moveFiles(ctx, targets, destination, fc, dstNavigator)
|
||||
}
|
||||
|
|
@ -621,6 +627,14 @@ func (f *DBFS) MoveOrCopy(ctx context.Context, path []*fs.URI, dst *fs.URI, isCo
|
|||
return serializer.NewError(serializer.CodeDBError, "Failed to commit move change", err)
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
if isCopy {
|
||||
f.emitFileCreated(ctx, newFile(destination, copiedNewTargetsMap[target.ID()]))
|
||||
} else {
|
||||
f.emitFileMoved(ctx, target, destination)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: after move, dbfs cache should be cleared
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +730,8 @@ func (f *DBFS) deleteEntity(ctx context.Context, target *File, entityId int) (in
|
|||
return nil, serializer.NewError(serializer.CodeDBError, "Failed to remove upload session metadata", err)
|
||||
}
|
||||
}
|
||||
|
||||
f.emitFileModified(ctx, target)
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
|
|
@ -753,6 +769,7 @@ func (f *DBFS) setCurrentVersion(ctx context.Context, target *File, versionId in
|
|||
return serializer.NewError(serializer.CodeDBError, "Failed to commit set current version", err)
|
||||
}
|
||||
|
||||
f.emitFileModified(ctx, target)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -355,6 +355,8 @@ func (f *DBFS) CompleteUpload(ctx context.Context, session *fs.UploadSession) (f
|
|||
}
|
||||
}
|
||||
|
||||
f.emitFileModified(ctx, filePrivate)
|
||||
|
||||
file, err = f.Get(ctx, session.Props.Uri, WithFileEntities(), WithNotRoot())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get updated file: %w", err)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ func NewFileManager(dep dependency.Dep, u *ent.User) FileManager {
|
|||
settings: dep.SettingProvider(),
|
||||
fs: dbfs.NewDatabaseFS(u, dep.FileClient(), dep.ShareClient(), dep.Logger(), dep.LockSystem(),
|
||||
dep.SettingProvider(), dep.StoragePolicyClient(), dep.HashIDEncoder(), dep.UserClient(), dep.KV(), dep.NavigatorStateKV(),
|
||||
dep.DirectLinkClient(), dep.EncryptorFactory(context.TODO())),
|
||||
dep.DirectLinkClient(), dep.EncryptorFactory(context.TODO()), dep.EventHub()),
|
||||
kv: dep.KV(),
|
||||
config: config,
|
||||
auth: dep.GeneralAuth(),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
|
@ -284,6 +285,7 @@ func (q *queue) run(ctx context.Context, t Task) (task.Status, error) {
|
|||
// handle panic issue
|
||||
defer func() {
|
||||
if p := recover(); p != nil {
|
||||
q.logger.Error("panic in queue %q: %s", q.name, debug.Stack())
|
||||
panicChan <- p
|
||||
}
|
||||
}()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ const (
|
|||
SiteVersionHeader = constants.CrHeaderPrefix + "Version"
|
||||
SiteIDHeader = constants.CrHeaderPrefix + "Site-Id"
|
||||
SlaveNodeIDHeader = constants.CrHeaderPrefix + "Node-Id"
|
||||
ClientIDHeader = constants.CrHeaderPrefix + "Client-Id"
|
||||
LocalIP = "localhost"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -426,3 +426,13 @@ func ListArchiveFiles(c *gin.Context) {
|
|||
Data: resp,
|
||||
})
|
||||
}
|
||||
|
||||
func HandleExplorerEventsPush(c *gin.Context) {
|
||||
service := ParametersFromContext[*explorer.ExplorerEventService](c, explorer.ExplorerEventParamCtx{})
|
||||
err := service.HandleExplorerEventsPush(c)
|
||||
if err != nil {
|
||||
c.JSON(200, serializer.Err(c, err))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -727,6 +727,13 @@ func initMasterRouter(dep dependency.Dep) *gin.Engine {
|
|||
controllers.FromJSON[explorer.PatchViewService](explorer.PatchViewParameterCtx{}),
|
||||
controllers.PatchView,
|
||||
)
|
||||
|
||||
// Server event push
|
||||
file.GET("events",
|
||||
middleware.LoginRequired(),
|
||||
controllers.FromQuery[explorer.ExplorerEventService](explorer.ExplorerEventParamCtx{}),
|
||||
controllers.HandleExplorerEventsPush,
|
||||
)
|
||||
}
|
||||
|
||||
// 分享相关
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
package explorer
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/auth/requestinfo"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type (
|
||||
ExplorerEventService struct {
|
||||
Uri string `form:"uri" binding:"required"`
|
||||
}
|
||||
ExplorerEventParamCtx struct{}
|
||||
)
|
||||
|
||||
func (s *ExplorerEventService) HandleExplorerEventsPush(c *gin.Context) error {
|
||||
dep := dependency.FromContext(c)
|
||||
user := inventory.UserFromContext(c)
|
||||
m := manager.NewFileManager(dep, user)
|
||||
l := logging.FromContext(c)
|
||||
defer m.Recycle()
|
||||
|
||||
uri, err := fs.NewUriFromString(s.Uri)
|
||||
if err != nil {
|
||||
return serializer.NewError(serializer.CodeParamErr, "Unknown uri", err)
|
||||
}
|
||||
|
||||
// Make sure target is a valid folder that the user can listen to
|
||||
parent, _, err := m.List(c, uri, &manager.ListArgs{
|
||||
Page: 0,
|
||||
PageSize: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return serializer.NewError(serializer.CodeParamErr, "Requested uri not available", err)
|
||||
}
|
||||
|
||||
requestInfo := requestinfo.RequestInfoFromContext(c)
|
||||
if requestInfo.ClientID == "" {
|
||||
return serializer.NewError(serializer.CodeParamErr, "Client ID is required", nil)
|
||||
}
|
||||
|
||||
// Subscribe
|
||||
eventHub := dep.EventHub()
|
||||
rx, resumed, err := eventHub.Subscribe(c, parent.ID(), requestInfo.ClientID)
|
||||
if err != nil {
|
||||
return serializer.NewError(serializer.CodeInternalSetting, "Failed to subscribe to events", err)
|
||||
}
|
||||
|
||||
// SSE Headers
|
||||
c.Writer.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Writer.Header().Set("Cache-Control", "no-cache")
|
||||
c.Writer.Header().Set("Connection", "keep-alive")
|
||||
c.Writer.Header().Set("X-Accel-Buffering", "no")
|
||||
|
||||
keepAliveTicker := time.NewTicker(30 * time.Second)
|
||||
defer keepAliveTicker.Stop()
|
||||
|
||||
if resumed {
|
||||
c.SSEvent("resumed", nil)
|
||||
c.Writer.Flush()
|
||||
} else {
|
||||
c.SSEvent("subscribed", nil)
|
||||
c.Writer.Flush()
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
// TODO: close connection after access token expired
|
||||
case <-c.Request.Context().Done():
|
||||
// Server shutdown or request cancelled
|
||||
eventHub.Unsubscribe(c, parent.ID(), requestInfo.ClientID)
|
||||
l.Debug("Request context done, unsubscribed from event hub")
|
||||
return nil
|
||||
case <-c.Writer.CloseNotify():
|
||||
eventHub.Unsubscribe(c, parent.ID(), requestInfo.ClientID)
|
||||
l.Debug("Unsubscribed from event hub")
|
||||
return nil
|
||||
case evt, ok := <-rx:
|
||||
if !ok {
|
||||
// Channel closed, EventHub is shutting down
|
||||
l.Debug("Event hub closed, disconnecting client")
|
||||
return nil
|
||||
}
|
||||
c.SSEvent("event", evt)
|
||||
l.Debug("Event sent: %+v", evt)
|
||||
c.Writer.Flush()
|
||||
case <-keepAliveTicker.C:
|
||||
c.SSEvent("keep-alive", nil)
|
||||
c.Writer.Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue