First version of automatic ID and COUNT columns, to discuss (for now,

columns created when NUC_SEQ views are closed if the columns don't
already exist)
This commit is contained in:
Celine Mercier
2017-07-17 17:31:09 +02:00
parent 1e57bfacb4
commit c88df2e12c
4 changed files with 200 additions and 5 deletions

View File

@ -1072,6 +1072,26 @@ static int finish_view(Obiview_p view)
return -1;
}
// Add count column if it's a NUC_SEQ_VIEW with no count column // TODO discuss
if ((!strcmp((view->infos)->view_type, VIEW_TYPE_NUC_SEQS)) && (!obi_view_column_exists(view, COUNT_COLUMN)))
{
if (obi_create_auto_count_column(view) < 0)
{
obidebug(1, "\nError creating an automatic count column when finishing a view");
return -1;
}
}
// Add id column if it's a NUC_SEQ_VIEW with no id column // TODO discuss
if ((!strcmp((view->infos)->view_type, VIEW_TYPE_NUC_SEQS)) && (!obi_view_column_exists(view, ID_COLUMN)))
{
if (obi_create_auto_id_column(view, NULL) < 0)
{
obidebug(1, "\nError creating an automatic id column when finishing a view");
return -1;
}
}
// Check predicates
predicates = view_check_all_predicates(view);
if (predicates == NULL)
@ -1824,7 +1844,7 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v
return NULL;
}
// Adding id column
if (obi_view_add_column(view, ID_COLUMN, -1, ID_COLUMN, OBI_STR, 0, 1, NULL, "", NULL, -1, "Ids", true) < 0)
if (obi_view_add_column(view, ID_COLUMN, -1, ID_COLUMN, OBI_STR, 0, 1, NULL, "", NULL, -1, "Sequence identifiers", true) < 0)
{
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL;
@ -2391,6 +2411,15 @@ OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name)
}
bool obi_view_column_exists(Obiview_p view, const char* column_name)
{
if (obi_view_get_column(view, column_name) == NULL)
return false;
else
return true;
}
OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const char* column_name)
{
return (OBIDMS_column_p*)(ht_get(view->column_dict, column_name));
@ -2459,8 +2488,8 @@ int obi_save_and_close_view(Obiview_p view)
int obi_create_auto_count_column(Obiview_p view)
{
index_t i;
OBIDMS_p column;
index_t i;
OBIDMS_column_p column;
// Check that the view is not read-only
if (view->read_only)
@ -2470,7 +2499,7 @@ int obi_create_auto_count_column(Obiview_p view)
return -1;
}
if (obi_view_add_column(view, COUNT_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, NULL, NULL, NULL, "Sequence counts", true) < 0)
if (obi_view_add_column(view, COUNT_COLUMN, -1, NULL, OBI_INT, 0, 1, NULL, NULL, NULL, -1, "Sequence counts", true) < 0)
{
obidebug(1, "Error adding an automatic count column in a view");
return -1;
@ -2486,7 +2515,7 @@ int obi_create_auto_count_column(Obiview_p view)
// Fill the column with 1s
for (i=0; i < (view->infos)->line_count; i++)
{
if (obi_column_set_obiint_with_elt_idx(column, i, 0, 1) < 0)
if (obi_set_int_with_elt_idx_and_col_p_in_view(view, column, i, 0, 1) < 0)
{
obidebug(1, "Error adding an automatic count column in a view");
return -1;
@ -2497,6 +2526,69 @@ int obi_create_auto_count_column(Obiview_p view)
}
int obi_create_auto_id_column(Obiview_p view, const char* prefix)
{
index_t i;
OBIDMS_column_p column;
char* id;
// Check that the view is not read-only
if (view->read_only)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError trying to create an automatic count column in a read-only view");
return -1;
}
// Delete old ID column if it exists
if (obi_view_get_column(view, ID_COLUMN) != NULL)
{
if (obi_view_delete_column(view, ID_COLUMN) < 0)
{
obidebug(1, "Error deleting an ID column to replace it in a view");
return -1;
}
}
// Create the new ID column
if (obi_view_add_column(view, ID_COLUMN, -1, NULL, OBI_STR, 0, 1, NULL, NULL, NULL, -1, "Sequence identifiers", true) < 0)
{
obidebug(1, "Error adding an automatic ID column in a view");
return -1;
}
column = obi_view_get_column(view, ID_COLUMN);
if (column == NULL)
{
obidebug(1, "Error adding an automatic ID column in a view");
return -1;
}
// If prefix is NULL, use default prefix
if (prefix == NULL)
prefix = ID_PREFIX;
// Fill the column with automatic ids
for (i=0; i < (view->infos)->line_count; i++)
{
id = build_word_with_idx(prefix, i);
if (id == NULL)
{
obidebug(1, "Error building an id for an automatic ID column");
return -1;
}
if (obi_set_str_with_elt_idx_and_col_p_in_view(view, column, i, 0, id) < 0)
{
obidebug(1, "Error adding an automatic count column in a view");
return -1;
}
free(id);
}
return 0;
}
// TODO Move to another file?
/*********** FOR BLOB COLUMNS ***********/

View File

@ -55,6 +55,8 @@
#define COUNT_COLUMN "COUNT" /**< The name of the column containing the sequence counts
* in NUC_SEQS_VIEW views.
*/
#define ID_PREFIX "seq" /**< The default prefix of sequence identifiers in automatic ID columns.
*/
/**
@ -409,6 +411,20 @@ int obi_view_delete_column(Obiview_p view, const char* column_name);
OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name);
/**
* @brief Checks if a column exists in a view.
*
* @param view A pointer on the view.
* @param column_name The name of the column in the view.
*
* @returns A boolean indicating whether or not the column exists in the view.
*
* @since July 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
bool obi_view_column_exists(Obiview_p view, const char* column_name);
/**
* @brief Gets the pointer on the pointer on a column from its name in a view.
*
@ -527,6 +543,25 @@ int obi_save_and_close_view(Obiview_p view);
int obi_create_auto_count_column(Obiview_p view);
/**
* @brief Creates an OBI_STR column with the line count of the view it belongs to, and sets all lines with automatic identifiers
* with the form prefix_index.
*
* @warning The number of lines set corresponds to the line count of the view.
*
* @param view A pointer on the view.
* @param prefix The prefix of automatic ids. The ids have the form prefix_index. If NULL, the default ID_PREFIX is used.
*
* @returns A value indicating the success of the operation.
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since July 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_create_auto_id_column(Obiview_p view, const char* prefix);
/**
* @brief Recovers an obiblob from an OBIDMS column containing indices referring to obiblobs,
* using the index of the element in the line, and the column pointer, in the context of a view.

View File

@ -18,6 +18,7 @@
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <math.h>
#include "utils.h"
#include "obidebug.h"
@ -35,6 +36,43 @@
**********************************************************************/
int digit_count(index_t i)
{
int n_digits;
if (i == 0)
n_digits = 1;
else
n_digits = floor(log10(llabs(i))) + 1;
return n_digits;
}
char* build_word_with_idx(const char* prefix, index_t idx)
{
char* word;
int n_digits;
n_digits = digit_count(idx);
word = (char*) malloc((strlen(prefix) + 1+ n_digits + 1)*sizeof(char));
if (word == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for a character string");
return NULL;
}
if (sprintf(word, "%s_%lld", prefix, idx) < 0)
{
obi_set_errno(OBI_UTILS_ERROR);
obidebug(1, "\nProblem building a word from a prefix and an index");
return NULL;
}
return word;
}
int count_dir(char* dir_path)
{
struct dirent* dp;

View File

@ -17,6 +17,7 @@
#include <sys/stat.h>
#include "obidms.h"
#include "obitypes.h"
#define FORMATTED_TIME_LENGTH (1024) /**< The length allocated for the character string containing a formatted date.
@ -25,6 +26,35 @@
*/
/**
* @brief Counts the number of digits of a number.
*
* @param i The number.
*
* @returns The number of digits of the number.
*
* @since July 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int digit_count(index_t i);
/**
* @brief Builds a word from a prefix and an index, with the form prefix_index.
*
* @warning The returned pointer has to be freed by the caller.
*
* @param prefix The prefix for the word.
* @param idx The index to use as suffix.
*
* @returns The built word.
*
* @since July 2017
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
char* build_word_with_idx(const char* prefix, index_t idx);
/**
* @brief Counts the number of files and directories in a directory.
*