From 2b08c24ce1911d4c85a3895490c4ee5490034af9 Mon Sep 17 00:00:00 2001 From: Luke Sikina Date: Fri, 23 Aug 2024 12:41:40 -0400 Subject: [PATCH] [ALS-7137] - Add full_name to facet list, details --- .../dbmi/avillach/dictionary/facet/Facet.java | 4 +- .../facet/FacetCategoryExtractor.java | 2 +- .../dictionary/facet/FacetMapper.java | 1 + .../dictionary/facet/FacetRepository.java | 8 +++- .../concept/ConceptControllerTest.java | 2 +- .../concept/ConceptRepositoryTest.java | 20 ++++---- .../dictionary/concept/model/ConceptTest.java | 2 +- .../dictionary/facet/FacetControllerTest.java | 10 ++-- .../dictionary/facet/FacetRepositoryTest.java | 47 ++++++------------- .../dictionary/facet/FacetServiceTest.java | 4 +- .../ConceptFilterQueryGeneratorTest.java | 8 ++-- src/test/resources/seed.sql | 3 ++ 12 files changed, 49 insertions(+), 62 deletions(-) diff --git a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/Facet.java b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/Facet.java index b3d71fc..1dd7ac4 100644 --- a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/Facet.java +++ b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/Facet.java @@ -6,11 +6,11 @@ import java.util.Map; public record Facet( - String name, String display, String description, + String name, String display, String description, String fullName, @Nullable Integer count, @Nullable List children, String category, @Nullable Map meta ) { public Facet(Facet core, Map meta) { - this(core.name(), core.display(), core.description(), core.count(), core.children(), core.category(), meta); + this(core.name(), core.display(), core.description(), core.fullName(), core.count(), core.children(), core.category(), meta); } } diff --git a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetCategoryExtractor.java b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetCategoryExtractor.java index 1379075..7fc3b49 100644 --- a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetCategoryExtractor.java +++ b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetCategoryExtractor.java @@ -20,7 +20,7 @@ public List extractData(ResultSet rs) throws SQLException, DataAc String category = rs.getString("category_name"); Facet facet = new Facet( rs.getString("name"), rs.getString("display"), - rs.getString("description"), rs.getInt("facet_count"), + rs.getString("description"), rs.getString("full_name"), rs.getInt("facet_count"), null, category, null ); FacetCategory facetCategory = new FacetCategory( diff --git a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetMapper.java b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetMapper.java index 436280b..7b52aa0 100644 --- a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetMapper.java +++ b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetMapper.java @@ -15,6 +15,7 @@ public Facet mapRow(ResultSet rs, int rowNum) throws SQLException { rs.getString("name"), rs.getString("display"), rs.getString("description"), + rs.getString("full_name"), null, null, rs.getString("category"), diff --git a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepository.java b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepository.java index 7283805..c0335a5 100644 --- a/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepository.java +++ b/src/main/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepository.java @@ -43,12 +43,14 @@ WITH facet_counts_q AS ( facet_counts_q.facet_count AS facet_count, facet_category.display as category_display, facet_category.description as category_description, - facet.name, facet.display, facet.description + facet.name, facet.display, facet.description, + facet_meta_full_name.value AS full_name FROM facet LEFT JOIN facet_counts_q ON facet.facet_id = facet_counts_q.facet_id LEFT JOIN facet_category ON facet_category.facet_category_id = facet.facet_category_id LEFT JOIN facet as parent_facet ON facet.parent_id = parent_facet.facet_id + LEFT JOIN facet_meta AS facet_meta_full_name ON facet.facet_id = facet_meta_full_name.facet_id AND facet_meta_full_name.KEY = 'full_name' """.formatted(innerSQL); @@ -59,10 +61,12 @@ public Optional getFacet(String facetCategory, String facet) { String sql = """ SELECT facet_category.name AS category, - facet.name, facet.display, facet.description + facet.name, facet.display, facet.description, + facet_meta_full_name.value AS full_name FROM facet LEFT JOIN facet_category ON facet_category.facet_category_id = facet.facet_category_id + LEFT JOIN facet_meta AS facet_meta_full_name ON facet.facet_id = facet_meta_full_name.facet_id AND facet_meta_full_name.KEY = 'full_name' WHERE facet.name = :facetName AND facet_category.name = :facetCategory diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptControllerTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptControllerTest.java index 878fe3f..28b3aba 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptControllerTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptControllerTest.java @@ -37,7 +37,7 @@ void shouldListConcepts() { new ContinuousConcept("/foo//baz", "baz", "Baz", "my_dataset", "foo!", 0, 100, Map.of()) ); Filter filter = new Filter( - List.of(new Facet("questionare", "Questionare", "?", 1, null, "category", null)), + List.of(new Facet("questionare", "Questionare", "?", "Questionare", 1, null, "category", null)), "foo" ); Mockito.when(conceptService.listConcepts(filter, Pageable.ofSize(10).withPage(1))) diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptRepositoryTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptRepositoryTest.java index 8e1494b..d087486 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptRepositoryTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/ConceptRepositoryTest.java @@ -76,15 +76,11 @@ void shouldListNextTwoConcepts() { @Test void shouldFilterConceptsByFacet() { List actual = - subject.getConcepts(new Filter(List.of(new Facet("bch", "", "", 1, null, "site", null)), ""), Pageable.unpaged()); + subject.getConcepts(new Filter(List.of(new Facet("phs000007", "", "", "", 1, null, "study_ids_dataset_ids", null)), ""), Pageable.unpaged()); List expected = List.of( - new CategoricalConcept("\\\\\\\\A\\\\\\\\", "a", "A", "invalid.invalid", null, List.of("0", "1"), null, null), - new CategoricalConcept("\\\\\\\\A\\\\\\\\1\\\\\\\\", "1", "1", "invalid.invalid", null, List.of("X", "Z"), null, null), - new CategoricalConcept("\\\\\\\\A\\\\\\\\0\\\\\\\\", "0", "0", "invalid.invalid", null, List.of("X", "Y"), null, null), - new CategoricalConcept("\\\\\\\\A\\\\\\\\0\\\\\\\\X\\\\\\\\", "x", "X", "invalid.invalid", null, List.of("foo", "bar"), null, null), - new CategoricalConcept("\\\\\\\\A\\\\\\\\0\\\\\\\\Y\\\\\\\\", "y", "Y", "invalid.invalid", null, List.of("foo", "bar", "baz"), null, null), - new ContinuousConcept("\\\\\\\\A\\\\\\\\1\\\\\\\\X\\\\\\\\", "x", "X", "invalid.invalid", null, 0, 0, null), - new ContinuousConcept("\\\\\\\\A\\\\\\\\1\\\\\\\\Z\\\\\\\\", "z", "Z", "invalid.invalid", null, 0, 0, null) + new ContinuousConcept("\\phs000007\\pht000022\\phv00004260\\FM219\\", "phv00004260", "FM219", "phs000007", "# 12 OZ CUPS OF CAFFEINATED COLA / DAY", 0, 1, null), + new ContinuousConcept("\\phs000007\\pht000021\\phv00003844\\FL200\\", "phv00003844", "FL200", "phs000007", "# 12 OZ CUPS OF CAFFEINATED COLA / DAY", 0, 3, null), + new ContinuousConcept("\\phs000007\\pht000033\\phv00008849\\D080\\", "phv00008849", "D080", "phs000007", "# 12 OZ CUPS OF CAFFEINATED COLA/DAY", 0, 5, null) ); Assertions.assertEquals(expected, actual); @@ -105,7 +101,7 @@ void shouldFilterBySearch() { @Test void shouldFilterByBothSearchAndFacet() { List actual = - subject.getConcepts(new Filter(List.of(new Facet("phs002715", "", "", 1, null, "study_ids_dataset_ids", null)), "phs002715"), Pageable.unpaged()); + subject.getConcepts(new Filter(List.of(new Facet("phs002715", "", "", "", 1, null, "study_ids_dataset_ids", null)), "phs002715"), Pageable.unpaged()); List expected = List.of( new CategoricalConcept("\\phs002715\\age\\", "AGE_CATEGORY", "age", "phs002715", "Participant's age (category)", List.of("21"), null, null), new CategoricalConcept("\\phs002715\\nsrr_ever_smoker\\", "nsrr_ever_smoker", "nsrr_ever_smoker", "phs002715", "Smoker status", List.of("yes"), null, null) @@ -123,15 +119,15 @@ void shouldGetCount() { @Test void shouldGetCountWithFilter() { - Long actual = subject.countConcepts(new Filter(List.of(new Facet("phs002715", "", "", 1, null, "study_ids_dataset_ids", null)), "")); + Long actual = subject.countConcepts(new Filter(List.of(new Facet("phs002715", "", "", "", 1, null, "study_ids_dataset_ids", null)), "")); Assertions.assertEquals(2L, actual); } @Test void shouldGetDetailForConcept() { ContinuousConcept expected = - new ContinuousConcept("\\\\\\\\B\\\\\\\\2\\\\\\\\Z\\\\\\\\", "z", "Z", "invalid.invalid", null, 0, 0, null); - Optional actual = subject.getConcept("AGE_CATEGORY", "\\phs002715\\age\\"); + new ContinuousConcept("\\phs000007\\pht000033\\phv00008849\\D080\\", "phv00008849", "D080", "phs000007", "# 12 OZ CUPS OF CAFFEINATED COLA/DAY", 0, 5, null); + Optional actual = subject.getConcept("phs000007", "\\phs000007\\pht000033\\phv00008849\\D080\\"); Assertions.assertEquals(Optional.of(expected), actual); } diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/model/ConceptTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/model/ConceptTest.java index c48b501..ba813ad 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/model/ConceptTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/concept/model/ConceptTest.java @@ -75,7 +75,7 @@ void shouldIncludeTypeInList() throws JsonProcessingException { ); String actual = new ObjectMapper().writeValueAsString(concepts); - String expected = ""; + String expected = "[{\"conceptPath\":\"/foo//baz\",\"name\":\"baz\",\"display\":\"Baz\",\"dataset\":\"study_a\",\"description\":null,\"min\":0,\"max\":1,\"meta\":{},\"type\":\"Continuous\"},{\"conceptPath\":\"/foo//bar\",\"name\":\"bar\",\"display\":\"Bar\",\"dataset\":\"study_a\",\"description\":null,\"values\":[\"a\",\"b\"],\"children\":null,\"meta\":{},\"type\":\"Categorical\"}]"; Assertions.assertEquals(expected, actual); } diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetControllerTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetControllerTest.java index 78cdda7..1be266f 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetControllerTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetControllerTest.java @@ -24,13 +24,13 @@ class FacetControllerTest { @Test void shouldListFacets() { - Facet questionnaire = new Facet("questionnaire", "Questionnaire", "questionnaire", 1, null, "category", null); - Facet examination = new Facet("examination", "Examination", "examination", 1, null, "category", null); + Facet questionnaire = new Facet("questionnaire", "Questionnaire", "questionnaire", "Questionnaire", 1, null, "category", null); + Facet examination = new Facet("examination", "Examination", "examination", "Examination", 1, null, "category", null); FacetCategory expected = new FacetCategory("category", "Category", "categories!", List.of(questionnaire, examination)); Filter filter = new Filter( - List.of(new Facet("questionare", "Questionare", "?", 1, null, "category", null)), + List.of(new Facet("questionare", "Questionare", "?", "Examination", 1, null, "category", null)), "foo" ); Mockito.when(facetService.getFacets(filter)) @@ -44,7 +44,7 @@ void shouldListFacets() { @Test void shouldGetFacetDetails() { - Facet expected = new Facet("questionnaire", "Questionnaire", "questionnaire", 1, null, "category", null); + Facet expected = new Facet("questionnaire", "Questionnaire", "questionnaire", "Questionare", 1, null, "category", null); Mockito.when(facetService.facetDetails("category", "questionnaire")) .thenReturn(Optional.of(expected)); @@ -56,7 +56,7 @@ void shouldGetFacetDetails() { @Test void shouldNotGetFacetDetails() { - Facet questionnaire = new Facet("questionnaire", "Questionnaire", "questionnaire", 1, null, "category", null); + Facet questionnaire = new Facet("questionnaire", "Questionnaire", "questionnaire", "Questionare", 1, null, "category", null); Mockito.when(facetService.facetDetails("category", "questionnaire")) .thenReturn(Optional.of(questionnaire)); diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepositoryTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepositoryTest.java index ed860bd..5b77d8e 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepositoryTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetRepositoryTest.java @@ -46,25 +46,8 @@ void shouldGetAllFacets() { Filter filter = new Filter(List.of(), ""); List actual = subject.getFacets(filter); - List expected = List.of( - new FacetCategory( - "site", "Site", "Filter variables by site", - List.of( - new Facet("bch", "BCH", "Boston Childrens Hospital", 7, null, "site", null), - new Facet("narnia", "Narnia", "Narnia", 8, null, "site", null) - ) - ), - new FacetCategory( - "data_source", "Data Source", "What does this data relate to (image, questionnaire...)", - List.of( - new Facet("imaging", "Imaging", "Data derived from an image", 5, null, "data_source", null), - new Facet("questionnaire", "questionnaire", "Data derived from a questionnaire", 2, null, "data_source", null), - new Facet("lab_test", "Lab Test", "Data derived from a lab test", 2, null, "data_source", null) - ) - ) - ); - Assertions.assertEquals(expected, actual); + Assertions.assertEquals(2, actual.size()); } @Test @@ -76,15 +59,15 @@ void shouldFilterFacetsBySearch() { new FacetCategory( "site", "Site", "Filter variables by site", List.of( - new Facet("bch", "BCH", "Boston Childrens Hospital", 1, null, "category", null) + new Facet("bch", "BCH", "Boston Childrens Hospital", "Boston Childrens Hospital", 1, null, "category", null) ) ), new FacetCategory( "data_source", "Data Source", "What does this data relate to (image, questionnaire...)", List.of( - new Facet("imaging", "Imaging", "Data derived from an image", 1, null, "data_source", null), - new Facet("questionnaire", "questionnaire", "Data derived from a questionnaire", 1, null, "data_source", null), - new Facet("lab_test", "Lab Test", "Data derived from a lab test", 1, null, "data_source", null) + new Facet("imaging", "Imaging", "Data derived from an image", "Data derived from an image", 1, null, "data_source", null), + new Facet("questionnaire", "questionnaire", "Data derived from a questionnaire", "Data derived from a questionnaire", 1, null, "data_source", null), + new Facet("lab_test", "Lab Test", "Data derived from a lab test", "Data derived from a lab test", 1, null, "data_source", null) ) ) ); @@ -92,23 +75,23 @@ void shouldFilterFacetsBySearch() { @Test void shouldFilterFacetsByFacet() { - Filter filter = new Filter(List.of(new Facet("bch", "BCH", "Boston Childrens Hospital", 1, null, "category", null)), ""); + Filter filter = new Filter(List.of(new Facet("bch", "BCH", "Boston Childrens Hospital", "Boston Childrens Hospital", 1, null, "category", null)), ""); List actual = subject.getFacets(filter); List expected = List.of( new FacetCategory( "site", "Site", "Filter variables by site", List.of( - new Facet("bch", "BCH", "Boston Childrens Hospital", 1, null, "category", null), - new Facet("narnia", "Narnia", "Narnia", 1, null, "category", null) + new Facet("bch", "BCH", "Boston Childrens Hospital", "Boston Childrens Hospital", 1, null, "category", null), + new Facet("narnia", "Narnia", "Narnia", "Narnia", 1, null, "category", null) ) ), new FacetCategory( "data_source", "Data Source", "What does this data relate to (image, questionnaire...)", List.of( - new Facet("imaging", "Imaging", "Data derived from an image", 1, null, "data_source", null), - new Facet("questionnaire", "questionnaire", "Data derived from a questionnaire", 1, null, "data_source", null), - new Facet("lab_test", "Lab Test", "Data derived from a lab test", 1, null, "data_source", null) + new Facet("imaging", "Imaging", "Data derived from an image", "Data derived from an image", 1, null, "data_source", null), + new Facet("questionnaire", "questionnaire", "Data derived from a questionnaire", "Data derived from a questionnaire", 1, null, "data_source", null), + new Facet("lab_test", "Lab Test", "Data derived from a lab test", "Data derived from a lab test", 1, null, "data_source", null) ) ) ); @@ -116,8 +99,8 @@ void shouldFilterFacetsByFacet() { @Test void shouldGetFacet() { - Optional actual = subject.getFacet("site", "bch"); - Optional expected = Optional.of(new Facet("bch", "BCH", "Boston Childrens Hospital", null, null, "site", null)); + Optional actual = subject.getFacet("study_ids_dataset_ids", "phs000007"); + Optional expected = Optional.of(new Facet("phs000007", "FHS", null, "Framingham Heart Study", null, null, "study_ids_dataset_ids", null)); Assertions.assertEquals(expected, actual); } @@ -132,8 +115,8 @@ void shouldNotGetFacetThatDNE() { @Test void shouldGetFacetMeta() { - Map actual = subject.getFacetMeta("site", "bch"); - Map expected = Map.of("spicy", "TRUE"); + Map actual = subject.getFacetMeta("study_ids_dataset_ids", "phs000007"); + Map expected = Map.of("full_name", "Framingham Heart Study"); Assertions.assertEquals(expected, actual); } diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetServiceTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetServiceTest.java index 61f2711..cb5269f 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetServiceTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/facet/FacetServiceTest.java @@ -24,7 +24,7 @@ class FacetServiceTest { void shouldGetFacets() { Filter filter = new Filter(List.of(), ""); List expected = - List.of(new FacetCategory("n", "d", "", List.of(new Facet("f_n", "f_d", "", 1, null, "n", null)))); + List.of(new FacetCategory("n", "d", "", List.of(new Facet("f_n", "f_d", "", "", 1, null, "n", null)))); Mockito.when(repository.getFacets(filter)) .thenReturn(expected); @@ -35,7 +35,7 @@ void shouldGetFacets() { @Test void shouldGetFacet() { - Optional expected = Optional.of(new Facet("n", "d", "", null, null, "c", Map.of("foo", "bar"))); + Optional expected = Optional.of(new Facet("n", "d", "", "", null, null, "c", Map.of("foo", "bar"))); Mockito.when(repository.getFacet("c", "n")) .thenReturn(expected); Mockito.when(repository.getFacetMeta("c", "n")) diff --git a/src/test/java/edu/harvard/dbmi/avillach/dictionary/filter/ConceptFilterQueryGeneratorTest.java b/src/test/java/edu/harvard/dbmi/avillach/dictionary/filter/ConceptFilterQueryGeneratorTest.java index de96c72..cba90e7 100644 --- a/src/test/java/edu/harvard/dbmi/avillach/dictionary/filter/ConceptFilterQueryGeneratorTest.java +++ b/src/test/java/edu/harvard/dbmi/avillach/dictionary/filter/ConceptFilterQueryGeneratorTest.java @@ -46,7 +46,7 @@ static void mySQLProperties(DynamicPropertyRegistry registry) { @Test void shouldGenerateForFacetAndSearchNoMatch() { - Filter f = new Filter(List.of(new Facet("phs000007", "FHS", "", null, null, "study_ids_dataset_ids", null)), "smoke"); + Filter f = new Filter(List.of(new Facet("phs000007", "FHS", "", "", null, null, "study_ids_dataset_ids", null)), "smoke"); QueryParamPair pair = subject.generateFilterQuery(f, Pageable.unpaged()); List actual = template.queryForList(pair.query(), pair.params(), Integer.class); @@ -57,7 +57,7 @@ void shouldGenerateForFacetAndSearchNoMatch() { @Test void shouldGenerateForFHSFacet() { - Filter f = new Filter(List.of(new Facet("phs000007", "FHS", "", null, null, "study_ids_dataset_ids", null)), ""); + Filter f = new Filter(List.of(new Facet("phs000007", "FHS", "", "", null, null, "study_ids_dataset_ids", null)), ""); QueryParamPair pair = subject.generateFilterQuery(f, Pageable.unpaged()); List actual = template.queryForList(pair.query(), pair.params(), Integer.class); @@ -68,7 +68,7 @@ void shouldGenerateForFHSFacet() { @Test void shouldGenerateForFacetAndSearchMatch() { - Filter f = new Filter(List.of(new Facet("phs002715", "NSRR", "", null, null, "study_ids_dataset_ids", null)), "smoke"); + Filter f = new Filter(List.of(new Facet("phs002715", "NSRR", "", "", null, null, "study_ids_dataset_ids", null)), "smoke"); QueryParamPair pair = subject.generateFilterQuery(f, Pageable.unpaged()); List actual = template.queryForList(pair.query(), pair.params(), Integer.class); @@ -79,7 +79,7 @@ void shouldGenerateForFacetAndSearchMatch() { @Test void shouldGenerateForNSRRFacet() { - Filter f = new Filter(List.of(new Facet("phs002715", "NSRR", "", null, null, "study_ids_dataset_ids", null)), ""); + Filter f = new Filter(List.of(new Facet("phs002715", "NSRR", "", "", null, null, "study_ids_dataset_ids", null)), ""); QueryParamPair pair = subject.generateFilterQuery(f, Pageable.unpaged()); List actual = template.queryForList(pair.query(), pair.params(), Integer.class); diff --git a/src/test/resources/seed.sql b/src/test/resources/seed.sql index ab1e635..db1b91f 100644 --- a/src/test/resources/seed.sql +++ b/src/test/resources/seed.sql @@ -738,6 +738,9 @@ COPY public.facet_category_meta (facet_category_meta_id, facet_category_id, key, -- COPY public.facet_meta (facet_meta_id, facet_id, key, value) FROM stdin; +1 25 full_name National Sleep Research Resource +2 26 full_name Chronic Fatigue Syndrome +3 27 full_name Framingham Heart Study \.