Commit b45b496b by Celine Mercier

Major update: new type of columns containing indices referring to lines

in other columns
parent 2cf10cb6
......@@ -19,6 +19,7 @@ cdef class OBIDMS:
str column_name,
bint create=*,
bint clone=*, bint clone_data=*,
bint referring=*,
obiversion_t version_number=*,
str type=*,
index_t nb_lines=*,
......@@ -30,16 +31,19 @@ cdef class OBIDMS:
cdef class OBIDMS_column:
cdef OBIDMS_column_p pointer
cdef OBIDMS dms
cdef str data_type
cdef str dms_name
cdef str column_name
cdef index_t nb_elements_per_line
cdef list elements_names
cdef OBIDMS_column_p pointer
cdef OBIDMS dms
cdef str data_type
cdef str dms_name
cdef str column_name
cdef index_t nb_elements_per_line
cdef list elements_names
cpdef OBIDMS_column_p referred_column_pointer
# cpdef object get_item(self, index_t line_nb, str element_name) TODO can't declare because not the same in all subclasses
# cpdef set_item(self, index_t line_nb, str element_name, object value) TODO can't declare because object value
cpdef grep_line(self, index_t line_nb)
cpdef list get_elements_names(self)
cpdef str get_data_type(self)
cpdef index_t get_nb_lines_used(self)
......
......@@ -14,6 +14,7 @@ from .capi.obidmscolumn cimport obi_column_get_header_from_name, \
obi_open_column, \
obi_close_column, \
obi_column_format_date, \
obi_grep_line, \
OBIDMS_column_header_p
from .capi.obitypes cimport const_char_p, \
OBIType_t, \
......@@ -109,7 +110,7 @@ cdef class OBIDMS :
column_name_b = str2bytes(column_name)
dms[column_name] = {}
header = obi_column_get_header_from_name(self.pointer, column_name_b, -1)
data_type = bytes2str(name_data_type(header.data_type))
data_type = bytes2str(name_data_type(header.returned_data_type))
line_count = header.line_count
creation_date = bytes2str(obi_column_format_date(header.creation_date))
obi_unmap_header(header)
......@@ -127,6 +128,7 @@ cdef class OBIDMS :
str column_name,
bint create=False,
bint clone=False, bint clone_data=True,
bint referring=False,
obiversion_t version_number=-1,
str type='',
index_t nb_lines=0,
......@@ -157,7 +159,7 @@ cdef class OBIDMS :
if create :
raise Exception("A data type must be specified")
else :
data_type = header.data_type
data_type = header.returned_data_type
else :
if type == 'OBI_INT' :
data_type = OBI_INT
......@@ -179,7 +181,7 @@ cdef class OBIDMS :
if create : # Set to one if not provided (default value)
nb_elements_per_line = 1
else :
nb_elements_per_line = header.nb_elements_per_line
nb_elements_per_line = header.returned_nb_elements_per_line
if nb_elements_per_line > 1 :
elements_names = bytes2str(header.elements_names).split(';')
......@@ -258,7 +260,8 @@ cdef class OBIDMS :
raise Exception("Problem with the data type")
column = subclass(self, column_name,
create, clone, clone_data,
create, clone, clone_data,
referring,
version_number, data_type,
nb_lines, nb_elements_per_line,
elements_names, array_name,
......@@ -276,6 +279,7 @@ cdef class OBIDMS_column :
str column_name,
bint create,
bint clone, bint clone_data,
bint referring,
obiversion_t version_number,
OBIType_t type,
index_t nb_lines,
......@@ -312,10 +316,14 @@ cdef class OBIDMS_column :
elements_names_b = str2bytes(";".join(elements_names))
self.pointer = obi_create_column(self.dms.pointer, column_name_b, type,
nb_lines, nb_elements_per_line,
elements_names_b, array_name_b, comments_b)
elements_names_b, array_name_b, comments_b,
referring)
else :
if clone :
self.pointer = obi_clone_column(self.dms.pointer, column_name_b, version_number, clone_data)
self.pointer = obi_clone_column(self.dms.pointer, column_name_b, version_number, referring, clone_data)
elif referring :
self.pointer = obi_clone_column(self.dms.pointer, column_name_b, version_number, referring, False)
referred_column_pointer = self.pointer.referred_column
else :
self.pointer = obi_open_column(self.dms.pointer, column_name_b, version_number)
......@@ -355,6 +363,9 @@ cdef class OBIDMS_column :
# cpdef set_item(self, index_t line_nb, str element_name, object value): TODO
# raise NotImplementedError
cpdef grep_line(self, index_t line_nb):
if obi_grep_line(self.pointer, line_nb) < 0 :
raise Exception("Error grepping line")
cpdef list get_elements_names(self):
return self.elements_names
......
......@@ -19,12 +19,16 @@ cdef extern from "obidmscolumn.h" nogil:
size_t data_size
index_t line_count
index_t lines_used
index_t nb_elements_per_line
index_t returned_nb_elements_per_line
index_t stored_nb_elements_per_line
const_char_p elements_names
OBIType_t data_type
OBIType_t returned_data_type
OBIType_t stored_data_type
time_t creation_date
obiversion_t version
obiversion_t cloned_from
bint referring
obiversion_t referred_column_version
const_char_p name
const_char_p array_name
const_char_p comments
......@@ -33,6 +37,7 @@ cdef extern from "obidmscolumn.h" nogil:
struct OBIDMS_column_t:
OBIDMS_column_header_p header
OBIDMS_column_t* referred_column
ctypedef OBIDMS_column_t* OBIDMS_column_p
......@@ -43,7 +48,8 @@ cdef extern from "obidmscolumn.h" nogil:
index_t nb_elements_per_line,
const_char_p elements_names,
const_char_p array_name,
const_char_p comments)
const_char_p comments,
bint referring)
OBIDMS_column_p obi_open_column(OBIDMS_p dms,
const_char_p column_name,
......@@ -54,6 +60,7 @@ cdef extern from "obidmscolumn.h" nogil:
OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
const_char_p column_name,
obiversion_t version_number,
bint referring,
bint clone_data)
int obi_truncate_and_close_column(OBIDMS_column_p column)
......@@ -69,6 +76,8 @@ cdef extern from "obidmscolumn.h" nogil:
char* obi_column_format_date(time_t date)
int obi_grep_line(OBIDMS_column_p referring_column, index_t line_to_grep)
cdef extern from "obidmscolumn_int.h" nogil:
int obi_column_set_obiint_with_elt_name(OBIDMS_column_p column,
......
......@@ -23,7 +23,8 @@ cdef extern from "obitypes.h" nogil:
OBI_BOOL,
OBI_CHAR,
OBI_STR,
OBI_SEQ
OBI_SEQ,
OBI_IDX
ctypedef OBIType OBIType_t
......
......@@ -320,9 +320,9 @@ char* decode_seq_on_4_bits(byte_t* seq_b, int32_t length_seq)
}
////////// FOR DEBUGGING ///////////
///////////////////// FOR DEBUGGING ///////////////////////////
//NOTE: The first byte is printed the first (at the left-most).
// little endian
void print_bits(void* ptr, int32_t size)
{
uint8_t* b = (uint8_t*) ptr;
......
......@@ -57,12 +57,20 @@ typedef struct OBIDMS_column_header {
*/
index_t lines_used; /**< Number of lines of data used.
*/
index_t nb_elements_per_line; /**< Number of elements per line (default: 1).
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.
*/
char elements_names[ELEMENTS_NAMES_MAX+1]; /**< Names of the line elements with ';' as separator
* (should be the column name if one element per line).
*/
OBIType_t data_type; /**< Type of the data.
OBIType_t returned_data_type; /**< Type of the data that is returned when getting an
* element from the column.
*/
OBIType_t stored_data_type; /**< Type of the data that is actually stored in the data
* part of the column.
*/
time_t creation_date; /**< Date of creation of the file.
*/
......@@ -72,6 +80,10 @@ 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 array_name[ARRAY_MAX_NAME+1]; /**< If there is one, the obi_array name as a NULL terminated string.
......@@ -96,6 +108,8 @@ typedef struct OBIDMS_column {
*/
OBIDMS_array_p array; /**< A pointer to the array 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
......@@ -170,6 +184,7 @@ size_t obi_get_platform_header_size();
* @param elements_names The names of the elements with ';' as separator.
* @param array_name The name of the array 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.
......@@ -184,7 +199,8 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_elements_per_line,
const char* elements_names,
const char* array_name,
const char* comments);
const char* comments,
bool referring);
/**
......@@ -217,7 +233,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 clone_data);
OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number, bool referring, bool clone_data);
/**
......@@ -354,4 +370,8 @@ 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);
#endif /* OBIDMSCOLUMN_H_ */
......@@ -30,6 +30,14 @@
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)
{
......@@ -51,7 +59,7 @@ 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)->nb_elements_per_line)) + element_idx) = value;
*(((obibool_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
return 0;
}
......@@ -59,13 +67,22 @@ 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)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return OBIBool_NA;
}
return *(((obibool_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
if ((column->header)->referring)
{
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);
}
else
return *(((obibool_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
}
......
......@@ -30,6 +30,14 @@
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)
{
......@@ -51,7 +59,7 @@ 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)->nb_elements_per_line)) + element_idx) = value;
*(((obichar_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
return 0;
}
......@@ -59,13 +67,22 @@ 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)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return OBIChar_NA;
}
return *(((obichar_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
if ((column->header)->referring)
{
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);
}
else
return *(((obichar_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
}
......
......@@ -30,6 +30,14 @@
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)
{
......@@ -51,7 +59,7 @@ 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)->nb_elements_per_line)) + element_idx) = value;
*(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
return 0;
}
......@@ -59,13 +67,22 @@ 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)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return OBIFloat_NA;
}
return *(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
if ((column->header)->referring)
{
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);
}
else
return *(((obifloat_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
}
......
......@@ -30,6 +30,14 @@
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)
{
......@@ -51,7 +59,7 @@ 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)->nb_elements_per_line)) + element_idx) = value;
*(((obiint_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = value;
return 0;
}
......@@ -59,13 +67,22 @@ 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)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
return OBIInt_NA;
}
return *(((obiint_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
if ((column->header)->referring)
{
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);
}
else
return *(((obiint_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
}
......
......@@ -34,6 +34,14 @@ int obi_column_set_obiseq_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)
{
......@@ -65,7 +73,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)->nb_elements_per_line)) + element_idx) = idx;
*(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = idx;
free(value_b);
......@@ -77,6 +85,7 @@ const char* obi_column_get_obiseq_with_elt_idx(OBIDMS_column_p column, index_t l
{
index_t idx;
byte_t* value_b;
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
{
......@@ -85,7 +94,13 @@ const char* obi_column_get_obiseq_with_elt_idx(OBIDMS_column_p column, index_t l
return "\0"; // TODO
}
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
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);
// Check NA
if (idx == OBIIdx_NA)
......
......@@ -34,6 +34,14 @@ 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)
{
......@@ -65,7 +73,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)->nb_elements_per_line)) + element_idx) = idx;
*(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = idx;
free(value_b);
......@@ -77,6 +85,7 @@ const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t l
{
index_t idx;
byte_t* value_b;
index_t referring_idx;
if ((line_nb+1) > (column->header)->lines_used)
{
......@@ -85,7 +94,13 @@ const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t l
return "\0"; // TODO
}
idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
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);
// Check NA
if (idx == OBIIdx_NA)
......
......@@ -40,10 +40,9 @@ size_t obi_sizeof(OBIType_t type)
case OBI_CHAR: size = sizeof(obichar_t);
break;
case OBI_STR: size = sizeof(index_t);
break;
case OBI_SEQ: size = sizeof(index_t);
case OBI_STR: // fallthrough
case OBI_SEQ: // fallthrough
case OBI_IDX: size = sizeof(index_t);
break;
default: size = 0;
......@@ -98,6 +97,9 @@ char* name_data_type(int data_type)
case OBI_SEQ: name = strdup("OBI_SEQ");
break;
case OBI_IDX: name = strdup("OBI_IDX");
break;
}
if (name == NULL)
......
......@@ -44,8 +44,9 @@ typedef enum OBIType {
OBI_FLOAT, /**< a floating value (C type : double) */
OBI_BOOL, /**< a boolean true/false value, see obibool_t enum */
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_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) */
} OBIType_t, *OBIType_p;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment