Views are now rollbacked if an error occurs, and unfinished views and

columns are deleted when an OBIDMS is opened.
This commit is contained in:
Celine Mercier
2017-10-26 18:58:48 +02:00
parent 1ae634d56b
commit dfd51939a0
11 changed files with 702 additions and 55 deletions

View File

@ -275,7 +275,6 @@ static char* build_column_file_name(const char* column_name, obiversion_t versio
}
static char* build_version_file_name(const char* column_name)
{
char* file_name;
@ -300,7 +299,6 @@ static char* build_version_file_name(const char* column_name)
}
static obiversion_t obi_get_new_version_number(OBIDMS_column_directory_p column_directory, bool block)
{
off_t loc_size;
@ -425,7 +423,6 @@ static obiversion_t obi_get_new_version_number(OBIDMS_column_directory_p column_
}
static obiversion_t create_version_file(OBIDMS_column_directory_p column_directory)
{
off_t loc_size;
@ -714,6 +711,71 @@ static index_t get_line_count_per_page(OBIType_t data_type, index_t nb_elements_
**********************************************************************/
char* obi_version_file_full_path(OBIDMS_p dms, const char* column_name)
{
char* version_file_name;
char* column_dir_name;
char* relative_path;
char* full_path;
version_file_name = build_version_file_name(column_name);
if (version_file_name == NULL)
return NULL;
column_dir_name = obi_build_column_directory_name(column_name);
if (column_dir_name == NULL)
return NULL;
relative_path = (char*) malloc(strlen(version_file_name) + strlen(column_dir_name) + 2);
strcpy(relative_path, column_dir_name);
strcat(relative_path, "/");
strcat(relative_path, version_file_name);
// Build path relative to DMS
full_path = obi_dms_get_full_path(dms, relative_path);
free(version_file_name);
free(column_dir_name);
free(relative_path);
return full_path;
}
char* obi_column_full_path(OBIDMS_p dms, const char* column_name, obiversion_t version_number)
{
char* column_file_name;
char* column_dir_name;
char* relative_path;
char* full_path;
column_file_name = build_column_file_name(column_name, version_number);
if (column_file_name == NULL)
return NULL;
column_dir_name = obi_build_column_directory_name(column_name);
if (column_dir_name == NULL)
return NULL;
relative_path = (char*) malloc(strlen(column_file_name) + strlen(column_dir_name) + 2);
strcpy(relative_path, column_dir_name);
strcat(relative_path, "/");
strcat(relative_path, column_file_name);
// Build path relative to DMS
full_path = obi_dms_get_full_path(dms, relative_path);
free(column_file_name);
free(column_dir_name);
free(relative_path);
return full_path;
}
obiversion_t obi_get_latest_version_number(OBIDMS_column_directory_p column_directory)
{
off_t loc_size;
@ -1046,6 +1108,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
header->creation_date = time(NULL);
header->version = version_number;
header->cloned_from = -1;
header->finished = false;
set_elements_names(new_column, elements_names, elts_names_length);
@ -1833,7 +1896,6 @@ index_t obi_column_get_element_index_from_name(OBIDMS_column_p column, const cha
}
// TODO doc, returns elements names with ; as separator (discuss maybe char**)
char* obi_get_elements_names(OBIDMS_column_p column)
{
char* elements_names;
@ -1921,3 +1983,183 @@ int obi_column_prepare_to_get_value(OBIDMS_column_p column, index_t line_nb)
return 0;
}
int obi_clean_unfinished_columns(OBIDMS_p dms)
{
struct dirent* dms_dirent;
struct dirent* col_dirent;
DIR* col_dir;
int i,j;
char* column_file_path;
char* column_dir_path;
char* col_name;
char* col_version_str;
char* version_file;
obiversion_t col_version;
OBIDMS_column_header_p col_header;
int n;
char* col_to_delete[1000];
char* dir_to_delete[1000];
int ddir;
int dcol;
int d;
int ret_value;
ret_value = 0;
// Find column directories
ddir = 0;
while ((dms_dirent = readdir(dms->directory)) != NULL)
{
if ((dms_dirent->d_name)[0] == '.')
continue;
i=0;
while (((dms_dirent->d_name)[i] != '.') && (i < strlen(dms_dirent->d_name)))
i++;
if ((i != strlen(dms_dirent->d_name)) && (strcmp((dms_dirent->d_name)+i, ".obicol") == 0)) // Found a column directory
{
column_dir_path = obi_dms_get_full_path(dms, dms_dirent->d_name);
if (column_dir_path == NULL)
{
obidebug(1, "\nError getting a column directory path when deleting unfinished columns");
ret_value = -1;
}
col_name = (char*) malloc(strlen(dms_dirent->d_name) * sizeof(char));
if (col_name == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for a column name when deleting unfinished columns: directory %s", dms_dirent->d_name);
ret_value = -1;
continue;
}
strncpy(col_name, dms_dirent->d_name, i);
col_name[i] = '\0';
col_dir = opendir_in_dms(dms, dms_dirent->d_name);
if (col_dir == NULL)
{
obidebug(1, "\nError opening a column directory when deleting unfinished columns");
ret_value = -1;
continue;
}
// Iteration on files of this column directory
dcol = 0;
while ((col_dirent = readdir(col_dir)) != NULL)
{
if ((col_dirent->d_name)[0] == '.')
continue;
i=0;
j=0;
while (((col_dirent->d_name)[i] != '@') && ((col_dirent->d_name)[i] != '.'))
i++;
if ((col_dirent->d_name)[i] == '@') // Found a column file
{
j=i;
while ((col_dirent->d_name)[j] != '.')
j++;
col_version_str = (char*) malloc(strlen(col_dirent->d_name) * sizeof(char));
if (col_version_str == NULL)
{
obi_set_errno(OBI_MALLOC_ERROR);
obidebug(1, "\nError allocating memory for a column version when deleting unfinished columns: directory %s", dms_dirent->d_name);
ret_value = -1;
continue;
}
strncpy(col_version_str, (col_dirent->d_name)+i, j-i);
col_version_str[j-i] = '\0';
col_version = atoi(col_version_str);
free(col_version_str);
col_header = obi_column_get_header_from_name(dms, col_name, col_version);
if (col_header == NULL) // TODO discuss if delete file or not
{
obidebug(1, "\nError reading a column header when deleting unfinished columns: file %s", col_dirent->d_name);
ret_value = -1;
continue;
}
// Check if the column is finished and delete it if not
if (col_header->finished == false)
{
// Build file and dir paths
column_file_path = obi_column_full_path(dms, col_name, col_version);
if (column_file_path == NULL)
{
obidebug(1, "\nError getting a column file path when deleting unfinished columns");
ret_value = -1;
continue;
}
// Add the column path in the list of files to delete (can't delete while in loop)
col_to_delete[dcol] = column_file_path;
dcol++;
}
// Close the header
if (obi_close_header(col_header) < 0)
ret_value = -1;
}
}
// Delete all column files in to_delete list
for (d=0; d<dcol; d++)
{
if (remove(col_to_delete[d]) < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError deleting a column file when deleting unfinished columns: file %s", col_to_delete[d]);
ret_value = -1;
}
free(col_to_delete[d]);
}
// Close column directory
if (closedir(col_dir) < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError closing a column directory when deleting unfinished columns");
ret_value = -1;
continue;
}
// Add column dir in list to delete if it's empty
n = count_dir(column_dir_path);
if (n == 1) // Only file left is the version file
{
// Delete the version file
version_file = obi_version_file_full_path(dms, col_name);
if (version_file == NULL)
{
obidebug(1, "\nError getting a version file path when deleting unfinished columns");
ret_value = -1;
continue;
}
if (remove(version_file) < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError deleting a version file when deleting unfinished columns: file %s", version_file);
ret_value = -1;
}
free(version_file);
dir_to_delete[ddir] = column_dir_path;
ddir++;
}
free(col_name);
}
}
// Delete all column dir in to_delete list
for (d=0; d<ddir; d++)
{
if (remove(dir_to_delete[d]) < 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError deleting a column directory when deleting unfinished columns: directory %s", dir_to_delete[d]);
ret_value = -1;
}
free(dir_to_delete[d]);
}
return ret_value;
}