The endianness of an OBIDMS is now stored in an informations file that
is read when opening the OBIDMS.
This commit is contained in:
@ -66,12 +66,12 @@ cdef class OBIDMS :
|
|||||||
|
|
||||||
|
|
||||||
cpdef close(self) :
|
cpdef close(self) :
|
||||||
#TODO close all columns
|
#TODO close all columns (needs to be discussed)
|
||||||
if (obi_close_dms(self.pointer)) < 0 :
|
if (obi_close_dms(self.pointer)) < 0 :
|
||||||
raise Exception("Problem closing an OBIDMS")
|
raise Exception("Problem closing an OBIDMS")
|
||||||
|
|
||||||
|
|
||||||
cpdef dict list(self):
|
cpdef dict list(self): # TDODO This is a temporary function that will be rewritten
|
||||||
|
|
||||||
# Declarations
|
# Declarations
|
||||||
cdef object p
|
cdef object p
|
||||||
@ -100,13 +100,12 @@ cdef class OBIDMS :
|
|||||||
data_type = bytes2str(name_data_type(header.data_type))
|
data_type = bytes2str(name_data_type(header.data_type))
|
||||||
line_count = header.line_count
|
line_count = header.line_count
|
||||||
creation_date = bytes2str(obi_column_format_date(header.creation_date))
|
creation_date = bytes2str(obi_column_format_date(header.creation_date))
|
||||||
obi_unmap_header(header) # TODO check if error? but C will already warn and there's nothing to do
|
obi_unmap_header(header)
|
||||||
latest_version = obi_column_get_latest_version_from_name(self.pointer, column_name_b)
|
latest_version = obi_column_get_latest_version_from_name(self.pointer, column_name_b)
|
||||||
dms[column_name]['data_type'] = data_type
|
dms[column_name]['data_type'] = data_type
|
||||||
dms[column_name]['latest_version'] = latest_version
|
dms[column_name]['latest_version'] = latest_version
|
||||||
dms[column_name]['line_count'] = line_count
|
dms[column_name]['line_count'] = line_count
|
||||||
dms[column_name]['creation_date'] = creation_date
|
dms[column_name]['creation_date'] = creation_date
|
||||||
# TODO : actually get all the informations in the header
|
|
||||||
print("{:<30} {:<12} {:<25} {:<30} {:<40}".format(column_name, data_type, latest_version, line_count, creation_date))
|
print("{:<30} {:<12} {:<25} {:<30} {:<40}".format(column_name, data_type, latest_version, line_count, creation_date))
|
||||||
|
|
||||||
return dms
|
return dms
|
||||||
|
@ -15,7 +15,6 @@ from ..capi.obitypes cimport const_char_p, \
|
|||||||
cdef extern from "obidmscolumn.h" nogil:
|
cdef extern from "obidmscolumn.h" nogil:
|
||||||
|
|
||||||
struct OBIDMS_column_header_t:
|
struct OBIDMS_column_header_t:
|
||||||
bint little_endian
|
|
||||||
size_t header_size
|
size_t header_size
|
||||||
size_t data_size
|
size_t data_size
|
||||||
index_t line_count
|
index_t line_count
|
||||||
|
166
src/obidms.c
166
src/obidms.c
@ -23,6 +23,7 @@
|
|||||||
#include "obidebug.h"
|
#include "obidebug.h"
|
||||||
#include "obidmscolumn.h"
|
#include "obidmscolumn.h"
|
||||||
#include "private_at_functions.h"
|
#include "private_at_functions.h"
|
||||||
|
#include "obilittlebigman.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
|
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
|
||||||
@ -54,6 +55,44 @@
|
|||||||
static char* build_directory_name(const char* dms_name);
|
static char* build_directory_name(const char* dms_name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal function building the informations file name from an OBIDMS name.
|
||||||
|
*
|
||||||
|
* The function builds the file name for the informations file of an OBIDMS.
|
||||||
|
*
|
||||||
|
* @warning The returned pointer has to be freed by the caller.
|
||||||
|
*
|
||||||
|
* @param dms_name The name of the OBIDMS.
|
||||||
|
*
|
||||||
|
* @returns A pointer to the file name.
|
||||||
|
* @retval NULL if an error occurred.
|
||||||
|
*
|
||||||
|
* @since November 2015
|
||||||
|
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||||
|
*/
|
||||||
|
static char* build_infos_file_name(const char* dms_name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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_dms_infos_file(int dms_file_descriptor, const char* dms_name);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
*
|
*
|
||||||
* 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
|
* 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
|
||||||
@ -85,6 +124,74 @@ static char* build_directory_name(const char* dms_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char* build_infos_file_name(const char* dms_name)
|
||||||
|
{
|
||||||
|
char* file_name;
|
||||||
|
|
||||||
|
// Build file name
|
||||||
|
if (asprintf(&file_name, "%s_infos", dms_name) < 0)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_MEMORY_ERROR);
|
||||||
|
obidebug(1, "\nProblem building an informations file name");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int create_dms_infos_file(int dms_file_descriptor, const char* dms_name)
|
||||||
|
{
|
||||||
|
char* file_name;
|
||||||
|
int infos_file_descriptor;
|
||||||
|
off_t file_size;
|
||||||
|
bool little_endian;
|
||||||
|
|
||||||
|
file_size = sizeof(bool);
|
||||||
|
|
||||||
|
// Create file name
|
||||||
|
file_name = build_infos_file_name(dms_name);
|
||||||
|
if (file_name == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// Create file
|
||||||
|
infos_file_descriptor = openat(dms_file_descriptor, file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||||
|
if (infos_file_descriptor < 0)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
|
obidebug(1, "\nError creating an informations file");
|
||||||
|
free(file_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(file_name);
|
||||||
|
|
||||||
|
// Truncate the infos file to the right size
|
||||||
|
if (ftruncate(infos_file_descriptor, file_size) < 0)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
|
obidebug(1, "\nError truncating an informations file");
|
||||||
|
close(infos_file_descriptor);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write endianness
|
||||||
|
little_endian = obi_is_little_endian();
|
||||||
|
if (write(infos_file_descriptor, &little_endian, sizeof(bool)) < ((ssize_t) sizeof(bool)))
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
|
obidebug(1, "\nError writing the endianness in an informations file");
|
||||||
|
close(infos_file_descriptor);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close file
|
||||||
|
close(infos_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
|
* 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
|
||||||
@ -116,8 +223,8 @@ int obi_dms_exists(const char* dms_name)
|
|||||||
OBIDMS_p obi_create_dms(const char* dms_name)
|
OBIDMS_p obi_create_dms(const char* dms_name)
|
||||||
{
|
{
|
||||||
char* directory_name;
|
char* directory_name;
|
||||||
DIR* dms_dir;
|
DIR* dms_dir;
|
||||||
int dms_file_descriptor;
|
int dms_file_descriptor;
|
||||||
|
|
||||||
// Build and check the directory name
|
// Build and check the directory name
|
||||||
directory_name = build_directory_name(dms_name);
|
directory_name = build_directory_name(dms_name);
|
||||||
@ -160,13 +267,17 @@ OBIDMS_p obi_create_dms(const char* dms_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the arrays directory
|
// Create the arrays directory
|
||||||
if (mkdirat(dms_file_descriptor, ARRAY_DIR_NAME, 00777) < 0)
|
if (mkdirat(dms_file_descriptor, ARRAYS_DIR_NAME, 00777) < 0)
|
||||||
{
|
{
|
||||||
obi_set_errno(OBI_ARRAY_ERROR);
|
obi_set_errno(OBI_ARRAY_ERROR);
|
||||||
obidebug(1, "\nProblem creating an arrays directory");
|
obidebug(1, "\nProblem creating an arrays directory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the informations file
|
||||||
|
if (create_dms_infos_file(dms_file_descriptor, dms_name) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return obi_open_dms(dms_name);
|
return obi_open_dms(dms_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +286,10 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
|||||||
{
|
{
|
||||||
OBIDMS_p dms;
|
OBIDMS_p dms;
|
||||||
char* directory_name;
|
char* directory_name;
|
||||||
|
char* infos_file_name;
|
||||||
|
int infos_file_descriptor;
|
||||||
|
bool little_endian_dms;
|
||||||
|
bool little_endian_platform;
|
||||||
|
|
||||||
dms = NULL;
|
dms = NULL;
|
||||||
|
|
||||||
@ -224,7 +339,7 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get file descriptor of DMS directory to open the arrays directory
|
// Get and store file descriptor of DMS directory to open the informations file
|
||||||
dms->dir_fd = dirfd(dms->directory);
|
dms->dir_fd = dirfd(dms->directory);
|
||||||
if (dms->dir_fd < 0)
|
if (dms->dir_fd < 0)
|
||||||
{
|
{
|
||||||
@ -235,8 +350,45 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open informations file to check endianness
|
||||||
|
infos_file_name = build_infos_file_name(dms_name);
|
||||||
|
infos_file_descriptor = openat(dms->dir_fd, infos_file_name, O_RDONLY, 0777);
|
||||||
|
if (infos_file_descriptor < 0)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
|
obidebug(1, "\nError opening an informations file");
|
||||||
|
closedir(dms->directory);
|
||||||
|
free(dms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(infos_file_name);
|
||||||
|
|
||||||
|
// Check endianness of the platform and DMS
|
||||||
|
little_endian_platform = obi_is_little_endian();
|
||||||
|
if (read(infos_file_descriptor, &little_endian_dms, sizeof(bool)) < ((ssize_t) sizeof(bool)))
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
|
obidebug(1, "\nError reading the endianness in an informations file");
|
||||||
|
close(infos_file_descriptor);
|
||||||
|
closedir(dms->directory);
|
||||||
|
free(dms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (little_endian_platform != little_endian_dms)
|
||||||
|
{
|
||||||
|
obi_set_errno(OBIDMS_BAD_ENDIAN_ERROR);
|
||||||
|
obidebug(1, "\nError: The DMS and the platform have different endianness");
|
||||||
|
close(infos_file_descriptor);
|
||||||
|
closedir(dms->directory);
|
||||||
|
free(dms);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(infos_file_descriptor);
|
||||||
|
|
||||||
// Open the arrays directory
|
// Open the arrays directory
|
||||||
dms->array_directory = private_opendirat(dms->dir_fd, ARRAY_DIR_NAME);
|
dms->array_directory = private_opendirat(dms->dir_fd, ARRAYS_DIR_NAME);
|
||||||
if (dms->array_directory == NULL)
|
if (dms->array_directory == NULL)
|
||||||
{
|
{
|
||||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
@ -251,9 +403,9 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
|||||||
if (dms->array_dir_fd < 0)
|
if (dms->array_dir_fd < 0)
|
||||||
{
|
{
|
||||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||||
obidebug(1, "\nError opening the arrays directory");
|
obidebug(1, "\nError getting the file descriptor of the arrays directory");
|
||||||
closedir(dms->directory);
|
|
||||||
closedir(dms->array_directory);
|
closedir(dms->array_directory);
|
||||||
|
closedir(dms->directory);
|
||||||
free(dms);
|
free(dms);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#define OBIDMS_MAX_NAME (2048) /**< The maximum length of an OBIDMS name.
|
#define OBIDMS_MAX_NAME (2048) /**< The maximum length of an OBIDMS name.
|
||||||
*/
|
*/
|
||||||
#define ARRAY_DIR_NAME "arrays" /**< The name of the arrays directory.
|
#define ARRAYS_DIR_NAME "arrays" /**< The name of the arrays directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ static obiversion_t create_version_file(OBIDMS_column_directory_p column_directo
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position offset to 0 to prepare for writing
|
// Position offset to 0 to prepare for writing // TODO Unnecessary?
|
||||||
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0)
|
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
obi_set_errno(OBICOL_UNKNOWN_ERROR);
|
obi_set_errno(OBICOL_UNKNOWN_ERROR);
|
||||||
@ -358,7 +358,7 @@ static obiversion_t create_version_file(OBIDMS_column_directory_p column_directo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for unlocking
|
// Prepare for unlocking
|
||||||
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0)
|
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0) // TODO Unnecessary?
|
||||||
{
|
{
|
||||||
obi_set_errno(OBICOL_UNKNOWN_ERROR);
|
obi_set_errno(OBICOL_UNKNOWN_ERROR);
|
||||||
obidebug(1, "\nError preparing a version file for unlocking");
|
obidebug(1, "\nError preparing a version file for unlocking");
|
||||||
|
Reference in New Issue
Block a user