示例#1
0
func (st *GormStore) BuildQuery(filter *usecases.Filter, ownerRelations []domain.DBRelation) (*gorm.DB, error) {
	query := st.db

	if ownerRelations != nil {
		for _, relation := range ownerRelations {
			relation.Ressource = utils.ToDBName(relation.Ressource)
			relation.Fk = utils.ToDBName(relation.Fk)
			relation.Related = utils.ToDBName(relation.Related)

			queryString := fmt.Sprintf("INNER JOIN %s ON %s.%s = %s.id", relation.Ressource, relation.Ressource, relation.Fk, relation.Related)
			query = query.Joins(queryString)
			query = query.Table(relation.Related)
		}
	}

	if filter != nil {
		gormFilter, err := processFilter(filter)
		if err != nil {
			return nil, err
		}

		if len(gormFilter.Fields) != 0 {
			query = query.Select(gormFilter.Fields)
		}

		if gormFilter.Offset != 0 {
			query = query.Offset(gormFilter.Offset)
		}

		if gormFilter.Limit != 0 {
			query = query.Limit(gormFilter.Limit)
		}

		if gormFilter.Order != "" {
			query = query.Order(gormFilter.Order)
		}

		if gormFilter.Where != "" {
			query = query.Where(gormFilter.Where)
		}

		for _, include := range gormFilter.Include {
			if include.Relation == "" {
				break
			}

			if include.Where == "" {
				query = query.Preload(include.Relation)
			} else {
				query = query.Preload(include.Relation, include.Where)
			}
		}
	}

	return query, nil
}
示例#2
0
func (r *RoleMappingRepo) UpdateByID(id int, roleMapping *domain.RoleMapping,
	context usecases.QueryContext) (*domain.RoleMapping, error) {

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	dbName := utils.ToDBName("roleMappings")
	oldRoleMapping := &domain.RoleMapping{}

	err = query.Where(dbName+".id = ?", id).First(oldRoleMapping).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return nil, internalerrors.NotFound
		}

		return nil, internalerrors.DatabaseError
	}

	roleMapping.ID = oldRoleMapping.ID
	roleMapping.CreatedAt = oldRoleMapping.CreatedAt

	err = r.store.GetDB().Save(&roleMapping).Error
	if err != nil {
		if strings.Contains(err.Error(), "constraint") {
			return nil, internalerrors.NewViolatedConstraint(err.Error())
		}

		return nil, internalerrors.DatabaseError
	}

	return roleMapping, nil
}
示例#3
0
func processSimpleOperationStr(buffer *bytes.Buffer, attribute, sign, condition string) {
	buffer.WriteString(utils.ToDBName(attribute))
	buffer.WriteString(sign)
	buffer.WriteRune('\'')
	buffer.WriteString(condition)
	buffer.WriteRune('\'')
}
示例#4
0
func (r *AccountRepo) UpdateByID(id int, account *domain.Account,
	context usecases.QueryContext) (*domain.Account, error) {

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	dbName := utils.ToDBName("accounts")
	oldAccount := &domain.Account{}

	err = query.Where(dbName+".id = ?", id).First(oldAccount).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return nil, internalerrors.NotFound
		}

		return nil, internalerrors.DatabaseError
	}

	account.ID = oldAccount.ID
	account.CreatedAt = oldAccount.CreatedAt

	err = r.store.GetDB().Save(&account).Error
	if err != nil {
		if strings.Contains(err.Error(), "constraint") {
			return nil, internalerrors.NewViolatedConstraint(err.Error())
		}

		return nil, internalerrors.DatabaseError
	}

	return account, nil
}
示例#5
0
func (r *UserRepo) UpdateAttributesByID(id int, attributes map[string]interface{},
	context usecases.QueryContext) (*domain.User, error) {

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	dbName := utils.ToDBName("users")
	user := &domain.User{}

	err = query.Where(dbName+".id = ?", id).First(user).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return nil, internalerrors.NotFound
		}

		return nil, internalerrors.DatabaseError
	}

	err = r.store.GetDB().Model(&user).Updates(attributes).Error
	if err != nil {
		if strings.Contains(err.Error(), "constraint") {
			return nil, internalerrors.NewViolatedConstraint(err.Error())
		}

		return nil, internalerrors.DatabaseError
	}

	return user, nil
}
示例#6
0
func (r *SessionRepo) UpdateByID(id int, session *domain.Session,
	context usecases.QueryContext) (*domain.Session, error) {

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	dbName := utils.ToDBName("sessions")

	err = query.Where(dbName+".id = ?", id).First(&domain.Session{}).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return nil, internalerrors.NotFound
		}

		return nil, internalerrors.DatabaseError
	}

	err = r.store.GetDB().Where(dbName+".id = ?", id).Model(&domain.Session{}).Updates(&session).Error
	if err != nil {
		if strings.Contains(err.Error(), "constraint") {
			return nil, internalerrors.NewViolatedConstraint(err.Error())
		}

		return nil, internalerrors.DatabaseError
	}

	return session, nil
}
示例#7
0
func processFilter(filter *usecases.Filter) (*interfaces.GormFilter, error) {
	fields := filter.Fields
	dbNamedFields := make([]string, len(fields))

	for i, field := range fields {
		dbNamedFields[i] = utils.ToDBName(field)
	}

	if filter.Order != "" {
		order := strings.ToLower(filter.Order)
		matched, err := regexp.MatchString("\\A\\w+ (asc|desc)\\z", order)
		if err != nil || !matched {
			return nil, errors.New("invalid order filter")
		}

		split := strings.Split(filter.Order, " ")
		filter.Order = utils.ToDBName(split[0]) + " " + split[1]
	}

	processedFilter := &interfaces.GormFilter{Fields: dbNamedFields, Limit: filter.Limit, Offset: filter.Offset, Order: filter.Order}

	buffer := &bytes.Buffer{}
	err := processCondition(buffer, "", andSql, "", filter.Where)
	if err != nil {
		return nil, err
	}
	processedFilter.Where = buffer.String()

	gormIncludes, err := processInclude(filter.Include)
	if err != nil {
		return nil, err
	}
	processedFilter.Include = gormIncludes

	return processedFilter, nil
}
示例#8
0
func (r *AccountRepo) DeleteByID(id int, context usecases.QueryContext) error {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return internalerrors.DatabaseError
	}

	account := &domain.Account{}

	err = query.Where(utils.ToDBName("accounts")+".id = ?", id).First(&account).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return internalerrors.NotFound
		}

		return internalerrors.DatabaseError
	}

	err = r.store.GetDB().Where(utils.ToDBName("accounts")+".id = ?", account.ID).Delete(domain.Account{}).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	return nil
}
示例#9
0
func (r *AclRepo) FindByID(id int, context usecases.QueryContext) (*domain.Acl, error) {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	acl := domain.Acl{}

	err = query.Where(utils.ToDBName("acls")+".id = ?", id).First(&acl).Error
	if err != nil {
		if strings.Contains(err.Error(), "record not found") {
			return nil, internalerrors.NotFound
		}

		return nil, internalerrors.DatabaseError
	}

	return &acl, nil
}
示例#10
0
func (r *AccountRepo) Update(accounts []domain.Account, context usecases.QueryContext) ([]domain.Account, error) {
	db := r.store.GetDB()
	transaction := db.Begin()

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	for _, account := range accounts {
		queryCopy := *query

		dbName := utils.ToDBName("accounts")
		oldAccount := &domain.Account{}

		err = queryCopy.Where(dbName+".id = ?", account.ID).First(oldAccount).Error
		if err != nil {
			if strings.Contains(err.Error(), "record not found") {
				return nil, internalerrors.NotFound
			}

			return nil, internalerrors.DatabaseError
		}

		account.ID = oldAccount.ID
		account.CreatedAt = oldAccount.CreatedAt

		err = r.store.GetDB().Save(&account).Error
		if err != nil {
			if strings.Contains(err.Error(), "constraint") {
				return nil, internalerrors.NewViolatedConstraint(err.Error())
			}

			return nil, internalerrors.DatabaseError
		}
	}

	transaction.Commit()
	return accounts, nil
}
示例#11
0
func (r *RoleMappingRepo) Update(roleMappings []domain.RoleMapping, context usecases.QueryContext) ([]domain.RoleMapping, error) {
	db := r.store.GetDB()
	transaction := db.Begin()

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	for _, roleMapping := range roleMappings {
		queryCopy := *query

		dbName := utils.ToDBName("roleMappings")
		oldRoleMapping := &domain.RoleMapping{}

		err = queryCopy.Where(dbName+".id = ?", roleMapping.ID).First(oldRoleMapping).Error
		if err != nil {
			if strings.Contains(err.Error(), "record not found") {
				return nil, internalerrors.NotFound
			}

			return nil, internalerrors.DatabaseError
		}

		roleMapping.ID = oldRoleMapping.ID
		roleMapping.CreatedAt = oldRoleMapping.CreatedAt

		err = r.store.GetDB().Save(&roleMapping).Error
		if err != nil {
			if strings.Contains(err.Error(), "constraint") {
				return nil, internalerrors.NewViolatedConstraint(err.Error())
			}

			return nil, internalerrors.DatabaseError
		}
	}

	transaction.Commit()
	return roleMappings, nil
}
示例#12
0
func (r *SessionRepo) Update(sessions []domain.Session, context usecases.QueryContext) ([]domain.Session, error) {
	db := r.store.GetDB()
	transaction := db.Begin()

	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return nil, internalerrors.DatabaseError
	}

	for _, session := range sessions {
		queryCopy := *query

		dbName := utils.ToDBName("sessions")

		err = queryCopy.Where(dbName+".id = ?", session.ID).First(&domain.Session{}).Error
		if err != nil {
			if strings.Contains(err.Error(), "record not found") {
				return nil, internalerrors.NotFound
			}

			return nil, internalerrors.DatabaseError
		}

		err = r.store.GetDB().Where(dbName+".id = ?", session.ID).Model(&domain.Session{}).Updates(&session).Error
		if err != nil {
			if strings.Contains(err.Error(), "constraint") {
				return nil, internalerrors.NewViolatedConstraint(err.Error())
			}

			return nil, internalerrors.DatabaseError
		}
	}

	transaction.Commit()
	return sessions, nil
}
示例#13
0
func (r *AccountRepo) DeleteAll(context usecases.QueryContext) error {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return internalerrors.DatabaseError
	}

	accounts := []domain.Account{}
	err = query.Find(&accounts).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	accountIDs := []int{}
	for _, account := range accounts {
		accountIDs = append(accountIDs, account.ID)
	}

	err = r.store.GetDB().Delete(&accounts, utils.ToDBName("accounts")+".id IN (?)", accountIDs).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	return nil
}
示例#14
0
func (r *SessionRepo) DeleteAll(context usecases.QueryContext) error {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return internalerrors.DatabaseError
	}

	sessions := []domain.Session{}
	err = query.Find(&sessions).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	sessionIDs := []int{}
	for _, session := range sessions {
		sessionIDs = append(sessionIDs, session.ID)
	}

	err = r.store.GetDB().Delete(&sessions, utils.ToDBName("sessions")+".id IN (?)", sessionIDs).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	return nil
}
示例#15
0
func (r *UserRepo) DeleteAll(context usecases.QueryContext) error {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return internalerrors.DatabaseError
	}

	users := []domain.User{}
	err = query.Find(&users).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	userIDs := []int{}
	for _, user := range users {
		userIDs = append(userIDs, user.ID)
	}

	err = r.store.GetDB().Delete(&users, utils.ToDBName("users")+".id IN (?)", userIDs).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	return nil
}
示例#16
0
func (r *RoleRepo) DeleteAll(context usecases.QueryContext) error {
	query, err := r.store.BuildQuery(context.Filter, context.OwnerRelations)
	if err != nil {
		return internalerrors.DatabaseError
	}

	roles := []domain.Role{}
	err = query.Find(&roles).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	roleIDs := []int{}
	for _, role := range roles {
		roleIDs = append(roleIDs, role.ID)
	}

	err = r.store.GetDB().Delete(&roles, utils.ToDBName("roles")+".id IN (?)", roleIDs).Error
	if err != nil {
		return internalerrors.DatabaseError
	}

	return nil
}
示例#17
0
func processOperation(buffer *bytes.Buffer, attribute, operator, sign string, condition interface{}) error {
	switch condition.(type) {
	case bool:
		if condition.(bool) {
			processSimpleOperationStr(buffer, attribute, sign, "1")
		} else {
			processSimpleOperationStr(buffer, attribute, sign, "0")
		}

	case string:
		processSimpleOperationStr(buffer, attribute, sign, condition.(string))

	case int:
		processSimpleOperation(buffer, attribute, sign, strconv.FormatInt(int64(condition.(int)), 10))

	case float64:
		processSimpleOperation(buffer, attribute, sign, strconv.FormatFloat(condition.(float64), 'f', -1, 64))

	case []int:
		intArray := condition.([]int)
		lenArray := len(intArray)

		buffer.WriteString(utils.ToDBName(attribute))
		buffer.WriteString(" IN (")

		for i, value := range intArray {
			buffer.WriteString(strconv.FormatInt(int64(value), 10))
			if i < lenArray-1 {
				buffer.WriteString(", ")
			}
		}

		buffer.WriteString(")")

	case []float64:
		floatArray := condition.([]float64)
		lenArray := len(floatArray)

		buffer.WriteString(utils.ToDBName(attribute))
		buffer.WriteString(" IN (")

		for i, value := range floatArray {
			buffer.WriteString(strconv.FormatFloat(value, 'f', -1, 64))
			if i < lenArray-1 {
				buffer.WriteString(", ")
			}
		}

		buffer.WriteString(")")

	case []interface{}:
		conditions := condition.([]interface{})

		arrStr := []string{}
		strType := reflect.TypeOf("")

		for _, condition := range conditions {
			if reflect.TypeOf(condition) == strType {
				arrStr = append(arrStr, condition.(string))
			}
		}

		if len(arrStr) == 0 {
			newBuffer := &bytes.Buffer{}

			buffer.WriteString("(")

			for _, condition := range conditions {
				processCondition(newBuffer, "", operator, sign, condition)
			}
			buffer.Write(newBuffer.Bytes())

			buffer.WriteString(")")
		} else {
			lenArray := len(arrStr)

			buffer.WriteString(utils.ToDBName(attribute))
			buffer.WriteString(" IN (")

			for i, value := range arrStr {
				buffer.WriteRune('\'')
				buffer.WriteString(value)
				buffer.WriteRune('\'')

				if i < lenArray-1 {
					buffer.WriteString(", ")
				}
			}

			buffer.WriteString(")")
		}
	}

	return nil
}