2411 lines
73 KiB
C
2411 lines
73 KiB
C
/********************************************************************
|
|
* Obiview functions *
|
|
********************************************************************/
|
|
|
|
/**
|
|
* @file obiview.c
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
* @date 16 December 2015
|
|
* @brief Obiview functions.
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
|
|
#include "obiview.h"
|
|
#include "obidms.h"
|
|
#include "obidmscolumn.h"
|
|
#include "obidmscolumn_idx.h"
|
|
#include "obidmscolumn_bool.h"
|
|
#include "obidmscolumn_char.h"
|
|
#include "obidmscolumn_float.h"
|
|
#include "obidmscolumn_int.h"
|
|
#include "obidmscolumn_qual.h"
|
|
#include "obidmscolumn_seq.h"
|
|
#include "obidmscolumn_str.h"
|
|
#include "obierrno.h"
|
|
#include "obidebug.h"
|
|
#include "obilittlebigman.h"
|
|
#include "hashtable.h"
|
|
#include "utils.h"
|
|
|
|
|
|
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* 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
|
|
*
|
|
**************************************************************************/
|
|
|
|
/**
|
|
* Internal function calculating the size of the file where the informations about an obiview are stored.
|
|
*
|
|
* @returns The size of the file in bytes.
|
|
*
|
|
* @since June 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
size_t get_platform_view_file_size();
|
|
|
|
|
|
/**
|
|
* Internal function building the file name where the informations about an obiview are stored.
|
|
*
|
|
* @warning The returned pointer has to be freed by the caller.
|
|
*
|
|
* @returns A pointer to the file name.
|
|
* @retval NULL if an error occurred.
|
|
*
|
|
* @param view_name The name of the view.
|
|
*
|
|
* @since June 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
static char* build_obiview_file_name(const char* view_name); // TODO delete after discussion
|
|
|
|
|
|
/**
|
|
* @brief Internal function creating a file containing all the informations on a view.
|
|
*
|
|
* The file is named with the name of the view.
|
|
*
|
|
* @param dms The DMS to which the view belongs.
|
|
* @param view_name The name of the view.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @since June 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
int create_obiview_file(OBIDMS_p dms, const char* view_name);
|
|
|
|
|
|
/**
|
|
* @brief Internal function to update the column references of a view.
|
|
*
|
|
* The column references stored in the mapped view infos structures are updated
|
|
* to match the columns opened in the opened view structure.
|
|
*
|
|
* @warning The column pointer array should be up to date before using this function.
|
|
* @warning Aliases are not updated by this function and have to be edited separately.
|
|
* This function simply reads the column pointer array associated with the view
|
|
* and fills the column names and versions in the column reference array accordingly,
|
|
* without touching the alias.
|
|
* That means that for example if there is a shift in the column pointer array, this
|
|
* function should not be used.
|
|
*
|
|
* @param view A pointer on the view.
|
|
*
|
|
* @since June 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
void update_column_refs(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function creating the column dictionary associated with a view.
|
|
*
|
|
* The column dictionary is built from the column references array, and associates each column alias
|
|
* with the pointer on the column.
|
|
*
|
|
* @warning The column reference array and the column pointer array should be up to date before using this function.
|
|
*
|
|
* @param view A pointer on the view.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
int create_column_dict(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function updating the column dictionary associated with a view.
|
|
*
|
|
* The column dictionary is built from the column references array, and associates each column alias
|
|
* with the pointer on the column.
|
|
*
|
|
* @warning The column reference array and the column pointer array should be up to date before using this function.
|
|
*
|
|
* @param view A pointer on the view.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
int update_column_dict(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function updating the column reference array and the column dictionary associated with a view.
|
|
*
|
|
* The column reference array is updated from the column pointer array, then the column dictionary that
|
|
* and associates each column alias with the pointer on the column is updated from the column reference array.
|
|
*
|
|
* @warning The column pointer array should be up to date before using this function.
|
|
* @warning Aliases are not updated by this function and have to be edited separately.
|
|
* This function simply reads the column pointer array associated with the view
|
|
* and fills the column names and versions in the column reference array accordingly,
|
|
* without touching the alias.
|
|
* That means that for example if there is a shift in the column pointer array, this
|
|
* function should not be used.
|
|
*
|
|
* @param view A pointer on the view.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
int update_column_refs_and_dict(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function to update the line count in the context of a view.
|
|
*
|
|
* All columns of the view are enlarged to contain at least the new line count.
|
|
*
|
|
* @warning The view must be writable.
|
|
*
|
|
* @param view A pointer on the view.
|
|
* @param line_count The new line count.
|
|
*
|
|
* @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 update_lines(Obiview_p view, index_t line_count);
|
|
|
|
|
|
/**
|
|
* @brief Internal function to clone a column in the context of a view.
|
|
*
|
|
* Clones with the right line selection and replaces the cloned columns with the new ones in the view.
|
|
* If there is a line selection, all columns have to be cloned, otherwise only the column of interest is cloned.
|
|
*
|
|
* @param view A pointer on the view.
|
|
* @param column_name The name of the column in the view that should be cloned.
|
|
*
|
|
* @returns A pointer on the new column.
|
|
* @retval NULL if an error occurred.
|
|
*
|
|
* @since February 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name);
|
|
|
|
|
|
/**
|
|
* @brief Internal function preparing to set a value in a column, in the context of a view.
|
|
*
|
|
* The function checks that the view is not read-only, clones the column or all columns if needed,
|
|
* and updates the line count if needed.
|
|
*
|
|
* @param view The view.
|
|
* @param column_pp A pointer on the pointer on the column, to allow replacing the column if it is cloned.
|
|
* @param line_nb_p A pointer on the index of the line that will be modified, to allow replacing it if needed.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @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);
|
|
|
|
|
|
/**
|
|
* @brief Internal function preparing to get a value from a column, in the context of a view.
|
|
*
|
|
* The function checks that the line index is not beyond the current line count of the view,
|
|
* and modifies it if there is a line selection associated with the view.
|
|
*
|
|
* @param view The view.
|
|
* @param line_nb_p A pointer on the index of the line, to allow replacing it if needed.
|
|
*
|
|
* @retval 0 if the operation was successfully completed.
|
|
* @retval -1 if an error occurred.
|
|
*
|
|
* @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);
|
|
|
|
|
|
/****** PREDICATE FUNCTIONS *******/
|
|
|
|
/**
|
|
* @brief Internal function checking if a view has a NUC_SEQUENCE_COLUMN column.
|
|
*
|
|
* The function checks that the view has a column with the name attributed to obligatory
|
|
* nucleotide sequence columns.
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_has_nuc_sequence_column(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking if a view has a QUALITY_COLUMN column.
|
|
*
|
|
* The function checks that the view has a column with the name attributed to obligatory
|
|
* quality columns.
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_has_quality_column(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking if a view has a ID_COLUMN column.
|
|
*
|
|
* The function checks that the view has a column with the name attributed to obligatory
|
|
* id columns.
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_has_id_column(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking if a view has a DEFINITION_COLUMN column.
|
|
*
|
|
* The function checks that the view has a column with the name attributed to obligatory
|
|
* definition columns.
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_has_definition_column(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking that the quality column of a view and the sequence column associated to it
|
|
* correspond properly:
|
|
* - when a line is defined for either column, it must also be defined for the other column
|
|
* - when a line is defined, the lengths of the sequence and of the quality must be equal
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_check_quality_matches_seq_column(Obiview_p view);
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking one predicate function on a view.
|
|
*
|
|
* @param view The view.
|
|
* @param predicate_function The predicate function to use.
|
|
*
|
|
* @returns A character string describing the predicate.
|
|
* @retval NULL if the predicate is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_check_one_predicate(Obiview_p view, char* (*predicate_function)(Obiview_p view));
|
|
|
|
|
|
/**
|
|
* @brief Internal function checking all the predicates associated with a view.
|
|
*
|
|
* @param view The view.
|
|
*
|
|
* @returns A character string describing all the predicates separated by line breaks.
|
|
* @retval NULL if at least one of the predicates is false or if there was an error.
|
|
*
|
|
* @since July 2016
|
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
|
*/
|
|
char* view_check_all_predicates(Obiview_p view);
|
|
|
|
|
|
/************************************************************************
|
|
*
|
|
* D E F I N I 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
|
|
*
|
|
************************************************************************/
|
|
|
|
// TODO
|
|
//static char* build_obiview_file_name(const char* view_name)
|
|
//{
|
|
// char* file_name;
|
|
//
|
|
// // Build file name
|
|
// file_name = (char*) malloc((strlen(view_name) + 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, view_name) < 0)
|
|
// {
|
|
// obi_set_errno(OBIVIEW_ERROR);
|
|
// obidebug(1, "\nProblem building an obiview file name");
|
|
// return NULL;
|
|
// }
|
|
//
|
|
// return file_name;
|
|
//}
|
|
|
|
|
|
size_t get_platform_view_file_size()
|
|
{
|
|
size_t obiview_size;
|
|
size_t rounded_obiview_size;
|
|
double multiple;
|
|
|
|
obiview_size = sizeof(Obiview_infos_t);
|
|
|
|
multiple = ceil((double) (obiview_size) / (double) getpagesize());
|
|
|
|
rounded_obiview_size = multiple * getpagesize();
|
|
|
|
return rounded_obiview_size;
|
|
}
|
|
|
|
|
|
int create_obiview_file(OBIDMS_p dms, const char* view_name)
|
|
{
|
|
// char* file_name;
|
|
int obiview_file_descriptor;
|
|
size_t file_size;
|
|
|
|
// TODO
|
|
// // Create file name
|
|
// file_name = build_obiview_file_name(view_name);
|
|
// if (file_name == NULL)
|
|
// return -1;
|
|
|
|
// Create file
|
|
obiview_file_descriptor = openat(dms->view_dir_fd, view_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
|
if (obiview_file_descriptor < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError creating an obiview file");
|
|
// free(file_name);
|
|
return -1;
|
|
}
|
|
|
|
//free(file_name);
|
|
|
|
// Truncate file to the right size
|
|
file_size = get_platform_view_file_size();
|
|
|
|
if (ftruncate(obiview_file_descriptor, file_size) < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError truncating an obiview file to the right size");
|
|
close(obiview_file_descriptor);
|
|
return -1;
|
|
}
|
|
|
|
close(obiview_file_descriptor);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void update_column_refs(Obiview_p view)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < (view->infos)->column_count; i++)
|
|
{
|
|
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, (((view->columns)[i])->header)->name);
|
|
((((view->infos)->column_references)[i]).column_refs).version = (((view->columns)[i])->header)->version;
|
|
}
|
|
}
|
|
|
|
|
|
int create_column_dict(Obiview_p view)
|
|
{
|
|
int i;
|
|
|
|
view->column_dict = ht_create(MAX_NB_OPENED_COLUMNS);
|
|
if (view->column_dict == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError creating a column dictionary");
|
|
return -1;
|
|
}
|
|
|
|
// Rebuild the dictionary from the column references and the column pointer array associated with the view
|
|
for (i=0; i < (view->infos)->column_count; i++)
|
|
{
|
|
// Check that each alias is unique
|
|
if (ht_get(view->column_dict, (((view->infos)->column_references)[i]).alias) != NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError: the name/alias identifying a column in a view is not unique");
|
|
return -1;
|
|
}
|
|
|
|
if (ht_set(view->column_dict, (((view->infos)->column_references)[i]).alias, (view->columns)[i]) < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError adding a column in a column dictionary");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int update_column_dict(Obiview_p view)
|
|
{
|
|
// Re-initialize the dictionary to rebuild it from scratch
|
|
ht_free(view->column_dict);
|
|
|
|
if (create_column_dict(view) < 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
while (line_count > (((view->columns)[i])->header)->line_count)
|
|
{
|
|
// Enlarge the column
|
|
if (obi_enlarge_column((view->columns)[i]) < 0)
|
|
return -1;
|
|
(((view->columns)[i])->header)->lines_used = line_count;
|
|
}
|
|
}
|
|
|
|
(view->infos)->line_count = line_count;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name)
|
|
{
|
|
int i;
|
|
OBIDMS_column_p current_line_selection = NULL;
|
|
OBIDMS_column_p column = NULL;
|
|
OBIDMS_column_p column_buffer;
|
|
bool found;
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to delete a column in a read-only view");
|
|
return NULL;
|
|
}
|
|
|
|
if (view->new_line_selection != NULL) // TODO Probably shouldn't happen, trigger error?
|
|
current_line_selection = view->new_line_selection;
|
|
else
|
|
current_line_selection = view->line_selection;
|
|
|
|
found = false;
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
if ((current_line_selection != NULL) || (!strcmp((((view->infos)->column_references)[i]).alias, column_name)))
|
|
{ // Clone with the right line selection and replace (for all columns if there is a line selection)
|
|
|
|
// Save pointer to close column after cloning
|
|
column_buffer = (view->columns)[i];
|
|
|
|
// Clone and replace the column in the view
|
|
(view->columns)[i] = obi_clone_column(view->dms, current_line_selection, (((view->columns)[i])->header)->name, (((view->columns)[i])->header)->version, 1);
|
|
if ((view->columns)[i] == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError cloning a column to replace in a view");
|
|
return NULL;
|
|
}
|
|
|
|
// Close old cloned column
|
|
obi_close_column(column_buffer);
|
|
|
|
if (!strcmp((((view->infos)->column_references)[i]).alias, column_name))
|
|
{ // Found the column to return
|
|
column = (view->columns)[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close old line selections
|
|
if (view->line_selection != NULL)
|
|
{
|
|
obi_close_column(view->line_selection);
|
|
view->line_selection = NULL;
|
|
// Update line selection reference
|
|
(((view->infos)->line_selection).column_name)[0] = '\0';
|
|
((view->infos)->line_selection).version = -1;
|
|
}
|
|
if (view->new_line_selection != NULL)
|
|
{
|
|
obi_close_column(view->new_line_selection);
|
|
view->new_line_selection = NULL;
|
|
}
|
|
|
|
// Update column refs and dict
|
|
update_column_refs_and_dict(view);
|
|
|
|
return column;
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to set a value in a column in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
// If there is a line selection associated with the view or if the column
|
|
// is read-only, all columns or this column respectively must be cloned
|
|
if ((view->line_selection != NULL) || (!((*column_pp)->writable)))
|
|
{
|
|
// Get the right line number
|
|
if (view->line_selection != NULL)
|
|
(*line_nb_p) = *(((index_t*) ((view->line_selection)->data)) + (*line_nb_p));
|
|
|
|
// Get the name/alias of the column from the pointer
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
if (obi_view_get_column(view, (((view->infos)->column_references)[i]).alias) == *column_pp)
|
|
column_name = (((view->infos)->column_references)[i]).alias;
|
|
}
|
|
if (column_name == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to clone a column in a view: column alias not found from pointer");
|
|
return -1;
|
|
}
|
|
|
|
(*column_pp) = clone_column_in_view(view, column_name);
|
|
if ((*column_pp) == NULL)
|
|
{
|
|
obidebug(1, "\nError trying to clone a column to modify it");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (((*line_nb_p)+1) > (view->infos)->line_count)
|
|
{
|
|
if (update_lines(view, ((*line_nb_p)+1)) < 0)
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p)
|
|
{
|
|
if (((*line_nb_p)+1) > ((view->infos)->line_count))
|
|
{
|
|
obi_set_errno(OBICOL_UNKNOWN_ERROR);
|
|
obidebug(1, "\nError trying to get a value that is beyond the current line count of the view");
|
|
return -1;
|
|
}
|
|
|
|
if (view->line_selection)
|
|
(*line_nb_p) = *(((index_t*) ((view->line_selection)->data)) + (*line_nb_p));
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/****** PREDICATE FUNCTIONS *******/
|
|
|
|
char* view_has_nuc_sequence_column(Obiview_p view)
|
|
{
|
|
char* predicate;
|
|
|
|
predicate = (char*) malloc((strlen("The view has an associated nucleotide sequence column.") + 1) * sizeof(char));
|
|
if (predicate == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
strcpy(predicate, "The view has an associated nucleotide sequence column.");
|
|
|
|
if (obi_view_get_column(view, NUC_SEQUENCE_COLUMN) != NULL)
|
|
return predicate;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
char* view_has_quality_column(Obiview_p view)
|
|
{
|
|
char* predicate;
|
|
|
|
predicate = (char*) malloc((strlen("The view has an associated sequence quality column.") + 1) * sizeof(char));
|
|
if (predicate == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
strcpy(predicate, "The view has an associated sequence quality column.");
|
|
|
|
if (obi_view_get_column(view, QUALITY_COLUMN) != NULL)
|
|
return predicate;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
char* view_has_id_column(Obiview_p view)
|
|
{
|
|
char* predicate;
|
|
|
|
predicate = (char*) malloc((strlen("The view has an associated identifier column.") + 1) * sizeof(char));
|
|
if (predicate == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
strcpy(predicate, "The view has an associated identifier column.");
|
|
|
|
if (obi_view_get_column(view, ID_COLUMN) != NULL)
|
|
return predicate;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
char* view_has_definition_column(Obiview_p view)
|
|
{
|
|
char* predicate;
|
|
|
|
predicate = (char*) malloc((strlen("The view has an associated definition column.") + 1) * sizeof(char));
|
|
if (predicate == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
strcpy(predicate, "The view has an associated definition column.");
|
|
|
|
if (obi_view_get_column(view, DEFINITION_COLUMN) != NULL)
|
|
return predicate;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
char* view_check_quality_matches_seq_column(Obiview_p view) // TODO Print error if there is one?
|
|
{
|
|
index_t i, j;
|
|
index_t nb_elements_per_line;
|
|
int qual_len;
|
|
const uint8_t* qual;
|
|
char* seq;
|
|
OBIDMS_column_p qual_column;
|
|
OBIDMS_column_p seq_column;
|
|
char* predicate;
|
|
|
|
predicate = (char*) malloc((strlen("The sequences and sequence quality arrays match.") + 1) * sizeof(char));
|
|
if (predicate == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
strcpy(predicate, "The sequences and sequence quality arrays match.");
|
|
|
|
qual_column = obi_view_get_column(view, QUALITY_COLUMN);
|
|
if (qual_column == NULL)
|
|
return NULL;
|
|
|
|
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 NULL;
|
|
|
|
nb_elements_per_line = (qual_column->header)->nb_elements_per_line;
|
|
// Check that the quality and the sequence columns have the same number of elements per line
|
|
if (nb_elements_per_line != (seq_column->header)->nb_elements_per_line)
|
|
return NULL;
|
|
|
|
for (i=0; i < (view->infos)->line_count; i++)
|
|
{
|
|
for (j=0; j < nb_elements_per_line; j++)
|
|
{
|
|
qual = obi_column_get_obiqual_int_with_elt_idx(qual_column, i, j, &qual_len);
|
|
seq = obi_column_get_obiseq_with_elt_idx(seq_column, i, j);
|
|
if ((qual != OBIQual_int_NA) && (seq != OBISeq_NA))
|
|
{
|
|
// Test that the lengths of the quality and the sequence are equal
|
|
if (qual_len != (int)strlen(seq))
|
|
return NULL;
|
|
}
|
|
// Test if one value is NA and not the other
|
|
else if (((qual == OBIQual_int_NA) && (seq != OBISeq_NA)) || ((qual != OBIQual_int_NA) && (seq == OBISeq_NA)))
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
//obi_close_column(seq_column);
|
|
|
|
return predicate;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
int i, j;
|
|
size_t size_to_allocate;
|
|
char* predicate = NULL;
|
|
char* all_predicates_string = NULL;
|
|
char** all_predicates = NULL;
|
|
|
|
size_to_allocate = 0;
|
|
|
|
// Allocate memory for predicate array
|
|
all_predicates = (char**) malloc((view->nb_predicates) * sizeof(char*));
|
|
if (all_predicates == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate array.");
|
|
return NULL;
|
|
}
|
|
|
|
for (i=0; i < view->nb_predicates; i++)
|
|
{
|
|
// Initialize predicate in predicate array
|
|
all_predicates[i] = NULL;
|
|
|
|
// Check the predicate
|
|
predicate = view_check_one_predicate(view, (view->predicate_functions)[i]);
|
|
if (predicate == NULL)
|
|
{
|
|
// TODO discuss
|
|
for (j=0; j<=i; j++)
|
|
free(all_predicates[j]);
|
|
free(all_predicates);
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
all_predicates[i] = predicate;
|
|
size_to_allocate = size_to_allocate + strlen(predicate) + 1; // +1 for '\n'
|
|
}
|
|
}
|
|
|
|
size_to_allocate += 1; // +1 for '\0'
|
|
|
|
all_predicates_string = (char*) malloc(size_to_allocate * sizeof(char));
|
|
if (all_predicates_string == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for predicate character string.");
|
|
return NULL;
|
|
}
|
|
|
|
// Build the character string with all the predicates
|
|
strcpy(all_predicates_string, all_predicates[0]);
|
|
for (i=1; i < view->nb_predicates; i++)
|
|
{
|
|
strcat(all_predicates_string, "\n");
|
|
strcat(all_predicates_string, all_predicates[i]);
|
|
}
|
|
|
|
// Free everything
|
|
for (i=0; i < view->nb_predicates; i++)
|
|
free(all_predicates[i]);
|
|
free(all_predicates);
|
|
|
|
return all_predicates_string;
|
|
}
|
|
|
|
|
|
// TODO predicate function that goes through each line / each elements
|
|
|
|
|
|
/**********************************************************************
|
|
*
|
|
* D E F I N I T I O N O F T H E P U B L I C F U N C T I O N S
|
|
*
|
|
**********************************************************************/
|
|
|
|
Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_clone, index_t* line_selection, const char* comments)
|
|
{
|
|
Obiview_p view;
|
|
int i;
|
|
index_t line_nb;
|
|
struct dirent* dp;
|
|
|
|
// Check uniqueness of name
|
|
while ((dp = readdir(dms->view_directory)) != NULL)
|
|
{
|
|
if ((dp->d_name)[0] == '.')
|
|
continue;
|
|
if (strcmp(dp->d_name, view_name) == 0) // TODO change if view name building changes
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nName of new view already exists");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// Allocate memory for view structure
|
|
view = (Obiview_p) malloc(sizeof(Obiview_t));
|
|
if (view == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError allocating memory for a view");
|
|
return NULL;
|
|
}
|
|
|
|
view->dms = dms;
|
|
view->read_only = 0;
|
|
|
|
// Create view file
|
|
if (create_obiview_file(dms, view_name) < 0)
|
|
{
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
|
|
// Map view file
|
|
view->infos = obi_view_map_file(dms, view_name);
|
|
if (view->infos == NULL)
|
|
{
|
|
obidebug(1, "\nError mapping the informations of a new view");
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
|
|
// Clone view to clone if there is one
|
|
if (view_to_clone != NULL)
|
|
{
|
|
if (!(view_to_clone->read_only))
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nA view can not be cloned if it is not read-only");
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
|
|
// If the view to clone has an associated line selection and there is no new line selection, open the associated line selection
|
|
if ((view_to_clone->line_selection != NULL) && (line_selection == NULL))
|
|
{
|
|
view->line_selection = obi_open_column(dms, ((view_to_clone->line_selection)->header)->name, ((view_to_clone->line_selection)->header)->version);
|
|
if (view->line_selection == NULL)
|
|
{
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
(view->infos)->line_count = (view_to_clone->infos)->line_count;
|
|
}
|
|
// 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, -1, NULL);
|
|
if ((view->line_selection) == NULL)
|
|
{
|
|
obidebug(1, "\nError creating a column corresponding to a line selection");
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
(view->infos)->all_lines = false;
|
|
(view->infos)->line_count = 0;
|
|
i = 0;
|
|
for (i=0; line_selection[i] != -1; i++)
|
|
{
|
|
line_nb = line_selection[i];
|
|
|
|
if (line_nb > (view_to_clone->infos)->line_count)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to select a line for a new view that is beyond the line count of the view to clone");
|
|
obi_close_column(view->line_selection);
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
|
|
if (view_to_clone->line_selection != NULL)
|
|
line_nb = obi_column_get_index(view_to_clone->line_selection, line_nb);
|
|
|
|
if (obi_column_set_index(view->line_selection, ((view->line_selection)->header)->lines_used, line_nb) < 0)
|
|
{
|
|
obi_close_column(view->line_selection);
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
|
|
// Update view line count
|
|
((view->infos)->line_count)++;
|
|
}
|
|
}
|
|
else // If there is no line selection associated with the view to clone or the new view
|
|
{
|
|
view->line_selection = NULL;
|
|
(view->infos)->all_lines = true;
|
|
(view->infos)->line_count = (view_to_clone->infos)->line_count;
|
|
}
|
|
|
|
// Fill informations
|
|
strcpy((view->infos)->view_type, (view_to_clone->infos)->view_type);
|
|
strcpy((view->infos)->created_from, (view_to_clone->infos)->name);
|
|
view->new_line_selection = NULL;
|
|
}
|
|
|
|
// Else, fill empty view structure
|
|
else
|
|
{
|
|
(view->infos)->column_count = 0;
|
|
(view->infos)->line_count = 0;
|
|
(view->infos)->all_lines = true;
|
|
view->line_selection = NULL;
|
|
view->new_line_selection = NULL;
|
|
((view->infos)->created_from)[0] = '\0';
|
|
((view->infos)->view_type)[0] = '\0';
|
|
//view->columns = NULL; // TODO
|
|
}
|
|
|
|
// Fill last informations
|
|
strcpy((view->infos)->name, view_name);
|
|
strcpy((view->infos)->comments, comments);
|
|
(view->infos)->creation_date = time(NULL);
|
|
view->nb_predicates = 0;
|
|
view->predicate_functions = NULL;
|
|
|
|
// Store reference for line selection
|
|
if (view->line_selection == NULL)
|
|
{
|
|
(((view->infos)->line_selection).column_name)[0] = '\0';
|
|
((view->infos)->line_selection).version = -1;
|
|
}
|
|
else
|
|
{
|
|
strcpy(((view->infos)->line_selection).column_name, ((view->line_selection)->header)->name);
|
|
((view->infos)->line_selection).version = ((view->line_selection)->header)->version;
|
|
}
|
|
|
|
// Create the column dictionary (hash table) associating column names (or aliases) to column pointers
|
|
if (create_column_dict(view) < 0)
|
|
{
|
|
obi_close_view(view);
|
|
return NULL;
|
|
}
|
|
|
|
// Once the view has been created with all its elements and informations, add the columns if the view is cloned from another view
|
|
// Add the columns from the view to clone in the new view
|
|
if (view_to_clone != NULL)
|
|
{
|
|
(view->infos)->column_count = 0;
|
|
for (i=0; i<((view_to_clone->infos)->column_count); i++)
|
|
{
|
|
if (obi_view_add_column(view,
|
|
(((view_to_clone->columns)[i])->header)->name,
|
|
(((view_to_clone->columns)[i])->header)->version,
|
|
(((view_to_clone->infos)->column_references)[i]).alias,
|
|
0,
|
|
(view->infos)->line_count,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
-1,
|
|
NULL,
|
|
false)
|
|
< 0)
|
|
{
|
|
obidebug(1, "\nError adding a column in a new view from a view to clone");
|
|
if (view->line_selection != NULL)
|
|
obi_close_column(view->line_selection);
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return view;
|
|
}
|
|
|
|
|
|
Obiview_p obi_new_view_cloned_from_name(OBIDMS_p dms, const char* view_name, const char* view_to_clone_name, index_t* line_selection, const char* comments)
|
|
{
|
|
Obiview_p view;
|
|
Obiview_p view_to_clone;
|
|
|
|
view_to_clone = obi_open_view(dms, view_to_clone_name);
|
|
if (view_to_clone == NULL)
|
|
return NULL;
|
|
view = obi_new_view(dms, view_name, view_to_clone, line_selection, comments);
|
|
|
|
obi_close_view(view_to_clone);
|
|
|
|
return view;
|
|
}
|
|
|
|
|
|
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;
|
|
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)
|
|
if (strcmp((view_to_clone->infos)->view_type, VIEW_TYPE_NUC_SEQS))
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "Trying to clone a non-NUC SEQS view to create a NUC SEQS view");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
view = obi_new_view(dms, view_name, view_to_clone, line_selection, comments);
|
|
if (view == NULL)
|
|
return NULL;
|
|
|
|
strcpy((view->infos)->view_type, VIEW_TYPE_NUC_SEQS);
|
|
|
|
if (view_to_clone == NULL)
|
|
{
|
|
// Adding sequence column
|
|
if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, NUC_SEQUENCE_COLUMN, 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, ID_COLUMN, 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, DEFINITION_COLUMN, 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
|
|
associated_nuc_column = obi_view_get_column(view, NUC_SEQUENCE_COLUMN);
|
|
if (obi_view_add_column(view, QUALITY_COLUMN, -1, QUALITY_COLUMN, 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;
|
|
}
|
|
}
|
|
|
|
// Add predicate functions of the view type
|
|
view->nb_predicates = 5; // TODO macro?
|
|
|
|
view->predicate_functions = malloc((view->nb_predicates) * sizeof(char* (*) (bool)));
|
|
|
|
(view->predicate_functions)[0] = view_has_nuc_sequence_column;
|
|
(view->predicate_functions)[1] = view_has_quality_column;
|
|
(view->predicate_functions)[2] = view_has_id_column;
|
|
(view->predicate_functions)[3] = view_has_definition_column;
|
|
(view->predicate_functions)[4] = view_check_quality_matches_seq_column;
|
|
|
|
return view;
|
|
}
|
|
|
|
|
|
Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_name, const char* view_to_clone_name, index_t* line_selection, const char* comments)
|
|
{
|
|
Obiview_p view;
|
|
Obiview_p view_to_clone;
|
|
|
|
view_to_clone = obi_open_view(dms, view_to_clone_name);
|
|
if (view_to_clone == NULL)
|
|
return NULL;
|
|
view = obi_new_view_nuc_seqs(dms, view_name, view_to_clone, line_selection, comments);
|
|
|
|
obi_close_view(view_to_clone);
|
|
|
|
return view;
|
|
}
|
|
|
|
|
|
Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name)
|
|
{
|
|
// char* file_name;
|
|
Obiview_infos_p view_infos;
|
|
int obiview_file_descriptor;
|
|
size_t file_size;
|
|
|
|
// TODO
|
|
// // Create file name
|
|
// file_name = build_obiview_file_name(view_name);
|
|
// if (file_name == NULL)
|
|
// return -1;
|
|
|
|
// Open view file
|
|
obiview_file_descriptor = openat(dms->view_dir_fd, view_name, O_RDWR, 0777);
|
|
if (obiview_file_descriptor < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError opening an obiview file");
|
|
// free(file_name);
|
|
return NULL;
|
|
}
|
|
|
|
//free(file_name);
|
|
|
|
// Map the view infos structure
|
|
file_size = get_platform_view_file_size();
|
|
view_infos = mmap(NULL,
|
|
file_size,
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_SHARED,
|
|
obiview_file_descriptor,
|
|
0
|
|
);
|
|
if (view_infos == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError mapping an obiview file");
|
|
return NULL;
|
|
}
|
|
|
|
close(obiview_file_descriptor);
|
|
|
|
return view_infos;
|
|
}
|
|
|
|
|
|
int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos)
|
|
{
|
|
// char* file_name;
|
|
int obiview_file_descriptor;
|
|
size_t file_size;
|
|
|
|
// TODO
|
|
// // Get file name
|
|
// file_name = build_obiview_file_name(view_name);
|
|
// if (file_name == NULL)
|
|
// return -1;
|
|
|
|
// Open view file
|
|
obiview_file_descriptor = openat(dms->view_dir_fd, view_infos->name, O_RDWR, 0777);
|
|
if (obiview_file_descriptor < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError opening an obiview file");
|
|
// free(file_name);
|
|
return -1;
|
|
}
|
|
|
|
//free(file_name);
|
|
|
|
// Unmap the view infos structure
|
|
file_size = get_platform_view_file_size();
|
|
if (munmap(view_infos, file_size) < 0)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError unmapping an obiview file");
|
|
close(obiview_file_descriptor);
|
|
return -1;
|
|
}
|
|
|
|
close(obiview_file_descriptor);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
|
|
{
|
|
Obiview_p view;
|
|
const char* column_name;
|
|
obiversion_t column_version;
|
|
OBIDMS_column_p column_pointer;
|
|
int i;
|
|
|
|
// Alllocate the memory for the view structure
|
|
view = (Obiview_p) malloc(sizeof(Obiview_t));
|
|
if (view == NULL)
|
|
{
|
|
obi_set_errno(OBI_MALLOC_ERROR);
|
|
obidebug(1, "\nError allocating memory for a view");
|
|
return NULL;
|
|
}
|
|
|
|
// Map view file
|
|
view->infos = obi_view_map_file(dms, view_name);
|
|
|
|
// Open the line selection associated with the view
|
|
if ((view->infos)->all_lines)
|
|
view->line_selection = NULL;
|
|
else
|
|
{
|
|
view->line_selection = obi_open_column(dms, ((view->infos)->line_selection).column_name, ((view->infos)->line_selection).version);
|
|
if (view->line_selection == NULL)
|
|
{
|
|
obidebug(1, "\nError opening a line selection for a view");
|
|
obi_view_unmap_file(view->dms, view->infos);
|
|
free(view);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// Open the columns to read
|
|
for (i=0; i < ((view->infos)->column_count); i++)
|
|
{
|
|
column_name = ((((view->infos)->column_references)[i]).column_refs).column_name;
|
|
column_version = ((((view->infos)->column_references)[i]).column_refs).version;
|
|
|
|
column_pointer = obi_open_column(dms, column_name, column_version);
|
|
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);
|
|
return NULL;
|
|
}
|
|
(view->columns)[i] = column_pointer;
|
|
|
|
}
|
|
|
|
view->dms = dms;
|
|
view->new_line_selection = NULL;
|
|
view->read_only = true;
|
|
view->nb_predicates = 0;
|
|
view->predicate_functions = NULL;
|
|
|
|
// Create the column dictionary associating each column alias with its pointer
|
|
if (create_column_dict(view) < 0)
|
|
{
|
|
obidebug(1, "\nError creating the column dictionary when opening a view");
|
|
obi_close_view(view);
|
|
return NULL;
|
|
}
|
|
|
|
return view;
|
|
}
|
|
|
|
|
|
int obi_view_add_column(Obiview_p view,
|
|
const char* column_name,
|
|
obiversion_t version_number,
|
|
const char* alias,
|
|
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,
|
|
bool create) // all infos for creation or open
|
|
{
|
|
int i;
|
|
OBIDMS_column_p column;
|
|
OBIDMS_column_p column_buffer;
|
|
OBIDMS_column_p current_line_selection;
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to add a column in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
// If there is a line selection, clone the columns to delete it
|
|
if (view->new_line_selection != NULL) // TODO Probably shouldn't happen, trigger error?
|
|
current_line_selection = view->new_line_selection;
|
|
else
|
|
current_line_selection = view->line_selection;
|
|
|
|
if (current_line_selection != NULL)
|
|
{
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
{ // Clone with the right line selection and replace for all columns
|
|
// Save pointer to close column after cloning
|
|
column_buffer = (view->columns)[i];
|
|
|
|
// Clone and replace the column in the view
|
|
(view->columns)[i] = obi_clone_column(view->dms, current_line_selection, (((view->columns)[i])->header)->name, (((view->columns)[i])->header)->version, 1);
|
|
if ((view->columns)[i] == NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError cloning a column to replace in a view");
|
|
return -1;
|
|
}
|
|
|
|
// Close old cloned column
|
|
obi_close_column(column_buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close old line selections
|
|
if (view->line_selection != NULL)
|
|
{
|
|
obi_close_column(view->line_selection);
|
|
view->line_selection = NULL;
|
|
// Update line selection reference
|
|
(((view->infos)->line_selection).column_name)[0] = '\0';
|
|
((view->infos)->line_selection).version = -1;
|
|
}
|
|
if (view->new_line_selection != NULL)
|
|
{
|
|
obi_close_column(view->new_line_selection);
|
|
view->new_line_selection = NULL;
|
|
}
|
|
|
|
// Update the line count
|
|
if ((view->infos)->line_count > nb_lines)
|
|
nb_lines = (view->infos)->line_count;
|
|
else if (nb_lines > (view->infos)->line_count)
|
|
update_lines(view, nb_lines);
|
|
|
|
// 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, associated_column_name, associated_column_version, comments);
|
|
}
|
|
else
|
|
{ // Open column
|
|
column = obi_open_column(view->dms, column_name, version_number);
|
|
}
|
|
|
|
if (column == NULL)
|
|
{
|
|
obidebug(1, "\nError creating or opening a column to add to a view");
|
|
return -1;
|
|
}
|
|
|
|
// Store column pointer in the view structure
|
|
(view->columns)[(view->infos)->column_count] = column;
|
|
|
|
// If an alias is not defined, it's the original name of the column. // TODO discuss
|
|
if (alias == NULL)
|
|
alias = column_name;
|
|
|
|
// Save column alias
|
|
strcpy((((view->infos)->column_references)[(view->infos)->column_count]).alias, alias);
|
|
|
|
(view->infos)->column_count++;
|
|
if ((view->infos)->column_count == 1) // first column in the view
|
|
(view->infos)->line_count = nb_lines;
|
|
|
|
// Update column references and dictionary
|
|
update_column_refs_and_dict(view);
|
|
|
|
// // Print dict
|
|
// for (i=0; i<((view->infos)->column_count); i++)
|
|
// {
|
|
// fprintf(stderr, "\n\nalias: %s", (((view->infos)->column_references)[i]).alias);
|
|
// fprintf(stderr, "\npointer: %x\n", obi_view_get_column(view, (((view->infos)->column_references)[i]).alias));
|
|
// }
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int obi_view_delete_column(Obiview_p view, const char* column_name)
|
|
{
|
|
int i;
|
|
bool found;
|
|
|
|
// TODO check that not deleting an obligatory column?
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to delete a column in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
found = false;
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
if ((!found) && (!strcmp((((view->infos)->column_references)[i]).alias, column_name)))
|
|
{
|
|
obi_close_column((view->columns)[i]);
|
|
found = true;
|
|
}
|
|
if (found)
|
|
{
|
|
if (i != (((view->infos)->column_count) - 1)) // not the last one
|
|
{ // Shift the pointer and the references
|
|
(view->columns)[i] = (view->columns)[i+1];
|
|
strcpy((((view->infos)->column_references)[i]).alias, (((view->infos)->column_references)[i+1]).alias);
|
|
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, ((((view->infos)->column_references)[i+1]).column_refs).column_name);
|
|
((((view->infos)->column_references)[i]).column_refs).version = ((((view->infos)->column_references)[i+1]).column_refs).version;
|
|
}
|
|
else // Last column
|
|
(view->columns)[i] = NULL;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to delete a column: column not found");
|
|
return -1;
|
|
}
|
|
|
|
((view->infos)->column_count)--;
|
|
|
|
// Update column dictionary
|
|
update_column_dict(view);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name)
|
|
{
|
|
return (OBIDMS_column_p)(ht_get(view->column_dict, column_name));
|
|
}
|
|
|
|
|
|
OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const char* column_name)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < (view->infos)->column_count; i++)
|
|
{
|
|
if (strcmp((((view->infos)->column_references)[i]).alias, column_name) == 0)
|
|
return ((view->columns)+i);
|
|
}
|
|
obidebug(1, "\nError: column not found");
|
|
return NULL;
|
|
}
|
|
|
|
|
|
int obi_view_create_column_alias(Obiview_p view, const char* current_name, const char* alias)
|
|
{
|
|
int i;
|
|
bool found;
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to change a column alias in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
// Check that the new alias is unique
|
|
if (ht_get(view->column_dict, alias) != NULL)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError: the new name/alias identifying a column in a view is not unique");
|
|
return -1;
|
|
}
|
|
|
|
// Set the new alias in the column references
|
|
found = false;
|
|
for (i=0; i<((view->infos)->column_count); i++)
|
|
{
|
|
if (!strcmp((((view->infos)->column_references)[i]).alias, current_name))
|
|
{
|
|
strcpy((((view->infos)->column_references)[i]).alias, alias);
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (found == false)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError: can't find the column '%s' to change its alias", current_name);
|
|
return -1;
|
|
}
|
|
|
|
// Update the column dictionary
|
|
update_column_dict(view);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int obi_select_line(Obiview_p view, index_t line_nb)
|
|
{
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to select a line in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
// 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, -1, NULL);
|
|
if ((view->new_line_selection) == NULL)
|
|
{
|
|
obidebug(1, "\nError creating a column corresponding to a line selection");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// If we are already working on a line selection, get the pointed line number
|
|
if (view->line_selection)
|
|
line_nb = obi_column_get_index(view->line_selection, line_nb);
|
|
|
|
if (obi_column_set_index(view->new_line_selection, ((view->new_line_selection)->header)->lines_used, line_nb) < 0)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int obi_select_lines(Obiview_p view, index_t* line_nbs)
|
|
{
|
|
int i;
|
|
index_t line_nb;
|
|
|
|
// Check that the view is not read-only
|
|
if (view->read_only)
|
|
{
|
|
obi_set_errno(OBIVIEW_ERROR);
|
|
obidebug(1, "\nError trying to select a line in a read-only view");
|
|
return -1;
|
|
}
|
|
|
|
// 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, -1, NULL);
|
|
if ((view->new_line_selection) == NULL)
|
|
{
|
|
obidebug(1, "\nError creating a column corresponding to a line selection");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
for (i=0; line_nbs[i] != -1; i++)
|
|
{
|
|
line_nb = line_nbs[i];
|
|
|
|
// If we are already working on a line selection, get the pointed line number
|
|
if (view->line_selection)
|
|
line_nb = obi_column_get_index(view->line_selection, line_nb);
|
|
|
|
if (obi_column_set_index(view->new_line_selection, ((view->new_line_selection)->header)->lines_used, line_nb) < 0)
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
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->new_line_selection != NULL)
|
|
{
|
|
(view->infos)->line_count = ((view->new_line_selection)->header)->lines_used;
|
|
strcpy(((view->infos)->line_selection).column_name, ((view->new_line_selection)->header)->name);
|
|
((view->infos)->line_selection).version = ((view->new_line_selection)->header)->version;
|
|
(view->infos)->all_lines = false;
|
|
}
|
|
else if (view->line_selection != NULL) // Unnecessary in theory
|
|
{
|
|
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 selections if they exist
|
|
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;
|
|
}
|
|
}
|
|
|
|
if (view->new_line_selection != NULL)
|
|
{
|
|
if (obi_close_column(view->new_line_selection) < 0)
|
|
{
|
|
obidebug(1, "\nError closing a new 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;
|
|
}
|
|
|
|
|
|
int obi_save_and_close_view(Obiview_p view)
|
|
{
|
|
char* predicates;
|
|
|
|
if (!(view->read_only))
|
|
{
|
|
predicates = view_check_all_predicates(view);
|
|
if (predicates == NULL)
|
|
return -1; // TODO reverse view (delete files)
|
|
else
|
|
{
|
|
// TODO check size and grow file if needed
|
|
strcpy((view->infos)->comments, predicates);
|
|
free(predicates);
|
|
}
|
|
if (obi_save_view(view) < 0)
|
|
return -1;
|
|
}
|
|
if (obi_close_view(view) < 0)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*********** FOR BOOL COLUMNS ***********/
|
|
|
|
int obi_set_bool_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column_p, index_t line_nb, index_t element_idx, obibool_t value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column_p, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obibool_with_elt_idx(column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obibool_t obi_get_bool_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column_p, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIBool_NA;
|
|
return obi_column_get_obibool_with_elt_idx(column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_bool_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column_p, index_t line_nb, const char* element_name, obibool_t value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column_p, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_bool_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obibool_t obi_get_bool_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column_p, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column_p, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIBool_NA;
|
|
return obi_get_bool_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_bool_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, obibool_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_bool_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_bool_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, obibool_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_bool_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obibool_t obi_get_bool_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIBool_NA;
|
|
return obi_get_bool_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
obibool_t obi_get_bool_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIBool_NA;
|
|
return obi_get_bool_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR CHAR COLUMNS ***********/
|
|
|
|
int obi_set_char_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obichar_t value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obichar_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obichar_t obi_get_char_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIChar_NA;
|
|
return obi_column_get_obichar_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_char_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obichar_t value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_char_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obichar_t obi_get_char_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIChar_NA;
|
|
return obi_get_char_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_char_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, obichar_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_char_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_char_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, obichar_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_char_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obichar_t obi_get_char_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIChar_NA;
|
|
return obi_get_char_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
obichar_t obi_get_char_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIChar_NA;
|
|
return obi_get_char_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR FLOAT COLUMNS ***********/
|
|
|
|
int obi_set_float_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obifloat_t value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obifloat_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obifloat_t obi_get_float_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIFloat_NA;
|
|
return obi_column_get_obifloat_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_float_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obifloat_t value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_float_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obifloat_t obi_get_float_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIFloat_NA;
|
|
return obi_get_float_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_float_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, obifloat_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_float_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_float_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, obifloat_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_float_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obifloat_t obi_get_float_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIFloat_NA;
|
|
return obi_get_float_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
obifloat_t obi_get_float_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIFloat_NA;
|
|
return obi_get_float_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR INT COLUMNS ***********/
|
|
|
|
int obi_set_int_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obiint_t value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obiint_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obiint_t obi_get_int_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIInt_NA;
|
|
return obi_column_get_obiint_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_int_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obiint_t value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_int_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obiint_t obi_get_int_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIInt_NA;
|
|
return obi_get_int_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_int_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, obiint_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_int_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_int_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, obiint_t value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_int_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
obiint_t obi_get_int_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIInt_NA;
|
|
return obi_get_int_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
obiint_t obi_get_int_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIInt_NA;
|
|
return obi_get_int_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR QUAL COLUMNS ***********/
|
|
|
|
int obi_set_qual_char_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obiqual_char_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
int obi_set_qual_int_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, const uint8_t* value, int value_length)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obiqual_int_with_elt_idx(column, line_nb, element_idx, value, value_length);
|
|
}
|
|
|
|
|
|
char* obi_get_qual_char_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIQual_char_NA;
|
|
return obi_column_get_obiqual_char_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
const uint8_t* obi_get_qual_int_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, int* value_length)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIQual_int_NA;
|
|
return obi_column_get_obiqual_int_with_elt_idx(column, line_nb, element_idx, value_length);
|
|
}
|
|
|
|
|
|
int obi_set_qual_char_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_qual_char_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
int obi_set_qual_int_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, const uint8_t* value, int value_length)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_qual_int_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value, value_length);
|
|
}
|
|
|
|
|
|
char* obi_get_qual_char_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIQual_char_NA;
|
|
return obi_get_qual_char_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
const uint8_t* obi_get_qual_int_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, int* value_length)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIQual_int_NA;
|
|
return obi_get_qual_int_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value_length);
|
|
}
|
|
|
|
|
|
int obi_set_qual_char_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_qual_char_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_qual_char_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_qual_char_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
char* obi_get_qual_char_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIQual_char_NA;
|
|
return obi_get_qual_char_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
char* obi_get_qual_char_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIQual_char_NA;
|
|
return obi_get_qual_char_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
|
|
int obi_set_qual_int_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, const uint8_t* value, int value_length)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_qual_int_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value, value_length);
|
|
}
|
|
|
|
|
|
int obi_set_qual_int_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, const uint8_t* value, int value_length)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_qual_int_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value, value_length);
|
|
}
|
|
|
|
|
|
const uint8_t* obi_get_qual_int_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, int* value_length)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIQual_int_NA;
|
|
return obi_get_qual_int_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value_length);
|
|
}
|
|
|
|
|
|
const uint8_t* obi_get_qual_int_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, int* value_length)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIQual_int_NA;
|
|
return obi_get_qual_int_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value_length);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR SEQ COLUMNS ***********/
|
|
|
|
int obi_set_seq_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obiseq_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
char* obi_get_seq_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBISeq_NA;
|
|
return obi_column_get_obiseq_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_seq_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_seq_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
char* obi_get_seq_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBISeq_NA;
|
|
return obi_get_seq_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_seq_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_seq_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_seq_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_seq_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
char* obi_get_seq_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBISeq_NA;
|
|
return obi_get_seq_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
char* obi_get_seq_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBISeq_NA;
|
|
return obi_get_seq_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|
|
|
|
/*********** FOR STR COLUMNS ***********/
|
|
|
|
int obi_set_str_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
if (prepare_to_set_value_in_column(view, &column, &line_nb) < 0)
|
|
return -1;
|
|
return obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
const char* obi_get_str_with_elt_idx_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
|
|
{
|
|
if (prepare_to_get_value_from_column(view, &line_nb) < 0)
|
|
return OBIStr_NA;
|
|
return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_str_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return -1;
|
|
return obi_set_str_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
const char* obi_get_str_with_elt_name_and_col_p_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
|
|
{
|
|
index_t element_idx = obi_column_get_element_index_from_name(column, element_name);
|
|
if (element_idx == OBIIdx_NA)
|
|
return OBIStr_NA;
|
|
return obi_get_str_with_elt_idx_and_col_p_in_view(view, column, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
int obi_set_str_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_str_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name, value);
|
|
}
|
|
|
|
|
|
int obi_set_str_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx, const char* value)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return -1;
|
|
return obi_set_str_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx, value);
|
|
}
|
|
|
|
|
|
const char* obi_get_str_with_elt_idx_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, index_t element_idx)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIStr_NA;
|
|
return obi_get_str_with_elt_idx_and_col_p_in_view(view, column_p, line_nb, element_idx);
|
|
}
|
|
|
|
|
|
const char* obi_get_str_with_elt_name_and_col_name_in_view(Obiview_p view, const char* column_name, index_t line_nb, const char* element_name)
|
|
{
|
|
OBIDMS_column_p column_p;
|
|
column_p = obi_view_get_column(view, column_name);
|
|
if (column_p == NULL)
|
|
return OBIStr_NA;
|
|
return obi_get_str_with_elt_name_and_col_p_in_view(view, column_p, line_nb, element_name);
|
|
}
|
|
|
|
/****************************************/
|
|
|