/* * obidms.c * * @date 23 May 2015 * @Author: coissac */ #include #include #include #include #include #include #include "obidms.h" #include "obierrno.h" #include "obidebug.h" #include "obidmscolumn.h" #define DEBUG_LEVEL 0 /************************************************************************** * * D E C L A R A T I O N O F T H E P R I V A T E F U N C T I O N S * **************************************************************************/ /** * Internal function building the directory name from an OBIDMS name. * * The function builds the directory name corresponding to an OBIDMS. * It checks also that the name is not too long. * * @warning The returned pointer has to be freed by the caller. * * @param dms_name the name of the OBIDMS * * @return a pointer to the directory name * @retvalue if everything is ok * @retvalue NULL if an error occurs * * ###Error values * - OBIDMS_MEMORY_ERROR : something wrong occurred during memory allocation. * - OBIDMS_LONG_NAME_ERROR : the database name exceeds the limit. * * @since May 2015 * @author Eric Coissac (eric.coissac@metabarcoding.org) */ static char *build_directory_name(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 * ************************************************************************/ static char *build_directory_name(const char *dms_name) { char *directory_name; // Build the database directory name if (asprintf(&directory_name, "%s.obidms", dms_name) < 0) { obi_set_errno(OBIDMS_MEMORY_ERROR); obidebug(1, "\nProblem building an OBIDMS directory name"); return NULL; } // Test if the database name is not too long if (strlen(directory_name) >= OBIDMS_MAX_NAME) { obi_set_errno(OBIDMS_LONG_NAME_ERROR); obidebug(1, "\nProblem building an OBIDMS directory name"); free(directory_name); return NULL; } return directory_name; } /********************************************************************** * * D E F I N I T I O N O F T H E P U B L I C F U N C T I O N S * **********************************************************************/ int obi_dms_exists(const char* dms_name) { struct stat buffer; char *directory_name; int check_dir; // Build and check the directory name directory_name = build_directory_name(dms_name); if (directory_name == NULL) return -1; check_dir = stat(directory_name, &buffer); free(directory_name); if (check_dir == 0) return 1; else return 0; } OBIDMS_p obi_create_dms(const char* dms_name) { char *directory_name; // Build and check the directory name directory_name = build_directory_name(dms_name); if (directory_name == NULL) return NULL; // Try to create the directory if (mkdir(directory_name, 0x777) < 0) { if (errno == EEXIST) obi_set_errno(OBIDMS_EXIST_ERROR); else obi_set_errno(OBIDMS_UNKNOWN_ERROR); obidebug(1, "\nProblem creating an OBIDMS directory"); free(directory_name); return NULL; } free(directory_name); return obi_open_dms(dms_name); } OBIDMS_p obi_open_dms(const char* dms_name) { OBIDMS_p dms; char* directory_name; DIR* directory; dms = NULL; // Build and check the directory name directory_name = build_directory_name(dms_name); if (directory_name == NULL) return NULL; // Try to open the directory directory = opendir(directory_name); if (directory == NULL) { switch (errno) { case ENOENT: obi_set_errno(OBIDMS_NOT_EXIST_ERROR); break; case EACCES: obi_set_errno(OBIDMS_ACCESS_ERROR); break; case ENOMEM: obi_set_errno(OBIDMS_MEMORY_ERROR); break; default: obi_set_errno(OBIDMS_UNKNOWN_ERROR); } obidebug(1, "\nCan't open OBIDMS directory"); free(directory_name); return NULL; } // Allocate the data structure dms = (OBIDMS_p) malloc(sizeof(OBIDMS_t)); if (dms == NULL) { obi_set_errno(OBIDMS_MEMORY_ERROR); obidebug(1, "\nError allocating the memory for the OBIDMS structure"); free(directory_name); return NULL; } // Initialize the data structure strcpy(dms->directory_name, directory_name); dms->directory = directory; free(directory_name); return dms; } OBIDMS_p obi_dms(const char* dms_name) { int exists; exists = obi_dms_exists(dms_name); switch (exists) { case 0: return obi_create_dms(dms_name); case 1: return obi_open_dms(dms_name); }; obidebug(1, "\nError checking if an OBIDMS directory exists"); return NULL; } int obi_list_columns(OBIDMS_p dms) { DIR *d; struct dirent *dir; char* dir_name; char* extension; OBIType_t data_type; obiversion_t latest_version; d = dms->directory; dir = readdir(d); if (dir == NULL) { obidebug(1, "\nError reading in the OBIDMS directory"); return -1; } fprintf(stderr, "Column name\tData type\tLatest version"); while (dir != NULL) { dir_name = strdup(dir->d_name); if (dir_name == NULL) { obidebug(1, "\nError strdup-ing a directory name"); return -1; } dir_name = strtok(dir_name, "."); extension = strtok(NULL, "."); if ((extension != NULL) && (strcmp("obicol", extension) == 0)) // Found a column directory { data_type = obi_column_get_data_type_from_name(dms, dir_name); latest_version = obi_column_get_latest_version_from_name(dms, dir_name); fprintf(stderr, "\n%s\t%d\t%d", dir_name, data_type, latest_version); } dir = readdir(d); } rewinddir(d); return 0; } int obi_close_dms(OBIDMS_p dms) { if (dms != NULL) { if (closedir(dms->directory) < 0) { obi_set_errno(OBIDMS_MEMORY_ERROR); obidebug(1, "\nError closing an OBIDSM directory"); free(dms); return -1; } free(dms); } return 0; }