diff --git a/python/obitools3/obidms/_obidms.pxd b/python/obitools3/obidms/_obidms.pxd index b0e8312..c834681 100644 --- a/python/obitools3/obidms/_obidms.pxd +++ b/python/obitools3/obidms/_obidms.pxd @@ -23,22 +23,24 @@ cdef class OBIDMS: OBIType_t data_type=*, size_t nb_lines=*, size_t nb_elements_per_line=*, - str elements_names=*) + list elements_names=*) cdef class OBIDMS_column: - cdef OBIDMS_column_p pointer - cdef OBIDMS dms - cdef str data_type # TODO keep as OBIType_t? both? - cdef str dms_name - cdef str column_name + cdef OBIDMS_column_p pointer + cdef OBIDMS dms + cdef str data_type # TODO keep as OBIType_t? both? + cdef str dms_name + cdef str column_name + cdef size_t nb_elements_per_line + cdef list elements_names - cpdef object get_item(self, size_t line_nb, str element_name) +# cpdef object get_item(self, size_t line_nb, str element_name) TODO can't declare because not the same in all subclasses # cpdef set_item(self, size_t line_nb, str element_name, object value) TODO can't declare because object value cpdef list get_elements_names(self) cpdef str get_data_type(self) cpdef size_t get_nb_lines_used(self) - cpdef str get_creation_date(self) +# cpdef str get_creation_date(self) cpdef close(self) diff --git a/python/obitools3/obidms/_obidms.pyx b/python/obitools3/obidms/_obidms.pyx index 83d4fc7..6f7818e 100644 --- a/python/obitools3/obidms/_obidms.pyx +++ b/python/obitools3/obidms/_obidms.pyx @@ -6,37 +6,48 @@ from obitools3.utils cimport bytes2str, str2bytes from .capi.obidms cimport obi_dms, \ obi_close_dms -from .capi.obidmscolumn cimport obi_column_get_data_type_from_name, \ - obi_column_get_latest_version_from_name, \ - obi_column_get_line_count_from_name, \ - obi_column_get_nb_lines_used, \ +from .capi.obidmscolumn cimport obi_column_get_nb_lines_used, \ obi_column_get_elements_names, \ - obi_column_get_formatted_creation_date, \ - obi_column_get_formatted_creation_date_from_name, \ + obi_column_get_header_from_name, \ + obi_unmap_header, \ + obi_column_get_latest_version_from_name, \ obi_create_column, \ obi_clone_column, \ obi_open_column, \ - obi_close_column -from .capi.obitypes cimport const_char_p, name_data_type - + obi_close_column, \ + OBIDMS_column_header_p + #obi_column_get_formatted_creation_date +from .capi.obitypes cimport const_char_p, \ + name_data_type + from ._obidms cimport OBIDMS from ._obidms cimport OBIDMS_column from ._obidmscolumn_int cimport OBIDMS_column_int, \ - OBIDMS_column_int_writable + OBIDMS_column_int_writable, \ + OBIDMS_column_int_multi_elts, \ + OBIDMS_column_int_multi_elts_writable from ._obidmscolumn_float cimport OBIDMS_column_float, \ - OBIDMS_column_float_writable + OBIDMS_column_float_writable, \ + OBIDMS_column_float_multi_elts, \ + OBIDMS_column_float_multi_elts_writable from ._obidmscolumn_bool cimport OBIDMS_column_bool, \ - OBIDMS_column_bool_writable + OBIDMS_column_bool_writable, \ + OBIDMS_column_bool_multi_elts, \ + OBIDMS_column_bool_multi_elts_writable from ._obidmscolumn_char cimport OBIDMS_column_char, \ - OBIDMS_column_char_writable + OBIDMS_column_char_writable, \ + OBIDMS_column_char_multi_elts, \ + OBIDMS_column_char_multi_elts_writable -from ._obidmscolumn_idx cimport OBIDMS_column_idx, \ - OBIDMS_column_idx_writable +# from ._obidmscolumn_idx cimport OBIDMS_column_idx, \ +# OBIDMS_column_idx_writable, \ +# OBIDMS_column_idx_multi_elts, \ +# OBIDMS_column_idx_multi_elts_writable cdef class OBIDMS : @@ -72,6 +83,7 @@ cdef class OBIDMS : cdef str creation_date cdef obiversion_t latest_version cdef size_t line_count + cdef OBIDMS_column_header_p header p = Path(self.dms_name+'.obidms') @@ -85,11 +97,12 @@ cdef class OBIDMS : column_name = entry.stem column_name_b = str2bytes(column_name) dms[column_name] = {} - data_type = bytes2str(name_data_type(obi_column_get_data_type_from_name(self.pointer, column_name_b))) + header = obi_column_get_header_from_name(self.pointer, column_name_b) + data_type = bytes2str(name_data_type(header.data_type)) + line_count = header.line_count latest_version = obi_column_get_latest_version_from_name(self.pointer, column_name_b) - line_count = obi_column_get_line_count_from_name(self.pointer, column_name_b) -# creation_date = bytes2str(obi_column_get_formatted_creation_date_from_name(self.pointer, column_name_b)) #TODO +# creation_date = bytes2str(obi_column_get_formatted_creation_date_from_name(self.pointer, column_name_b)) #TODO (deprecated, use header) # print(creation_date) dms[column_name]['data_type'] = data_type @@ -98,6 +111,7 @@ cdef class OBIDMS : # dms[column_name]['creation_date'] = creation_date print("{:<25} {:<25} {:<25} {:<25}".format(column_name, data_type, latest_version, line_count)) + obi_unmap_header(header) # TODO check if error? but C will already warn and there's nothing to do return dms @@ -108,97 +122,110 @@ cdef class OBIDMS : obiversion_t version_number=-1, OBIType_t data_type= 0, size_t nb_lines=0, - size_t nb_elements_per_line=1, - str elements_names=None): + size_t nb_elements_per_line=0, + list elements_names=None): # Declarations cdef OBIDMS_column column + cdef object subclass # TODO object? cdef bytes column_name_b + cdef OBIDMS_column_header_p header + + header = NULL # Format the character string to send to C function column_name_b = str2bytes(column_name) + # Get the header of the latest version of the column if + # some needed informations are not provided + if ((not data_type or not nb_elements_per_line) and not create) : + header = obi_column_get_header_from_name(self.pointer, column_name_b) + # Get the data type if not provided if not data_type : if create : raise Exception("A data type must be specified") else : - data_type = obi_column_get_data_type_from_name(self.pointer, column_name_b) + data_type = header.data_type - # Open the column with the right subclass depending on the data type and the mode (read-only or writable) + # Get the number of elements per line if not provided and needed + if not nb_elements_per_line : + 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 + if nb_elements_per_line > 1 : + elements_names = bytes2str(header.elements_names).split(';') + + if header != NULL : + obi_unmap_header(header) # TODO check if error? but C will already warn and there's nothing to do + + # Open the column with the right subclass depending on the data type, the mode + # (read-only or writable) and whether there are multiple elements per line or not if data_type == 1 : if (create or clone) : - column = OBIDMS_column_int_writable(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_int_writable + else : + subclass = OBIDMS_column_int_multi_elts_writable else : - column = OBIDMS_column_int(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) - + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_int + else : + subclass = OBIDMS_column_int_multi_elts elif data_type == 2 : if (create or clone) : - column = OBIDMS_column_float_writable(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_float_writable + else : + subclass = OBIDMS_column_float_multi_elts_writable else : - column = OBIDMS_column_float(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) - + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_float + else : + subclass = OBIDMS_column_float_multi_elts elif data_type == 3 : if (create or clone) : - column = OBIDMS_column_bool_writable(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_bool_writable + else : + subclass = OBIDMS_column_bool_multi_elts_writable else : - column = OBIDMS_column_bool(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) - + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_bool + else : + subclass = OBIDMS_column_bool_multi_elts elif data_type == 4 : if (create or clone) : - column = OBIDMS_column_char_writable(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_char_writable + else : + subclass = OBIDMS_column_char_multi_elts_writable else : - column = OBIDMS_column_char(self, column_name, - create, clone, clone_data, - version_number, data_type, - nb_lines, nb_elements_per_line, - elements_names) - + if nb_elements_per_line == 1 : + subclass = OBIDMS_column_char + else : + subclass = OBIDMS_column_char_multi_elts # elif data_type == 5 : # if (create or clone) : -# column = OBIDMS_column_idx_writable(self, column_name, -# create, clone, clone_data, -# version_number, data_type, -# nb_lines, nb_elements_per_line, -# elements_names) +# if nb_elements_per_line == 1 : +# subclass = OBIDMS_column_idx_writable +# else : +# subclass = OBIDMS_column_idx_multi_elts_writable # else : -# column = OBIDMS_column_idx(self, column_name, -# create, clone, clone_data, -# version_number, data_type, -# nb_lines, nb_elements_per_line, -# elements_names) - +# if nb_elements_per_line == 1 : +# subclass = OBIDMS_column_idx +# else : +# subclass = OBIDMS_column_idx_multi_elts else : raise Exception("Problem with the data type") + column = subclass(self, column_name, + create, clone, clone_data, + version_number, data_type, + nb_lines, nb_elements_per_line, + elements_names) + return column @@ -215,7 +242,7 @@ cdef class OBIDMS_column : OBIType_t type, size_t nb_lines, size_t nb_elements_per_line, - str elements_names): + list elements_names): # Declarations cdef bytes column_name_b @@ -226,6 +253,8 @@ cdef class OBIDMS_column : self.dms = dms self.data_type = bytes2str(name_data_type(type)) self.column_name = column_name + self.nb_elements_per_line = nb_elements_per_line + self.elements_names = elements_names # Format the character strings to send them to C functions column_name_b = str2bytes(column_name) @@ -236,7 +265,7 @@ cdef class OBIDMS_column : if elements_names == None : elements_names_b = column_name_b else : - elements_names_b = str2bytes(elements_names) + 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) else : if clone : @@ -248,49 +277,28 @@ cdef class OBIDMS_column : def __iter__(self): # Declarations - cdef list elements_names - cdef str element_name - cdef bint multiple_elements - cdef object line # TODO cdef size_t lines_used cdef size_t line_nb - # Check if there are multiple elements per line anf if yes, get their names - elements_names = self.get_elements_names() - if len(elements_names) > 1 : - multiple_elements = True - else : - element_name = elements_names[0] - # Yield each line lines_used = obi_column_get_nb_lines_used(self.pointer) - for line_nb in xrange(lines_used): - if multiple_elements : - line = [] - for element_name in elements_names : - line.append(self.get_item(line_nb, element_name)) - else : - line = self.get_item(line_nb, element_name) - yield line - + for line_nb in range(lines_used): + yield self.get_line(line_nb) def __setitem__(self, size_t line_nb, object value): - self.set_item(line_nb, "", value) + self.set_line(line_nb, value) - def __getitem__(self, size_t line_nb): - return self.get_item(line_nb, "") + return self.get_line(line_nb) - cpdef object get_item(self, size_t line_nb, str element_name): - raise NotImplementedError +# cpdef object get_item(self, size_t line_nb, str element_name): TODO +# raise NotImplementedError # cpdef set_item(self, size_t line_nb, str element_name, object value): TODO # raise NotImplementedError cpdef list get_elements_names(self): - cdef bytes elements_names - elements_names = obi_column_get_elements_names(self.pointer) - return (bytes2str(elements_names)).split(';') + return self.elements_names cpdef str get_data_type(self): return self.data_type @@ -298,8 +306,8 @@ cdef class OBIDMS_column : cpdef size_t get_nb_lines_used(self): return obi_column_get_nb_lines_used(self.pointer) - cpdef str get_creation_date(self): - return bytes2str(obi_column_get_formatted_creation_date(self.pointer)) +# cpdef str get_creation_date(self): +# return bytes2str(obi_column_get_formatted_creation_date(self.pointer)) cpdef close(self): raise NotImplementedError diff --git a/python/obitools3/obidms/_obidmscolumn_bool.pxd b/python/obitools3/obidms/_obidmscolumn_bool.pxd index 98809c6..6a9f6ae 100644 --- a/python/obitools3/obidms/_obidmscolumn_bool.pxd +++ b/python/obitools3/obidms/_obidmscolumn_bool.pxd @@ -1,17 +1,25 @@ #cython: language_level=3 from .capi.obitypes cimport obibool_t -from .capi.obidmscolumn cimport OBIDMS_column_p - -from ._obidms cimport OBIDMS_column +from ._obidms cimport OBIDMS_column cdef class OBIDMS_column_bool(OBIDMS_column): + cpdef object get_line(self, size_t line_nb) + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_bool_writable(OBIDMS_column_bool): + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_bool_multi_elts(OBIDMS_column_bool): cpdef object get_item(self, size_t line_nb, str element_name) + cpdef object get_line(self, size_t line_nb) cpdef set_item(self, size_t line_nb, str element_name, obibool_t value) - cpdef close(self) + cpdef set_line(self, size_t line_nb, object values) -cdef class OBIDMS_column_bool_writable(OBIDMS_column_bool): +cdef class OBIDMS_column_bool_multi_elts_writable(OBIDMS_column_bool_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obibool_t value) + cpdef set_line(self, size_t line_nb, object values) cpdef close(self) - diff --git a/python/obitools3/obidms/_obidmscolumn_bool.pyx b/python/obitools3/obidms/_obidmscolumn_bool.pyx index 9426b9e..1e5c6ca 100644 --- a/python/obitools3/obidms/_obidmscolumn_bool.pyx +++ b/python/obitools3/obidms/_obidmscolumn_bool.pyx @@ -3,7 +3,9 @@ from .capi.obidmscolumn cimport obi_close_column,\ obi_truncate_and_close_column, \ obi_column_get_obibool_with_elt_name, \ - obi_column_set_obibool_with_elt_name + obi_column_get_obibool_with_elt_idx, \ + obi_column_set_obibool_with_elt_name, \ + obi_column_set_obibool_with_elt_idx from .capi.obierrno cimport obi_errno from .capi.obitypes cimport OBIBool_NA @@ -13,7 +15,40 @@ from cpython.bool cimport PyBool_FromLong cdef class OBIDMS_column_bool(OBIDMS_column): - + + cpdef object get_line(self, size_t line_nb): + cdef obibool_t value + cdef object result + value = obi_column_get_obibool_with_elt_idx(self.pointer, line_nb, 0) + if obi_errno > 0 : + raise IndexError(line_nb) + if value == OBIBool_NA : + result = None + else : + result = PyBool_FromLong(value) + return result + + cpdef set_line(self, size_t line_nb, object value): + raise Exception("Column is read-only") + + cpdef close(self): + if obi_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_bool_writable(OBIDMS_column_bool): + + cpdef set_line(self, size_t line_nb, object value): + if obi_column_set_obibool_with_elt_idx(self.pointer, line_nb, 0, value) < 0: + raise Exception("Problem setting a value in a column") + + cpdef close(self): + if obi_truncate_and_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_bool_multi_elts(OBIDMS_column_bool): + cpdef object get_item(self, size_t line_nb, str element_name): cdef obibool_t value cdef object result @@ -25,22 +60,45 @@ cdef class OBIDMS_column_bool(OBIDMS_column): else : result = PyBool_FromLong(value) return result - + + cpdef object get_line(self, size_t line_nb) : + cdef obibool_t value + cdef object result + cdef size_t i + cdef bint all_NA + result = {} + all_NA = True + for i in range(self.nb_elements_per_line) : + value = obi_column_get_obibool_with_elt_idx(self.pointer, line_nb, i) + if obi_errno > 0 : + raise IndexError(line_nb) + result[self.elements_names[i]] = PyBool_FromLong(value) + if all_NA and (value != OBIBool_NA) : + all_NA = False + if all_NA : + result = None + return result + cpdef set_item(self, size_t line_nb, str element_name, obibool_t value): raise Exception("Column is read-only") - - cpdef close(self): - if obi_close_column(self.pointer) < 0 : - raise Exception("Problem closing a column") + + cpdef set_line(self, size_t line_nb, object values): + raise Exception("Column is read-only") -cdef class OBIDMS_column_bool_writable(OBIDMS_column_bool): - +cdef class OBIDMS_column_bool_multi_elts_writable(OBIDMS_column_bool_multi_elts): + cpdef set_item(self, size_t line_nb, str element_name, obibool_t value): - if obi_column_set_obibool_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value) < 0 : + if obi_column_set_obibool_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value) < 0: raise Exception("Problem setting a value in a column") - + + cpdef set_line(self, size_t line_nb, object values): + cdef obibool_t value + for element_name in values : + value = values[element_name] + self.set_item(line_nb, element_name, value) + cpdef close(self): if obi_truncate_and_close_column(self.pointer) < 0 : raise Exception("Problem closing a column") - \ No newline at end of file + diff --git a/python/obitools3/obidms/_obidmscolumn_char.pxd b/python/obitools3/obidms/_obidmscolumn_char.pxd index e0b5ca1..6c88ee4 100644 --- a/python/obitools3/obidms/_obidmscolumn_char.pxd +++ b/python/obitools3/obidms/_obidmscolumn_char.pxd @@ -1,17 +1,25 @@ #cython: language_level=3 from .capi.obitypes cimport obichar_t -from .capi.obidmscolumn cimport OBIDMS_column_p - -from ._obidms cimport OBIDMS_column +from ._obidms cimport OBIDMS_column cdef class OBIDMS_column_char(OBIDMS_column): + cpdef object get_line(self, size_t line_nb) + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_char_writable(OBIDMS_column_char): + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_char_multi_elts(OBIDMS_column_char): cpdef object get_item(self, size_t line_nb, str element_name) + cpdef object get_line(self, size_t line_nb) cpdef set_item(self, size_t line_nb, str element_name, bytes value) - cpdef close(self) + cpdef set_line(self, size_t line_nb, object values) -cdef class OBIDMS_column_char_writable(OBIDMS_column_char): +cdef class OBIDMS_column_char_multi_elts_writable(OBIDMS_column_char_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, bytes value) + cpdef set_line(self, size_t line_nb, object values) cpdef close(self) - diff --git a/python/obitools3/obidms/_obidmscolumn_char.pyx b/python/obitools3/obidms/_obidmscolumn_char.pyx index f1cc4a0..98bc220 100644 --- a/python/obitools3/obidms/_obidmscolumn_char.pyx +++ b/python/obitools3/obidms/_obidmscolumn_char.pyx @@ -3,17 +3,52 @@ from .capi.obidmscolumn cimport obi_close_column,\ obi_truncate_and_close_column, \ obi_column_get_obichar_with_elt_name, \ - obi_column_set_obichar_with_elt_name + obi_column_get_obichar_with_elt_idx, \ + obi_column_set_obichar_with_elt_name, \ + obi_column_set_obichar_with_elt_idx from .capi.obierrno cimport obi_errno from .capi.obitypes cimport OBIChar_NA from obitools3.utils cimport str2bytes -cdef class OBIDMS_column_char(OBIDMS_column) : - +cdef class OBIDMS_column_char(OBIDMS_column): + + cpdef object get_line(self, size_t line_nb): + cdef obichar_t value + cdef object result + value = obi_column_get_obichar_with_elt_idx(self.pointer, line_nb, 0) + if obi_errno > 0 : + raise IndexError(line_nb) + if value == OBIChar_NA : + result = None + else : + result = value + return result + + cpdef set_line(self, size_t line_nb, object value): + raise Exception("Column is read-only") + + cpdef close(self): + if obi_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_char_writable(OBIDMS_column_char): + + cpdef set_line(self, size_t line_nb, object value): + if obi_column_set_obichar_with_elt_idx(self.pointer, line_nb, 0, value[0]) < 0: + raise Exception("Problem setting a value in a column") + + cpdef close(self): + if obi_truncate_and_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_char_multi_elts(OBIDMS_column_char): + cpdef object get_item(self, size_t line_nb, str element_name): - cdef char value + cdef obichar_t value cdef object result value = obi_column_get_obichar_with_elt_name(self.pointer, line_nb, str2bytes(element_name)) if obi_errno > 0 : @@ -23,22 +58,81 @@ cdef class OBIDMS_column_char(OBIDMS_column) : else : result = value return result + + cpdef object get_line(self, size_t line_nb) : + cdef obichar_t value + cdef object result + cdef size_t i + cdef bint all_NA + result = {} + all_NA = True + for i in range(self.nb_elements_per_line) : + value = obi_column_get_obichar_with_elt_idx(self.pointer, line_nb, i) + if obi_errno > 0 : + raise IndexError(line_nb) + result[self.elements_names[i]] = value + if all_NA and (value != OBIChar_NA) : + all_NA = False + if all_NA : + result = None + return result cpdef set_item(self, size_t line_nb, str element_name, bytes value): raise Exception("Column is read-only") - - cpdef close(self): - if obi_close_column(self.pointer) < 0 : - raise Exception("Problem closing a column") - - -cdef class OBIDMS_column_char_writable(OBIDMS_column_char) : - + + cpdef set_line(self, size_t line_nb, object values): + raise Exception("Column is read-only") + + +cdef class OBIDMS_column_char_multi_elts_writable(OBIDMS_column_char_multi_elts): + cpdef set_item(self, size_t line_nb, str element_name, bytes value): if obi_column_set_obichar_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value[0]) < 0: raise Exception("Problem setting a value in a column") - + + cpdef set_line(self, size_t line_nb, object values): + cdef bytes value + for element_name in values : + value = values[element_name] + self.set_item(line_nb, element_name, value) + cpdef close(self): if obi_truncate_and_close_column(self.pointer) < 0 : raise Exception("Problem closing a column") - + + + + + +# cdef class OBIDMS_column_char(OBIDMS_column) : +# +# cpdef object get_item(self, size_t line_nb, str element_name): +# cdef char value +# cdef object result +# value = obi_column_get_obichar_with_elt_name(self.pointer, line_nb, str2bytes(element_name)) +# if obi_errno > 0 : +# raise IndexError(line_nb, element_name) +# if value == OBIChar_NA : +# result = None +# else : +# result = value +# return result +# +# cpdef set_item(self, size_t line_nb, str element_name, bytes value): +# raise Exception("Column is read-only") +# +# cpdef close(self): +# if obi_close_column(self.pointer) < 0 : +# raise Exception("Problem closing a column") +# +# +# cdef class OBIDMS_column_char_writable(OBIDMS_column_char) : +# +# cpdef set_item(self, size_t line_nb, str element_name, bytes value): +# if obi_column_set_obichar_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value[0]) < 0: +# raise Exception("Problem setting a value in a column") +# +# cpdef close(self): +# if obi_truncate_and_close_column(self.pointer) < 0 : +# raise Exception("Problem closing a column") +# diff --git a/python/obitools3/obidms/_obidmscolumn_float.pxd b/python/obitools3/obidms/_obidmscolumn_float.pxd index c8cb52e..dba433d 100644 --- a/python/obitools3/obidms/_obidmscolumn_float.pxd +++ b/python/obitools3/obidms/_obidmscolumn_float.pxd @@ -1,16 +1,25 @@ #cython: language_level=3 from .capi.obitypes cimport obifloat_t -from .capi.obidmscolumn cimport OBIDMS_column_p - -from ._obidms cimport OBIDMS_column +from ._obidms cimport OBIDMS_column cdef class OBIDMS_column_float(OBIDMS_column): + cpdef object get_line(self, size_t line_nb) + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_float_writable(OBIDMS_column_float): + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_float_multi_elts(OBIDMS_column_float): cpdef object get_item(self, size_t line_nb, str element_name) + cpdef object get_line(self, size_t line_nb) cpdef set_item(self, size_t line_nb, str element_name, obifloat_t value) - cpdef close(self) - -cdef class OBIDMS_column_float_writable(OBIDMS_column_float): + cpdef set_line(self, size_t line_nb, object values) + +cdef class OBIDMS_column_float_multi_elts_writable(OBIDMS_column_float_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obifloat_t value) + cpdef set_line(self, size_t line_nb, object values) cpdef close(self) diff --git a/python/obitools3/obidms/_obidmscolumn_float.pyx b/python/obitools3/obidms/_obidmscolumn_float.pyx index e7fc1f1..77c2ff3 100644 --- a/python/obitools3/obidms/_obidmscolumn_float.pyx +++ b/python/obitools3/obidms/_obidmscolumn_float.pyx @@ -3,7 +3,9 @@ from .capi.obidmscolumn cimport obi_close_column,\ obi_truncate_and_close_column, \ obi_column_get_obifloat_with_elt_name, \ - obi_column_set_obifloat_with_elt_name + obi_column_get_obifloat_with_elt_idx, \ + obi_column_set_obifloat_with_elt_name, \ + obi_column_set_obifloat_with_elt_idx from .capi.obierrno cimport obi_errno from .capi.obitypes cimport OBIFloat_NA @@ -12,6 +14,39 @@ from obitools3.utils cimport str2bytes cdef class OBIDMS_column_float(OBIDMS_column): + cpdef object get_line(self, size_t line_nb): + cdef obifloat_t value + cdef object result + value = obi_column_get_obifloat_with_elt_idx(self.pointer, line_nb, 0) + if obi_errno > 0 : + raise IndexError(line_nb) + if value == OBIFloat_NA : + result = None + else : + result = value + return result + + cpdef set_line(self, size_t line_nb, object value): + raise Exception("Column is read-only") + + cpdef close(self): + if obi_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_float_writable(OBIDMS_column_float): + + cpdef set_line(self, size_t line_nb, object value): + if obi_column_set_obifloat_with_elt_idx(self.pointer, line_nb, 0, value) < 0: + raise Exception("Problem setting a value in a column") + + cpdef close(self): + if obi_truncate_and_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_float_multi_elts(OBIDMS_column_float): + cpdef object get_item(self, size_t line_nb, str element_name): cdef obifloat_t value cdef object result @@ -24,21 +59,45 @@ cdef class OBIDMS_column_float(OBIDMS_column): result = value return result + cpdef object get_line(self, size_t line_nb) : + cdef obifloat_t value + cdef object result + cdef size_t i + cdef bint all_NA + result = {} + all_NA = True + for i in range(self.nb_elements_per_line) : + value = obi_column_get_obifloat_with_elt_idx(self.pointer, line_nb, i) + if obi_errno > 0 : + raise IndexError(line_nb) + result[self.elements_names[i]] = value + if all_NA and (value != OBIFloat_NA) : + all_NA = False + if all_NA : + result = None + return result + cpdef set_item(self, size_t line_nb, str element_name, obifloat_t value): raise Exception("Column is read-only") - cpdef close(self): - if obi_close_column(self.pointer) < 0 : - raise Exception("Problem closing a column") - + cpdef set_line(self, size_t line_nb, object values): + raise Exception("Column is read-only") -cdef class OBIDMS_column_float_writable(OBIDMS_column_float): + +cdef class OBIDMS_column_float_multi_elts_writable(OBIDMS_column_float_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obifloat_t value): if obi_column_set_obifloat_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value) < 0: raise Exception("Problem setting a value in a column") + + cpdef set_line(self, size_t line_nb, object values): + cdef obifloat_t value + for element_name in values : + value = values[element_name] + self.set_item(line_nb, element_name, value) cpdef close(self): if obi_truncate_and_close_column(self.pointer) < 0 : raise Exception("Problem closing a column") + \ No newline at end of file diff --git a/python/obitools3/obidms/_obidmscolumn_idx.pxd b/python/obitools3/obidms/_obidmscolumn_idx.pxd index b997522..da49e46 100644 --- a/python/obitools3/obidms/_obidmscolumn_idx.pxd +++ b/python/obitools3/obidms/_obidmscolumn_idx.pxd @@ -1,16 +1,25 @@ #cython: language_level=3 from .capi.obitypes cimport obiidx_t -from .capi.obidmscolumn cimport OBIDMS_column_p - -from ._obidms cimport OBIDMS_column +from ._obidms cimport OBIDMS_column cdef class OBIDMS_column_idx(OBIDMS_column): + cpdef object get_line(self, size_t line_nb) + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_idx_writable(OBIDMS_column_idx): + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_idx_multi_elts(OBIDMS_column_idx): cpdef object get_item(self, size_t line_nb, str element_name) + cpdef object get_line(self, size_t line_nb) cpdef set_item(self, size_t line_nb, str element_name, obiidx_t value) - cpdef close(self) - -cdef class OBIDMS_column_idx_writable(OBIDMS_column_idx): + cpdef set_line(self, size_t line_nb, object values) + +cdef class OBIDMS_column_idx_multi_elts_writable(OBIDMS_column_idx_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obiidx_t value) + cpdef set_line(self, size_t line_nb, object values) cpdef close(self) diff --git a/python/obitools3/obidms/_obidmscolumn_idx.pyx b/python/obitools3/obidms/_obidmscolumn_idx.pyx index 47a8336..fa59c01 100644 --- a/python/obitools3/obidms/_obidmscolumn_idx.pyx +++ b/python/obitools3/obidms/_obidmscolumn_idx.pyx @@ -1,9 +1,11 @@ #cython: language_level=3 - + from .capi.obidmscolumn cimport obi_close_column,\ obi_truncate_and_close_column, \ obi_column_get_obiidx_with_elt_name, \ - obi_column_set_obiidx_with_elt_name + obi_column_get_obiidx_with_elt_idx, \ + obi_column_set_obiidx_with_elt_name, \ + obi_column_set_obiidx_with_elt_idx from .capi.obierrno cimport obi_errno from .capi.obitypes cimport OBIIdx_NA @@ -14,6 +16,39 @@ from cpython.int cimport PyInt_FromSsize_t cdef class OBIDMS_column_idx(OBIDMS_column): + cpdef object get_line(self, size_t line_nb): + cdef obiidx_t value + cdef object result + value = obi_column_get_obiidx_with_elt_idx(self.pointer, line_nb, 0) + if obi_errno > 0 : + raise IndexError(line_nb) + if value == OBIIdx_NA : + result = None + else : + result = PyInt_FromSsize_t(value) + return result + + cpdef set_line(self, size_t line_nb, object value): + raise Exception("Column is read-only") + + cpdef close(self): + if obi_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_idx_writable(OBIDMS_column_idx): + + cpdef set_line(self, size_t line_nb, object value): + if obi_column_set_obiidx_with_elt_idx(self.pointer, line_nb, 0, value) < 0: + raise Exception("Problem setting a value in a column") + + cpdef close(self): + if obi_truncate_and_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_idx_multi_elts(OBIDMS_column_idx): + cpdef object get_item(self, size_t line_nb, str element_name): cdef obiidx_t value cdef object result @@ -26,21 +61,45 @@ cdef class OBIDMS_column_idx(OBIDMS_column): result = PyInt_FromSsize_t(value) return result + cpdef object get_line(self, size_t line_nb) : + cdef obiidx_t value + cdef object result + cdef size_t i + cdef bint all_NA + result = {} + all_NA = True + for i in range(self.nb_elements_per_line) : + value = obi_column_get_obiidx_with_elt_idx(self.pointer, line_nb, i) + if obi_errno > 0 : + raise IndexError(line_nb) + result[self.elements_names[i]] = PyInt_FromSsize_t(value) + if all_NA and (value != OBIIdx_NA) : + all_NA = False + if all_NA : + result = None + return result + cpdef set_item(self, size_t line_nb, str element_name, obiidx_t value): raise Exception("Column is read-only") - cpdef close(self): - if obi_close_column(self.pointer) < 0 : - raise Exception("Problem closing a column") - + cpdef set_line(self, size_t line_nb, object values): + raise Exception("Column is read-only") -cdef class OBIDMS_column_idx_writable(OBIDMS_column_idx): + +cdef class OBIDMS_column_idx_multi_elts_writable(OBIDMS_column_idx_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obiidx_t value): if obi_column_set_obiidx_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value) < 0: raise Exception("Problem setting a value in a column") + + cpdef set_line(self, size_t line_nb, object values): + cdef obiidx_t value + for element_name in values : + value = values[element_name] + self.set_item(line_nb, element_name, value) cpdef close(self): if obi_truncate_and_close_column(self.pointer) < 0 : raise Exception("Problem closing a column") + \ No newline at end of file diff --git a/python/obitools3/obidms/_obidmscolumn_int.pxd b/python/obitools3/obidms/_obidmscolumn_int.pxd index eae7dd2..d851c42 100644 --- a/python/obitools3/obidms/_obidmscolumn_int.pxd +++ b/python/obitools3/obidms/_obidmscolumn_int.pxd @@ -1,16 +1,25 @@ #cython: language_level=3 from .capi.obitypes cimport obiint_t -from .capi.obidmscolumn cimport OBIDMS_column_p - -from ._obidms cimport OBIDMS_column +from ._obidms cimport OBIDMS_column cdef class OBIDMS_column_int(OBIDMS_column): + cpdef object get_line(self, size_t line_nb) + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_int_writable(OBIDMS_column_int): + cpdef set_line(self, size_t line_nb, object value) + cpdef close(self) + +cdef class OBIDMS_column_int_multi_elts(OBIDMS_column_int): cpdef object get_item(self, size_t line_nb, str element_name) + cpdef object get_line(self, size_t line_nb) cpdef set_item(self, size_t line_nb, str element_name, obiint_t value) - cpdef close(self) - -cdef class OBIDMS_column_int_writable(OBIDMS_column_int): + cpdef set_line(self, size_t line_nb, object values) + +cdef class OBIDMS_column_int_multi_elts_writable(OBIDMS_column_int_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obiint_t value) + cpdef set_line(self, size_t line_nb, object values) cpdef close(self) diff --git a/python/obitools3/obidms/_obidmscolumn_int.pyx b/python/obitools3/obidms/_obidmscolumn_int.pyx index 8ae54bf..5f50f82 100644 --- a/python/obitools3/obidms/_obidmscolumn_int.pyx +++ b/python/obitools3/obidms/_obidmscolumn_int.pyx @@ -3,7 +3,9 @@ from .capi.obidmscolumn cimport obi_close_column,\ obi_truncate_and_close_column, \ obi_column_get_obiint_with_elt_name, \ - obi_column_set_obiint_with_elt_name + obi_column_get_obiint_with_elt_idx, \ + obi_column_set_obiint_with_elt_name, \ + obi_column_set_obiint_with_elt_idx from .capi.obierrno cimport obi_errno from .capi.obitypes cimport OBIInt_NA @@ -11,11 +13,42 @@ from obitools3.utils cimport str2bytes from cpython.int cimport PyInt_FromLong -from ._obidms cimport OBIDMS_column - cdef class OBIDMS_column_int(OBIDMS_column): + cpdef object get_line(self, size_t line_nb): + cdef obiint_t value + cdef object result + value = obi_column_get_obiint_with_elt_idx(self.pointer, line_nb, 0) + if obi_errno > 0 : + raise IndexError(line_nb) + if value == OBIInt_NA : + result = None + else : + result = PyInt_FromLong(value) + return result + + cpdef set_line(self, size_t line_nb, object value): + raise Exception("Column is read-only") + + cpdef close(self): + if obi_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_int_writable(OBIDMS_column_int): + + cpdef set_line(self, size_t line_nb, object value): + if obi_column_set_obiint_with_elt_idx(self.pointer, line_nb, 0, value) < 0: + raise Exception("Problem setting a value in a column") + + cpdef close(self): + if obi_truncate_and_close_column(self.pointer) < 0 : + raise Exception("Problem closing a column") + + +cdef class OBIDMS_column_int_multi_elts(OBIDMS_column_int): + cpdef object get_item(self, size_t line_nb, str element_name): cdef obiint_t value cdef object result @@ -28,21 +61,44 @@ cdef class OBIDMS_column_int(OBIDMS_column): result = PyInt_FromLong(value) return result + cpdef object get_line(self, size_t line_nb) : + cdef obiint_t value + cdef object result + cdef size_t i + cdef bint all_NA + result = {} + all_NA = True + for i in range(self.nb_elements_per_line) : + value = obi_column_get_obiint_with_elt_idx(self.pointer, line_nb, i) + if obi_errno > 0 : + raise IndexError(line_nb) + result[self.elements_names[i]] = PyInt_FromLong(value) + if all_NA and (value != OBIInt_NA) : + all_NA = False + if all_NA : + result = None + return result + cpdef set_item(self, size_t line_nb, str element_name, obiint_t value): raise Exception("Column is read-only") - cpdef close(self): - if obi_close_column(self.pointer) < 0 : - raise Exception("Problem closing a column") - + cpdef set_line(self, size_t line_nb, object values): + raise Exception("Column is read-only") -cdef class OBIDMS_column_int_writable(OBIDMS_column_int): + +cdef class OBIDMS_column_int_multi_elts_writable(OBIDMS_column_int_multi_elts): cpdef set_item(self, size_t line_nb, str element_name, obiint_t value): if obi_column_set_obiint_with_elt_name(self.pointer, line_nb, str2bytes(element_name), value) < 0: raise Exception("Problem setting a value in a column") + + cpdef set_line(self, size_t line_nb, object values): + cdef obiint_t value + for element_name in values : + value = values[element_name] + self.set_item(line_nb, element_name, value) cpdef close(self): if obi_truncate_and_close_column(self.pointer) < 0 : raise Exception("Problem closing a column") - \ No newline at end of file + diff --git a/python/obitools3/obidms/capi/obidmscolumn.pxd b/python/obitools3/obidms/capi/obidmscolumn.pxd index 0b314e6..6e3f72e 100644 --- a/python/obitools3/obidms/capi/obidmscolumn.pxd +++ b/python/obitools3/obidms/capi/obidmscolumn.pxd @@ -8,13 +8,32 @@ from ..capi.obitypes cimport const_char_p, \ obibool_t, \ obichar_t, \ obifloat_t, \ - obiidx_t + obiidx_t, \ + time_t + cdef extern from "obidmscolumn.h" nogil: + struct OBIDMS_column_t: pass ctypedef OBIDMS_column_t* OBIDMS_column_p + + struct OBIDMS_column_header_t: + bint little_endian + int header_size + size_t line_count + size_t lines_used + size_t nb_elements_per_line + const_char_p elements_names + OBIType_t data_type + time_t creation_date + obiversion_t version + obiversion_t cloned_from + const_char_p name + const_char_p comments + + ctypedef OBIDMS_column_header_t* OBIDMS_column_header_p OBIDMS_column_p obi_create_column(OBIDMS_p dms, const_char_p column_name, @@ -36,10 +55,7 @@ cdef extern from "obidmscolumn.h" nogil: OBIType_t obi_column_get_type(OBIDMS_column_p column) int obi_close_column(OBIDMS_column_p column) - - OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, - const_char_p column_name) - + OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const_char_p column_name, obiversion_t version_number, @@ -49,17 +65,16 @@ cdef extern from "obidmscolumn.h" nogil: obiversion_t obi_column_get_latest_version_from_name(OBIDMS_p dms, const_char_p column_name) + + OBIDMS_column_header_p obi_column_get_header_from_name(OBIDMS_p dms, + const_char_p column_name) - OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, - const_char_p column_name) + int obi_unmap_header(OBIDMS_column_header_p header) - size_t obi_column_get_line_count_from_name(OBIDMS_p dms, - const_char_p column_name) +# char* obi_column_get_formatted_creation_date(OBIDMS_column_p column) - char* obi_column_get_formatted_creation_date(OBIDMS_column_p column) - - char* obi_column_get_formatted_creation_date_from_name(OBIDMS_p dms, - const_char_p column_name) +# char* obi_column_get_formatted_creation_date_from_name(OBIDMS_p dms, +# const_char_p column_name) cdef extern from "obidmscolumn_int.h" nogil: @@ -67,10 +82,20 @@ cdef extern from "obidmscolumn_int.h" nogil: size_t line_nb, const_char_p element_name, obiint_t value) + + int obi_column_set_obiint_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx, + obiint_t value) obiint_t obi_column_get_obiint_with_elt_name(OBIDMS_column_p column, size_t line_nb, const_char_p element_name) + + obiint_t obi_column_get_obiint_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx) + cdef extern from "obidmscolumn_bool.h" nogil: @@ -79,9 +104,18 @@ cdef extern from "obidmscolumn_bool.h" nogil: const_char_p element_name, obibool_t value) + int obi_column_set_obibool_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx, + obibool_t value) + obibool_t obi_column_get_obibool_with_elt_name(OBIDMS_column_p column, size_t line_nb, const_char_p element_name) + + obibool_t obi_column_get_obibool_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx) cdef extern from "obidmscolumn_char.h" nogil: @@ -90,9 +124,18 @@ cdef extern from "obidmscolumn_char.h" nogil: const_char_p element_name, obichar_t value) + int obi_column_set_obichar_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx, + obichar_t value) + obichar_t obi_column_get_obichar_with_elt_name(OBIDMS_column_p column, size_t line_nb, const_char_p element_name) + + obichar_t obi_column_get_obichar_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx) cdef extern from "obidmscolumn_float.h" nogil: @@ -101,9 +144,18 @@ cdef extern from "obidmscolumn_float.h" nogil: const_char_p element_name, obifloat_t value) + int obi_column_set_obifloat_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx, + obifloat_t value) + obifloat_t obi_column_get_obifloat_with_elt_name(OBIDMS_column_p column, size_t line_nb, const_char_p element_name) + + obifloat_t obi_column_get_obifloat_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx) cdef extern from "obidmscolumn_idx.h" nogil: @@ -112,7 +164,16 @@ cdef extern from "obidmscolumn_idx.h" nogil: const_char_p element_name, obiidx_t value) + int obi_column_set_obiidx_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx, + obiidx_t value) + obiidx_t obi_column_get_obiidx_with_elt_name(OBIDMS_column_p column, size_t line_nb, const_char_p element_name) + + obiidx_t obi_column_get_obiidx_with_elt_idx(OBIDMS_column_p column, + size_t line_nb, + size_t element_idx) diff --git a/python/obitools3/obidms/capi/obitypes.pxd b/python/obitools3/obidms/capi/obitypes.pxd index 1b62ea4..4150eca 100644 --- a/python/obitools3/obidms/capi/obitypes.pxd +++ b/python/obitools3/obidms/capi/obitypes.pxd @@ -2,6 +2,7 @@ from libc.stdint cimport int32_t +from posix.types cimport time_t cdef extern from *: diff --git a/python/obitools3/unit_tests.py b/python/obitools3/unit_tests.py index 91134ca..4d5ea3d 100644 --- a/python/obitools3/unit_tests.py +++ b/python/obitools3/unit_tests.py @@ -25,15 +25,15 @@ def create_test_column(dms, data_type_code, multiple_elements_per_line=False): data_types = DATA_TYPES data_type_code = data_type_code data_type_str = data_types[data_type_code-1] - col_name = "test_col"+data_type_str + col_name = "test_col_"+data_type_str if multiple_elements_per_line : - elts_names = elements_names().split(";") + elts_names = elements_names() col = dms.open_column(col_name, create=True, data_type=data_type_code, nb_elements_per_line=NB_ELEMENTS_PER_LINE, - elements_names=elements_names()) + elements_names=elts_names) return (col, col_name, elts_names, data_type_str) else : @@ -44,10 +44,8 @@ def create_test_column(dms, data_type_code, multiple_elements_per_line=False): def elements_names(): - names = "" - for i in range(NB_ELEMENTS_PER_LINE): - names = names + str(i) + ";" - return names[:-1] + names = [str(i) for i in range(NB_ELEMENTS_PER_LINE)] + return names def random_obivalue(data_type): @@ -94,26 +92,36 @@ class OBIDMS_Column_TestCase(unittest.TestCase): class OBIDMS_Column_multiple_elements_TestCase(OBIDMS_Column_TestCase): def test_OBIDMS_column_cloning(self): + pass for i in range(SMALLER_LINE_COUNT_FOR_TEST_COLUMN): - for e in range(NB_ELEMENTS_PER_LINE) : - self.col.set_item(i, self.elts_names[e], random_obivalue(self.data_type_str)) + v = {} + for e in self.elts_names : + v[e] = random_obivalue(self.data_type_str) + self.col[i] = v self.col.close() clone = self.dms.open_column(self.col_name, clone=True) self.col = self.dms.open_column(self.col_name) assert clone.get_nb_lines_used() == self.col.get_nb_lines_used(), "Cloned column doesn't have the same number of lines used" i=0 for i in range(SMALLER_LINE_COUNT_FOR_TEST_COLUMN): - for e in range(NB_ELEMENTS_PER_LINE) : - assert clone.get_item(i, self.elts_names[e]) == self.col.get_item(i, self.elts_names[e]), "Different value in original column and cloned column" - assert clone.get_item(i, self.elts_names[e]) is not None, "None value" + assert self.col[i] == clone[i], "Different value in original column and cloned column" + assert self.col[i] is not None, "None value" clone.close() - def test_OBIDMS_column_set_and_get(self): + def test_OBIDMS_column_set_and_get_with_elements_names(self): for i in range(SMALLER_LINE_COUNT_FOR_TEST_COLUMN): for e in range(NB_ELEMENTS_PER_LINE) : v = random_obivalue(self.data_type_str) self.col.set_item(i, self.elts_names[e], v) assert self.col.get_item(i, self.elts_names[e]) == v, "Different value than the set value" assert self.col.get_item(i, self.elts_names[e]) is not None, "None value" + def test_OBIDMS_column_set_and_get(self): + for i in range(SMALLER_LINE_COUNT_FOR_TEST_COLUMN): + v = {} + for e in self.elts_names : + v[e] = random_obivalue(self.data_type_str) + self.col[i] = v + assert self.col[i] == v, "Different value than the set value" + assert self.col[i] is not None, "None value" class OBIDMS_Column_OBI_INT_TestCase(OBIDMS_Column_TestCase): diff --git a/src/obidmscolumn.c b/src/obidmscolumn.c index d01e532..37dd0b2 100644 --- a/src/obidmscolumn.c +++ b/src/obidmscolumn.c @@ -639,7 +639,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, minimum_line_count = get_line_count_per_page(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 (%lld)", MAXIMUM_LINE_COUNT); + obidebug(1, "\nCan't create column because of line count greater than the maximum allowed (%ld)", MAXIMUM_LINE_COUNT); return NULL; } else if (nb_lines < minimum_line_count) @@ -1341,7 +1341,7 @@ OBIType_t obi_column_get_data_type(OBIDMS_column_p column) } -OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_name) +OBIDMS_column_header_p obi_column_get_header_from_name(OBIDMS_p dms, const char* column_name) { OBIDMS_column_header_p header; OBIDMS_column_directory_p column_directory; @@ -1349,7 +1349,6 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na int column_file_descriptor; int column_dir_file_descriptor; size_t header_size; - OBIType_t data_type; obiversion_t version_number; // Get the column directory structure associated to the column @@ -1357,7 +1356,7 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na if (column_directory == NULL) { obidebug(1, "\nError opening a column directory structure"); - return -1; + return NULL; } // Get the file descriptor associated to the column directory @@ -1367,7 +1366,7 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); obidebug(1, "\nError getting the file descriptor of a column directory"); obi_close_column_directory(column_directory); - return -1; + return NULL; } // Calculate the header size @@ -1378,14 +1377,14 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na if (version_number < 0) { obidebug(1, "\nError getting the latest version number in a column directory"); - return -1; + return NULL; } // Get the column file name column_file_name = build_column_file_name(column_name, version_number); if (column_file_name == NULL) { - return -1; + return NULL; } // Open the column file (READ-ONLY) @@ -1395,7 +1394,7 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na obidebug(1, "\nError opening a column file"); obi_set_errno(OBICOL_UNKNOWN_ERROR); free(column_file_name); - return -1; + return NULL; } // Fill the header structure @@ -1413,103 +1412,27 @@ OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_na obidebug(1, "\nError mmapping the header of a column"); close(column_file_descriptor); free(column_file_name); - return -1; + return NULL; } // TODO Check endianness? - data_type = header->data_type; - free(column_file_name); close(column_file_descriptor); - munmap(header, header_size); - return data_type; + + return header; } -size_t obi_column_get_line_count_from_name(OBIDMS_p dms, const char* column_name) +int obi_unmap_header(OBIDMS_column_header_p header) { - OBIDMS_column_header_p header; - OBIDMS_column_directory_p column_directory; - char* column_file_name; - int column_file_descriptor; - int column_dir_file_descriptor; - size_t header_size; - size_t line_count; - obiversion_t version_number; - - // Get the column directory structure associated to the column - column_directory = obi_open_column_directory(dms, column_name); - if (column_directory == NULL) - { - obidebug(1, "\nError opening a column directory structure"); - return -1; - } - - // Get the file descriptor associated to the column directory - column_dir_file_descriptor = dirfd(column_directory->directory); - if (column_dir_file_descriptor < 0) - { - obi_set_errno(OBICOLDIR_UNKNOWN_ERROR); - obidebug(1, "\nError getting the file descriptor of a column directory"); - obi_close_column_directory(column_directory); - return -1; - } - - // Calculate the header size - header_size = obi_get_platform_header_size(); - - // Get the latest version number - version_number = obi_get_latest_version_number(column_directory); - if (version_number < 0) - { - obidebug(1, "\nError getting the latest version number in a column directory"); - return -1; - } - - // Get the column file name - column_file_name = build_column_file_name(column_name, version_number); - if (column_file_name == NULL) - { - return -1; - } - - // Open the column file (READ-ONLY) - column_file_descriptor = openat(column_dir_file_descriptor, column_file_name, O_RDONLY); - if (column_file_descriptor < 0) - { - obidebug(1, "\nError opening a column file"); - obi_set_errno(OBICOL_UNKNOWN_ERROR); - free(column_file_name); - return -1; - } - - // Fill the header structure - header = mmap(NULL, - header_size, - PROT_READ, - MAP_SHARED, - column_file_descriptor, - 0 - ); - - if (header == MAP_FAILED) + if (munmap(header, header->header_size) < 0) { obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nError mmapping the header of a column"); - close(column_file_descriptor); - free(column_file_name); + obidebug(1, "\nError munmapping a column header"); return -1; } - - // TODO Check endianness? - - line_count = header->line_count; - - free(column_file_name); - close(column_file_descriptor); - munmap(header, header_size); - return line_count; + return 0; } @@ -1567,7 +1490,7 @@ size_t obi_column_get_nb_elements_per_line(OBIDMS_column_p column) } -char* obi_column_get_formatted_creation_date(OBIDMS_column_p column) +char* obi_column_get_formatted_creation_date(OBIDMS_column_p column) // TODO { char* formatted_time; struct tm* tmp; @@ -1593,7 +1516,7 @@ char* obi_column_get_formatted_creation_date(OBIDMS_column_p column) } -char* obi_column_get_formatted_creation_date_from_name(OBIDMS_p dms, const char* column_name) +char* obi_column_get_formatted_creation_date_from_name(OBIDMS_p dms, const char* column_name) // TODO { OBIDMS_column_header_p header; OBIDMS_column_directory_p column_directory; @@ -1691,8 +1614,15 @@ char* obi_column_get_formatted_creation_date_from_name(OBIDMS_p dms, const char* return NULL; } + // Munmap header + if (munmap(header, header->header_size) < 0) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError munmapping header after getting the creation date of a column"); + } + free(column_file_name); close(column_file_descriptor); - munmap(header, header_size); + return formatted_time; } diff --git a/src/obidmscolumn.h b/src/obidmscolumn.h index b0d2918..5fc8796 100644 --- a/src/obidmscolumn.h +++ b/src/obidmscolumn.h @@ -334,31 +334,34 @@ OBIType_t obi_column_get_data_type(OBIDMS_column_p column); /** - * @brief Recovers the data type of an OBIDMS column from the column name. + * @brief Recovers the header of an OBIDMS column from the column name. + * + * @warning The header structure has to be munmapped by the caller. * * @param dms A pointer on an OBIDMS. * @param column_name The name of an OBIDMS column. * - * @returns The data type of the column. + * @returns A pointer on the mmapped header of the column. + * @retval NULL if an error occurred. * - * @since July 2015 + * @since October 2015 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_name); +OBIDMS_column_header_p obi_column_get_header_from_name(OBIDMS_p dms, const char* column_name); /** - * @brief Recovers the line count of an OBIDMS column from the column name. + * @brief Munmap a mmapped header as returned by obi_column_get_header_from_name(). * - * @param dms A pointer on an OBIDMS. - * @param column_name The name of an OBIDMS column. + * @param header A pointer on the mmapped header structure. * - * @returns The line count of the column. + * @retval 0 if the operation was successfully completed. + * @retval -1 if an error occurred. * - * @since September 2015 + * @since October 2015 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -size_t obi_column_get_line_count_from_name(OBIDMS_p dms, const char* column_name); +int obi_unmap_header(OBIDMS_column_header_p header); /** diff --git a/src/obidmscolumn_bool.c b/src/obidmscolumn_bool.c index e4d8487..10f605a 100644 --- a/src/obidmscolumn_bool.c +++ b/src/obidmscolumn_bool.c @@ -72,27 +72,10 @@ obibool_t obi_column_get_obibool_with_elt_idx(OBIDMS_column_p column, size_t lin int obi_column_set_obibool_with_elt_name(OBIDMS_column_p column, size_t line_nb, const char* element_name, obibool_t value) { size_t element_idx; - - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return -1; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return -1; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return -1; obi_column_set_obibool_with_elt_idx(column, line_nb, element_idx, value); - return 0; } @@ -101,24 +84,9 @@ obibool_t obi_column_get_obibool_with_elt_name(OBIDMS_column_p column, size_t li { size_t element_idx; - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return OBIBool_NA; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return OBIBool_NA; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return OBIBool_NA; return obi_column_get_obibool_with_elt_idx(column, line_nb, element_idx); } diff --git a/src/obidmscolumn_char.c b/src/obidmscolumn_char.c index 4b99870..51f5922 100644 --- a/src/obidmscolumn_char.c +++ b/src/obidmscolumn_char.c @@ -65,7 +65,6 @@ obichar_t obi_column_get_obichar_with_elt_idx(OBIDMS_column_p column, size_t lin 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); } @@ -73,27 +72,10 @@ obichar_t obi_column_get_obichar_with_elt_idx(OBIDMS_column_p column, size_t lin int obi_column_set_obichar_with_elt_name(OBIDMS_column_p column, size_t line_nb, const char* element_name, obichar_t value) { size_t element_idx; - - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return -1; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return -1; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return -1; obi_column_set_obichar_with_elt_idx(column, line_nb, element_idx, value); - return 0; } @@ -102,24 +84,9 @@ obichar_t obi_column_get_obichar_with_elt_name(OBIDMS_column_p column, size_t li { size_t element_idx; - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return OBIChar_NA; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return OBIChar_NA; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return OBIChar_NA; return obi_column_get_obichar_with_elt_idx(column, line_nb, element_idx); } diff --git a/src/obidmscolumn_float.c b/src/obidmscolumn_float.c index 50e26db..497629b 100644 --- a/src/obidmscolumn_float.c +++ b/src/obidmscolumn_float.c @@ -72,27 +72,10 @@ obifloat_t obi_column_get_obifloat_with_elt_idx(OBIDMS_column_p column, size_t l int obi_column_set_obifloat_with_elt_name(OBIDMS_column_p column, size_t line_nb, const char* element_name, obifloat_t value) { size_t element_idx; - - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return -1; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return -1; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return -1; obi_column_set_obifloat_with_elt_idx(column, line_nb, element_idx, value); - return 0; } @@ -101,24 +84,9 @@ obifloat_t obi_column_get_obifloat_with_elt_name(OBIDMS_column_p column, size_t { size_t element_idx; - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return OBIFloat_NA; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return OBIFloat_NA; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return OBIFloat_NA; return obi_column_get_obifloat_with_elt_idx(column, line_nb, element_idx); } diff --git a/src/obidmscolumn_idx.c b/src/obidmscolumn_idx.c index c9569e3..fa8484e 100644 --- a/src/obidmscolumn_idx.c +++ b/src/obidmscolumn_idx.c @@ -10,6 +10,18 @@ */ +/**************************************************************************** + * OBIDMS_column_idx functions * + ****************************************************************************/ + +/** + * @file obidsmcolumn_idx.c + * @author Celine Mercier + * @date August 10th 2015 + * @brief Functions handling OBIColumns containing data with the OBIType OBI_BOOL. + */ + + #include #include @@ -72,27 +84,10 @@ obiidx_t obi_column_get_obiidx_with_elt_idx(OBIDMS_column_p column, size_t line_ int obi_column_set_obiidx_with_elt_name(OBIDMS_column_p column, size_t line_nb, const char* element_name, obiidx_t value) { size_t element_idx; - - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return -1; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return -1; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return -1; obi_column_set_obiidx_with_elt_idx(column, line_nb, element_idx, value); - return 0; } @@ -101,24 +96,9 @@ obiidx_t obi_column_get_obiidx_with_elt_name(OBIDMS_column_p column, size_t line { size_t element_idx; - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return OBIIdx_NA; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return OBIIdx_NA; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return OBIIdx_NA; return obi_column_get_obiidx_with_elt_idx(column, line_nb, element_idx); } diff --git a/src/obidmscolumn_int.c b/src/obidmscolumn_int.c index 1c43a4a..6a04649 100644 --- a/src/obidmscolumn_int.c +++ b/src/obidmscolumn_int.c @@ -72,27 +72,10 @@ obiint_t obi_column_get_obiint_with_elt_idx(OBIDMS_column_p column, size_t line_ int obi_column_set_obiint_with_elt_name(OBIDMS_column_p column, size_t line_nb, const char* element_name, obiint_t value) { size_t element_idx; - - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return -1; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return -1; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return -1; obi_column_set_obiint_with_elt_idx(column, line_nb, element_idx, value); - return 0; } @@ -101,24 +84,9 @@ obiint_t obi_column_get_obiint_with_elt_name(OBIDMS_column_p column, size_t line { size_t element_idx; - if (!strcmp(element_name, "\0")) // element name is empty - { - if (obi_column_get_nb_elements_per_line(column) == 1) // check that there is only one element per line - element_idx = 0; - else // there is more than one element per line - { - obi_set_errno(OBICOL_UNKNOWN_ERROR); - obidebug(1, "\nAn element name must be specified"); - return OBIInt_NA; - } - } - else - { - element_idx = obi_column_get_element_index_from_name(column, element_name); - if (element_idx == SIZE_MAX) //TODO - return OBIInt_NA; - } - + element_idx = obi_column_get_element_index_from_name(column, element_name); + if (element_idx == SIZE_MAX) //TODO + return OBIInt_NA; return obi_column_get_obiint_with_elt_idx(column, line_nb, element_idx); }