Commit e8417b4f authored by Celine Mercier's avatar Celine Mercier

The endianness of an OBIDMS is now stored in an informations file that

is read when opening the OBIDMS.
parent 6579566c
......@@ -66,12 +66,12 @@ cdef class OBIDMS :
cpdef close(self) :
#TODO close all columns
#TODO close all columns (needs to be discussed)
if (obi_close_dms(self.pointer)) < 0 :
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
cdef object p
......@@ -100,13 +100,12 @@ cdef class OBIDMS :
data_type = bytes2str(name_data_type(header.data_type))
line_count = header.line_count
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)
dms[column_name]['data_type'] = data_type
dms[column_name]['latest_version'] = latest_version
dms[column_name]['line_count'] = line_count
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))
return dms
......
......@@ -15,7 +15,6 @@ from ..capi.obitypes cimport const_char_p, \
cdef extern from "obidmscolumn.h" nogil:
struct OBIDMS_column_header_t:
bint little_endian
size_t header_size
size_t data_size
index_t line_count
......
......@@ -23,6 +23,7 @@
#include "obidebug.h"
#include "obidmscolumn.h"
#include "private_at_functions.h"
#include "obilittlebigman.h"
#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);
/**
* 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
......@@ -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
......@@ -116,8 +223,8 @@ int obi_dms_exists(const char* dms_name)
OBIDMS_p obi_create_dms(const char* dms_name)
{
char* directory_name;
DIR* dms_dir;
int dms_file_descriptor;
DIR* dms_dir;
int dms_file_descriptor;
// Build and check the directory 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
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);
obidebug(1, "\nProblem creating an arrays directory");
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);
}
......@@ -175,6 +286,10 @@ OBIDMS_p obi_open_dms(const char* dms_name)
{
OBIDMS_p dms;
char* directory_name;
char* infos_file_name;
int infos_file_descriptor;
bool little_endian_dms;
bool little_endian_platform;
dms = NULL;
......@@ -224,7 +339,7 @@ OBIDMS_p obi_open_dms(const char* dms_name)
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);
if (dms->dir_fd < 0)
{
......@@ -235,8 +350,45 @@ OBIDMS_p obi_open_dms(const char* dms_name)
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
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)
{
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)
{
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
obidebug(1, "\nError opening the arrays directory");
closedir(dms->directory);
obidebug(1, "\nError getting the file descriptor of the arrays directory");
closedir(dms->array_directory);
closedir(dms->directory);
free(dms);
return NULL;
}
......
......@@ -26,7 +26,7 @@
#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;
}
// 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)
{
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
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);
obidebug(1, "\nError preparing a version file for unlocking");
......
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