From 38718320f97acb41d8a4f8b010cbb5cc9189ca9f Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Fri, 15 Jul 2016 15:38:49 +0200 Subject: [PATCH] First version for the association of one column to another. Closes #55 --- src/obidmscolumn.c | 44 +++++++++++++++++++----- src/obidmscolumn.h | 85 +++++++++++++++++++++++++++------------------- src/obiview.c | 31 +++++++++++------ src/obiview.h | 13 ++----- 4 files changed, 110 insertions(+), 63 deletions(-) diff --git a/src/obidmscolumn.c b/src/obidmscolumn.c index 9f875df..f475c73 100644 --- a/src/obidmscolumn.c +++ b/src/obidmscolumn.c @@ -527,14 +527,16 @@ size_t obi_get_platform_header_size() } -OBIDMS_column_p obi_create_column(OBIDMS_p dms, - const char* column_name, - OBIType_t data_type, - index_t nb_lines, - index_t nb_elements_per_line, - const char* elements_names, - const char* indexer_name, - const char* comments +OBIDMS_column_p obi_create_column(OBIDMS_p dms, + const char* column_name, + OBIType_t data_type, + index_t nb_lines, + index_t nb_elements_per_line, + const char* elements_names, + const char* indexer_name, + const char* associated_column_name, + obiversion_t associated_column_version, + const char* comments ) { OBIDMS_column_p new_column; @@ -750,6 +752,30 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, if (comments != NULL) strncpy(header->comments, comments, COMMENTS_MAX_LENGTH); + // Store the associated column reference if needed // TODO discuss cases + if (data_type == OBI_QUAL) + { + if (associated_column_name == NULL) + { + obidebug(1, "\nError: The name of the associated column when creating a new column is NULL"); + munmap(new_column->header, header_size); + close(column_file_descriptor); + free(new_column); + return NULL; + } + strcpy((header->associated_column).column_name, associated_column_name); + + if (associated_column_version == -1) + { + obidebug(1, "\nError: The version of the associated column when creating a new column is not defined"); + munmap(new_column->header, header_size); + close(column_file_descriptor); + free(new_column); + return NULL; + } + (header->associated_column).version = associated_column_version; + } + // If the data type is OBI_STR, OBI_SEQ or OBI_QUAL, the associated obi_indexer is opened or created if ((returned_data_type == OBI_STR) || (returned_data_type == OBI_SEQ) || (returned_data_type == OBI_QUAL)) { @@ -964,6 +990,8 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms, nb_elements_per_line, (column_to_clone->header)->elements_names, (column_to_clone->header)->indexer_name, + ((column_to_clone->header)->associated_column).column_name, + ((column_to_clone->header)->associated_column).version, (column_to_clone->header)->comments ); diff --git a/src/obidmscolumn.h b/src/obidmscolumn.h index ebc996c..ddf7f81 100644 --- a/src/obidmscolumn.h +++ b/src/obidmscolumn.h @@ -38,43 +38,56 @@ */ +/** + * @brief Structure referencing a column by its name and its version. + */ +typedef struct Column_reference { + char column_name[OBIDMS_COLUMN_MAX_NAME+1]; /**< Name of the column. + */ + obiversion_t version; /**< Version of the column. + */ +} Column_reference_t, *Column_reference_p; + + /** * @brief OBIDMS column header structure. */ typedef struct OBIDMS_column_header { - size_t header_size; /**< Size of the header in bytes. - */ - size_t data_size; /**< Size of the data in bytes. - */ - index_t line_count; /**< Number of lines of data allocated. - */ - index_t lines_used; /**< Number of lines of data used. - */ - index_t nb_elements_per_line; /**< Number of elements per line. - */ - char elements_names[ELEMENTS_NAMES_MAX+1]; /**< Names of the line elements with ';' as separator - * (should be the column name if one element per line). - */ - OBIType_t returned_data_type; /**< Type of the data that is returned when getting an - * element from the column. - */ - OBIType_t stored_data_type; /**< Type of the data that is actually stored in the data - * part of the column. - */ - time_t creation_date; /**< Date of creation of the file. - */ - obiversion_t version; /**< Version of the column. - */ - obiversion_t cloned_from; /**< Version of the column from which this column - * was cloned from (-1 if it was not created by cloning - * another column). - */ - char name[OBIDMS_COLUMN_MAX_NAME+1]; /**< The column name as a NULL terminated string. - */ - char indexer_name[INDEXER_MAX_NAME+1]; /**< If there is one, the indexer name as a NULL terminated string. - */ - char comments[COMMENTS_MAX_LENGTH+1]; /**< Comments stored as a classical zero end C string. - */ + size_t header_size; /**< Size of the header in bytes. + */ + size_t data_size; /**< Size of the data in bytes. + */ + index_t line_count; /**< Number of lines of data allocated. + */ + index_t lines_used; /**< Number of lines of data used. + */ + index_t nb_elements_per_line; /**< Number of elements per line. + */ + char elements_names[ELEMENTS_NAMES_MAX+1]; /**< Names of the line elements with ';' as separator + * (should be the column name if one element per line). + */ + OBIType_t returned_data_type; /**< Type of the data that is returned when getting an + * element from the column. + */ + OBIType_t stored_data_type; /**< Type of the data that is actually stored in the data + * part of the column. + */ + time_t creation_date; /**< Date of creation of the file. + */ + obiversion_t version; /**< Version of the column. + */ + obiversion_t cloned_from; /**< Version of the column from which this column + * was cloned from (-1 if it was not created by cloning + * another column). + */ + char name[OBIDMS_COLUMN_MAX_NAME+1]; /**< The column name as a NULL terminated string. + */ + char indexer_name[INDEXER_MAX_NAME+1]; /**< If there is one, the indexer name as a NULL terminated string. + */ + Column_reference_t associated_column; /**< If there is one, the reference to the associated column. + */ + char comments[COMMENTS_MAX_LENGTH+1]; /**< Comments stored as a classical zero end C string. + */ } OBIDMS_column_header_t, *OBIDMS_column_header_p; @@ -168,13 +181,15 @@ size_t obi_get_platform_header_size(); * @param nb_elements_per_line The number of elements per line. // TODO talk about default values * @param elements_names The names of the elements with ';' as separator. * @param indexer_name The name of the indexer if there is one associated with the column. + * @param associated_column_name The name of the associated column if there is one. + * @param associated_column_version The version of the associated column if there is one. * @param comments Optional comments associated with the column. * * @returns A pointer on the newly created column structure. * @retval NULL if an error occurred. * * @since May 2015 - * @author Eric Coissac (eric.coissac@metabarcoding.org) + * @author Celine Mercier (celine.mercier@metabarcoding.org) */ OBIDMS_column_p obi_create_column(OBIDMS_p dms, const char* column_name, @@ -183,6 +198,8 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, index_t nb_elements_per_line, const char* elements_names, const char* indexer_name, + const char* associated_column_name, + obiversion_t associated_column_version, const char* comments ); diff --git a/src/obiview.c b/src/obiview.c index 98ac2f9..491661d 100644 --- a/src/obiview.c +++ b/src/obiview.c @@ -582,7 +582,11 @@ bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error i if (qual_column == NULL) return false; - seq_column = obi_view_get_column(view, NUC_SEQUENCE_COLUMN); // TODO Get associated nuc column + seq_column = obi_view_get_column(view, ((qual_column->header)->associated_column).column_name); + //seq_column = obi_open_column(view->dms, ((qual_column->header)->associated_column).column_name, ((qual_column->header)->associated_column).version); + // TODO discuss the fact that it's opened outside of the context of the view or not + // TODO if outside of view, make function that opens a column from a column reference structure? + if (seq_column == NULL) return false; @@ -608,6 +612,9 @@ bool view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error i return false; } } + + //obi_close_column(seq_column); + return true; } @@ -714,7 +721,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl // If there is a new line selection, build it by combining it with the one from the view to clone if there is one else if (line_selection != NULL) { - view->line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL); + view->line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL, -1, NULL); if ((view->line_selection) == NULL) { obidebug(1, "\nError creating a column corresponding to a line selection"); @@ -836,7 +843,8 @@ Obiview_p obi_new_view_cloned_from_name(OBIDMS_p dms, const char* view_name, con Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p view_to_clone, index_t* line_selection, const char* comments) { - Obiview_p view; + Obiview_p view; + OBIDMS_column_p associated_nuc_column; if (view_to_clone != NULL) { // Check that the view to clone is already a NUC_SEQS view (TODO discuss possibility of transforming type of a view) @@ -857,25 +865,26 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v if (view_to_clone == NULL) { // Adding sequence column - if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, OBI_SEQ, 0, 1, NUC_SEQUENCE_COLUMN, "", "Nucleotide sequences", true) < 0) + if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, OBI_SEQ, 0, 1, NUC_SEQUENCE_COLUMN, "", NULL, -1, "Nucleotide sequences", true) < 0) { obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); return NULL; } // Adding id column - if (obi_view_add_column(view, ID_COLUMN, -1, OBI_STR, 0, 1, ID_COLUMN, "", "Ids", true) < 0) + if (obi_view_add_column(view, ID_COLUMN, -1, OBI_STR, 0, 1, ID_COLUMN, "", NULL, -1, "Ids", true) < 0) { obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); return NULL; } // Adding definition column - if (obi_view_add_column(view, DEFINITION_COLUMN, -1, OBI_STR, 0, 1, DEFINITION_COLUMN, "", "Definitions", true) < 0) + if (obi_view_add_column(view, DEFINITION_COLUMN, -1, OBI_STR, 0, 1, DEFINITION_COLUMN, "", NULL, -1, "Definitions", true) < 0) { obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); return NULL; } // Adding quality column - if (obi_view_add_column(view, QUALITY_COLUMN, -1, OBI_QUAL, 0, 1, QUALITY_COLUMN, "", "Sequence qualities", true) < 0) + associated_nuc_column = obi_view_get_column(view, NUC_SEQUENCE_COLUMN); + if (obi_view_add_column(view, QUALITY_COLUMN, -1, OBI_QUAL, 0, 1, QUALITY_COLUMN, "", (associated_nuc_column->header)->name, (associated_nuc_column->header)->version, "Sequence qualities", true) < 0) // TODO discuss automatic association { obidebug(1, "Error adding an obligatory column in a nucleotide sequences view"); return NULL; @@ -1062,6 +1071,8 @@ int obi_view_add_column(Obiview_p view, index_t nb_elements_per_line, const char* elements_names, const char* indexer_name, + const char* associated_column_name, + obiversion_t associated_column_version, const char* comments, bool create) // all infos for creation or open { @@ -1131,7 +1142,7 @@ int obi_view_add_column(Obiview_p view, // Open or create the column if (create) { // Create column - column = obi_create_column(view->dms, column_name, data_type, nb_lines, nb_elements_per_line, elements_names, indexer_name, comments); + column = obi_create_column(view->dms, column_name, data_type, nb_lines, nb_elements_per_line, elements_names, indexer_name, associated_column_name, associated_column_version, comments); } else { // Open column @@ -1241,7 +1252,7 @@ int obi_select_line(Obiview_p view, index_t line_nb) // If the column for line selection doesn't already exists, create it and store its informations if ((view->new_line_selection) == NULL) { - view->new_line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL); + view->new_line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL, -1, NULL); if ((view->new_line_selection) == NULL) { obidebug(1, "\nError creating a column corresponding to a line selection"); @@ -1276,7 +1287,7 @@ int obi_select_lines(Obiview_p view, index_t* line_nbs) // If column for line selection doesn't already exists, create it and store its informations if ((view->new_line_selection) == NULL) { - view->new_line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL); + view->new_line_selection = obi_create_column(view->dms, LINES_COLUMN_NAME, OBI_IDX, 0, 1, LINES_COLUMN_NAME, NULL, NULL, -1, NULL); if ((view->new_line_selection) == NULL) { obidebug(1, "\nError creating a column corresponding to a line selection"); diff --git a/src/obiview.h b/src/obiview.h index 04cf454..d086513 100644 --- a/src/obiview.h +++ b/src/obiview.h @@ -54,17 +54,6 @@ */ -/** - * @brief Structure referencing a column by its name and its version. - */ -typedef struct Column_reference { - char column_name[OBIDMS_COLUMN_MAX_NAME+1]; /**< Name of the column. - */ - obiversion_t version; /**< Version of the column. - */ -} Column_reference_t, *Column_reference_p; - - /** * @brief Structure for a closed view stored in the view file. * Views are identified by their name. @@ -333,6 +322,8 @@ int obi_view_add_column(Obiview_p view, index_t nb_elements_per_line, const char* elements_names, const char* indexer_name, + const char* associated_column_name, + obiversion_t associated_column_version, const char* comments, bool create);