Esempio n. 1
0
// Find returns one or more records by the specified index
func (n *node) Find(fieldName string, value interface{}, to interface{}, options ...func(q *index.Options)) error {
	if value == nil {
		return ErrNotFound
	}

	sink, err := newListSink(n, to)
	if err != nil {
		return err
	}
	bucketName := sink.bucketName()
	if bucketName == "" {
		return ErrNoName
	}

	ref := reflect.Indirect(reflect.New(sink.elemType))
	cfg, err := extractSingleField(&ref, fieldName)
	if err != nil {
		return err
	}

	opts := index.NewOptions()
	for _, fn := range options {
		fn(opts)
	}

	field, ok := cfg.Fields[fieldName]
	if !ok || (!field.IsID && field.Index == "") {
		sink.limit = opts.Limit
		sink.skip = opts.Skip
		query := newQuery(n, q.StrictEq(fieldName, value))

		if opts.Reverse {
			query.Reverse()
		}

		err = n.readTx(func(tx *bolt.Tx) error {
			return query.query(tx, sink)
		})

		if err != nil {
			return err
		}

		return sink.flush()
	}

	val, err := toBytes(value, n.s.codec)
	if err != nil {
		return err
	}

	return n.readTx(func(tx *bolt.Tx) error {
		return n.find(tx, bucketName, fieldName, cfg, sink, val, opts)
	})
}
Esempio n. 2
0
// One returns one record by the specified index
func (n *node) One(fieldName string, value interface{}, to interface{}) error {
	sink, err := newFirstSink(n, to)
	if err != nil {
		return err
	}

	bucketName := sink.bucketName()
	if bucketName == "" {
		return ErrNoName
	}

	if fieldName == "" {
		return ErrNotFound
	}

	ref := reflect.Indirect(sink.ref)
	cfg, err := extractSingleField(&ref, fieldName)
	if err != nil {
		return err
	}

	field, ok := cfg.Fields[fieldName]
	if !ok || (!field.IsID && field.Index == "") {
		query := newQuery(n, q.StrictEq(fieldName, value))

		if n.tx != nil {
			err = query.query(n.tx, sink)
		} else {
			err = n.s.Bolt.View(func(tx *bolt.Tx) error {
				return query.query(tx, sink)
			})
		}

		if err != nil {
			return err
		}

		return sink.flush()
	}

	val, err := toBytes(value, n.s.codec)
	if err != nil {
		return err
	}

	return n.readTx(func(tx *bolt.Tx) error {
		return n.one(tx, bucketName, fieldName, cfg, to, val, field.IsID)
	})
}