Views: Files for unfinished views now have the extension

'.obiview_unfinished', renamed to '.obiview' when the view is finished.
This commit is contained in:
Celine Mercier
2017-02-07 17:16:09 +01:00
parent a9102620f5
commit e524041013
5 changed files with 384 additions and 214 deletions

View File

@ -690,7 +690,7 @@ cdef class OBIDMS :
cdef int i, j
cdef str column_name
view_infos_p = obi_view_map_file(self._pointer, str2bytes(view_name))
view_infos_p = obi_view_map_file(self._pointer, str2bytes(view_name), True)
view_infos_d = {}
view_infos_d["name"] = bytes2str(view_infos_p.name)
view_infos_d["comments"] = bytes2str(view_infos_p.comments)

View File

@ -68,7 +68,7 @@ cdef extern from "obiview.h" nogil:
Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const_char_p view_name, const_char_p view_to_clone_name, index_t* line_selection, const_char_p comments, bint quality_column)
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name)
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name, bint finished)
int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos)
@ -96,10 +96,6 @@ cdef extern from "obiview.h" nogil:
int obi_view_create_column_alias(Obiview_p view, const_char_p current_name, const_char_p alias)
int obi_save_view(Obiview_p view)
int obi_close_view(Obiview_p view)
int obi_save_and_close_view(Obiview_p view)

View File

@ -4,7 +4,7 @@
/**
* @file obi_align.c
* @author Celine Mercier
* @author Celine Mercier (celine.mercier@metabarcoding.org)
* @date May 4th 2016
* @brief Functions handling LCS sequence alignments.
*/
@ -31,10 +31,6 @@
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
// TODO
// use openMP pragmas
/**************************************************************************
*
* D E C L A R A T I O N O F T H E P R I V A T E F U N C T I O N S
@ -618,12 +614,12 @@ int obi_lcs_align_one_column(OBIDMS_p dms, const char* seq_view_name, const char
}
// Close views
if (obi_close_view(seq_view) < 0)
if (obi_save_and_close_view(seq_view) < 0)
{
obidebug(1, "\nError closing the input view after aligning");
return -1;
}
if (obi_close_view(output_view) < 0)
if (obi_save_and_close_view(output_view) < 0)
{
obidebug(1, "\nError closing the output view after aligning");
return -1;
@ -963,19 +959,19 @@ int obi_lcs_align_two_columns(OBIDMS_p dms,
// Close views
if (seq2_view != seq1_view)
{
if (obi_close_view(seq2_view) < 0)
if (obi_save_and_close_view(seq2_view) < 0)
{
obidebug(1, "\nError closing the second input view after aligning");
return -1;
}
}
if (obi_close_view(seq1_view) < 0)
if (obi_save_and_close_view(seq1_view) < 0)
{
obidebug(1, "\nError closing the first input view after aligning");
return -1;
}
if (obi_close_view(output_view) < 0)
if (obi_save_and_close_view(output_view) < 0)
{
obidebug(1, "\nError closing the output view after aligning");
return -1;

View File

@ -47,7 +47,7 @@
/**
* Internal function building the file name where the informations about an obiview are stored.
* Internal function building the file name where the informations about a finished, read-only obiview are stored.
*
* @warning The returned pointer has to be freed by the caller.
*
@ -63,7 +63,23 @@ static char* build_obiview_file_name(const char* view_name);
/**
* Internal function checking if a view with a given name already exists in a DMS.
* Internal function building the file name where the informations about an unfinished, writable obiview are stored.
*
* @warning The returned pointer has to be freed by the caller.
*
* @param view_name The name of the view.
*
* @returns A pointer to the file name.
* @retval NULL if an error occurred.
*
* @since February 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static char* build_unfinished_obiview_file_name(const char* view_name);
/**
* Internal function checking if a view (either finished or unfinished) with a given name already exists in a DMS.
*
* @param dms The DMS.
* @param view_name The name of the view.
@ -73,7 +89,7 @@ static char* build_obiview_file_name(const char* view_name);
* @since September 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
bool view_exists(OBIDMS_p dms, const char* view_name);
static bool view_exists(OBIDMS_p dms, const char* view_name);
/**
@ -84,7 +100,7 @@ bool view_exists(OBIDMS_p dms, const char* view_name);
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
size_t get_platform_view_file_size();
static size_t get_platform_view_file_size();
/**
@ -99,7 +115,7 @@ size_t get_platform_view_file_size();
* @since August 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int enlarge_view_file(Obiview_p view, size_t new_size);
static int enlarge_view_file(Obiview_p view, size_t new_size);
/**
@ -117,7 +133,7 @@ int enlarge_view_file(Obiview_p view, size_t new_size);
* @since August 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int write_comments_to_view_file(Obiview_p view, const char* comments);
static int write_comments_to_view_file(Obiview_p view, const char* comments);
/**
@ -134,7 +150,7 @@ int write_comments_to_view_file(Obiview_p view, const char* comments);
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int create_obiview_file(OBIDMS_p dms, const char* view_name);
static int create_obiview_file(OBIDMS_p dms, const char* view_name);
/**
@ -156,7 +172,7 @@ int create_obiview_file(OBIDMS_p dms, const char* view_name);
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
void update_column_refs(Obiview_p view);
static void update_column_refs(Obiview_p view);
/**
@ -175,7 +191,7 @@ void update_column_refs(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int create_column_dict(Obiview_p view);
static int create_column_dict(Obiview_p view);
/**
@ -194,7 +210,7 @@ int create_column_dict(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int update_column_dict(Obiview_p view);
static int update_column_dict(Obiview_p view);
/**
@ -219,7 +235,7 @@ int update_column_dict(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int update_column_refs_and_dict(Obiview_p view);
static int update_column_refs_and_dict(Obiview_p view);
/**
@ -239,7 +255,7 @@ int update_column_refs_and_dict(Obiview_p view);
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int update_lines(Obiview_p view, index_t line_count);
static int update_lines(Obiview_p view, index_t line_count);
/**
@ -257,7 +273,71 @@ int update_lines(Obiview_p view, index_t line_count);
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name);
static OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name);
/**
* @brief Saves a view, updating its informations in the view file.
*
* @warning The view must be writable.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static int save_view(Obiview_p view);
/**
* @brief Rename a view file once the view is finished, replacing the '*.obiview_unfinished' extension with '*.obiview'.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since February 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static int rename_finished_view(Obiview_p view);
/**
* @brief Finishes a view: check the predicates, save all the informations, rename the view file.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since February 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static int finish_view(Obiview_p view);
/**
* @brief Closes an opened view.
*
* @warning Doesn't save the view.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @see obi_save_and_close_view()
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static int close_view(Obiview_p view);
/**
@ -276,7 +356,7 @@ OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name);
* @since April 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, index_t* line_nb_p);
static int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, index_t* line_nb_p);
/**
@ -294,7 +374,7 @@ int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, i
* @since April 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p);
static int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p);
/****** PREDICATE FUNCTIONS *******/
@ -313,7 +393,7 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_has_nuc_sequence_column(Obiview_p view);
static char* view_has_nuc_sequence_column(Obiview_p view);
/**
@ -330,7 +410,7 @@ char* view_has_nuc_sequence_column(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_has_quality_column(Obiview_p view);
static char* view_has_quality_column(Obiview_p view);
/**
@ -347,7 +427,7 @@ char* view_has_quality_column(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_has_id_column(Obiview_p view);
static char* view_has_id_column(Obiview_p view);
/**
@ -364,7 +444,7 @@ char* view_has_id_column(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_has_definition_column(Obiview_p view);
static char* view_has_definition_column(Obiview_p view);
/**
@ -381,7 +461,7 @@ char* view_has_definition_column(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_check_qual_match_seqs(Obiview_p view);
static char* view_check_qual_match_seqs(Obiview_p view);
/**
@ -396,7 +476,7 @@ char* view_check_qual_match_seqs(Obiview_p view);
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view));
static char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view));
/**
@ -410,7 +490,7 @@ char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obivi
* @since July 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* view_check_all_predicates(Obiview_p view);
static char* view_check_all_predicates(Obiview_p view);
/************************************************************************
@ -443,11 +523,35 @@ static char* build_obiview_file_name(const char* view_name)
}
bool view_exists(OBIDMS_p dms, const char* view_name)
static char* build_unfinished_obiview_file_name(const char* view_name)
{
char* file_name;
// Build file name
file_name = (char*) malloc((strlen(view_name) + 19 + 1)*sizeof(char));
if (file_name == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for a view file name");
return NULL;
}
if (sprintf(file_name, "%s.obiview_unfinished", view_name) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nProblem building an unfinished obiview file name");
return NULL;
}
return file_name;
}
static bool view_exists(OBIDMS_p dms, const char* view_name)
{
struct dirent* dp;
char* file_name;
// Check finished views
// Create file name
file_name = build_obiview_file_name(view_name);
if (file_name == NULL)
@ -458,13 +562,38 @@ bool view_exists(OBIDMS_p dms, const char* view_name)
if ((dp->d_name)[0] == '.')
continue;
if (strcmp(dp->d_name, file_name) == 0)
{
free(file_name);
return true;
}
}
free(file_name);
// Check unfinished views
// Create file name
file_name = build_unfinished_obiview_file_name(view_name);
if (file_name == NULL)
return -1;
while ((dp = readdir(dms->view_directory)) != NULL)
{
if ((dp->d_name)[0] == '.')
continue;
if (strcmp(dp->d_name, file_name) == 0)
{
free(file_name);
return true;
}
}
free(file_name);
return false;
}
size_t get_platform_view_file_size()
static size_t get_platform_view_file_size()
{
size_t obiview_size;
size_t rounded_obiview_size;
@ -480,7 +609,7 @@ size_t get_platform_view_file_size()
}
int enlarge_view_file(Obiview_p view, size_t new_size)
static int enlarge_view_file(Obiview_p view, size_t new_size)
{
int obiview_file_descriptor;
double multiple;
@ -488,7 +617,7 @@ int enlarge_view_file(Obiview_p view, size_t new_size)
char* file_name;
// Create file name
file_name = build_obiview_file_name((view->infos)->name);
file_name = build_unfinished_obiview_file_name((view->infos)->name);
if (file_name == NULL)
return -1;
@ -556,7 +685,7 @@ int enlarge_view_file(Obiview_p view, size_t new_size)
}
int write_comments_to_view_file(Obiview_p view, const char* comments)
static int write_comments_to_view_file(Obiview_p view, const char* comments)
{
size_t new_size;
@ -580,14 +709,14 @@ int write_comments_to_view_file(Obiview_p view, const char* comments)
}
int create_obiview_file(OBIDMS_p dms, const char* view_name)
static int create_obiview_file(OBIDMS_p dms, const char* view_name)
{
char* file_name;
int obiview_file_descriptor;
size_t file_size;
// Create file name
file_name = build_obiview_file_name(view_name);
file_name = build_unfinished_obiview_file_name(view_name);
if (file_name == NULL)
return -1;
@ -634,7 +763,7 @@ int create_obiview_file(OBIDMS_p dms, const char* view_name)
}
void update_column_refs(Obiview_p view)
static void update_column_refs(Obiview_p view)
{
int i;
@ -646,7 +775,7 @@ void update_column_refs(Obiview_p view)
}
int create_column_dict(Obiview_p view)
static int create_column_dict(Obiview_p view)
{
int i;
@ -681,7 +810,7 @@ int create_column_dict(Obiview_p view)
}
int update_column_dict(Obiview_p view)
static int update_column_dict(Obiview_p view)
{
// Re-initialize the dictionary to rebuild it from scratch
ht_free(view->column_dict);
@ -693,14 +822,14 @@ int update_column_dict(Obiview_p view)
}
int update_column_refs_and_dict(Obiview_p view)
static int update_column_refs_and_dict(Obiview_p view)
{
update_column_refs(view);
return update_column_dict(view);
}
int update_lines(Obiview_p view, index_t line_count)
static int update_lines(Obiview_p view, index_t line_count)
{
int i;
@ -739,7 +868,7 @@ int update_lines(Obiview_p view, index_t line_count)
}
OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name)
static OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name)
{
int i;
OBIDMS_column_p column = NULL;
@ -799,7 +928,161 @@ OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name)
}
int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, index_t* line_nb_p)
static int save_view(Obiview_p view)
{
// Check that the view is not read-only
if (view->read_only)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError trying to save a read-only view");
return -1;
}
// Store reference for the line selection associated with that view if there is one
if (view->line_selection != NULL) // Unnecessary in theory, the line selection references are already saved
{
strcpy(((view->infos)->line_selection).column_name, ((view->line_selection)->header)->name);
((view->infos)->line_selection).version = ((view->line_selection)->header)->version;
(view->infos)->all_lines = false;
}
else // Necessary because line selection could have been deleted if a column was cloned
{
(((view->infos)->line_selection).column_name)[0] = '\0';
((view->infos)->line_selection).version = -1;
(view->infos)->all_lines = true;
}
update_column_refs(view);
return 0;
}
static int rename_finished_view(Obiview_p view)
{
char* old_name;
char* new_name;
char* path_old_name;
char* path_new_name;
char* full_path_old_name;
char* full_path_new_name;
old_name = build_unfinished_obiview_file_name((view->infos)->name);
new_name = build_obiview_file_name((view->infos)->name);
path_old_name = malloc(MAX_PATH_LEN);
path_new_name = malloc(MAX_PATH_LEN);
strcpy(path_old_name, "VIEWS/");
strcat(path_old_name, old_name);
strcpy(path_new_name, "VIEWS/");
strcat(path_new_name, new_name);
full_path_old_name = obi_dms_get_full_path(view->dms, path_old_name);
full_path_new_name = obi_dms_get_full_path(view->dms, path_new_name);
if (rename(full_path_old_name, full_path_new_name) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError renaming the file of a finished view: %s", full_path_new_name);
free(old_name);
free(new_name);
return -1;
}
free(old_name);
free(new_name);
free(path_new_name);
free(path_old_name);
free(full_path_old_name);
free(full_path_new_name);
return 0;
}
static int finish_view(Obiview_p view)
{
char* predicates;
// Check that the view is not read-only
if (view->read_only)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError trying to save a read-only view");
return -1;
}
// Check predicates
predicates = view_check_all_predicates(view);
if (predicates == NULL)
{
obidebug(1, "\nView predicates not respected");
return -1; // TODO reverse view (delete files)
}
else
{
write_comments_to_view_file(view, predicates);
free(predicates);
}
if (save_view(view) < 0)
return -1;
if (rename_finished_view(view) < 0)
return -1;
// Flag the view as finished
(view->infos)->finished = true;
return 0;
}
static int close_view(Obiview_p view)
{
int i;
int ret_value;
ret_value = 0;
for (i=0; i < ((view->infos)->column_count); i++)
{
if (obi_close_column((view->columns)[i]) < 0)
{
obidebug(1, "\nError closing a column while closing a view");
ret_value = -1;
}
}
// Close line selection if there is one
if (view->line_selection != NULL)
{
if (obi_close_column(view->line_selection) < 0)
{
obidebug(1, "\nError closing a line selection while closing a view");
ret_value = -1;
}
}
// Free the column dictionary
ht_free(view->column_dict);
// Unmap view file
if (obi_view_unmap_file(view->dms, view->infos) < 0)
{
obidebug(1, "\nError unmaping a view file while closing a view");
ret_value = -1;
}
free(view);
return ret_value;
}
static int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, index_t* line_nb_p)
{
int i;
char* column_name = NULL;
@ -846,7 +1129,7 @@ int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, i
}
int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p)
static int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p)
{
if (((*line_nb_p)+1) > ((view->infos)->line_count))
{
@ -865,7 +1148,7 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p)
/****** PREDICATE FUNCTIONS *******/
char* view_has_nuc_sequence_column(Obiview_p view)
static char* view_has_nuc_sequence_column(Obiview_p view)
{
char* predicate;
@ -889,7 +1172,7 @@ char* view_has_nuc_sequence_column(Obiview_p view)
}
char* view_has_quality_column(Obiview_p view)
static char* view_has_quality_column(Obiview_p view)
{
char* predicate;
@ -913,7 +1196,7 @@ char* view_has_quality_column(Obiview_p view)
}
char* view_has_id_column(Obiview_p view)
static char* view_has_id_column(Obiview_p view)
{
char* predicate;
@ -936,7 +1219,8 @@ char* view_has_id_column(Obiview_p view)
}
}
char* view_has_definition_column(Obiview_p view)
static char* view_has_definition_column(Obiview_p view)
{
char* predicate;
@ -960,7 +1244,7 @@ char* view_has_definition_column(Obiview_p view)
}
char* view_check_qual_match_seqs(Obiview_p view)
static char* view_check_qual_match_seqs(Obiview_p view)
{
index_t i, j, k;
index_t nb_elements_per_line;
@ -1053,13 +1337,13 @@ char* view_check_qual_match_seqs(Obiview_p view)
}
char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view))
static char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view))
{
return predicate_function(view);
}
char* view_check_all_predicates(Obiview_p view)
static char* view_check_all_predicates(Obiview_p view)
{
int i, j;
size_t size_to_allocate;
@ -1195,7 +1479,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
}
// Map view file
view->infos = obi_view_map_file(dms, view_name);
view->infos = obi_view_map_file(dms, view_name, false);
if (view->infos == NULL)
{
obidebug(1, "\nError mapping the informations of a new view");
@ -1305,7 +1589,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
if (write_comments_to_view_file(view, clone_comment) < 0)
{
obidebug(1, "\nError writing comments when creating a view");
obi_close_view(view);
close_view(view);
return NULL;
}
}
@ -1341,7 +1625,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
if (write_comments_to_view_file(view, comments) < 0)
{
obidebug(1, "\nError writing comments when creating a view");
obi_close_view(view);
close_view(view);
return NULL;
}
@ -1360,7 +1644,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
// Create the column dictionary (hash table) associating column names (or aliases) to column pointers
if (create_column_dict(view) < 0)
{
obi_close_view(view);
close_view(view);
return NULL;
}
@ -1409,7 +1693,7 @@ Obiview_p obi_new_view_cloned_from_name(OBIDMS_p dms, const char* view_name, con
return NULL;
view = obi_new_view(dms, view_name, view_to_clone, line_selection, comments);
obi_close_view(view_to_clone);
close_view(view_to_clone);
return view;
}
@ -1511,26 +1795,43 @@ Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_
return NULL;
view = obi_new_view_nuc_seqs(dms, view_name, view_to_clone, line_selection, comments, quality_column);
obi_close_view(view_to_clone);
close_view(view_to_clone);
return view;
}
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name)
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name, bool finished)
{
char* file_name;
Obiview_infos_p view_infos;
int obiview_file_descriptor;
size_t file_size;
int open_flag;
int mmap_flag;
// Create file name
file_name = build_obiview_file_name(view_name);
if (finished)
file_name = build_obiview_file_name(view_name);
else
file_name = build_unfinished_obiview_file_name(view_name);
if (file_name == NULL)
return NULL;
// Set flags (read-only or not)
if (finished)
{
open_flag = O_RDONLY;
mmap_flag = PROT_READ;
}
else
{
open_flag = O_RDWR;
mmap_flag = PROT_READ | PROT_WRITE;
}
// Open view file
obiview_file_descriptor = openat(dms->view_dir_fd, file_name, O_RDWR, 0777);
obiview_file_descriptor = openat(dms->view_dir_fd, file_name, open_flag, 0777);
if (obiview_file_descriptor < 0)
{
if (errno == ENOENT)
@ -1560,7 +1861,7 @@ Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name)
// Map the view infos structure
view_infos = mmap(NULL,
file_size,
PROT_READ | PROT_WRITE,
mmap_flag,
MAP_SHARED,
obiview_file_descriptor,
0
@ -1585,17 +1886,20 @@ Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name)
int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos)
{
char* file_name;
int obiview_file_descriptor;
size_t file_size;
char* file_name;
int obiview_file_descriptor;
size_t file_size;
// Get file name
file_name = build_obiview_file_name(view_infos->name);
if (view_infos->finished)
file_name = build_obiview_file_name(view_infos->name);
else
file_name = build_unfinished_obiview_file_name(view_infos->name);
if (file_name == NULL)
return -1;
// Open view file
obiview_file_descriptor = openat(dms->view_dir_fd, file_name, O_RDWR, 0777);
obiview_file_descriptor = openat(dms->view_dir_fd, file_name, O_RDONLY, 0777);
if (obiview_file_descriptor < 0)
{
obi_set_errno(OBIVIEW_ERROR);
@ -1661,13 +1965,9 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
}
// Map view file
view->infos = obi_view_map_file(dms, view_name);
// Check that the view is finished and can be opened
if ((view->infos)->finished == false)
view->infos = obi_view_map_file(dms, view_name, true);
if ((view->infos) == NULL)
{
obidebug(1, "\nError opening a view: the view is not finished");
obi_view_unmap_file(view->dms, view->infos);
free(view);
return NULL;
}
@ -1697,7 +1997,7 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
if (column_pointer == NULL)
{
obidebug(1, "\nError opening a column for a view: column %d: %s, version %d", i, column_name, column_version);
obi_close_view(view);
close_view(view);
return NULL;
}
(view->columns)[i] = column_pointer;
@ -1713,7 +2013,7 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
if (create_column_dict(view) < 0)
{
obidebug(1, "\nError creating the column dictionary when opening a view");
obi_close_view(view);
close_view(view);
return NULL;
}
@ -1963,103 +2263,16 @@ int obi_view_create_column_alias(Obiview_p view, const char* current_name, const
}
int obi_save_view(Obiview_p view)
{
// Check that the view is not read-only
if (view->read_only)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError trying to save a read-only view");
return -1;
}
// Store reference for the line selection associated with that view if there is one
if (view->line_selection != NULL) // Unnecessary in theory, the line selection references are already saved
{
strcpy(((view->infos)->line_selection).column_name, ((view->line_selection)->header)->name);
((view->infos)->line_selection).version = ((view->line_selection)->header)->version;
(view->infos)->all_lines = false;
}
else // Necessary because line selection could have been deleted if a column was cloned
{
(((view->infos)->line_selection).column_name)[0] = '\0';
((view->infos)->line_selection).version = -1;
(view->infos)->all_lines = true;
}
update_column_refs(view);
return 0;
}
int obi_close_view(Obiview_p view)
{
int i;
int ret_value;
ret_value = 0;
for (i=0; i < ((view->infos)->column_count); i++)
{
if (obi_close_column((view->columns)[i]) < 0)
{
obidebug(1, "\nError closing a column while closing a view");
ret_value = -1;
}
}
// Close line selection if there is one
if (view->line_selection != NULL)
{
if (obi_close_column(view->line_selection) < 0)
{
obidebug(1, "\nError closing a line selection while closing a view");
ret_value = -1;
}
}
// Flag the view as finished
(view->infos)->finished = true;
// Free the column dictionary
ht_free(view->column_dict);
// Unmap view file
if (obi_view_unmap_file(view->dms, view->infos) < 0)
{
obidebug(1, "\nError unmaping a view file while closing a view");
ret_value = -1;
}
free(view);
return ret_value;
}
int obi_save_and_close_view(Obiview_p view)
{
char* predicates;
if (!(view->read_only))
{
predicates = view_check_all_predicates(view);
if (predicates == NULL)
{
obidebug(1, "\nView predicates not respected");
return -1; // TODO reverse view (delete files)
}
else
{
write_comments_to_view_file(view, predicates);
free(predicates);
}
if (obi_save_view(view) < 0)
// Finish and save the view if it is not read-only
if ( ! (view->read_only))
if (finish_view(view) < 0)
return -1;
}
if (obi_close_view(view) < 0)
if (close_view(view) < 0)
return -1;
return 0;
}

View File

@ -242,6 +242,7 @@ Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_
*
* @param dms A pointer on the OBIDMS.
* @param view_name The unique name identifying the view.
* @param finished Whether the view is finished or not.
*
* @returns A pointer on the mapped view infos structure.
* @retval NULL if an error occurred.
@ -249,7 +250,7 @@ Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name);
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name, bool finished);
/**
@ -444,42 +445,6 @@ int obi_select_line(Obiview_p view, index_t line_nb);
int obi_select_lines(Obiview_p view, index_t* line_nbs);
/**
* @brief Saves a view, writing it in the view file.
*
* The view is written at the end of the view file, following the latest written view.
*
* @warning The view must be writable.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_save_view(Obiview_p view);
/**
* @brief Closes an opened view.
*
* @warning Uses obi_save_and_close_view() to automatically save the view if it's not already saved in the view file.
*
* @param view A pointer on the view.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_close_view(Obiview_p view);
/**
* @brief Closes an opened view, and saves it if it is not read-only (meaning it is not already saved in the view file).
*