diff --git a/pkg/api/data_managements.go b/pkg/api/data_managements.go index 034032ed..78845e5e 100644 --- a/pkg/api/data_managements.go +++ b/pkg/api/data_managements.go @@ -81,25 +81,11 @@ func (a *DataManagementsApi) ExportDataHandler(c *core.Context) ([]byte, string, categoryMap := a.categories.GetCategoryMapByList(categories) tagMap := a.tags.GetTagMapByList(tags) - maxTime := utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix()) - var allTransactions []*models.Transaction + allTransactions, err := a.transactions.GetAllTransactions(uid, pageCountForDataExport, true) - for maxTime > 0 { - transactions, err := a.transactions.GetAllTransactionsByMaxTime(uid, maxTime, pageCountForDataExport, true) - - if err != nil { - log.ErrorfWithRequestId(c, "[data_managements.ExportDataHandler] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", maxTime, uid, err.Error()) - return nil, "", errs.ErrOperationFailed - } - - allTransactions = append(allTransactions, transactions...) - - if len(transactions) < pageCountForDataExport { - maxTime = 0 - break - } - - maxTime = transactions[len(transactions)-1].TransactionTime - 1 + if err != nil { + log.ErrorfWithRequestId(c, "[data_managements.ExportDataHandler] failed to all transactions user \"uid:%d\", because %s", uid, err.Error()) + return nil, "", errs.ErrOperationFailed } result, err := a.exporter.GetOutputContent(uid, allTransactions, accountMap, categoryMap, tagMap, tagIndexs) diff --git a/pkg/cli/user_data.go b/pkg/cli/user_data.go index 362833a2..a717331f 100644 --- a/pkg/cli/user_data.go +++ b/pkg/cli/user_data.go @@ -1,18 +1,15 @@ package cli import ( - "time" - "github.com/urfave/cli/v2" "github.com/mayswind/lab/pkg/errs" "github.com/mayswind/lab/pkg/log" "github.com/mayswind/lab/pkg/models" "github.com/mayswind/lab/pkg/services" - "github.com/mayswind/lab/pkg/utils" ) -const pageCountForAccountCheck = 1000 +const pageCountForGettingTransactions = 1000 // UserDataCli represents user data cli type UserDataCli struct { @@ -36,72 +33,26 @@ var ( // CheckTransactionAndAccount checks whether all user transactions and all user accounts are correct func (a *UserDataCli) CheckTransactionAndAccount(c *cli.Context, uid int64) (bool, error) { - if uid <= 0 { - log.BootErrorf("[user_data.CheckAccountBalance] user uid \"%d\" is invalid", uid) - return false, errs.ErrUserIdInvalid - } - - accounts, err := a.accounts.GetAllAccountsByUid(uid) + accountMap, categoryMap, tagMap, tagIndexs, err := a.getUserEssentialData(uid) if err != nil { - log.BootErrorf("[user_data.CheckAccountBalance] failed to get accounts for user \"uid:%d\", because %s", uid, err.Error()) + log.BootErrorf("[user_data.CheckTransactionAndAccount] failed to get essential data for user \"uid:%d\", because %s", uid, err.Error()) return false, err } - categories, err := a.categories.GetAllCategoriesByUid(uid, 0, -1) - - if err != nil { - log.BootErrorf("[user_data.CheckAccountBalance] failed to get categories for user \"uid:%d\", because %s", uid, err.Error()) - return false, err - } - - tags, err := a.tags.GetAllTagsByUid(uid) - - if err != nil { - log.BootErrorf("[user_data.CheckAccountBalance] failed to get tags for user \"uid:%d\", because %s", uid, err.Error()) - return false, err - } - - tagIndexs, err := a.tags.GetAllTagIdsOfAllTransactions(uid) - - if err != nil { - log.BootErrorf("[user_data.CheckAccountBalance] failed to get tag index for user \"uid:%d\", because %s", uid, err.Error()) - return false, err - } - - accountMap := a.accounts.GetAccountMapByList(accounts) - categoryMap := a.categories.GetCategoryMapByList(categories) - tagMap := a.tags.GetTagMapByList(tags) - accountHasChild := make(map[int64]bool) - for i := 0; i < len(accounts); i++ { - account := accounts[i] - + for _, account := range accountMap { if account.ParentAccountId > models.LevelOneAccountParentId { accountHasChild[account.ParentAccountId] = true } } - maxTime := utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix()) - var allTransactions []*models.Transaction + allTransactions, err := a.transactions.GetAllTransactions(uid, pageCountForGettingTransactions, false) - for maxTime > 0 { - transactions, err := a.transactions.GetAllTransactionsByMaxTime(uid, maxTime, pageCountForAccountCheck, false) - - if err != nil { - log.BootErrorf("[user_data.CheckAccountBalance] failed to get transactions earlier than \"%d\" for user \"uid:%d\", because %s", maxTime, uid, err.Error()) - return false, err - } - - allTransactions = append(allTransactions, transactions...) - - if len(transactions) < pageCountForAccountCheck { - maxTime = 0 - break - } - - maxTime = transactions[len(transactions)-1].TransactionTime - 1 + if err != nil { + log.BootErrorf("[user_data.CheckTransactionAndAccount] failed to all transactions for user \"uid:%d\", because %s", uid, err.Error()) + return false, err } transactionMap := a.transactions.GetTransactionMapByList(allTransactions) @@ -158,8 +109,7 @@ func (a *UserDataCli) CheckTransactionAndAccount(c *cli.Context, uid int64) (boo accountBalance[transaction.AccountId] = balance } - for i := 0; i < len(accounts); i++ { - account := accounts[i] + for _, account := range accountMap { actualBalance, exists := accountBalance[account.AccountId] if !exists && account.Balance == 0 { @@ -206,6 +156,49 @@ func (a *UserDataCli) GetUserIdByUsername(c *cli.Context, username string) (int6 return user.Uid, nil } +func (a *UserDataCli) getUserEssentialData(uid int64) (accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, tagIndexs map[int64][]int64, err error) { + if uid <= 0 { + log.BootErrorf("[user_data.getUserEssentialData] user uid \"%d\" is invalid", uid) + return nil, nil, nil, nil, errs.ErrUserIdInvalid + } + + accounts, err := a.accounts.GetAllAccountsByUid(uid) + + if err != nil { + log.BootErrorf("[user_data.getUserEssentialData] failed to get accounts for user \"uid:%d\", because %s", uid, err.Error()) + return nil, nil, nil, nil, err + } + + accountMap = a.accounts.GetAccountMapByList(accounts) + + categories, err := a.categories.GetAllCategoriesByUid(uid, 0, -1) + + if err != nil { + log.BootErrorf("[user_data.getUserEssentialData] failed to get categories for user \"uid:%d\", because %s", uid, err.Error()) + return nil, nil, nil, nil, err + } + + categoryMap = a.categories.GetCategoryMapByList(categories) + + tags, err := a.tags.GetAllTagsByUid(uid) + + if err != nil { + log.BootErrorf("[user_data.getUserEssentialData] failed to get tags for user \"uid:%d\", because %s", uid, err.Error()) + return nil, nil, nil, nil, err + } + + tagMap = a.tags.GetTagMapByList(tags) + + tagIndexs, err = a.tags.GetAllTagIdsOfAllTransactions(uid) + + if err != nil { + log.BootErrorf("[user_data.getUserEssentialData] failed to get tag index for user \"uid:%d\", because %s", uid, err.Error()) + return nil, nil, nil, nil, err + } + + return accountMap, categoryMap, tagMap, tagIndexs, nil +} + func (a *UserDataCli) checkTransactionAccount(c *cli.Context, transaction *models.Transaction, accountMap map[int64]*models.Account, accountHasChild map[int64]bool) error { account, exists := accountMap[transaction.AccountId] diff --git a/pkg/services/transactions.go b/pkg/services/transactions.go index c9a8a273..406bf6de 100644 --- a/pkg/services/transactions.go +++ b/pkg/services/transactions.go @@ -32,6 +32,31 @@ var ( } ) +// GetAllTransactions returns all transactions +func (s *TransactionService) GetAllTransactions(uid int64, pageCount int, noDuplicated bool) ([]*models.Transaction, error) { + maxTime := utils.GetMaxTransactionTimeFromUnixTime(time.Now().Unix()) + var allTransactions []*models.Transaction + + for maxTime > 0 { + transactions, err := s.GetAllTransactionsByMaxTime(uid, maxTime, pageCount, noDuplicated) + + if err != nil { + return nil, err + } + + allTransactions = append(allTransactions, transactions...) + + if len(transactions) < pageCount { + maxTime = 0 + break + } + + maxTime = transactions[len(transactions)-1].TransactionTime - 1 + } + + return allTransactions, nil +} + // GetAllTransactionsByMaxTime returns all transactions before given time func (s *TransactionService) GetAllTransactionsByMaxTime(uid int64, maxTime int64, count int, noDuplicated bool) ([]*models.Transaction, error) { return s.GetTransactionsByMaxTime(uid, maxTime, 0, 0, nil, 0, "", count, noDuplicated)