Ejemplo n.º 1
0
func (b *Backend) ExecQuery(statement FieldedExpression) ([]interface{}, apperror.Error) {
	translator := b.translator.New()
	if err := translator.PrepareExpression(statement); err != nil {
		return nil, err
	}
	if err := translator.Translate(statement); err != nil {
		return nil, err
	}

	sql := translator.String()
	args := translator.RawArguments()

	res := b.SqlExec(sql, args...)
	if res.Err() != nil {
		return nil, apperror.Wrap(res.Err(), "orient_error")
	}
	defer res.Close()

	var rawData interface{}
	if err := res.All(&rawData); err != nil {
		return nil, apperror.Wrap(err, "orient_result_retrieval_error")
	}

	rows, ok := rawData.([]orient.OIdentifiable)
	if !ok {
		return nil, apperror.New("invalid_non_record_orient_result")
	}

	items := make([]interface{}, len(rows), len(rows))

	var info *db.ModelInfo
	if sel, ok := statement.(*SelectStmt); ok {
		info = b.ModelInfos().Find(sel.Collection())
	}

	for i, rawItem := range rows {
		document, ok := rawItem.(*orient.Document)
		if !ok {
			continue
		}
		data := make(map[string]interface{})

		if info != nil && info.PkAttribute() != nil {
			data[info.PkAttribute().Name()] = document.RId
		}

		for _, docEntry := range document.Fields() {
			data[docEntry.Name] = docEntry.Value
		}

		items[i] = data
	}

	return items, nil
}
Ejemplo n.º 2
0
func (d *PostgresDialect) AfterCollectionCreate(info *db.ModelInfo) apperror.Error {
	for _, attr := range info.Attributes() {
		// Alter sequences to start at 1 instead of 0.
		if attr.AutoIncrement() {
			stmt := fmt.Sprintf("ALTER SEQUENCE %v_%v_seq RESTART WITH %v", info.BackendName(), attr.BackendName(), 1)
			if _, err := d.backend.SqlExec(stmt); err != nil {
				return apperror.Wrap(err, "sql_error")
			}
		}
	}

	return nil
}
Ejemplo n.º 3
0
func (b *Backend) analyzeRelations(info *db.ModelInfo) apperror.Error {
	for _, field := range info.TransientFields() {
		relatedItem := reflect.New(field.StructType())
		relatedInfo, err := b.InfoForModel(relatedItem)
		if err != nil {
			// No collection found, so assume a regular attribute.
			attr := db.BuildAttribute(field)
			info.AddAttribute(attr)
			continue
		}

		relation := db.BuildRelation(field)
		relation.SetModel(info)
		relation.SetRelatedModel(relatedInfo)

		if !relation.IsMany() {
			relation.SetRelationType(db.RELATION_TYPE_HAS_ONE)
		} else {
			relation.SetRelationType(db.RELATION_TYPE_HAS_MANY)
		}
		info.AddRelation(relation)
	}

	info.SetTransientFields(nil)

	return nil
}
Ejemplo n.º 4
0
func (b *Backend) sort(info *db.ModelInfo, items *reflector.SliceReflector, field Expression, asc bool) apperror.Error {
	fieldName := ""
	if id, ok := field.(*IdentifierExpr); ok {
		fieldName = id.Identifier()
	} else if id, ok := field.(*ColFieldIdentifierExpr); ok {
		if id.Collection() != info.Collection() {
			return apperror.New("unsupported_sort", fmt.Sprint("The memory backend does not support sorting with joined collections"))
		}
		fieldName = id.Field()
	} else {
		return apperror.New("unsupported_sort", fmt.Sprintf("The memory backend does not support sorting with custom field expressions"))
	}

	attr := info.FindAttribute(fieldName)
	if attr == nil {
		return apperror.New("invalid_sort", fmt.Sprintf("Invalid sort for inexistant field %v", fieldName))
	}

	if err := items.SortByField(attr.Name(), asc); err != nil {
		return apperror.Wrap(err, "sort_error")
	}

	return nil
}
Ejemplo n.º 5
0
func (b *Backend) filterItem(info *db.ModelInfo, item *reflector.Reflector, filter Expression) (bool, apperror.Error) {
	switch f := filter.(type) {
	case *AndExpr:
		// Check each filter.
		for _, e := range f.Expressions() {
			flag, err := b.filterItem(info, item, e)
			if err != nil {
				return false, err
			} else if !flag {
				// One filter does not match, so return false.
				return false, nil
			}
		}
		// All filters matched, we can return true.
		return true, nil

	case *OrExpr:
		// Check each filter.
		for _, e := range f.Expressions() {
			flag, err := b.filterItem(info, item, e)
			if err != nil {
				return false, err
			} else if flag {
				// One match is enough, so return true.
				return true, nil
			}
		}
		// No filters matched, so return false.
		return false, nil

	case *NotExpr:
		// Reverse nested filter.
		flag, err := b.filterItem(info, item, f.Not())
		if err != nil {
			return false, err
		} else {
			return !flag, nil
		}

	case FilterExpression:
		field := f.Field()

		fieldName := ""

		if id, ok := field.(*IdentifierExpr); ok {
			fieldName = id.Identifier()
		} else if id, ok := field.(*ColFieldIdentifierExpr); ok {
			if id.Collection() != info.Collection() {
				return false, apperror.New("unsupported_filter", fmt.Sprint("The memory backend does not support filtering with joined collections"))
			}
			fieldName = id.Field()
		} else {
			return false, apperror.New("unsupported_filter", fmt.Sprintf("The memory backend does not support filtering with custom field expressions"))
		}

		attr := info.FindAttribute(fieldName)
		if attr == nil {
			return false, apperror.New("invalid_filter", fmt.Sprintf("Invalid filter for inexistant field %v", fieldName))
		}

		operator := f.Operator()

		var clauseValue interface{}

		if valExpr, ok := f.Clause().(*ValueExpr); ok {
			clauseValue = valExpr.Value()
		} else {
			return false, apperror.New("unsupported_filter_clause", fmt.Sprintf("The memory backend does not support filtering with custom clause expressions"))
		}

		if info.StructName() != "" {
			b.Logger().Infof("filtering item with %v %v %v", fieldName, operator, clauseValue)
			s, err := item.Struct()
			if err != nil {
				return false, apperror.Wrap(err, "invalid_model_error")
			}
			flag, err := s.Field(attr.Name()).CompareTo(clauseValue, operator)
			if err != nil {
				return false, apperror.Wrap(err, "compare_error")
			}
			return flag, nil
		} else {
			// Assume a map.
			if !item.IsMap() {
				return false, apperror.New("filter_invalid_model", "Could not filter because model value is neither struct nor map.")
			}
			flag, err := reflector.R(item.Value().MapIndex(reflect.ValueOf(attr.BackendName()))).CompareTo(clauseValue, operator)
			if err != nil {
				return false, apperror.Wrap(err, "compare_error")
			}
			return flag, nil
		}

	default:
		b.Logger().Panicf("Unhandled filter expression: %v", reflect.TypeOf(filter))
	}

	return false, nil
}