fix: todos (#1346)

* fix: pub sub in new eventstore

* fix: todos

* fix: todos

* fix: todos

* fix: todos

* fix: todos
This commit is contained in:
Fabi
2021-03-01 08:48:50 +01:00
committed by GitHub
parent c0f55e7209
commit 3c07a186fc
145 changed files with 645 additions and 575 deletions

View File

@@ -1,10 +1,10 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
@@ -12,8 +12,8 @@ import (
func IAMMemberByIDs(db *gorm.DB, table, orgID, userID string) (*model.IAMMemberView, error) {
member := new(model.IAMMemberView)
iamIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyIamID, Value: orgID, Method: global_model.SearchMethodEquals}
userIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyUserID, Value: userID, Method: global_model.SearchMethodEquals}
iamIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyIamID, Value: orgID, Method: domain.SearchMethodEquals}
userIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyUserID, Value: userID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, iamIDQuery, userIDQuery)
err := query(db, member)
if caos_errs.IsNotFound(err) {
@@ -37,7 +37,7 @@ func IAMMembersByUserID(db *gorm.DB, table string, userID string) ([]*model.IAMM
{
Key: iam_model.IAMMemberSearchKeyUserID,
Value: userID,
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.IAMMemberSearchRequest{Queries: queries})

View File

@@ -1,18 +1,18 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetIDPProviderByAggregateIDAndConfigID(db *gorm.DB, table, aggregateID, idpConfigID string) (*model.IDPProviderView, error) {
policy := new(model.IDPProviderView)
aggIDQuery := &model.IDPProviderSearchQuery{Key: iam_model.IDPProviderSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
idpConfigIDQuery := &model.IDPProviderSearchQuery{Key: iam_model.IDPProviderSearchKeyIdpConfigID, Value: idpConfigID, Method: global_model.SearchMethodEquals}
aggIDQuery := &model.IDPProviderSearchQuery{Key: iam_model.IDPProviderSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
idpConfigIDQuery := &model.IDPProviderSearchQuery{Key: iam_model.IDPProviderSearchKeyIdpConfigID, Value: idpConfigID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggIDQuery, idpConfigIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {
@@ -27,7 +27,7 @@ func IDPProvidersByIdpConfigID(db *gorm.DB, table string, idpConfigID string) ([
{
Key: iam_model.IDPProviderSearchKeyIdpConfigID,
Value: idpConfigID,
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.IDPProviderSearchRequest{Queries: queries})
@@ -44,12 +44,12 @@ func IDPProvidersByAggregateIDAndState(db *gorm.DB, table string, aggregateID st
{
Key: iam_model.IDPProviderSearchKeyAggregateID,
Value: aggregateID,
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
{
Key: iam_model.IDPProviderSearchKeyState,
Value: int(idpConfigState),
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.IDPProviderSearchRequest{Queries: queries})

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func IDPByID(db *gorm.DB, table, idpID string) (*model.IDPConfigView, error) {
idp := new(model.IDPConfigView)
idpIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: global_model.SearchMethodEquals}
idpIDQuery := &model.IDPConfigSearchQuery{Key: iam_model.IDPConfigSearchKeyIdpConfigID, Value: idpID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, idpIDQuery)
err := query(db, idp)
if caos_errs.IsNotFound(err) {
@@ -26,7 +26,7 @@ func GetIDPConfigsByAggregateID(db *gorm.DB, table string, aggregateID string) (
{
Key: iam_model.IDPConfigSearchKeyAggregateID,
Value: aggregateID,
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.IDPConfigSearchRequest{Queries: queries})

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetLabelPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LabelPolicyView, error) {
policy := new(model.LabelPolicyView)
aggregateIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.LabelPolicySearchQuery{Key: iam_model.LabelPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {

View File

@@ -1,10 +1,10 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
@@ -12,7 +12,7 @@ import (
func GetDefaultLoginPolicies(db *gorm.DB, table string) ([]*model.LoginPolicyView, error) {
loginPolicies := make([]*model.LoginPolicyView, 0)
queries := []*iam_model.LoginPolicySearchQuery{
{Key: iam_model.LoginPolicySearchKeyDefault, Value: true, Method: global_model.SearchMethodEquals},
{Key: iam_model.LoginPolicySearchKeyDefault, Value: true, Method: domain.SearchMethodEquals},
}
query := repository.PrepareSearchQuery(table, model.LoginPolicySearchRequest{Queries: queries})
_, err := query(db, &loginPolicies)
@@ -24,7 +24,7 @@ func GetDefaultLoginPolicies(db *gorm.DB, table string) ([]*model.LoginPolicyVie
func GetLoginPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.LoginPolicyView, error) {
policy := new(model.LoginPolicyView)
aggregateIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.LoginPolicySearchQuery{Key: iam_model.LoginPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetMailTemplateByAggregateID(db *gorm.DB, table, aggregateID string) (*model.MailTemplateView, error) {
template := new(model.MailTemplateView)
aggregateIDQuery := &model.MailTemplateSearchQuery{Key: iam_model.MailTemplateSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.MailTemplateSearchQuery{Key: iam_model.MailTemplateSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, template)
if caos_errs.IsNotFound(err) {

View File

@@ -1,10 +1,10 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
"strings"
@@ -16,7 +16,7 @@ func GetMailTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MailT
{
Key: iam_model.MailTextSearchKeyAggregateID,
Value: aggregateID,
Method: global_model.SearchMethodEquals,
Method: domain.SearchMethodEquals,
},
}
query := repository.PrepareSearchQuery(table, model.MailTextSearchRequest{Queries: queries})
@@ -29,9 +29,9 @@ func GetMailTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MailT
func GetMailTextByIDs(db *gorm.DB, table, aggregateID string, textType string, language string) (*model.MailTextView, error) {
mailText := new(model.MailTextView)
aggregateIDQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: global_model.SearchMethodEquals}
languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: strings.ToUpper(language), Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
textTypeQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyMailTextType, Value: textType, Method: domain.SearchMethodEquals}
languageQuery := &model.MailTextSearchQuery{Key: iam_model.MailTextSearchKeyLanguage, Value: strings.ToUpper(language), Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery)
err := query(db, mailText)
if caos_errs.IsNotFound(err) {

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req IAMMemberSearchQuery) GetKey() repository.ColumnKey {
return IAMMemberSearchKey(req.Key)
}
func (req IAMMemberSearchQuery) GetMethod() global_model.SearchMethod {
func (req IAMMemberSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req IDPConfigSearchQuery) GetKey() repository.ColumnKey {
return IDPConfigSearchKey(req.Key)
}
func (req IDPConfigSearchQuery) GetMethod() global_model.SearchMethod {
func (req IDPConfigSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req IDPProviderSearchQuery) GetKey() repository.ColumnKey {
return IDPProviderSearchKey(req.Key)
}
func (req IDPProviderSearchQuery) GetMethod() global_model.SearchMethod {
func (req IDPProviderSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req LabelPolicySearchQuery) GetKey() repository.ColumnKey {
return LabelPolicySearchKey(req.Key)
}
func (req LabelPolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req LabelPolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req LoginPolicySearchQuery) GetKey() repository.ColumnKey {
return LoginPolicySearchKey(req.Key)
}
func (req LoginPolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req LoginPolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req MailTemplateSearchQuery) GetKey() repository.ColumnKey {
return MailTemplateSearchKey(req.Key)
}
func (req MailTemplateSearchQuery) GetMethod() global_model.SearchMethod {
func (req MailTemplateSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req MailTextSearchQuery) GetKey() repository.ColumnKey {
return MailTextSearchKey(req.Key)
}
func (req MailTextSearchQuery) GetMethod() global_model.SearchMethod {
func (req MailTextSearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req OrgIAMPolicySearchQuery) GetKey() repository.ColumnKey {
return OrgIAMPolicySearchKey(req.Key)
}
func (req OrgIAMPolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req OrgIAMPolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req PasswordAgePolicySearchQuery) GetKey() repository.ColumnKey {
return PasswordAgePolicySearchKey(req.Key)
}
func (req PasswordAgePolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req PasswordAgePolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req PasswordComplexityPolicySearchQuery) GetKey() repository.ColumnKey {
return PasswordComplexityPolicySearchKey(req.Key)
}
func (req PasswordComplexityPolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req PasswordComplexityPolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,8 +1,8 @@
package model
import (
"github.com/caos/zitadel/internal/domain"
iam_model "github.com/caos/zitadel/internal/iam/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
)
@@ -41,7 +41,7 @@ func (req PasswordLockoutPolicySearchQuery) GetKey() repository.ColumnKey {
return PasswordLockoutPolicySearchKey(req.Key)
}
func (req PasswordLockoutPolicySearchQuery) GetMethod() global_model.SearchMethod {
func (req PasswordLockoutPolicySearchQuery) GetMethod() domain.SearchMethod {
return req.Method
}

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetOrgIAMPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.OrgIAMPolicyView, error) {
policy := new(model.OrgIAMPolicyView)
aggregateIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.OrgIAMPolicySearchQuery{Key: iam_model.OrgIAMPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetPasswordAgePolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordAgePolicyView, error) {
policy := new(model.PasswordAgePolicyView)
aggregateIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.PasswordAgePolicySearchQuery{Key: iam_model.PasswordAgePolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetPasswordComplexityPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordComplexityPolicyView, error) {
policy := new(model.PasswordComplexityPolicyView)
aggregateIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.PasswordComplexityPolicySearchQuery{Key: iam_model.PasswordComplexityPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {

View File

@@ -1,17 +1,17 @@
package view
import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/iam/repository/view/model"
global_model "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/view/repository"
"github.com/jinzhu/gorm"
)
func GetPasswordLockoutPolicyByAggregateID(db *gorm.DB, table, aggregateID string) (*model.PasswordLockoutPolicyView, error) {
policy := new(model.PasswordLockoutPolicyView)
aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: global_model.SearchMethodEquals}
aggregateIDQuery := &model.PasswordLockoutPolicySearchQuery{Key: iam_model.PasswordLockoutPolicySearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals}
query := repository.PrepareGetByQuery(table, aggregateIDQuery)
err := query(db, policy)
if caos_errs.IsNotFound(err) {