Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GO-3964 ListRelationsByValue RPC #1552

Merged
merged 13 commits into from
Sep 24, 2024
Merged

Conversation

KirillSto
Copy link
Member

@KirillSto KirillSto commented Sep 6, 2024

https://linear.app/anytype/issue/GO-3964/provide-the-list-of-relations-on-the-layout-with-date-as-a-value

  • Introducing new RPC for listing relations that hold the value provided in request parameter. Response includes list of relation keys in alphabetical order and number of objects that have such value under particular relation
  • New method objectstore.QueryIterate allows to query records from object store and process its details using custom functor
  • Big bench of block.Service methods are drawn into new detailservice.Service
  • Unit tests on new service are added

@KirillSto KirillSto requested a review from deff7 September 6, 2024 12:44
@KirillSto KirillSto self-assigned this Sep 6, 2024
Copy link

github-actions bot commented Sep 6, 2024

Previous Coverage 47.3% of statements
New Coverage 47.9% of statements
Patch Coverage 52.5% of changed statements (243/463)

Coverage provided by /~https://github.com/seriousben/go-patch-cover-action

@@ -504,3 +504,41 @@ func (s *dsObjectStore) QueryByIDAndSubscribeForChanges(ids []string, sub databa
s.addSubscriptionIfNotExists(sub)
return
}

func (s *dsObjectStore) QueryAndProcess(q database.Query, proc func(details *types.Struct)) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QueryIterate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed!

@@ -56,3 +64,75 @@ func (s *Service) ObjectTypeRemoveRelations(ctx context.Context, objectTypeId st
return b.Apply(st)
})
}

func (s *Service) ListRelationsWithValue(spaceId string, value *types.Value) (keys []string, counters []int64, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it time for relationService?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 😌

@@ -48,3 +48,10 @@ func ExtractVirtualSourceType(id string) (model.SmartBlockType, error) {
func TimeToID(t time.Time) string {
return DatePrefix + t.Format("2006-01-02")
}

func DateIDToDayStart(id string) (time.Time, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it shouldn't be here, it's pretty specific case, put it near usage

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@KirillSto KirillSto requested a review from deff7 September 12, 2024 16:11
}

func (s *service) partitionObjectIDsBySpaceID(objectIDs []string) (map[string][]string, error) {
res := map[string][]string{}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be it can be preallocated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

return fmt.Errorf("get space: %w", err)
}
return cache.Do(s, spc.DerivedIDs().Archive, func(b smartblock.SmartBlock) error {
archive, ok := b.(collection.Collection)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe extract to separate function?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have splitted this function onto two separate ones

return fmt.Errorf("unexpected archive block type: %T", b)
}

var multiErr multierror.Error

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be combined
var (
multiErr multierror.Error.
anySucceed bool
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

if err := multiErr.ErrorOrNil(); err != nil {
log.Warn("failed to archive", zap.Error(err))
}
if anySucceed {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is seems like unnecessary check, because multiErr.ErrorOrNil() is nil for sure. So can we just return nil instead of lines 243-246?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point here is to return nil, if at least one object was processed without error.
If some objects were processed with error, than we should log it.
If all objects were processed with error, than we should return error.
So there is no issue here

if resultError != nil {
log.Warn("failed to set objects as favorite", zap.Error(resultError))
}
if anySucceed {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same comment as for isArchive function

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same situation is here

Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String(spaceId),
}}}, func(details *types.Struct) {
for key, v := range details.Fields {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename v to value or something? Because it looks like not consistent naming 🧐

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, fixed

if err != nil {
return errors.Join(fmt.Errorf("iterate: %w", err), iter.Close())
}
err = iter.Close()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call "Close" in the defer, because it may cause a connection leak

iter, err := query.Iter(s.componentCtx)
	if err != nil {
		return fmt.Errorf("find: %w", err)
	}
	defer func() {
	    err = iter.Close()
	}()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@KirillSto KirillSto merged commit 2c41e9b into main Sep 24, 2024
5 checks passed
@KirillSto KirillSto deleted the go-3964-relations-list-by-value branch September 24, 2024 20:26
@github-actions github-actions bot locked and limited conversation to collaborators Sep 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants