Skip to content

Instantly share code, notes, and snippets.

@harryalto
Last active January 10, 2022 07:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harryalto/b5509985b425f692e16d1e3e1b9a2e68 to your computer and use it in GitHub Desktop.
Save harryalto/b5509985b425f692e16d1e3e1b9a2e68 to your computer and use it in GitHub Desktop.
@Table
@Value
@Builder(toBuilder = true)
public class Child {
@Id
private int id;
private int parentId;
private String name;
private String path;
List<GrandChild> grandChildList;
}
@Repository
public interface ChildRepository extends ReactiveCrudRepository<Child, Integer> {
@Query("select id,parent_id,name,path from child ")
Flux<Child>findAll();
@Query("select id,parent_id,name,path from child where parent_id = :parent_id ")
Flux<Child> findAllByParentId(@Param("parent_id")final Integer parentId);
}
@Component
@Slf4j
public class FamilyService {
@Autowired
private ParentRepository parentRepository;
@Autowired
private ChildRepository childRepository;
@Autowired
private GrandChildRepository grandChildRepository;
public Flux<Parent> getAllParents() {
return parentRepository.findAll();
}
public Mono<List<Child>> getAllChildsList(final Integer parentId) {
return childRepository.findAllByParentId(parentId).collectList();
}
public Flux<GrandChild> getGrandKids(final Integer childId) {
return grandChildRepository.findAllByChildId(childId);
}
public Mono<List<GrandChild>> getGrandKidsList(final Integer childId) {
return grandChildRepository.findAllByChildId(childId).collectList();
}
private Mono<List<Child>> getChildsWithKids(final List<Child> childList) {
return Flux.fromIterable(childList).flatMap(child ->
Mono.zip(Mono.just(child), getGrandKidsList(child.getId()))
.map(tuple2 -> tuple2.getT1().toBuilder().grandChildList(tuple2.getT2()).build())
).collectList();
}
public Flux<Parent> getFamiliesHierarchy() {
return getAllParents()
.flatMap(parent ->
getAllChildsList(parent.getId())
.flatMap(childList -> getChildsWithKids(childList))
.map(childList ->
parent.toBuilder().childList(childList).build()
)
);
}
}
@RestController
@Slf4j
public class FamilyTreeController {
@Autowired
private FamilyService familyService;
@GetMapping("/v1/families")
public Flux<Parent> viewAllParents() {
return familyService.getFamiliesHierarchy();
}
}
@Table
@Value
@Builder(toBuilder = true)
public class GrandChild {
@Id
private int id;
private int childId;
private String name;
private String path;
}
@Repository
public interface GrandChildRepository extends ReactiveCrudRepository<GrandChild, Integer> {
@Query("select id,child_id,name,path from grand_child")
Flux<GrandChild> findAll();
@Query("select id,child_id,name,path from grand_child where child_id = :child_id ")
Flux<GrandChild> findAllByChildId(@Param("child_id") final Integer childId);
}
@Table
@Value
@Builder(toBuilder = true)
public class Parent {
@Id
private int id;
private String name;
private String path;
List<Child> childList;
}
@Repository
public interface ParentRepository extends ReactiveCrudRepository<Parent, Integer> {
}
create table if not exists parent
(
id serial
constraint parent_pk
primary key,
name varchar(255) not null,
path varchar(255) not null
);
create table if not exists child
(
id serial
constraint child_pk
primary key,
parent_id integer not null
constraint fk_parent_id
references parent,
name varchar(255) not null,
path varchar(255) not null
);
create table if not exists grand_child
(
id serial
constraint grand_child_pk
primary key,
child_id integer not null
constraint fk_child_id
references child,
name varchar(255) not null,
path varchar(255)
);
-- Sample Data --
INSERT INTO public.parent(id, name, path) VALUES (1,'William Rockefeller Sr.','1');
INSERT INTO public.parent(id, name, path) VALUES (2,'George H. W. Bush','2');
INSERT INTO public.parent(id, name, path) VALUES (3,'Obama','3');
insert into public.child(id, parent_id, name, path) VALUES (1,1,'John D. Rockefeller','1.1')
insert into public.child(id, parent_id, name, path) VALUES (2,1,'William Rockefeller','1.2');
insert into public.child(id, parent_id, name, path) VALUES (3,1,'Frank Rockefeller','1.3');
insert into public.child(id, parent_id, name, path) VALUES (4,2,'George W Bush','2.1');
insert into public.child(id, parent_id, name, path) VALUES (5,2,'Jeb Bush','2.2');
insert into public.child(id, parent_id, name, path) VALUES (6,3,'Malia Obama','3.1');
insert into public.child(id, parent_id, name, path) VALUES (7,3,'Sasha Obama','3.2');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (1, 1, 'Elizabeth', '1.1.1');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (2, 1, 'ALta', '1.1.2');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (3, 1, 'Edith', '1.1.3');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (4, 2, 'Godfrey', '1.2.1');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (5, 2, 'James', '1.2.2');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (6, 2, 'Isabel', '1.2.3');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (7, 4, 'Barbara Bush', '2.1.1');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (8, 4, 'Jenna Bush', '2.1.2');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (9, 5, 'Noel Bush', '2.2.1');
INSERT INTO public.grand_child (id, child_id, name, path) VALUES (10, 5, 'Jebby Bush', '2.2.2');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment