Last active
January 10, 2022 07:07
-
-
Save harryalto/b5509985b425f692e16d1e3e1b9a2e68 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Table | |
@Value | |
@Builder(toBuilder = true) | |
public class Child { | |
@Id | |
private int id; | |
private int parentId; | |
private String name; | |
private String path; | |
List<GrandChild> grandChildList; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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() | |
) | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RestController | |
@Slf4j | |
public class FamilyTreeController { | |
@Autowired | |
private FamilyService familyService; | |
@GetMapping("/v1/families") | |
public Flux<Parent> viewAllParents() { | |
return familyService.getFamiliesHierarchy(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Table | |
@Value | |
@Builder(toBuilder = true) | |
public class GrandChild { | |
@Id | |
private int id; | |
private int childId; | |
private String name; | |
private String path; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Table | |
@Value | |
@Builder(toBuilder = true) | |
public class Parent { | |
@Id | |
private int id; | |
private String name; | |
private String path; | |
List<Child> childList; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Repository | |
public interface ParentRepository extends ReactiveCrudRepository<Parent, Integer> { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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