diff --git a/satellite/console/accountfreezes.go b/satellite/console/accountfreezes.go new file mode 100644 index 000000000..1798c4e0e --- /dev/null +++ b/satellite/console/accountfreezes.go @@ -0,0 +1,49 @@ +// Copyright (C) 2022 Storj Labs, Inc. +// See LICENSE for copying information. + +package console + +import ( + "context" + "time" + + "storj.io/common/uuid" +) + +// AccountFreezeEvents exposes methods to manage the account freeze events table in database. +// +// architecture: Database +type AccountFreezeEvents interface { + // Insert is a method for inserting account freeze event into the database. + Insert(ctx context.Context, event *AccountFreezeEvent) (*AccountFreezeEvent, error) + // Get is a method for querying account freeze event from the database by user ID and event type. + Get(ctx context.Context, userID uuid.UUID, eventType AccountFreezeEventType) (*AccountFreezeEvent, error) + // UpdateLimits is a method for updating the limits of an account freeze event by user ID and event type. + UpdateLimits(ctx context.Context, userID uuid.UUID, eventType AccountFreezeEventType, limits *AccountFreezeEventLimits) error + // DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID. + DeleteAllByUserID(ctx context.Context, userID uuid.UUID) error +} + +// AccountFreezeEvent represents an event related to account freezing. +type AccountFreezeEvent struct { + UserID uuid.UUID + Type AccountFreezeEventType + Limits *AccountFreezeEventLimits + CreatedAt time.Time +} + +// AccountFreezeEventLimits represents the usage limits for a user's account and projects before they were frozen. +type AccountFreezeEventLimits struct { + User UsageLimits `json:"user"` + Projects map[uuid.UUID]UsageLimits `json:"projects"` +} + +// AccountFreezeEventType is used to indicate the account freeze event's type. +type AccountFreezeEventType int + +const ( + // Freeze signifies that the user has been frozen. + Freeze AccountFreezeEventType = 0 + // Warning signifies that the user has been warned that they may be frozen soon. + Warning AccountFreezeEventType = 1 +) diff --git a/satellite/console/database.go b/satellite/console/database.go index bf0178ba8..56a413cf0 100644 --- a/satellite/console/database.go +++ b/satellite/console/database.go @@ -27,6 +27,8 @@ type DB interface { ResetPasswordTokens() ResetPasswordTokens // WebappSessions is a getter for WebappSessions repository. WebappSessions() consoleauth.WebappSessions + // AccountFreezeEvents is a getter for AccountFreezeEvents repository. + AccountFreezeEvents() AccountFreezeEvents // WithTx is a method for executing transactions with retrying as necessary. WithTx(ctx context.Context, fn func(ctx context.Context, tx DBTx) error) error diff --git a/satellite/console/projectusagelimits.go b/satellite/console/projectusagelimits.go index 257fb11ca..0f89ab4ce 100644 --- a/satellite/console/projectusagelimits.go +++ b/satellite/console/projectusagelimits.go @@ -3,8 +3,6 @@ package console -import "storj.io/common/memory" - // ProjectUsageLimits holds project usage limits and current usage. type ProjectUsageLimits struct { StorageLimit int64 `json:"storageLimit"` @@ -15,9 +13,9 @@ type ProjectUsageLimits struct { SegmentCount int64 `json:"segmentCount"` } -// UserProjectLimits holds a users storage, bandwidth, and segment limits for new projects. -type UserProjectLimits struct { - BandwidthLimit memory.Size `json:"bandwidthLimit"` - StorageLimit memory.Size `json:"storageUsed"` - SegmentLimit int64 `json:"segmentLimit"` +// UsageLimits represents storage, bandwidth, and segment limits imposed on an entity. +type UsageLimits struct { + Storage int64 `json:"storage"` + Bandwidth int64 `json:"bandwidth"` + Segment int64 `json:"segment"` } diff --git a/satellite/console/service.go b/satellite/console/service.go index a2d361bc2..830b6da43 100644 --- a/satellite/console/service.go +++ b/satellite/console/service.go @@ -1472,6 +1472,8 @@ func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p var projectID uuid.UUID err = s.store.WithTx(ctx, func(ctx context.Context, tx DBTx) error { + storageLimit := memory.Size(newProjectLimits.Storage) + bandwidthLimit := memory.Size(newProjectLimits.Bandwidth) p, err = tx.Projects().Insert(ctx, &Project{ Description: projectInfo.Description, @@ -1479,9 +1481,9 @@ func (s *Service) CreateProject(ctx context.Context, projectInfo ProjectInfo) (p OwnerID: user.ID, PartnerID: user.PartnerID, UserAgent: user.UserAgent, - StorageLimit: &newProjectLimits.StorageLimit, - BandwidthLimit: &newProjectLimits.BandwidthLimit, - SegmentLimit: &newProjectLimits.SegmentLimit, + StorageLimit: &storageLimit, + BandwidthLimit: &bandwidthLimit, + SegmentLimit: &newProjectLimits.Segment, }, ) if err != nil { @@ -1538,6 +1540,8 @@ func (s *Service) GenCreateProject(ctx context.Context, projectInfo ProjectInfo) var projectID uuid.UUID err = s.store.WithTx(ctx, func(ctx context.Context, tx DBTx) error { + storageLimit := memory.Size(newProjectLimits.Storage) + bandwidthLimit := memory.Size(newProjectLimits.Bandwidth) p, err = tx.Projects().Insert(ctx, &Project{ Description: projectInfo.Description, @@ -1545,9 +1549,9 @@ func (s *Service) GenCreateProject(ctx context.Context, projectInfo ProjectInfo) OwnerID: user.ID, PartnerID: user.PartnerID, UserAgent: user.UserAgent, - StorageLimit: &newProjectLimits.StorageLimit, - BandwidthLimit: &newProjectLimits.BandwidthLimit, - SegmentLimit: &newProjectLimits.SegmentLimit, + StorageLimit: &storageLimit, + BandwidthLimit: &bandwidthLimit, + SegmentLimit: &newProjectLimits.Segment, }, ) if err != nil { @@ -2711,7 +2715,7 @@ func (s *Service) checkProjectLimit(ctx context.Context, userID uuid.UUID) (curr } // getUserProjectLimits is a method to get the users storage and bandwidth limits for new projects. -func (s *Service) getUserProjectLimits(ctx context.Context, userID uuid.UUID) (_ *UserProjectLimits, err error) { +func (s *Service) getUserProjectLimits(ctx context.Context, userID uuid.UUID) (_ *UsageLimits, err error) { defer mon.Task()(&ctx)(&err) result, err := s.store.Users().GetUserProjectLimits(ctx, userID) @@ -2719,10 +2723,10 @@ func (s *Service) getUserProjectLimits(ctx context.Context, userID uuid.UUID) (_ return nil, Error.Wrap(err) } - return &UserProjectLimits{ - StorageLimit: result.ProjectStorageLimit, - BandwidthLimit: result.ProjectBandwidthLimit, - SegmentLimit: result.ProjectSegmentLimit, + return &UsageLimits{ + Storage: result.ProjectStorageLimit.Int64(), + Bandwidth: result.ProjectBandwidthLimit.Int64(), + Segment: result.ProjectSegmentLimit, }, nil } diff --git a/satellite/satellitedb/accountfreezeevents.go b/satellite/satellitedb/accountfreezeevents.go new file mode 100644 index 000000000..ea4dc4a58 --- /dev/null +++ b/satellite/satellitedb/accountfreezeevents.go @@ -0,0 +1,117 @@ +// Copyright (C) 2022 Storj Labs, Inc. +// See LICENSE for copying information. + +package satellitedb + +import ( + "context" + "encoding/json" + + "storj.io/common/uuid" + "storj.io/storj/satellite/console" + "storj.io/storj/satellite/satellitedb/dbx" +) + +// Ensure that accountFreezeEvents implements console.AccountFreezeEvents. +var _ console.AccountFreezeEvents = (*accountFreezeEvents)(nil) + +// accountFreezeEvents is an implementation of console.AccountFreezeEvents. +type accountFreezeEvents struct { + db dbx.Methods +} + +// Insert is a method for inserting account freeze event into the database. +func (events *accountFreezeEvents) Insert(ctx context.Context, event *console.AccountFreezeEvent) (_ *console.AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + + if event == nil { + return nil, Error.New("event is nil") + } + + createFields := dbx.AccountFreezeEvent_Create_Fields{} + if event.Limits != nil { + limitBytes, err := json.Marshal(event.Limits) + if err != nil { + return nil, err + } + createFields.Limits = dbx.AccountFreezeEvent_Limits(limitBytes) + } + + dbxEvent, err := events.db.Create_AccountFreezeEvent(ctx, + dbx.AccountFreezeEvent_UserId(event.UserID.Bytes()), + dbx.AccountFreezeEvent_Event(int(event.Type)), + createFields, + ) + if err != nil { + return nil, err + } + + return fromDBXAccountFreezeEvent(dbxEvent) +} + +// Get is a method for querying account freeze event from the database by user ID and event type. +func (events *accountFreezeEvents) Get(ctx context.Context, userID uuid.UUID, eventType console.AccountFreezeEventType) (event *console.AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + + dbxEvent, err := events.db.Get_AccountFreezeEvent_By_UserId_And_Event(ctx, + dbx.AccountFreezeEvent_UserId(userID.Bytes()), + dbx.AccountFreezeEvent_Event(int(eventType)), + ) + if err != nil { + return nil, err + } + + return fromDBXAccountFreezeEvent(dbxEvent) +} + +// UpdateLimits is a method for updating the limits of an account freeze event by user ID and event type. +func (events *accountFreezeEvents) UpdateLimits(ctx context.Context, userID uuid.UUID, eventType console.AccountFreezeEventType, limits *console.AccountFreezeEventLimits) (err error) { + defer mon.Task()(&ctx)(&err) + + limitBytes, err := json.Marshal(limits) + if err != nil { + return err + } + + _, err = events.db.Update_AccountFreezeEvent_By_UserId_And_Event(ctx, + dbx.AccountFreezeEvent_UserId(userID.Bytes()), + dbx.AccountFreezeEvent_Event(int(eventType)), + dbx.AccountFreezeEvent_Update_Fields{ + Limits: dbx.AccountFreezeEvent_Limits(limitBytes), + }, + ) + + return err +} + +// DeleteAllByUserID is a method for deleting all account freeze events from the database by user ID. +func (events *accountFreezeEvents) DeleteAllByUserID(ctx context.Context, userID uuid.UUID) (err error) { + defer mon.Task()(&ctx)(&err) + + _, err = events.db.Delete_AccountFreezeEvent_By_UserId(ctx, dbx.AccountFreezeEvent_UserId(userID.Bytes())) + + return err +} + +// fromDBXAccountFreezeEvent converts *dbx.AccountFreezeEvent to *console.AccountFreezeEvent. +func fromDBXAccountFreezeEvent(dbxEvent *dbx.AccountFreezeEvent) (_ *console.AccountFreezeEvent, err error) { + if dbxEvent == nil { + return nil, Error.New("dbx event is nil") + } + userID, err := uuid.FromBytes(dbxEvent.UserId) + if err != nil { + return nil, err + } + event := &console.AccountFreezeEvent{ + UserID: userID, + Type: console.AccountFreezeEventType(dbxEvent.Event), + CreatedAt: dbxEvent.CreatedAt, + } + if dbxEvent.Limits != nil { + err := json.Unmarshal(dbxEvent.Limits, &event.Limits) + if err != nil { + return nil, err + } + } + return event, nil +} diff --git a/satellite/satellitedb/accountfreezeevents_test.go b/satellite/satellitedb/accountfreezeevents_test.go new file mode 100644 index 000000000..378a72ee5 --- /dev/null +++ b/satellite/satellitedb/accountfreezeevents_test.go @@ -0,0 +1,97 @@ +// Copyright (C) 2022 Storj Labs, Inc. +// See LICENSE for copying information. + +package satellitedb_test + +import ( + "database/sql" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "storj.io/common/testcontext" + "storj.io/common/testrand" + "storj.io/common/uuid" + "storj.io/storj/satellite" + "storj.io/storj/satellite/console" + "storj.io/storj/satellite/satellitedb/satellitedbtest" +) + +func TestAccountFreezeEvents(t *testing.T) { + satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) { + randUsageLimits := func() console.UsageLimits { + return console.UsageLimits{ + Storage: rand.Int63(), + Bandwidth: rand.Int63(), + Segment: rand.Int63(), + } + } + + event := &console.AccountFreezeEvent{ + UserID: testrand.UUID(), + Type: console.Freeze, + Limits: &console.AccountFreezeEventLimits{ + User: randUsageLimits(), + Projects: map[uuid.UUID]console.UsageLimits{ + testrand.UUID(): randUsageLimits(), + testrand.UUID(): randUsageLimits(), + }, + }, + } + + eventsDB := db.Console().AccountFreezeEvents() + + t.Run("Can't insert nil event", func(t *testing.T) { + _, err := eventsDB.Insert(ctx, nil) + require.Error(t, err) + }) + + t.Run("Insert event", func(t *testing.T) { + dbEvent, err := eventsDB.Insert(ctx, event) + require.NoError(t, err) + require.NotNil(t, dbEvent) + require.WithinDuration(t, time.Now(), dbEvent.CreatedAt, time.Minute) + dbEvent.CreatedAt = event.CreatedAt + require.Equal(t, event, dbEvent) + }) + + t.Run("Can't insert duplicate event", func(t *testing.T) { + _, err := eventsDB.Insert(ctx, event) + require.Error(t, err) + }) + + t.Run("Get event", func(t *testing.T) { + dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type) + require.NoError(t, err) + require.NotNil(t, dbEvent) + dbEvent.CreatedAt = event.CreatedAt + require.Equal(t, event, dbEvent) + }) + + t.Run("Update event limits", func(t *testing.T) { + limits := &console.AccountFreezeEventLimits{ + User: randUsageLimits(), + Projects: map[uuid.UUID]console.UsageLimits{ + testrand.UUID(): randUsageLimits(), + }, + } + require.NoError(t, eventsDB.UpdateLimits(ctx, event.UserID, event.Type, limits)) + dbEvent, err := eventsDB.Get(ctx, event.UserID, event.Type) + require.NoError(t, err) + require.Equal(t, limits, dbEvent.Limits) + + require.NoError(t, eventsDB.UpdateLimits(ctx, event.UserID, event.Type, nil)) + dbEvent, err = eventsDB.Get(ctx, event.UserID, event.Type) + require.NoError(t, err) + require.Nil(t, dbEvent.Limits) + }) + + t.Run("Delete event", func(t *testing.T) { + require.NoError(t, eventsDB.DeleteAllByUserID(ctx, event.UserID)) + _, err := eventsDB.Get(ctx, event.UserID, event.Type) + require.ErrorIs(t, err, sql.ErrNoRows) + }) + }) +} diff --git a/satellite/satellitedb/consoledb.go b/satellite/satellitedb/consoledb.go index f57b2a49b..af78530df 100644 --- a/satellite/satellitedb/consoledb.go +++ b/satellite/satellitedb/consoledb.go @@ -74,6 +74,11 @@ func (db *ConsoleDB) WebappSessions() consoleauth.WebappSessions { return &webappSessions{db.methods} } +// AccountFreezeEvents is a getter for AccountFreezeEvents repository. +func (db *ConsoleDB) AccountFreezeEvents() console.AccountFreezeEvents { + return &accountFreezeEvents{db.methods} +} + // WithTx is a method for executing and retrying transaction. func (db *ConsoleDB) WithTx(ctx context.Context, fn func(context.Context, console.DBTx) error) error { if db.db == nil { diff --git a/satellite/satellitedb/dbx/satellitedb.dbx b/satellite/satellitedb/dbx/satellitedb.dbx index a4803ea9e..5861d9d64 100644 --- a/satellite/satellitedb/dbx/satellitedb.dbx +++ b/satellite/satellitedb/dbx/satellitedb.dbx @@ -6,10 +6,25 @@ model account_freeze_event ( field user_id blob field event int // enum indicating the type of event - field limits json ( nullable ) + field limits json ( nullable, updatable ) field created_at timestamp ( default current_timestamp ) ) +create account_freeze_event() + +read one ( + select account_freeze_event + where account_freeze_event.user_id = ? + where account_freeze_event.event = ? +) + +update account_freeze_event ( + where account_freeze_event.user_id = ? + where account_freeze_event.event = ? +) + +delete account_freeze_event ( where account_freeze_event.user_id = ? ) + //-- Node Events --// model node_event ( key id diff --git a/satellite/satellitedb/dbx/satellitedb.dbx.go b/satellite/satellitedb/dbx/satellitedb.dbx.go index 4a5e977b2..f4a5352b4 100644 --- a/satellite/satellitedb/dbx/satellitedb.dbx.go +++ b/satellite/satellitedb/dbx/satellitedb.dbx.go @@ -1747,6 +1747,7 @@ type AccountFreezeEvent_Create_Fields struct { } type AccountFreezeEvent_Update_Fields struct { + Limits AccountFreezeEvent_Limits_Field } type AccountFreezeEvent_UserId_Field struct { @@ -12829,6 +12830,54 @@ type WalletAddress_Row struct { WalletAddress []byte } +func (obj *pgxImpl) Create_AccountFreezeEvent(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + optional AccountFreezeEvent_Create_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + __user_id_val := account_freeze_event_user_id.value() + __event_val := account_freeze_event_event.value() + __limits_val := optional.Limits.value() + + var __columns = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("user_id, event, limits")} + var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")} + var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}} + + var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("INSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}} + + var __values []interface{} + __values = append(__values, __user_id_val, __event_val, __limits_val) + + __optional_columns := __sqlbundle_Literals{Join: ", "} + __optional_placeholders := __sqlbundle_Literals{Join: ", "} + + if optional.CreatedAt._set { + __values = append(__values, optional.CreatedAt.value()) + __optional_columns.SQLs = append(__optional_columns.SQLs, __sqlbundle_Literal("created_at")) + __optional_placeholders.SQLs = append(__optional_placeholders.SQLs, __sqlbundle_Literal("?")) + } + + if len(__optional_columns.SQLs) == 0 { + if __columns.SQL == nil { + __clause.SQL = __sqlbundle_Literal("DEFAULT VALUES") + } + } else { + __columns.SQL = __sqlbundle_Literals{Join: ", ", SQLs: []__sqlbundle_SQL{__columns.SQL, __optional_columns}} + __placeholders.SQL = __sqlbundle_Literals{Join: ", ", SQLs: []__sqlbundle_SQL{__placeholders.SQL, __optional_placeholders}} + } + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err != nil { + return nil, obj.makeErr(err) + } + return account_freeze_event, nil + +} + func (obj *pgxImpl) Create_NodeEvent(ctx context.Context, node_event_id NodeEvent_Id_Field, node_event_email NodeEvent_Email_Field, @@ -14198,6 +14247,29 @@ func (obj *pgxImpl) CreateNoReturn_OauthToken(ctx context.Context, } +func (obj *pgxImpl) Get_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + + var __embed_stmt = __sqlbundle_Literal("SELECT account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at FROM account_freeze_events WHERE account_freeze_events.user_id = ? AND account_freeze_events.event = ?") + + var __values []interface{} + __values = append(__values, account_freeze_event_user_id.value(), account_freeze_event_event.value()) + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err != nil { + return (*AccountFreezeEvent)(nil), obj.makeErr(err) + } + return account_freeze_event, nil + +} + func (obj *pgxImpl) Get_NodeEvent_By_Id(ctx context.Context, node_event_id NodeEvent_Id_Field) ( node_event *NodeEvent, err error) { @@ -17670,6 +17742,48 @@ func (obj *pgxImpl) Get_OauthToken_By_Kind_And_Token(ctx context.Context, } +func (obj *pgxImpl) Update_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + update AccountFreezeEvent_Update_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + var __sets = &__sqlbundle_Hole{} + + var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPDATE account_freeze_events SET "), __sets, __sqlbundle_Literal(" WHERE account_freeze_events.user_id = ? AND account_freeze_events.event = ? RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}} + + __sets_sql := __sqlbundle_Literals{Join: ", "} + var __values []interface{} + var __args []interface{} + + if update.Limits._set { + __values = append(__values, update.Limits.value()) + __sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("limits = ?")) + } + + if len(__sets_sql.SQLs) == 0 { + return nil, emptyUpdate() + } + + __args = append(__args, account_freeze_event_user_id.value(), account_freeze_event_event.value()) + + __values = append(__values, __args...) + __sets.SQL = __sets_sql + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err == sql.ErrNoRows { + return nil, nil + } + if err != nil { + return nil, obj.makeErr(err) + } + return account_freeze_event, nil +} + func (obj *pgxImpl) UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context, accounting_timestamps_name AccountingTimestamps_Name_Field, update AccountingTimestamps_Update_Fields) ( @@ -19630,6 +19744,33 @@ func (obj *pgxImpl) UpdateNoReturn_OauthToken_By_Token_And_Kind(ctx context.Cont return nil } +func (obj *pgxImpl) Delete_AccountFreezeEvent_By_UserId(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field) ( + count int64, err error) { + defer mon.Task()(&ctx)(&err) + + var __embed_stmt = __sqlbundle_Literal("DELETE FROM account_freeze_events WHERE account_freeze_events.user_id = ?") + + var __values []interface{} + __values = append(__values, account_freeze_event_user_id.value()) + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + __res, err := obj.driver.ExecContext(ctx, __stmt, __values...) + if err != nil { + return 0, obj.makeErr(err) + } + + count, err = __res.RowsAffected() + if err != nil { + return 0, obj.makeErr(err) + } + + return count, nil + +} + func (obj *pgxImpl) Delete_NodeEvent_By_CreatedAt_Less(ctx context.Context, node_event_created_at_less NodeEvent_CreatedAt_Field) ( count int64, err error) { @@ -20689,6 +20830,54 @@ func (obj *pgxImpl) deleteAll(ctx context.Context) (count int64, err error) { } +func (obj *pgxcockroachImpl) Create_AccountFreezeEvent(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + optional AccountFreezeEvent_Create_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + __user_id_val := account_freeze_event_user_id.value() + __event_val := account_freeze_event_event.value() + __limits_val := optional.Limits.value() + + var __columns = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("user_id, event, limits")} + var __placeholders = &__sqlbundle_Hole{SQL: __sqlbundle_Literal("?, ?, ?")} + var __clause = &__sqlbundle_Hole{SQL: __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("("), __columns, __sqlbundle_Literal(") VALUES ("), __placeholders, __sqlbundle_Literal(")")}}} + + var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("INSERT INTO account_freeze_events "), __clause, __sqlbundle_Literal(" RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}} + + var __values []interface{} + __values = append(__values, __user_id_val, __event_val, __limits_val) + + __optional_columns := __sqlbundle_Literals{Join: ", "} + __optional_placeholders := __sqlbundle_Literals{Join: ", "} + + if optional.CreatedAt._set { + __values = append(__values, optional.CreatedAt.value()) + __optional_columns.SQLs = append(__optional_columns.SQLs, __sqlbundle_Literal("created_at")) + __optional_placeholders.SQLs = append(__optional_placeholders.SQLs, __sqlbundle_Literal("?")) + } + + if len(__optional_columns.SQLs) == 0 { + if __columns.SQL == nil { + __clause.SQL = __sqlbundle_Literal("DEFAULT VALUES") + } + } else { + __columns.SQL = __sqlbundle_Literals{Join: ", ", SQLs: []__sqlbundle_SQL{__columns.SQL, __optional_columns}} + __placeholders.SQL = __sqlbundle_Literals{Join: ", ", SQLs: []__sqlbundle_SQL{__placeholders.SQL, __optional_placeholders}} + } + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err != nil { + return nil, obj.makeErr(err) + } + return account_freeze_event, nil + +} + func (obj *pgxcockroachImpl) Create_NodeEvent(ctx context.Context, node_event_id NodeEvent_Id_Field, node_event_email NodeEvent_Email_Field, @@ -22058,6 +22247,29 @@ func (obj *pgxcockroachImpl) CreateNoReturn_OauthToken(ctx context.Context, } +func (obj *pgxcockroachImpl) Get_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + + var __embed_stmt = __sqlbundle_Literal("SELECT account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at FROM account_freeze_events WHERE account_freeze_events.user_id = ? AND account_freeze_events.event = ?") + + var __values []interface{} + __values = append(__values, account_freeze_event_user_id.value(), account_freeze_event_event.value()) + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err != nil { + return (*AccountFreezeEvent)(nil), obj.makeErr(err) + } + return account_freeze_event, nil + +} + func (obj *pgxcockroachImpl) Get_NodeEvent_By_Id(ctx context.Context, node_event_id NodeEvent_Id_Field) ( node_event *NodeEvent, err error) { @@ -25530,6 +25742,48 @@ func (obj *pgxcockroachImpl) Get_OauthToken_By_Kind_And_Token(ctx context.Contex } +func (obj *pgxcockroachImpl) Update_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + update AccountFreezeEvent_Update_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + defer mon.Task()(&ctx)(&err) + var __sets = &__sqlbundle_Hole{} + + var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPDATE account_freeze_events SET "), __sets, __sqlbundle_Literal(" WHERE account_freeze_events.user_id = ? AND account_freeze_events.event = ? RETURNING account_freeze_events.user_id, account_freeze_events.event, account_freeze_events.limits, account_freeze_events.created_at")}} + + __sets_sql := __sqlbundle_Literals{Join: ", "} + var __values []interface{} + var __args []interface{} + + if update.Limits._set { + __values = append(__values, update.Limits.value()) + __sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("limits = ?")) + } + + if len(__sets_sql.SQLs) == 0 { + return nil, emptyUpdate() + } + + __args = append(__args, account_freeze_event_user_id.value(), account_freeze_event_event.value()) + + __values = append(__values, __args...) + __sets.SQL = __sets_sql + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + account_freeze_event = &AccountFreezeEvent{} + err = obj.queryRowContext(ctx, __stmt, __values...).Scan(&account_freeze_event.UserId, &account_freeze_event.Event, &account_freeze_event.Limits, &account_freeze_event.CreatedAt) + if err == sql.ErrNoRows { + return nil, nil + } + if err != nil { + return nil, obj.makeErr(err) + } + return account_freeze_event, nil +} + func (obj *pgxcockroachImpl) UpdateNoReturn_AccountingTimestamps_By_Name(ctx context.Context, accounting_timestamps_name AccountingTimestamps_Name_Field, update AccountingTimestamps_Update_Fields) ( @@ -27490,6 +27744,33 @@ func (obj *pgxcockroachImpl) UpdateNoReturn_OauthToken_By_Token_And_Kind(ctx con return nil } +func (obj *pgxcockroachImpl) Delete_AccountFreezeEvent_By_UserId(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field) ( + count int64, err error) { + defer mon.Task()(&ctx)(&err) + + var __embed_stmt = __sqlbundle_Literal("DELETE FROM account_freeze_events WHERE account_freeze_events.user_id = ?") + + var __values []interface{} + __values = append(__values, account_freeze_event_user_id.value()) + + var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt) + obj.logStmt(__stmt, __values...) + + __res, err := obj.driver.ExecContext(ctx, __stmt, __values...) + if err != nil { + return 0, obj.makeErr(err) + } + + count, err = __res.RowsAffected() + if err != nil { + return 0, obj.makeErr(err) + } + + return count, nil + +} + func (obj *pgxcockroachImpl) Delete_NodeEvent_By_CreatedAt_Less(ctx context.Context, node_event_created_at_less NodeEvent_CreatedAt_Field) ( count int64, err error) { @@ -28988,6 +29269,19 @@ func (rx *Rx) CreateNoReturn_StorjscanWallet(ctx context.Context, } +func (rx *Rx) Create_AccountFreezeEvent(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + optional AccountFreezeEvent_Create_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + var tx *Tx + if tx, err = rx.getTx(ctx); err != nil { + return + } + return tx.Create_AccountFreezeEvent(ctx, account_freeze_event_user_id, account_freeze_event_event, optional) + +} + func (rx *Rx) Create_ApiKey(ctx context.Context, api_key_id ApiKey_Id_Field, api_key_project_id ApiKey_ProjectId_Field, @@ -29311,6 +29605,17 @@ func (rx *Rx) Create_WebappSession(ctx context.Context, } +func (rx *Rx) Delete_AccountFreezeEvent_By_UserId(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field) ( + count int64, err error) { + var tx *Tx + if tx, err = rx.getTx(ctx); err != nil { + return + } + return tx.Delete_AccountFreezeEvent_By_UserId(ctx, account_freeze_event_user_id) + +} + func (rx *Rx) Delete_ApiKey_By_Id(ctx context.Context, api_key_id ApiKey_Id_Field) ( deleted bool, err error) { @@ -29566,6 +29871,17 @@ func (rx *Rx) First_StorjscanPayment_BlockNumber_By_Status_OrderBy_Desc_BlockNum return tx.First_StorjscanPayment_BlockNumber_By_Status_OrderBy_Desc_BlockNumber_Desc_LogIndex(ctx, storjscan_payment_status) } +func (rx *Rx) Get_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field) ( + account_freeze_event *AccountFreezeEvent, err error) { + var tx *Tx + if tx, err = rx.getTx(ctx); err != nil { + return + } + return tx.Get_AccountFreezeEvent_By_UserId_And_Event(ctx, account_freeze_event_user_id, account_freeze_event_event) +} + func (rx *Rx) Get_ApiKey_By_Head(ctx context.Context, api_key_head ApiKey_Head_Field) ( api_key *ApiKey, err error) { @@ -30454,6 +30770,18 @@ func (rx *Rx) UpdateNoReturn_Reputation_By_Id(ctx context.Context, return tx.UpdateNoReturn_Reputation_By_Id(ctx, reputation_id, update) } +func (rx *Rx) Update_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + update AccountFreezeEvent_Update_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) { + var tx *Tx + if tx, err = rx.getTx(ctx); err != nil { + return + } + return tx.Update_AccountFreezeEvent_By_UserId_And_Event(ctx, account_freeze_event_user_id, account_freeze_event_event, update) +} + func (rx *Rx) Update_BillingBalance_By_UserId_And_Balance(ctx context.Context, billing_balance_user_id BillingBalance_UserId_Field, billing_balance_balance BillingBalance_Balance_Field, @@ -30779,6 +31107,12 @@ type Methods interface { storjscan_wallet_wallet_address StorjscanWallet_WalletAddress_Field) ( err error) + Create_AccountFreezeEvent(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + optional AccountFreezeEvent_Create_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) + Create_ApiKey(ctx context.Context, api_key_id ApiKey_Id_Field, api_key_project_id ApiKey_ProjectId_Field, @@ -30955,6 +31289,10 @@ type Methods interface { webapp_session_expires_at WebappSession_ExpiresAt_Field) ( webapp_session *WebappSession, err error) + Delete_AccountFreezeEvent_By_UserId(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field) ( + count int64, err error) + Delete_ApiKey_By_Id(ctx context.Context, api_key_id ApiKey_Id_Field) ( deleted bool, err error) @@ -31060,6 +31398,11 @@ type Methods interface { storjscan_payment_status StorjscanPayment_Status_Field) ( row *BlockNumber_Row, err error) + Get_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field) ( + account_freeze_event *AccountFreezeEvent, err error) + Get_ApiKey_By_Head(ctx context.Context, api_key_head ApiKey_Head_Field) ( api_key *ApiKey, err error) @@ -31460,6 +31803,12 @@ type Methods interface { update Reputation_Update_Fields) ( err error) + Update_AccountFreezeEvent_By_UserId_And_Event(ctx context.Context, + account_freeze_event_user_id AccountFreezeEvent_UserId_Field, + account_freeze_event_event AccountFreezeEvent_Event_Field, + update AccountFreezeEvent_Update_Fields) ( + account_freeze_event *AccountFreezeEvent, err error) + Update_BillingBalance_By_UserId_And_Balance(ctx context.Context, billing_balance_user_id BillingBalance_UserId_Field, billing_balance_balance BillingBalance_Balance_Field,