2

I'm attempting to use reactive programming (RxGroovy) to create objects using a builder pattern, where property values come from database queries. I'm looking first of all, for how to do it, and second of all, thoughts on whether or not it is a good idea.

The objects I'm trying to create are of this type:

class Foo {
    final String name;
    final Long[] relatedIds;

    Foo(String name, Long[] relatedIds) {
        this.name = name;
        this.relatedIds = relatedIds;
    }
}

And the builder:

class FooBuilder {
    String name;
    LinkedList<Long> relatedIds;

    {
        relatedIds = new LinkedList<>();
    }

    FooBuilder name(String name) {
        this.name = name;
        return this;
    }

    FooBuilder relatedId(Long id) {
        this.relatedIds.add(id);
        return this;
    }

    Foo build() {
        return new Foo(this.name, this.relatedIds.toArray());
    }

}

I have two queries, one that returns the names of all the Foo objects, and then a separate query that I run once for each Foo object to get all the related IDs.

I already have a method (call it queryAsObservable) to do a query and get an Observable that emits each row of the result set. So setting the name would look something like this:

Observable<FooBuilder> buidlersWithNameSet = queryAsObservable(queryAllFoos)
.map { return new FooBuilder().name(it.name); }

And given a FooBuilder, I could set the relatedIds like this:

final FooBuilder builder;
queryAsObservable(queryRelatedIds, builder.name)
    .subscribe { builder.relatedId(it.id); }

My problem is how to tie the two together? How do I create the observable to set the related IDs, as shown, for each FooBuilder emitted by the first observable? In the end, I just need to get all of the FooBuilder objects, with the name and relatedIds properties all set.

Note about JOINs

I know I can get the related Ids and the name all in one query with a JOIN. My thought was that I can use lots of smaller queries running in parallel and uses the Observable streams to do the work for each result as the result becomes available, instead of waiting for all the results to come in and then building the objects serially. I'm open to ideas on why that's a good or bad idea.

brianmearns
  • 9,581
  • 10
  • 52
  • 79

1 Answers1

2

To combine the Observables use flatMap(). Not sure of the Groovy syntax but I'll take a shot. Starting with your builderWithNameSet:

Observable<FooBuilder> completeBuilder =
    buildersWithNameSet
        .flatMap { builder ->
            return queryAsObservable(queryRelatedIds, builder.name)
                .map { builder.relatedId(it.id); }
        }
kjones
  • 5,783
  • 2
  • 27
  • 27