Major update : views

This commit is contained in:
Celine Mercier
2016-02-18 10:38:51 +01:00
parent cfaf069095
commit a8f03248a8
46 changed files with 3207 additions and 1070 deletions

View File

@ -202,8 +202,8 @@ int create_dms_infos_file(int dms_file_descriptor, const char* dms_name)
int obi_dms_exists(const char* dms_name)
{
struct stat buffer;
char *directory_name;
int check_dir;
char* directory_name;
int check_dir;
// Build and check the directory name
directory_name = build_directory_name(dms_name);

View File

@ -39,7 +39,7 @@ struct OBIDMS_column; // TODO
typedef struct Opened_columns_list {
size_t nb_opened_columns;
struct OBIDMS_column** columns;
struct OBIDMS_column** columns; // TODO allocate array size here
} Opened_columns_list_t, *Opened_columns_list_p;

View File

@ -515,8 +515,8 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_elements_per_line,
const char* elements_names,
const char* avl_name,
const char* comments,
bool referring)
const char* comments
)
{
OBIDMS_column_p new_column;
OBIDMS_column_directory_p column_directory;
@ -531,8 +531,6 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t minimum_line_count;
OBIType_t returned_data_type;
OBIType_t stored_data_type;
index_t returned_nb_elements_per_line;
index_t stored_nb_elements_per_line;
new_column = NULL;
@ -547,7 +545,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
obidebug(1, "\nCan't create column because of empty column name");
return NULL;
}
if ((data_type < 1) || (data_type > 6))
if ((data_type < 1) || (data_type > 7))
{
obidebug(1, "\nCan't create column because of invalid data type");
return NULL;
@ -559,21 +557,14 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
}
returned_data_type = data_type;
if ((data_type == OBI_STR) || (data_type == OBI_SEQ) || referring)
if ((data_type == OBI_STR) || (data_type == OBI_SEQ))
// stored data is indices referring to data stored elsewhere
stored_data_type = OBI_IDX;
else
stored_data_type = returned_data_type;
returned_nb_elements_per_line = nb_elements_per_line;
if (referring)
// stored data is indices referring to lines in another column
stored_nb_elements_per_line = 1;
else
stored_nb_elements_per_line = returned_nb_elements_per_line;
// The initial line count should be between the minimum (corresponding to the page size) and the maximum allowed
minimum_line_count = get_line_count_per_page(stored_data_type, stored_nb_elements_per_line);
minimum_line_count = get_line_count_per_page(stored_data_type, nb_elements_per_line);
if (nb_lines > MAXIMUM_LINE_COUNT)
{
obidebug(1, "\nCan't create column because of line count greater than the maximum allowed (%d)", MAXIMUM_LINE_COUNT);
@ -583,12 +574,12 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
nb_lines = minimum_line_count;
// The number of elements names should be equal to the number of elements per line
if ((elements_names == NULL) && (returned_nb_elements_per_line > 1))
if ((elements_names == NULL) && (nb_elements_per_line > 1))
{
obidebug(1, "\nCan't create column because no elements names were given for a number of elements per line greater than 1");
return NULL;
}
else if ((elements_names != NULL) && (returned_nb_elements_per_line > 1))
else if ((elements_names != NULL) && (nb_elements_per_line > 1))
{
char* token;
index_t n = 0;
@ -605,7 +596,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
return NULL;
}
}
else if ((returned_nb_elements_per_line == 1) && (strcmp(elements_names, column_name) != 0))
else if ((nb_elements_per_line == 1) && (strcmp(elements_names, column_name) != 0))
{
obidebug(1, "\nCan't create column because the element name does not match the column name");
return NULL;
@ -622,7 +613,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
// Calculate the size needed
header_size = obi_get_platform_header_size();
data_size = obi_array_sizeof(stored_data_type, nb_lines, stored_nb_elements_per_line);
data_size = obi_array_sizeof(stored_data_type, nb_lines, nb_elements_per_line);
file_size = header_size + data_size;
// Get the latest version number
@ -708,22 +699,19 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
return NULL;
}
new_column->writable = true;
new_column->writable = true;
header = new_column->header;
header->header_size = header_size;
header->data_size = data_size;
header->line_count = nb_lines;
header->lines_used = 0;
header->stored_nb_elements_per_line = stored_nb_elements_per_line;
header->returned_nb_elements_per_line = returned_nb_elements_per_line;
header->nb_elements_per_line = nb_elements_per_line;
header->stored_data_type = stored_data_type;
header->returned_data_type = returned_data_type;
header->creation_date = time(NULL);
header->version = version_number;
header->cloned_from = -1;
header->referring = referring;
header->referred_column_version = -1;
obi_column_set_elements_names(new_column, elements_names);
@ -780,7 +768,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
column_directory = obi_open_column_directory(dms, column_name);
if (column_directory == NULL)
{
obidebug(1, "\nError opening a column directory structure");
//obidebug(1, "\nError opening a column directory structure");
return NULL;
}
@ -818,7 +806,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
if (column_file_descriptor < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError opening column file");
//obidebug(1, "\nError opening column file");
free(column_file_name);
return NULL;
}
@ -854,7 +842,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
MAP_PRIVATE,
column_file_descriptor,
0
);
);
if (column->header == MAP_FAILED)
{
@ -872,7 +860,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
MAP_PRIVATE,
column_file_descriptor,
header_size
);
);
if (column->data == MAP_FAILED)
{
@ -884,7 +872,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
return NULL;
}
column->writable = false;
column->writable = false;
// If the data type is OBI_STR or OBI_SEQ, the associated AVL tree is opened
if (((column->header)->returned_data_type == OBI_STR) || ((column->header)->returned_data_type == OBI_SEQ))
@ -901,18 +889,6 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
column->avl = avl;
}
if ((column->header)->referring)
{
column->referred_column = obi_open_column(dms, column_name, (column->header)->referred_column_version);
if (column->referred_column == NULL)
{
obidebug(1, "\nError opening a referred column");
obi_close_column(column);
close(column_file_descriptor);
return NULL;
}
}
close(column_file_descriptor);
// Add in the list of opened columns and set column counter to 1
@ -925,9 +901,9 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
OBIDMS_column_p line_selection,
const char* column_name,
obiversion_t version_number,
bool referring,
bool clone_data)
{
OBIDMS_column_p column_to_clone;
@ -935,6 +911,10 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
index_t nb_lines;
index_t nb_elements_per_line;
OBIType_t data_type;
size_t line_size;
index_t i, index;
obidebug(1, "\nline_selection == NULL = %d\n", (line_selection == NULL));
column_to_clone = obi_open_column(dms, column_name, version_number);
if (column_to_clone == NULL)
@ -944,25 +924,11 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
return NULL;
}
// A referring column can't be cloned
if ((column_to_clone->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: can't clone a referring column");
return NULL;
}
data_type = (column_to_clone->header)->returned_data_type;
nb_elements_per_line = (column_to_clone->header)->returned_nb_elements_per_line;
nb_elements_per_line = (column_to_clone->header)->nb_elements_per_line;
if (clone_data && referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: can't clone the data when creating a referring column");
return NULL;
}
else if (clone_data)
if (clone_data)
nb_lines = (column_to_clone->header)->line_count;
else
nb_lines = get_line_count_per_page(data_type, nb_elements_per_line); // minimum line count corresponding to one memory page
@ -974,8 +940,8 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
nb_elements_per_line,
(column_to_clone->header)->elements_names,
(column_to_clone->header)->avl_name,
(column_to_clone->header)->comments,
referring);
(column_to_clone->header)->comments
);
if (new_column == NULL)
{
@ -989,24 +955,29 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
(new_column->header)->cloned_from = (column_to_clone->header)->version;
if (referring)
{
if ((column_to_clone->header)->referring)
(new_column->header)->referred_column_version = (column_to_clone->header)->referred_column_version;
else
(new_column->header)->referred_column_version = (column_to_clone->header)->version;
}
if (clone_data)
if (clone_data && (line_selection == NULL))
{
memcpy(new_column->data, column_to_clone->data, (column_to_clone->header)->data_size);
(new_column->header)->lines_used = (column_to_clone->header)->lines_used;
}
else if (clone_data && (line_selection != NULL))
{
obidebug(1, "\nCloning data from line selection\n");
line_size = obi_sizeof((new_column->header)->stored_data_type) * (new_column->header)->nb_elements_per_line;
fprintf(stderr, "\nline size = %ld\n", line_size);
for (i=0; i<((line_selection->header)->lines_used); i++)
{
index = *(((index_t*) (line_selection->data)) + i);
fprintf(stderr, "\nindex = %lld, i = %lld\n", index, i);
memcpy((new_column->data)+(i*line_size), (column_to_clone->data)+(index*line_size), line_size);
fprintf(stderr, "\nmemcpied\n");
}
(new_column->header)->lines_used = (line_selection->header)->lines_used;
obidebug(1, "\nCloned data from line selection\n");
}
// close column_to_clone or store the pointer if it's referred
if (referring)
new_column->referred_column = column_to_clone;
else if (obi_close_column(column_to_clone) < 0)
// Close column_to_clone
if (obi_close_column(column_to_clone) < 0)
{
obidebug(1, "\nError closing a column that has been cloned");
// TODO return NULL or not?
@ -1049,9 +1020,6 @@ int obi_close_column(OBIDMS_column_p column)
}
}
if ((column->header)->referring)
obi_close_column(column->referred_column);
// If the data type is OBI_STR or OBI_SEQ, the associated AVL tree is closed
if (((column->header)->returned_data_type == OBI_STR) || ((column->header)->returned_data_type == OBI_SEQ))
{
@ -1095,8 +1063,8 @@ int obi_truncate_column_to_lines_used(OBIDMS_column_p column) // TODO is it nece
char* column_file_name;
// Compute the new line count = the number of lines used rounded to the nearest greater multiple of page size greater than 0
multiple = ceil((double) (ONE_IF_ZERO((column->header)->lines_used) * (column->header)->stored_nb_elements_per_line * obi_sizeof((column->header)->stored_data_type)) / (double) getpagesize());
new_line_count = floor((((int) multiple) * getpagesize()) / ((column->header)->stored_nb_elements_per_line * obi_sizeof((column->header)->stored_data_type)));
multiple = ceil((double) (ONE_IF_ZERO((column->header)->lines_used) * (column->header)->nb_elements_per_line * obi_sizeof((column->header)->stored_data_type)) / (double) getpagesize());
new_line_count = floor((((int) multiple) * getpagesize()) / ((column->header)->nb_elements_per_line * obi_sizeof((column->header)->stored_data_type)));
// Check that it is actually greater than the current number of lines allocated in the file, otherwise no need to truncate
if ((column->header)->line_count == new_line_count)
@ -1131,7 +1099,7 @@ int obi_truncate_column_to_lines_used(OBIDMS_column_p column) // TODO is it nece
}
// Truncate the column file
data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->stored_nb_elements_per_line);
data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line);
file_size = (column->header)->header_size + data_size;
if (ftruncate(column_file_descriptor, file_size) < 0)
{
@ -1262,8 +1230,11 @@ int obi_enlarge_column(OBIDMS_column_p column)
int obi_truncate_and_close_column(OBIDMS_column_p column)
{
if (obi_truncate_column_to_lines_used(column) < 0)
return -1;
if (column->writable) // TODO discuss
{
if (obi_truncate_column_to_lines_used(column) < 0)
return -1;
}
if (obi_close_column(column) < 0)
return -1;
@ -1277,8 +1248,8 @@ void obi_ini_to_NA_values(OBIDMS_column_p column,
{
index_t i, start, end, nb_elements;
nb_elements = nb_lines*((column->header)->stored_nb_elements_per_line);
start = first_line_nb*((column->header)->stored_nb_elements_per_line);
nb_elements = nb_lines*((column->header)->nb_elements_per_line);
start = first_line_nb*((column->header)->nb_elements_per_line);
end = start + nb_elements;
switch ((column->header)->stored_data_type) {
@ -1476,35 +1447,3 @@ char* obi_column_format_date(time_t date)
return formatted_time;
}
// TODO put in separate file ?
// warning for the dependency and for the fact that it's always added at the next line (or not cuz might not be a good idea?)
int obi_grep_line(OBIDMS_column_p referring_column, index_t line_to_grep)
{
// Check that the column is referring another
if (!((referring_column->header)->referring))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Grepping a line can only be done with a referring column");
return -1;
}
// Check if the file needs to be enlarged
if ((referring_column->header)->lines_used == (referring_column->header)->line_count)
{
// Enlarge the file
if (obi_enlarge_column(referring_column) < 0)
return -1;
}
// Set the value
*(((index_t*) (referring_column->data)) + (referring_column->header)->lines_used) = line_to_grep;
// Update lines used
((referring_column->header)->lines_used)++;
return 0;
}

View File

@ -57,11 +57,7 @@ typedef struct OBIDMS_column_header {
*/
index_t lines_used; /**< Number of lines of data used.
*/
index_t returned_nb_elements_per_line; /**< Number of elements per line returned when getting a
* line from the column.
*/
index_t stored_nb_elements_per_line; /**< Number of elements per line that is actually stored
* in the data part of the column.
index_t nb_elements_per_line; /**< Number of elements per line.
*/
char elements_names[ELEMENTS_NAMES_MAX+1]; /**< Names of the line elements with ';' as separator
* (should be the column name if one element per line).
@ -80,10 +76,6 @@ typedef struct OBIDMS_column_header {
* was cloned from (-1 if it was not created by cloning
* another column).
*/
bool referring; /**< Whether the column contains indices referring to another column.
*/
obiversion_t referred_column_version; /**< Version of the column to which this column is referring.
*/
char name[OBIDMS_COLUMN_MAX_NAME+1]; /**< The column name as a NULL terminated string.
*/
char avl_name[AVL_MAX_NAME+1]; /**< If there is one, the AVL tree name as a NULL terminated string.
@ -108,14 +100,12 @@ typedef struct OBIDMS_column {
*/
OBIDMS_avl_p avl; /**< A pointer to the AVL tree associated with the column if there is one.
*/
struct OBIDMS_column* referred_column; /**< A pointer to the referred column if the column is referring.
*/
void* data; /**< A `void` pointer to the beginning of the data.
*
* @warning Never use this member directly outside of the code of the
* low level functions of the OBIDMS.
*/
bool writable; /**< Indicates if the column is writable or not. TODO delete?
bool writable; /**< Indicates if the column is writable or not.
* - `true` the column is writable
* - `false` the column is read-only
*
@ -186,7 +176,6 @@ size_t obi_get_platform_header_size();
* @param elements_names The names of the elements with ';' as separator.
* @param avl_name The name of the AVL tree if there is one associated with the column.
* @param comments Optional comments associated with the column.
* @param referring
*
* @returns A pointer on the newly created column structure.
* @retval NULL if an error occurred.
@ -201,8 +190,8 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_elements_per_line,
const char* elements_names,
const char* avl_name,
const char* comments,
bool referring);
const char* comments
);
/**
@ -235,7 +224,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms, const char* column_name, obiversio
* @since August 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number, bool referring, bool clone_data);
OBIDMS_column_p obi_clone_column(OBIDMS_p dms, OBIDMS_column_p line_selection, const char* column_name, obiversion_t version_number, bool clone_data);
/**
@ -372,7 +361,7 @@ index_t obi_column_get_element_index_from_name(OBIDMS_column_p column, const cha
char* obi_column_format_date(time_t date);
int obi_grep_line(OBIDMS_column_p referring_column, index_t line_to_grep);
int obi_select(OBIDMS_column_p lines_column, index_t line_to_grep);

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -28,16 +29,9 @@
*
**********************************************************************/
int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, obibool_t value)
{
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -59,7 +53,44 @@ int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
(column->header)->lines_used = line_nb+1;
// Set the value
*(((obibool_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
*(((obibool_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = value;
return 0;
}
int obi_column_set_obibool_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obibool_t value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obibool_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
@ -67,22 +98,30 @@ int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
obibool_t obi_column_get_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIBool_NA;
}
if ((column->header)->referring)
return *(((obibool_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
}
obibool_t obi_column_get_obibool_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->line_count))
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
return *(((obibool_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
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 OBIBool_NA;
}
else
return *(((obibool_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obibool_with_elt_idx(column, line_nb, element_idx);
}
@ -97,6 +136,17 @@ int obi_column_set_obibool_with_elt_name(OBIDMS_column_p column, index_t line_nb
}
int obi_column_set_obibool_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obibool_t value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obibool_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
obibool_t obi_column_get_obibool_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
@ -107,3 +157,13 @@ obibool_t obi_column_get_obibool_with_elt_name(OBIDMS_column_p column, index_t l
return obi_column_get_obibool_with_elt_idx(column, line_nb, element_idx);
}
obibool_t obi_column_get_obibool_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBIBool_NA;
return obi_column_get_obibool_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -38,7 +39,7 @@
* @since July 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, size_t element_idx, obibool_t value);
int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, obibool_t value);
/**
@ -54,7 +55,7 @@ int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
* @since July 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obibool_t obi_column_get_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, size_t element_idx);
obibool_t obi_column_get_obibool_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
@ -95,5 +96,79 @@ int obi_column_set_obibool_with_elt_name(OBIDMS_column_p column, index_t line_nb
obibool_t obi_column_get_obibool_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_BOOL, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obibool_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obibool_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_BOOL.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obibool_t obi_column_get_obibool_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_BOOL,
* using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obibool_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obibool_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_BOOL,
* using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obibool_t obi_column_get_obibool_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_BOOL_H_ */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -28,16 +29,9 @@
*
**********************************************************************/
int obi_column_set_obichar_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, obichar_t value)
{
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -59,7 +53,44 @@ int obi_column_set_obichar_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
(column->header)->lines_used = line_nb+1;
// Set the value
*(((obichar_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
*(((obichar_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = value;
return 0;
}
int obi_column_set_obichar_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obichar_t value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obichar_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
@ -67,22 +98,30 @@ int obi_column_set_obichar_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
obichar_t obi_column_get_obichar_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIChar_NA;
}
if ((column->header)->referring)
return *(((obichar_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
}
obichar_t obi_column_get_obichar_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->line_count))
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
return *(((obichar_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
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 OBIChar_NA;
}
else
return *(((obichar_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obichar_with_elt_idx(column, line_nb, element_idx);
}
@ -97,6 +136,17 @@ int obi_column_set_obichar_with_elt_name(OBIDMS_column_p column, index_t line_nb
}
int obi_column_set_obichar_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obichar_t value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obichar_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
obichar_t obi_column_get_obichar_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
@ -107,3 +157,13 @@ obichar_t obi_column_get_obichar_with_elt_name(OBIDMS_column_p column, index_t l
return obi_column_get_obichar_with_elt_idx(column, line_nb, element_idx);
}
obichar_t obi_column_get_obichar_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBIChar_NA;
return obi_column_get_obichar_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -49,7 +50,7 @@ int obi_column_set_obichar_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
* @retval OBIChar_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since July 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
@ -87,7 +88,7 @@ int obi_column_set_obichar_with_elt_name(OBIDMS_column_p column, index_t line_nb
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
* @retval OBIChar_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since August 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
@ -95,5 +96,79 @@ int obi_column_set_obichar_with_elt_name(OBIDMS_column_p column, index_t line_nb
obichar_t obi_column_get_obichar_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_CHAR, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obichar_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obichar_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_CHAR.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIChar_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obichar_t obi_column_get_obichar_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_CHAR,
* using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obichar_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obichar_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_CHAR,
* using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIChar_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obichar_t obi_column_get_obichar_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_CHAR_H_ */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -30,14 +31,6 @@
int obi_column_set_obifloat_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, obifloat_t value)
{
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -59,7 +52,44 @@ int obi_column_set_obifloat_with_elt_idx(OBIDMS_column_p column, index_t line_nb
(column->header)->lines_used = line_nb+1;
// Set the value
*(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
*(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = value;
return 0;
}
int obi_column_set_obifloat_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obifloat_t value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obifloat_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
@ -67,22 +97,30 @@ int obi_column_set_obifloat_with_elt_idx(OBIDMS_column_p column, index_t line_nb
obifloat_t obi_column_get_obifloat_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIFloat_NA;
}
if ((column->header)->referring)
return *(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
}
obifloat_t obi_column_get_obifloat_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->line_count))
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
return *(((obifloat_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
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 OBIFloat_NA;
}
else
return *(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obifloat_with_elt_idx(column, line_nb, element_idx);
}
@ -97,6 +135,17 @@ int obi_column_set_obifloat_with_elt_name(OBIDMS_column_p column, index_t line_n
}
int obi_column_set_obifloat_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obifloat_t value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obifloat_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
obifloat_t obi_column_get_obifloat_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
@ -107,3 +156,13 @@ obifloat_t obi_column_get_obifloat_with_elt_name(OBIDMS_column_p column, index_t
return obi_column_get_obifloat_with_elt_idx(column, line_nb, element_idx);
}
obifloat_t obi_column_get_obifloat_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBIFloat_NA;
return obi_column_get_obifloat_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -49,7 +50,7 @@ int obi_column_set_obifloat_with_elt_idx(OBIDMS_column_p column, index_t line_nb
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
* @retval OBIFloat_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since July 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
@ -87,7 +88,7 @@ int obi_column_set_obifloat_with_elt_name(OBIDMS_column_p column, index_t line_n
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
* @retval OBIFloat_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since August 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
@ -95,5 +96,79 @@ int obi_column_set_obifloat_with_elt_name(OBIDMS_column_p column, index_t line_n
obifloat_t obi_column_get_obifloat_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_FLOAT, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obifloat_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obifloat_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_FLOAT.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIFloat_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obifloat_t obi_column_get_obifloat_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_FLOAT,
* using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obifloat_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obifloat_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_FLOAT,
* using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIFloat_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obifloat_t obi_column_get_obifloat_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_FLOAT_H_ */

72
src/obidmscolumn_idx.c Normal file
View File

@ -0,0 +1,72 @@
/****************************************************************************
* OBIDMS_column_idx functions *
****************************************************************************/
/**
* @file obidsmcolumn_idx.c
* @author Celine Mercier
* @date February 14th 2016
* @brief Functions handling OBIColumns containing data with the index_t type.
*/
#include <stdlib.h>
#include <stdio.h>
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
/**********************************************************************
*
* 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
*
**********************************************************************/
int obi_column_set_index(OBIDMS_column_p column, index_t line_nb, index_t value)
{
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to set a value at a line number greater than the maximum allowed");
return -1;
}
// Check if the file needs to be enlarged
while ((line_nb+1) > (column->header)->line_count)
{
// Enlarge the file
if (obi_enlarge_column(column) < 0)
return -1;
}
// Update lines used
if ((line_nb+1) > (column->header)->lines_used)
(column->header)->lines_used = line_nb+1;
// Set the value
*(((index_t*) (column->data)) + line_nb) = value;
return 0;
}
index_t obi_column_get_index(OBIDMS_column_p column, index_t line_nb)
{
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIIdx_NA;
}
return *(((index_t*) (column->data)) + line_nb);
}

30
src/obidmscolumn_idx.h Normal file
View File

@ -0,0 +1,30 @@
/****************************************************************************
* OBIDMS_column_idx header file *
****************************************************************************/
/**
* @file obidsmcolumn_idx.h
* @author Celine Mercier
* @date February 14th 2016
* @brief Header file for the functions handling OBIColumns containing data with the OBIType OBI_IDX.
*/
#ifndef OBIDMSCOLUMN_IDX_H_
#define OBIDMSCOLUMN_IDX_H_
#include <stdlib.h>
#include <stdio.h>
#include "obidmscolumn.h"
#include "obitypes.h"
int obi_column_set_index(OBIDMS_column_p column, index_t line_nb, index_t value);
index_t obi_column_get_index(OBIDMS_column_p column, index_t line_nb);
#endif /* OBIDMSCOLUMN_IDX_H_ */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -28,16 +29,9 @@
*
**********************************************************************/
int obi_column_set_obiint_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, obiint_t value)
{
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -59,7 +53,44 @@ int obi_column_set_obiint_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
(column->header)->lines_used = line_nb+1;
// Set the value
*(((obiint_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
*(((obiint_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = value;
return 0;
}
int obi_column_set_obiint_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obiint_t value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obiint_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
@ -67,22 +98,30 @@ int obi_column_set_obiint_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
obiint_t obi_column_get_obiint_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIInt_NA;
}
if ((column->header)->referring)
return *(((obiint_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
}
obiint_t obi_column_get_obiint_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->line_count))
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
return *(((obiint_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
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 OBIInt_NA;
}
else
return *(((obiint_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obiint_with_elt_idx(column, line_nb, element_idx);
}
@ -97,6 +136,17 @@ int obi_column_set_obiint_with_elt_name(OBIDMS_column_p column, index_t line_nb,
}
int obi_column_set_obiint_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obiint_t value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obiint_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
obiint_t obi_column_get_obiint_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
@ -107,3 +157,14 @@ obiint_t obi_column_get_obiint_with_elt_name(OBIDMS_column_p column, index_t lin
return obi_column_get_obiint_with_elt_idx(column, line_nb, element_idx);
}
obiint_t obi_column_get_obiint_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBIInt_NA;
return obi_column_get_obiint_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -95,5 +96,79 @@ int obi_column_set_obiint_with_elt_name(OBIDMS_column_p column, index_t line_nb,
obiint_t obi_column_get_obiint_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_INT, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obiint_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obiint_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_INT.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obiint_t obi_column_get_obiint_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data with the type OBI_INT,
* using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obiint_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, obiint_t value);
/**
* @brief Recovers a value in an OBIDMS column containing data with the type OBI_INT,
* using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval OBIBool_NA the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
obiint_t obi_column_get_obiint_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_INT_H_ */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -29,19 +30,12 @@
*
**********************************************************************/
int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
{
byte_t* value_b;
index_t idx;
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -73,7 +67,7 @@ int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
return -1;
// Add the value's index in the column
*(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = idx;
*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;
free(value_b);
@ -81,44 +75,100 @@ int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
}
int obi_column_set_obiseq_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obiseq_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
const char* obi_column_get_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t idx;
byte_t* value_b;
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return "\0"; // TODO
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBISeq_NA;
}
if ((column->header)->referring)
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
idx = *(((index_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
}
else
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
// Check NA
if (idx == OBIIdx_NA)
return "\0"; // TODO
return OBISeq_NA;
value_b = obi_avl_get(column->avl, idx);
return obi_obibytes_to_seq(value_b);
}
const char* obi_column_get_obiseq_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->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 OBISeq_NA;
}
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obiseq_with_elt_idx(column, line_nb, element_idx);
}
int obi_column_set_obiseq_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
if (obi_column_set_obiseq_with_elt_idx(column, line_nb, element_idx, value) < 0)
obi_column_set_obiseq_with_elt_idx(column, line_nb, element_idx, value);
return 0;
}
int obi_column_set_obiseq_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obiseq_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
@ -129,7 +179,18 @@ const char* obi_column_get_obiseq_with_elt_name(OBIDMS_column_p column, index_t
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return "\0";
return OBISeq_NA;
return obi_column_get_obiseq_with_elt_idx(column, line_nb, element_idx);
}
const char* obi_column_get_obiseq_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBISeq_NA;
return obi_column_get_obiseq_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -97,5 +98,81 @@ int obi_column_set_obiseq_with_elt_name(OBIDMS_column_p column, index_t line_nb,
const char* obi_column_get_obiseq_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an AVL tree, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obiseq_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value);
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an AVL tree, using the index of the element in the line.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval '\0' the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
const char* obi_column_get_obiseq_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an AVL tree, using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obiseq_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value);
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an AVL tree, using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval '\0' the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
const char* obi_column_get_obiseq_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_SEQ_H_ */

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#include "obidmscolumn.h"
#include "obiview.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
@ -34,14 +35,6 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
byte_t* value_b;
index_t idx;
// Check that the column is not referring another
if ((column->header)->referring)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
return -1;
}
// Check that the line number is not greater than the maximum allowed
if (line_nb >= MAXIMUM_LINE_COUNT)
{
@ -73,7 +66,7 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
return -1;
// Add the value's index in the column
*(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = idx;
*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;
free(value_b);
@ -81,44 +74,100 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
}
int obi_column_set_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
{
// 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 ((view->line_selection != NULL) || (!(column->writable)))
{
// Get the right line number
if (column->writable)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
column = obi_view_clone_column(view, (column->header)->name);
if (column == NULL)
{
obidebug(1, "\nError trying to clone a column to modify it");
return -1;
}
}
if ((line_nb+1) > view->line_count)
{
if (obi_view_update_lines(view, (line_nb+1)) < 0)
return -1;
}
if (obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value) < 0)
return -1;
return 0;
}
const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
index_t idx;
byte_t* value_b;
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
if ((line_nb+1) > ((column->header)->line_count))
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return "\0"; // TODO
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
return OBIStr_NA;
}
if ((column->header)->referring)
{
referring_idx = *(((index_t*) (column->data)) + line_nb);
idx = *(((index_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
}
else
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
// Check NA
if (idx == OBIIdx_NA)
return "\0"; // TODO
return OBIStr_NA;
value_b = obi_avl_get(column->avl, idx);
return obi_obibytes_to_str(value_b);
}
const char* obi_column_get_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
if ((line_nb+1) > (view->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 OBIStr_NA;
}
if (view->line_selection)
line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);
return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
}
int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
if (obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value) < 0)
obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value);
return 0;
}
int obi_column_set_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return -1;
obi_column_set_obistr_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
return 0;
}
@ -129,7 +178,18 @@ const char* obi_column_get_obistr_with_elt_name(OBIDMS_column_p column, index_t
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return "\0";
return OBIStr_NA;
return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
}
const char* obi_column_get_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
index_t element_idx;
element_idx = obi_column_get_element_index_from_name(column, element_name);
if (element_idx == OBIIdx_NA)
return OBIStr_NA;
return obi_column_get_obistr_with_elt_idx_in_view(view, column, line_nb, element_idx);
}

View File

@ -19,6 +19,7 @@
#include "obidmscolumn.h"
#include "obitypes.h"
#include "obiview.h"
/**
@ -97,5 +98,81 @@ int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb,
const char* obi_column_get_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name);
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an AVL tree, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_idx The index of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value);
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an AVL tree, using the index of the element in the line.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_idx The index of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval '\0' the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
const char* obi_column_get_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx);
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an AVL tree, using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be set.
* @param element_name The name of the element that should be set in the line.
* @param value The value that should be set.
*
* @returns An integer value indicating the success of the operation.
* @retval 0 on success.
* @retval -1 if an error occurred.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int obi_column_set_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value);
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an AVL tree, using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
* @param element_name The name of the element that should be recovered in the line.
*
* @returns The recovered value.
* @retval '\0' the NA value of the type if an error occurred and obi_errno is set.
*
* @since February 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
const char* obi_column_get_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name);
#endif /* OBIDMSCOLUMN_STR_H_ */

View File

@ -100,6 +100,8 @@ extern int obi_errno;
*/
#define OBI_AVL_ERROR (20) /** Error while handling an AVL tree
*/
#define OBIVIEW_ERROR (21) /** Error while handling an OBIView
*/
/**@}*/
#endif /* OBIERRNO_H_ */

View File

@ -23,6 +23,8 @@
#define OBIFloat_NA (float_NA()) /**< NA value for the type OBI_FLOAT */
#define OBIChar_NA (0) /**< NA value for the type OBI_CHAR */
// TODO not sure about this one as it can be impossible to distinguish from uninitialized values
#define OBISeq_NA ("\0") // TODO
#define OBIStr_NA ("\0") // TODO
/**
@ -32,7 +34,7 @@ typedef enum OBIBool {
FALSE = 0,
TRUE = 1,
OBIBool_NA = 2
} obibool_t, *obibool_p; /**< a boolean true/false value */
} obibool_t, *obibool_p; /**< a boolean true/false value */ // TODO check name convention?
/**
@ -46,7 +48,7 @@ typedef enum OBIType {
OBI_CHAR, /**< a character (C type : char) */
OBI_STR, /**< an index in a data structure (C type : int64_t) referring to a character string */
OBI_SEQ, /**< an index in a data structure (C type : int64_t) referring to a DNA sequence */
OBI_IDX /**< an index referring to a line in another column (C type : int64_t) */
OBI_IDX /**< an index referring to a line in another column (C type : int64_t) */ // TODO delete?
} OBIType_t, *OBIType_p;

949
src/obiview.c Normal file
View File

@ -0,0 +1,949 @@
/********************************************************************
* Obiview functions *
********************************************************************/
/**
* @file obiview.c
* @author Celine Mercier (celine.mercier@metabarcoding.org)
* @date 16 December 2015
* @brief Obiview functions.
*/
// TODO
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "obidms.h"
#include "obiview.h"
#include "obierrno.h"
#include "obidebug.h"
#include "obidmscolumn.h"
#include "private_at_functions.h"
#include "obilittlebigman.h"
#include "obidmscolumn_idx.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 building the file name where obiviews 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 dms_name The name of the OBIDMS.
*
* @since December 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static char* build_obiview_file_name();
/** TODO public
* Internal function creating the file containing basic informations on the OBIDMS.
*
* This file contains:
* - The endianness of the platform
*
* @warning The returned pointer has to be freed by the caller.
*
* @param dms_file_descriptor The file descriptor for the OBIDMS directory.
* @param dms_name The name of the OBIDMS.
*
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since November 2015
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int create_obiview_file(int dms_file_descriptor);
/************************************************************************
*
* 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
*
************************************************************************/
static char* build_obiview_file_name()
{
char* file_name;
// Build file name
if (asprintf(&file_name, OBIVIEW_FILE_NAME) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nProblem building an obiview file name");
return NULL;
}
return file_name;
}
size_t get_platform_header_size()
{
size_t header_size;
size_t rounded_header_size;
double multiple;
header_size = sizeof(Obiviews_header_t);
multiple = ceil((double) header_size / (double) getpagesize());
rounded_header_size = multiple * getpagesize();
return rounded_header_size;
}
size_t get_platform_views_size(nb_of_views)
{
size_t obiview_size;
size_t rounded_obiview_size;
double multiple;
obiview_size = sizeof(Obiview_infos_t);
multiple = ceil((double) (obiview_size*nb_of_views) / (double) getpagesize());
rounded_obiview_size = multiple * getpagesize();
return rounded_obiview_size;
}
int create_obiview_file(int dms_file_descriptor)
{
char* file_name;
int obiview_file_descriptor;
size_t header_size;
// size_t view_size;
size_t file_size;
Obiviews_header_p header;
// Create file name
file_name = build_obiview_file_name();
if (file_name == NULL)
return -1;
// Create file
obiview_file_descriptor = openat(dms_file_descriptor, file_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
header_size = get_platform_header_size();
//view_size = get_platform_views_size(1);
file_size = header_size; // + view_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;
}
// Map the header
header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
obiview_file_descriptor,
0
);
if (header == MAP_FAILED)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError mmapping an obiview file header");
close(obiview_file_descriptor);
return -1;
}
// Initialize the header
header->header_size = header_size;
header->views_size = 0;
header->view_count = 0;
// Unmap the header
if (munmap(header, header_size) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError munmapping an obiview file header");
close(obiview_file_descriptor);
return -1;
}
close(obiview_file_descriptor);
return 0;
}
/**********************************************************************
*
* 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)
{
Obiview_p view;
int i;
index_t line_nb;
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;
}
// 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");
free(view);
return NULL;
}
view->dms = dms;
view->column_count = view_to_clone->column_count;
if ((view_to_clone->line_selection != NULL) && (line_selection == NULL)) // reorder conditions
{
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)
return NULL;
view->line_count = view_to_clone->line_count;
}
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);
if ((view->line_selection) == NULL)
{
obidebug(1, "\nError creating a column corresponding to a line selection");
return NULL;
}
view->line_count = 0;
i = 0;
for (i=0; line_selection[i] != -1; i++)
{
line_nb = line_selection[i];
if (line_nb > view_to_clone->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);
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);
free(view);
return NULL;
}
// Update view line count
(view->line_count)++;
}
}
else
{
view->line_selection = NULL;
view->line_count = view_to_clone->line_count;
}
for (i=0; i<(view_to_clone->column_count); i++)
{
(view->columns)[i] = obi_open_column(dms, (((view_to_clone->columns)[i])->header)->name, (((view_to_clone->columns)[i])->header)->version);
if ((view->columns)[i] == NULL)
{
obi_close_column(view->line_selection);
free(view);
return NULL;
}
}
strcpy(view->created_from, view_to_clone->name);
view->new_line_selection = NULL;
}
// Else, fill empty view structure
else
{
view->dms = dms;
view->column_count = 0;
view->line_count = 0;
view->line_selection = NULL;
view->new_line_selection = NULL;
(view->created_from)[0] = '\0';
//view->columns = NULL; TODO
}
strcpy(view->name, view_name);
view->read_only = 0;
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)
{
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);
return view;
}
Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
{
Obiview_p view;
bool first_view;
char* view_file_name;
int obiview_file_descriptor;
size_t header_size;
Obiviews_header_p header;
Obiview_infos_p views;
Obiview_infos_p view_infos;
OBIDMS_column_p column;
int i;
int view_number;
// Check if 1st view : view file doesn't exist
first_view = 0;
view_file_name = build_obiview_file_name();
if (view_file_name == NULL)
return NULL;
// Open view file, read header size and map header and views
obiview_file_descriptor = openat(dms->dir_fd, view_file_name, O_RDWR, 0777);
if (obiview_file_descriptor < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError opening an obiview file");
free(view_file_name);
return NULL;
}
free(view_file_name);
// Read the header size
if (read(obiview_file_descriptor, &header_size, sizeof(size_t)) < ((ssize_t) sizeof(size_t)))
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError reading the header size of an obiview file (trying to open a view when there are none?)");
close(obiview_file_descriptor);
return NULL;
}
// Map the header
header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
obiview_file_descriptor,
0
);
if (header == MAP_FAILED)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError mmapping an obiview file header");
close(obiview_file_descriptor);
return NULL;
}
// Map the views
views = mmap(NULL,
header->views_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
obiview_file_descriptor,
header_size
);
if (views == MAP_FAILED)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError mmapping the views from an obiview file");
munmap(header, header_size);
close(obiview_file_descriptor);
return NULL;
}
// Find and open view that should be read with the line selection associated
view_number = -1;
if (view_name == NULL) // If view name is NULL, open the latest view TODO discuss
view_number = (header->view_count) - 1;
else
{
for (i=0; i<(header->view_count); i++)
{
if (!strcmp((views+i)->name, view_name))
{ // Found the view to open
view_number = i;
}
}
}
if (view_number == -1)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError: the view '%s' to open was not found", view_name);
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return NULL;
}
view_infos = views + view_number;
view = (Obiview_p) malloc(sizeof(Obiview_t));
if (view == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError allocating memory for a view");
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return NULL;
}
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)
{
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return NULL;
}
}
view->dms = dms;
view->new_line_selection = NULL;
view->read_only = 1;
view->column_count = 0;
view->line_count = view_infos->line_count;
strcpy(view->created_from, view_infos->created_from);
strcpy(view->name, view_infos->name);
// Open the columns to read
for (i=0; i<(view_infos->column_count); i++)
{
column = obi_open_column(dms, ((view_infos->column_references)+i)->column_name, ((view_infos->column_references)+i)->version);
if (column == NULL)
{
obidebug(1, "\nError opening a column for a view: column %d: %s, version %d", i, ((view_infos->column_references)+i)->column_name, ((view_infos->column_references)+i)->version);
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return NULL;
}
// Store column in the view
(view->columns)[view->column_count] = column;
view->column_count++;
}
// Munmap and close things TODO
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return view;
}
int obi_view_add_column(Obiview_p view,
const char* column_name,
obiversion_t version_number,
OBIType_t data_type,
index_t nb_lines,
index_t nb_elements_per_line,
const char* elements_names,
const char* avl_name,
const char* comments,
bool create) // all infos for creation or open
{
OBIDMS_column_p column;
// 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 (view->line_count > nb_lines)
nb_lines = view->line_count;
else if (nb_lines > view->line_count)
obi_view_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, avl_name, 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 in the view
(view->columns)[view->column_count] = column;
view->column_count++;
if (view->column_count == 1) // first column in the view
view->line_count = (column->header)->lines_used;
return 0;
}
OBIDMS_column_p obi_view_clone_column(Obiview_p view, const char* column_name)
{
int i;
OBIDMS_column_p current_line_selection = NULL;
OBIDMS_column_p column;
OBIDMS_column_p column_buffer;
// 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
current_line_selection = view->new_line_selection;
else
current_line_selection = view->line_selection;
for (i=0; i<(view->column_count); i++)
{
if ((current_line_selection != NULL) || (!(strcmp((((view->columns)[i])->header)->name, column_name))))
{ // Clone with the right line selection and replace
column_buffer = (view->columns)[i];
(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;
}
// Found the column to return
if (!(strcmp((((view->columns)[i])->header)->name, column_name)))
column = (view->columns)[i];
else
obi_truncate_and_close_column(column_buffer); // TODO weird closing after cloning but can't think of cleaner yet
}
}
if (view->line_selection != NULL)
{
obi_truncate_and_close_column(view->line_selection);
view->line_selection = NULL;
}
if (view->new_line_selection != NULL)
{
obi_truncate_and_close_column(view->new_line_selection);
view->new_line_selection = NULL;
}
return column;
}
int obi_view_delete_column(Obiview_p view, const char* column_name)
{
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 delete a column in a read-only view");
return -1;
}
found = 0;
for (i=0; i<(view->column_count); i++)
{
if (!strcmp((((view->columns)[i])->header)->name, column_name))
{
obi_truncate_and_close_column((view->columns)[i]);
found = 1;
}
if (found)
{
if (i != ((view->column_count) - 1)) // not the last one
(view->columns)[i] = (view->columns)[i+1];
else // Last column
(view->columns)[i] = NULL;
}
}
if (!found)
return -1;
(view->column_count)--;
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 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);
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);
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_view_update_lines(Obiview_p view, index_t line_count)
{
int i;
for (i=0; i<(view->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->line_count = line_count;
return 0;
}
OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name)
{
int i;
for (i=0; i<(view->column_count); i++)
{
if (!(strcmp((((view->columns)[i])->header)->name, column_name)))
return (view->columns)[i];
}
return NULL;
}
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->column_count); i++)
{
if (!(strcmp((((view->columns)[i])->header)->name, column_name)))
return ((view->columns)+i);
}
return NULL;
}
int obi_save_view(Obiview_p view)
{
int i;
struct stat buffer;
char* view_file_name;
char* full_path;
int check_file;
int obiview_file_descriptor;
size_t header_size;
size_t views_size;
size_t file_size;
Obiviews_header_p header;
Obiview_infos_p views;
Obiview_infos_p view_infos;
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 save a read-only view");
return -1;
}
view_file_name = build_obiview_file_name();
if (view_file_name == NULL)
return -1;
// Get the full path for the column directory
full_path = get_full_path((view->dms)->dir_fd, view_file_name);
if (full_path == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting the full path of an obiview file");
free(view_file_name);
return -1;
}
check_file = stat(full_path, &buffer);
if (check_file < 0)
{ // 1st view: create view file
if (create_obiview_file((view->dms)->dir_fd) < 0)
return -1;
}
// Open view file, read header size and map header and views
obiview_file_descriptor = openat((view->dms)->dir_fd, view_file_name, O_RDWR, 0777);
if (obiview_file_descriptor < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError opening an obiview file");
free(view_file_name);
return -1;
}
free(view_file_name);
// Read the header size
if (read(obiview_file_descriptor, &header_size, sizeof(size_t)) < ((ssize_t) sizeof(size_t)))
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError reading the header size of an obiview file");
close(obiview_file_descriptor);
return -1;
}
// Map the header
header = mmap(NULL,
header_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
obiview_file_descriptor,
0
);
if (header == MAP_FAILED)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError mmapping an obiview file header");
close(obiview_file_descriptor);
return -1;
}
// Truncate file to the right size to add a new view // TODO lock for multithreading
views_size = get_platform_views_size((header->view_count)+1);
file_size = header_size + views_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");
munmap(header, header_size);
close(obiview_file_descriptor);
return -1;
}
header->views_size = views_size;
// Map the views
views = mmap(NULL,
header->views_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
obiview_file_descriptor,
header_size
);
if (views == MAP_FAILED)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError mmapping the views from an obiview file");
munmap(header, header_size);
close(obiview_file_descriptor);
return -1;
}
// Write view infos
view_infos = views + (header->view_count);
view_infos->view_number = (header->view_count);
view_infos->column_count = view->column_count;
view_infos->creation_date = time(NULL);
strcpy(view_infos->created_from, view->created_from);
strcpy(view_infos->name, view->name);
// Store reference for the line selection associated with that view
if (view->new_line_selection != NULL)
{
view_infos->line_count = ((view->new_line_selection)->header)->lines_used;
current_line_selection = view->new_line_selection;
}
else
{
view_infos->line_count = view->line_count;
current_line_selection = view->line_selection;
}
if (current_line_selection != NULL)
{
view_infos->all_lines = 0;
strcpy((view_infos->line_selection).column_name, (current_line_selection->header)->name);
(view_infos->line_selection).version = (current_line_selection->header)->version;
}
else
{
view_infos->all_lines = 1;
((view_infos->line_selection).column_name)[0] = '\0';
(view_infos->line_selection).version = -1;
}
for (i=0; i<view->column_count; i++)
{
strcpy(((view_infos->column_references)+i)->column_name, (((view->columns)[i])->header)->name);
((view_infos->column_references)+i)->version = (((view->columns)[i])->header)->version;
}
// Increment view count
(header->view_count)++;
// Unmap and close file
munmap(views, header->views_size);
munmap(header, header_size);
close(obiview_file_descriptor);
return 0;
}
int obi_close_view(Obiview_p view)
{
int i;
for (i=0; i < (view->column_count); i++)
{
obi_close_column((view->columns)[i]);
}
free(view);
return 0;
}
int obi_save_and_close_view(Obiview_p view)
{
if (!(view->read_only)) // TODO discuss
{
if (obi_save_view(view) < 0)
return -1;
}
if (obi_close_view(view) < 0)
return -1;
return 0;
}

158
src/obiview.h Normal file
View File

@ -0,0 +1,158 @@
/********************************************************************
* Obiview header file *
********************************************************************/
/**
* @file obiview.h
* @author Celine Mercier (celine.mercier@metabarcoding.org)
* @date 16 December 2015
* @brief Header file for the OBIDMS view functions and structures.
*/
#ifndef OBIVIEW_H_
#define OBIVIEW_H_
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <math.h>
#include "obidms.h"
#include "obidmscolumn.h"
#include "obierrno.h"
#define OBIVIEW_NAME_MAX_LENGTH (10239) /**< The maximum length of an OBIDMS view name.
*/
#define OBIVIEW_FILE_NAME "obiviews"
#define LINES_COLUMN_NAME "LINES"
/**
* @brief .
*/
typedef struct Column_reference {
char column_name[OBIDMS_COLUMN_MAX_NAME+1]; /**< Name of the column.
*/
obiversion_t version; /**< Version of the column.
*/
} Column_reference_t, *Column_reference_p;
/**
* @brief .
*/
typedef struct Obiview {
OBIDMS_p dms;
bool read_only;
OBIDMS_column_p line_selection;
OBIDMS_column_p new_line_selection;
index_t line_count;
int column_count;
OBIDMS_column_p columns[MAX_NB_OPENED_COLUMNS];
char name[OBIVIEW_NAME_MAX_LENGTH+1];
char created_from[OBIVIEW_NAME_MAX_LENGTH+1];
int view_number;
} Obiview_t, *Obiview_p;
/**
* @brief .
*/
typedef struct Obiview_infos {
int view_number;
int column_count;
index_t line_count;
char name[OBIVIEW_NAME_MAX_LENGTH+1];
char created_from[OBIVIEW_NAME_MAX_LENGTH+1];
time_t creation_date;
bool all_lines;
Column_reference_t line_selection;
Column_reference_t column_references[MAX_NB_OPENED_COLUMNS];
} Obiview_infos_t, *Obiview_infos_p;
/**
* @brief .
*/
typedef struct Obiviews_header {
size_t header_size;
size_t views_size;
int view_count;
} Obiviews_header_t, *Obiviews_header_p;
/**
* @brief .
*/
typedef struct Obiviews { // not used
Obiviews_header_p header;
Obiview_infos_p views;
} Obiviews_t, *Obiviews_p;
Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_clone, index_t* line_selection);
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);
Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name);
int obi_view_add_column(Obiview_p view,
const char* column_name,
obiversion_t version_number,
OBIType_t data_type,
index_t nb_lines,
index_t nb_elements_per_line,
const char* elements_names,
const char* avl_name,
const char* comments,
bool create);
int obi_view_delete_column(Obiview_p view, const char* column_name);
int obi_select_line(Obiview_p view, index_t line_nb);
int obi_select_lines(Obiview_p view, index_t* line_nbs);
int obi_view_update_lines(Obiview_p view, index_t line_count);
OBIDMS_column_p obi_view_clone_column(Obiview_p view, const char* column_name);
OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name);
OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const char* column_name);
int obi_save_view(Obiview_p view);
int obi_close_view(Obiview_p view);
int obi_save_and_close_view(Obiview_p view);
#endif /* OBIVIEW_H_ */