2015-09-30 12:03:46 +02:00
/********************************************************************
* OBIDMS functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ file obidms . c
* @ author Eric Coissac ( eric . coissac @ metabarcoding . org )
* @ date 23 May 2015
* @ brief OBIDMS functions .
2015-05-23 16:29:06 +03:00
*/
2015-09-30 12:03:46 +02:00
2015-06-17 16:51:16 +02:00
# include <stdlib.h>
# include <stdio.h>
2015-06-23 18:35:34 +02:00
# include <string.h>
2015-11-18 15:35:09 +01:00
# include <stdbool.h>
2015-06-23 18:35:34 +02:00
# include <sys/stat.h>
2015-11-03 14:22:00 +01:00
# include <fcntl.h>
2015-06-23 18:35:34 +02:00
# include <sys/types.h>
# include <dirent.h>
2016-04-29 17:46:36 +02:00
# include <unistd.h>
2017-08-03 16:33:12 +02:00
# include <libgen.h> /* <EC> : Added July 28th 2017 to include basename */
2018-10-07 18:53:25 +02:00
# include <sys/mman.h>
2019-03-13 11:17:25 +01:00
# include <math.h>
2015-06-17 16:51:16 +02:00
# include "obidms.h"
2015-06-23 18:35:34 +02:00
# include "obierrno.h"
2015-07-31 18:03:48 +02:00
# include "obidebug.h"
# include "obidmscolumn.h"
2017-08-03 16:33:12 +02:00
# include "obiview.h"
2016-04-15 10:49:12 +02:00
# include "obiblob_indexer.h"
2016-04-08 15:38:57 +02:00
# include "utils.h"
2015-11-16 14:37:51 +01:00
# include "obilittlebigman.h"
2018-10-07 18:53:25 +02:00
# include "libjson/json_utils.h"
2019-09-21 16:47:22 +02:00
# include "obisig.h"
2015-07-31 18:03:48 +02:00
2015-08-03 15:10:39 +02:00
2015-09-30 12:03:46 +02:00
# define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
2015-05-23 16:29:06 +03:00
2015-05-26 21:36:55 +02:00
2017-11-24 17:58:47 +01:00
// Initialize global list of opened DMS and their associated counters
2017-10-16 10:35:07 +02:00
OBIDMS_p global_opened_dms_list [ MAX_NB_OPENED_DMS + 1 ] = { 0 } ;
2017-11-24 17:58:47 +01:00
int global_opened_dms_counter_list [ MAX_NB_OPENED_DMS + 1 ] = { 0 } ;
2017-10-16 10:35:07 +02:00
2015-06-23 18:35:34 +02:00
/**************************************************************************
2015-05-26 21:36:55 +02:00
*
2015-06-23 18:35:34 +02:00
* 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
2015-05-26 21:36:55 +02:00
*
2015-06-23 18:35:34 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-05-26 21:36:55 +02:00
2015-05-23 16:29:06 +03:00
/**
2015-09-30 12:03:46 +02:00
* Internal function building the OBIDMS directory name from an OBIDMS name .
2015-05-23 16:29:06 +03:00
*
2015-06-10 15:19:02 +02:00
* The function builds the directory name corresponding to an OBIDMS .
2015-09-30 12:03:46 +02:00
* It also checks that the name is not too long .
2015-05-23 16:29:06 +03:00
*
* @ warning The returned pointer has to be freed by the caller .
*
2015-09-30 12:03:46 +02:00
* @ param dms_name The name of the OBIDMS .
2015-05-23 16:29:06 +03:00
*
2015-09-30 12:03:46 +02:00
* @ returns A pointer to the directory name .
* @ retval NULL if an error occurred .
2015-05-23 16:29:06 +03:00
*
* @ since May 2015
* @ author Eric Coissac ( eric . coissac @ metabarcoding . org )
*/
2015-09-30 12:03:46 +02:00
static char * build_directory_name ( const char * dms_name ) ;
2015-06-17 16:51:16 +02:00
2015-11-16 14:37:51 +01:00
/**
* 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 .
*
2018-10-07 18:53:25 +02:00
* @ returns A pointer on the file name .
2015-11-16 14:37:51 +01:00
* @ 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 ) ;
2018-10-07 18:53:25 +02:00
/**
* Internal function calculating the initial size of the file where the informations about a DMS are stored .
*
* @ returns The initial size of the file in bytes , rounded to a multiple of page size .
*
* @ since September 2018
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
2018-10-17 12:00:40 +02:00
static size_t get_platform_infos_file_size ( void ) ;
2018-10-07 18:53:25 +02:00
/**
* @ brief Internal function enlarging a DMS information file .
*
* @ param dms A pointer on the DMS .
* @ param new_size The new size needed , in bytes ( not necessarily rounded to a page size multiple ) .
*
* @ retval 0 if the operation was successfully completed .
* @ retval - 1 if an error occurred .
*
* @ since September 2018
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static int enlarge_infos_file ( OBIDMS_p dms , size_t new_size ) ;
/**
* @ brief Internal function mapping a DMS information file and returning the mapped structure stored in it .
*
* The function checks that endianness of the platform and of the DMS match .
*
* @ param dms_file_descriptor The file descriptor of the DMS directory .
* @ param dms_name The base name of the DMS .
*
* @ returns A pointer on the mapped DMS infos structure .
* @ retval NULL if an error occurred .
*
* @ since September 2018
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static OBIDMS_infos_p map_infos_file ( int dms_file_descriptor , const char * dms_name ) ;
/**
* @ brief Unmaps a DMS information file .
*
* @ param dms A pointer on the OBIDMS .
*
* @ returns A value indicating the success of the operation .
* @ retval 0 if the operation was successfully completed .
* @ retval - 1 if an error occurred .
*
* @ since October 2018
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static int unmap_infos_file ( OBIDMS_p dms ) ;
2015-11-16 14:37:51 +01:00
/**
* Internal function creating the file containing basic informations on the OBIDMS .
*
2018-10-07 18:53:25 +02:00
* This file contains an OBIDMS_infos structure .
2015-11-16 14:37:51 +01:00
*
* @ warning The returned pointer has to be freed by the caller .
*
2018-10-07 18:53:25 +02:00
* @ param dms_file_descriptor The file descriptor of the DMS directory .
* @ param dms_name The base name of the DMS .
2015-11-16 14:37:51 +01:00
*
* @ retval 0 if the operation was successfully completed .
* @ retval - 1 if an error occurred .
*
* @ since November 2015
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
2018-10-07 18:53:25 +02:00
static int create_dms_infos_file ( int dms_file_descriptor , const char * dms_name ) ;
2015-11-16 14:37:51 +01:00
2017-10-16 10:35:07 +02:00
/**
* Internal function adding a DMS in the global list of DMS opened by a program .
*
* @ param dms A pointer on the DMS to add .
*
* @ retval 0 if the operation was successfully completed .
* @ retval - 1 if an error occurred .
*
* @ since October 2017
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static int list_dms ( OBIDMS_p dms ) ;
/**
* Internal function removing a DMS from the global list of DMS opened by a program .
*
* @ param dms A pointer on the DMS to remove .
2017-11-24 17:58:47 +01:00
* @ param force Whether the DMS should be unlisted even if it is opened more than once .
*
* @ retval 0 if the operation was successfully completed .
* @ retval - 1 if the DMS was not found .
2017-10-16 10:35:07 +02:00
*
* @ since October 2017
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
2017-11-24 17:58:47 +01:00
static int unlist_dms ( OBIDMS_p dms , bool force ) ;
/**
* Internal function checking if a DMS is already in the global list of DMS opened by the program .
*
* @ param full_dms_path The absolute path to the DMS directory .
*
* @ returns A pointer on the DMS if it is already opened , or NULL if it was not opened .
*
* @ since November 2017
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static OBIDMS_p check_if_dms_in_list ( const char * full_dms_path ) ;
/**
* Internal function returning the count for an opened DMS ( how many times the DMS is opened ) in the global list of DMS opened by the program .
*
* @ param dms A pointer on the DMS .
*
* @ returns The count indicating how many times the DMS has been opened by the program .
*
* @ retval - 1 if the DMS was not found .
*
* @ since November 2017
* @ author Celine Mercier ( celine . mercier @ metabarcoding . org )
*/
static int dms_count_in_list ( OBIDMS_p dms ) ;
2017-10-16 10:35:07 +02:00
2015-06-23 18:35:34 +02:00
/************************************************************************
2015-06-17 16:51:16 +02:00
*
2015-06-23 18:35:34 +02:00
* 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
2015-06-17 16:51:16 +02:00
*
2015-06-23 18:35:34 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-05-23 16:29:06 +03:00
2015-09-30 12:03:46 +02:00
static char * build_directory_name ( const char * dms_name )
2015-06-17 16:51:16 +02:00
{
2015-09-30 12:03:46 +02:00
char * directory_name ;
2015-05-23 16:29:06 +03:00
// Build the database directory name
2016-03-21 11:33:06 +01:00
directory_name = ( char * ) malloc ( ( strlen ( dms_name ) + 8 ) * sizeof ( char ) ) ;
if ( sprintf ( directory_name , " %s.obidms " , dms_name ) < 0 )
2015-05-23 16:29:06 +03:00
{
obi_set_errno ( OBIDMS_MEMORY_ERROR ) ;
2015-08-03 15:10:39 +02:00
obidebug ( 1 , " \n Problem building an OBIDMS directory name " ) ;
2015-05-23 16:29:06 +03:00
return NULL ;
}
// Test if the database name is not too long
2015-06-17 16:51:16 +02:00
if ( strlen ( directory_name ) > = OBIDMS_MAX_NAME )
2015-05-23 16:29:06 +03:00
{
obi_set_errno ( OBIDMS_LONG_NAME_ERROR ) ;
2015-08-03 15:10:39 +02:00
obidebug ( 1 , " \n Problem building an OBIDMS directory name " ) ;
2015-06-17 16:51:16 +02:00
free ( directory_name ) ;
2015-05-23 16:29:06 +03:00
return NULL ;
}
2015-06-17 16:51:16 +02:00
return directory_name ;
2015-05-23 16:29:06 +03:00
}
2015-06-10 15:19:02 +02:00
2015-11-16 14:37:51 +01:00
static char * build_infos_file_name ( const char * dms_name )
{
char * file_name ;
// Build file name
2016-03-21 11:33:06 +01:00
file_name = ( char * ) malloc ( ( strlen ( dms_name ) + 7 ) * sizeof ( char ) ) ;
if ( sprintf ( file_name , " %s_infos " , dms_name ) < 0 )
2015-11-16 14:37:51 +01:00
{
obi_set_errno ( OBIDMS_MEMORY_ERROR ) ;
obidebug ( 1 , " \n Problem building an informations file name " ) ;
return NULL ;
}
return file_name ;
}
2018-10-07 18:53:25 +02:00
static size_t get_platform_infos_file_size ( )
2015-11-16 14:37:51 +01:00
{
2018-10-07 18:53:25 +02:00
size_t infos_size ;
size_t rounded_infos_size ;
double multiple ;
2015-11-16 14:37:51 +01:00
2018-10-07 18:53:25 +02:00
infos_size = sizeof ( OBIDMS_infos_t ) ;
multiple = ceil ( ( double ) ( infos_size ) / ( double ) getpagesize ( ) ) ;
rounded_infos_size = multiple * getpagesize ( ) ;
return rounded_infos_size ;
}
static int enlarge_infos_file ( OBIDMS_p dms , size_t new_size )
{
int infos_file_descriptor ;
double multiple ;
size_t rounded_new_size ;
char * file_name ;
2015-11-16 14:37:51 +01:00
// Create file name
2018-10-07 18:53:25 +02:00
file_name = build_infos_file_name ( dms - > dms_name ) ;
if ( file_name = = NULL )
return - 1 ;
// Open infos file
infos_file_descriptor = openat ( dms - > dir_fd , file_name , O_RDWR , 0777 ) ;
if ( infos_file_descriptor < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening a DMS information file " ) ;
free ( file_name ) ;
return - 1 ;
}
free ( file_name ) ;
// Round new size to a multiple of page size // TODO make function in utils
multiple = ceil ( ( double ) new_size / ( double ) getpagesize ( ) ) ;
rounded_new_size = multiple * getpagesize ( ) ;
// Enlarge the file
if ( ftruncate ( infos_file_descriptor , rounded_new_size ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error enlarging a DMS information file " ) ;
close ( infos_file_descriptor ) ;
return - 1 ;
}
// Unmap and remap the file
if ( munmap ( dms - > infos , ( dms - > infos ) - > file_size ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error munmapping a DMS information file when enlarging " ) ;
close ( infos_file_descriptor ) ;
return - 1 ;
}
dms - > infos = mmap ( NULL ,
rounded_new_size ,
PROT_READ | PROT_WRITE ,
MAP_SHARED ,
infos_file_descriptor ,
0
) ;
if ( dms - > infos = = MAP_FAILED )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error re-mmapping a DMS information file after enlarging the file " ) ;
close ( infos_file_descriptor ) ;
return - 1 ;
}
// Set new size
( dms - > infos ) - > file_size = rounded_new_size ;
if ( close ( infos_file_descriptor ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error closing a DMS information file " ) ;
return - 1 ;
}
return 0 ;
}
static OBIDMS_infos_p map_infos_file ( int dms_file_descriptor , const char * dms_name )
{
char * file_name ;
OBIDMS_infos_p dms_infos ;
int file_descriptor ;
size_t min_size ;
size_t full_size ;
bool little_endian_platform ;
// Build file name
file_name = build_infos_file_name ( dms_name ) ;
if ( file_name = = NULL )
return NULL ;
// Open file
file_descriptor = openat ( dms_file_descriptor ,
file_name ,
O_RDWR , 0777 ) ;
if ( file_descriptor < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening a DMS information file (DMS %s) " , dms_name ) ;
free ( file_name ) ;
return NULL ;
}
free ( file_name ) ;
// Map minimum size to read endianness and file size
// (fread() fails to read properly from the structure in the file because of padding)
min_size = get_platform_infos_file_size ( ) ;
dms_infos = mmap ( NULL ,
min_size ,
PROT_READ | PROT_WRITE ,
MAP_SHARED ,
file_descriptor ,
0
) ;
if ( dms_infos = = NULL )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error mapping a DMS information file " ) ;
return NULL ;
}
// Check endianness of the platform and DMS
little_endian_platform = obi_is_little_endian ( ) ;
if ( little_endian_platform ! = dms_infos - > little_endian )
{
obi_set_errno ( OBIDMS_BAD_ENDIAN_ERROR ) ;
obidebug ( 1 , " \n Error: The DMS and the platform have different endianness " ) ;
close ( file_descriptor ) ;
return NULL ;
}
// Read actual file size
full_size = dms_infos - > file_size ;
// Unmap the minimum size and remap the file with the full size
if ( munmap ( dms_infos , min_size ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error munmapping a DMS information file " ) ;
close ( file_descriptor ) ;
return NULL ;
}
dms_infos = mmap ( NULL ,
full_size ,
PROT_READ | PROT_WRITE ,
MAP_SHARED ,
file_descriptor ,
0
) ;
if ( dms_infos = = NULL )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error mapping a DMS information file " ) ;
return NULL ;
}
if ( close ( file_descriptor ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error closing a DMS information file " ) ;
return NULL ;
}
return dms_infos ;
}
static int unmap_infos_file ( OBIDMS_p dms )
{
OBIDMS_infos_p dms_infos ;
char * file_name ;
int file_descriptor ;
size_t file_size ;
dms_infos = dms - > infos ;
// Build file name
file_name = build_infos_file_name ( dms - > dms_name ) ;
if ( file_name = = NULL )
return - 1 ;
// Open file
file_descriptor = openat ( dms - > dir_fd ,
file_name ,
O_RDWR , 0777 ) ;
if ( file_descriptor < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening a DMS information file (DMS %s) to unmap it " , dms - > dms_name ) ;
free ( file_name ) ;
return - 1 ;
}
free ( file_name ) ;
// Unmap the DMS infos structure
file_size = dms_infos - > file_size ;
if ( munmap ( dms_infos , file_size ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error unmapping a DMS information file " ) ;
close ( file_descriptor ) ;
return - 1 ;
}
if ( close ( file_descriptor ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error closing a DMS information file " ) ;
return - 1 ;
}
return 0 ;
}
static int create_dms_infos_file ( int dms_file_descriptor , const char * dms_name )
{
char * file_name ;
int infos_file_descriptor ;
size_t file_size ;
// Build file name
2015-11-16 14:37:51 +01:00
file_name = build_infos_file_name ( dms_name ) ;
if ( file_name = = NULL )
return - 1 ;
// Create file
2017-07-28 15:56:21 +02:00
infos_file_descriptor = openat ( dms_file_descriptor ,
file_name ,
2018-10-07 18:53:25 +02:00
O_RDWR | O_CREAT | O_EXCL ,
0777 ) ;
2015-11-16 14:37:51 +01:00
if ( infos_file_descriptor < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2018-10-07 18:53:25 +02:00
obidebug ( 1 , " \n Error creating a DMS information file (DMS %s) " , dms_name ) ;
2015-11-16 14:37:51 +01:00
free ( file_name ) ;
return - 1 ;
}
free ( file_name ) ;
2018-10-07 18:53:25 +02:00
// Truncate file to the initial size
file_size = get_platform_infos_file_size ( ) ;
2015-11-16 14:37:51 +01:00
if ( ftruncate ( infos_file_descriptor , file_size ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2018-10-07 18:53:25 +02:00
obidebug ( 1 , " \n Error truncating a DMS information file to the right size " ) ;
2015-11-16 14:37:51 +01:00
close ( infos_file_descriptor ) ;
return - 1 ;
}
2018-10-07 18:53:25 +02:00
// Map the DMS infos structure
OBIDMS_infos_p infos = mmap ( NULL ,
file_size ,
PROT_READ | PROT_WRITE ,
MAP_SHARED ,
infos_file_descriptor ,
0
) ;
// Initialize values
infos - > little_endian = obi_is_little_endian ( ) ;
infos - > file_size = file_size ;
infos - > used_size = 0 ;
2019-09-20 20:37:19 +02:00
infos - > working = false ;
2018-10-07 18:53:25 +02:00
infos - > comments [ 0 ] = ' \0 ' ;
// Unmap the infos file
if ( munmap ( infos , file_size ) < 0 )
2015-11-16 14:37:51 +01:00
{
2018-10-07 18:53:25 +02:00
obi_set_errno ( OBIVIEW_ERROR ) ;
obidebug ( 1 , " \n Error munmapping a DMS information file " ) ;
2015-11-16 14:37:51 +01:00
return - 1 ;
}
2016-09-15 11:50:30 +02:00
if ( close ( infos_file_descriptor ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2018-10-07 18:53:25 +02:00
obidebug ( 1 , " \n Error closing a view file " ) ;
2016-09-15 11:50:30 +02:00
return - 1 ;
}
2017-10-16 10:35:07 +02:00
return 0 ;
}
2015-11-16 14:37:51 +01:00
2017-10-16 10:35:07 +02:00
static int list_dms ( OBIDMS_p dms )
{
int i = 0 ;
2017-11-24 17:58:47 +01:00
while ( ( global_opened_dms_list [ i ] ! = NULL ) & & ( global_opened_dms_list [ i ] ! = dms ) )
2017-10-16 10:35:07 +02:00
i + + ;
if ( i = = ( MAX_NB_OPENED_DMS - 1 ) )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening a DMS: maximum number of DMS opened by a program reached " ) ;
return - 1 ;
}
2017-11-24 17:58:47 +01:00
if ( global_opened_dms_list [ i ] = = NULL )
{ // new dms
global_opened_dms_list [ i ] = dms ;
2018-10-29 16:12:37 +01:00
global_opened_dms_counter_list [ i ] = 1 ;
2017-11-24 17:58:47 +01:00
}
else
{ // already opened dms
( global_opened_dms_counter_list [ i ] ) + + ;
}
return 0 ;
}
static int unlist_dms ( OBIDMS_p dms , bool force )
{
int i = 0 ;
while ( ( global_opened_dms_list [ i ] ! = dms ) & & ( i < = MAX_NB_OPENED_DMS ) )
i + + ;
if ( i = = MAX_NB_OPENED_DMS )
return - 1 ; // DMS not found
// If opened more than once, and the unlisting is not forced, decrement counter
if ( ( global_opened_dms_counter_list [ i ] > 1 ) & & ( ! force ) )
( global_opened_dms_counter_list [ i ] ) - - ;
else
{ // If opened once or forced unlisting, delete and unlist by shifting the list
while ( global_opened_dms_list [ i ] ! = NULL )
{
global_opened_dms_list [ i ] = global_opened_dms_list [ i + 1 ] ;
i + + ;
}
}
2015-11-16 14:37:51 +01:00
return 0 ;
}
2017-11-24 17:58:47 +01:00
static OBIDMS_p check_if_dms_in_list ( const char * full_dms_path )
2017-10-16 10:35:07 +02:00
{
int i = 0 ;
2017-11-24 17:58:47 +01:00
while ( ( i < = MAX_NB_OPENED_DMS ) & & ( global_opened_dms_list [ i ] ! = NULL ) & & ( strcmp ( global_opened_dms_list [ i ] - > directory_path , full_dms_path ) ! = 0 ) )
2017-10-16 10:35:07 +02:00
i + + ;
2017-11-24 17:58:47 +01:00
if ( i = = MAX_NB_OPENED_DMS )
return NULL ; // DMS not found
if ( global_opened_dms_list [ i ] ! = NULL )
return global_opened_dms_list [ i ] ;
return NULL ;
}
static int dms_count_in_list ( OBIDMS_p dms )
{
int i = 0 ;
while ( ( i < = MAX_NB_OPENED_DMS ) & & ( global_opened_dms_list [ i ] ! = dms ) )
2017-10-16 10:35:07 +02:00
i + + ;
2017-11-24 17:58:47 +01:00
if ( i = = MAX_NB_OPENED_DMS )
return - 1 ; // DMS not found
return global_opened_dms_counter_list [ i ] ;
2017-10-16 10:35:07 +02:00
}
2015-06-23 18:35:34 +02:00
/**********************************************************************
2015-05-26 21:36:55 +02:00
*
2015-06-23 18:35:34 +02:00
* 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
2015-05-26 21:36:55 +02:00
*
2015-06-23 18:35:34 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-05-26 21:36:55 +02:00
2019-09-20 20:37:19 +02:00
int obi_dms_is_clean ( OBIDMS_p dms )
{
int ret_val1 ;
int ret_val2 ;
ret_val1 = obi_dms_has_unfinished_views ( dms ) ;
if ( ret_val1 < 0 )
return - 1 ;
ret_val2 = obi_dms_has_unfinished_columns ( dms ) ;
if ( ret_val2 < 0 )
return - 1 ;
return ! ( ret_val1 | | ret_val2 ) ;
}
int obi_clean_dms ( const char * dms_path )
{
OBIDMS_p dms ;
dms = obi_open_dms ( dms_path , true ) ;
if ( dms = = NULL )
{
obidebug ( 1 , " \n Error opening a DMS before cleaning unfinished views and columns " ) ;
return - 1 ;
}
// Currently done in obi_open_dms
// // Clean unfinished views
// if (obi_clean_unfinished_views(dms) < 0)
// {
// obidebug(1, "\nError cleaning unfinished views");
// return -1;
// }
//
// // Clean unfinished columns
// if (obi_clean_unfinished_columns(dms) < 0)
// {
// obidebug(1, "\nError cleaning unfinished columns");
// return -1;
// }
2020-01-18 17:27:35 +01:00
if ( obi_close_dms ( dms , true ) < 0 )
{
obidebug ( 1 , " \n Error closing a DMS after cleaning " ) ;
return - 1 ;
}
2019-09-20 20:37:19 +02:00
return 0 ;
}
2016-04-29 17:46:36 +02:00
int obi_dms_exists ( const char * dms_path )
2015-06-17 16:51:16 +02:00
{
2015-05-26 21:36:55 +02:00
struct stat buffer ;
2016-02-18 10:38:51 +01:00
char * directory_name ;
int check_dir ;
2015-05-26 21:36:55 +02:00
// Build and check the directory name
2016-04-29 17:46:36 +02:00
directory_name = build_directory_name ( dms_path ) ;
2015-06-17 16:51:16 +02:00
if ( directory_name = = NULL )
2015-05-26 21:36:55 +02:00
return - 1 ;
2015-06-23 18:35:34 +02:00
check_dir = stat ( directory_name , & buffer ) ;
2015-05-26 21:36:55 +02:00
2015-06-17 16:51:16 +02:00
free ( directory_name ) ;
2015-05-26 21:36:55 +02:00
2015-06-23 18:35:34 +02:00
if ( check_dir = = 0 )
2015-05-26 21:36:55 +02:00
return 1 ;
2015-06-23 18:35:34 +02:00
else
return 0 ;
2015-05-26 21:36:55 +02:00
}
2016-04-29 17:46:36 +02:00
OBIDMS_p obi_create_dms ( const char * dms_path )
2015-06-17 16:51:16 +02:00
{
2018-10-07 18:53:25 +02:00
char * directory_name ;
DIR * dms_dir ;
int dms_file_descriptor ;
OBIDMS_p dms ;
2015-05-23 16:29:06 +03:00
// Build and check the directory name
2016-04-29 17:46:36 +02:00
directory_name = build_directory_name ( dms_path ) ;
2015-06-17 16:51:16 +02:00
if ( directory_name = = NULL )
2015-05-23 16:29:06 +03:00
return NULL ;
// Try to create the directory
2015-09-21 15:48:02 +02:00
if ( mkdir ( directory_name , 00777 ) < 0 )
2015-05-23 16:29:06 +03:00
{
2015-06-17 16:51:16 +02:00
if ( errno = = EEXIST )
2015-11-09 15:22:01 +01:00
{
2015-05-23 16:29:06 +03:00
obi_set_errno ( OBIDMS_EXIST_ERROR ) ;
2015-11-09 15:22:01 +01:00
obidebug ( 1 , " \n An OBIDMS directory with the same name already exists in this directory. " ) ;
}
2015-05-23 16:29:06 +03:00
else
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2015-08-03 15:10:39 +02:00
obidebug ( 1 , " \n Problem creating an OBIDMS directory " ) ;
2015-06-17 16:51:16 +02:00
free ( directory_name ) ;
2015-05-23 16:29:06 +03:00
return NULL ;
}
2016-06-30 11:41:30 +02:00
// Get file descriptor of DMS directory to create other directories
2015-11-03 14:22:00 +01:00
dms_dir = opendir ( directory_name ) ;
if ( dms_dir = = NULL )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Problem opening a newly created OBIDMS directory " ) ;
free ( directory_name ) ;
return NULL ;
}
2015-11-09 11:22:51 +01:00
free ( directory_name ) ;
2015-11-03 14:22:00 +01:00
dms_file_descriptor = dirfd ( dms_dir ) ;
if ( dms_file_descriptor < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Problem getting the file descriptor of a newly created OBIDMS directory " ) ;
return NULL ;
}
2016-04-12 14:53:33 +02:00
// Create the indexer directory
if ( mkdirat ( dms_file_descriptor , INDEXER_DIR_NAME , 00777 ) < 0 )
2015-11-03 14:22:00 +01:00
{
2016-04-12 14:53:33 +02:00
obi_set_errno ( OBI_INDEXER_ERROR ) ;
2016-10-10 17:02:51 +02:00
obidebug ( 1 , " \n Problem creating the indexer directory " ) ;
2015-11-03 14:22:00 +01:00
return NULL ;
}
2016-06-30 11:41:30 +02:00
// Create the view directory
if ( mkdirat ( dms_file_descriptor , VIEW_DIR_NAME , 00777 ) < 0 )
{
obi_set_errno ( OBIVIEW_ERROR ) ;
2016-10-10 17:02:51 +02:00
obidebug ( 1 , " \n Problem creating the view directory " ) ;
return NULL ;
}
// Create the taxonomy directory
if ( mkdirat ( dms_file_descriptor , TAXONOMY_DIR_NAME , 00777 ) < 0 )
{
obi_set_errno ( OBIVIEW_ERROR ) ;
obidebug ( 1 , " \n Problem creating the taxonomy directory " ) ;
2016-06-30 11:41:30 +02:00
return NULL ;
}
2018-10-07 18:53:25 +02:00
// Create the information file
if ( create_dms_infos_file ( dms_file_descriptor , basename ( ( char * ) dms_path ) ) < 0 )
return NULL ;
// Open DMS
2019-09-20 20:37:19 +02:00
dms = obi_open_dms ( dms_path , false ) ;
2018-10-07 18:53:25 +02:00
if ( dms = = NULL )
2016-04-29 17:46:36 +02:00
{
2018-10-07 18:53:25 +02:00
obidebug ( 1 , " \n Problem opening a DMS " ) ;
return NULL ;
2016-04-29 17:46:36 +02:00
}
2018-10-07 18:53:25 +02:00
// Write empty json string in comments (Python json lib doesn't like empty "")
if ( obi_dms_write_comments ( dms , " {} " ) < 0 )
{
obidebug ( 1 , " \n Problem initializing empty json string in new DMS comments " ) ;
2015-11-16 14:37:51 +01:00
return NULL ;
2018-10-07 18:53:25 +02:00
}
2015-11-16 14:37:51 +01:00
2019-08-29 16:35:10 +02:00
if ( closedir ( dms_dir ) < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error closing a directory " ) ;
return NULL ;
}
2018-10-07 18:53:25 +02:00
return dms ;
2015-05-23 16:29:06 +03:00
}
2015-06-10 15:19:02 +02:00
2019-09-20 20:37:19 +02:00
OBIDMS_p obi_open_dms ( const char * dms_path , bool cleaning )
2015-06-17 16:51:16 +02:00
{
OBIDMS_p dms ;
2017-11-24 17:58:47 +01:00
char * relative_dms_path ;
char * absolute_dms_path ;
2019-09-25 11:38:00 +02:00
//int clean_dms;
2015-06-17 16:51:16 +02:00
dms = NULL ;
2015-05-23 16:29:06 +03:00
2017-11-24 17:58:47 +01:00
// Build and check the directory name including the relative path
relative_dms_path = build_directory_name ( dms_path ) ;
if ( relative_dms_path = = NULL )
2015-11-09 15:06:02 +01:00
return NULL ;
2017-11-24 17:58:47 +01:00
// Get and store the absolute path to the DMS directory
absolute_dms_path = realpath ( relative_dms_path , NULL ) ;
if ( absolute_dms_path = = NULL )
2016-08-29 17:30:31 +02:00
{
2017-11-24 17:58:47 +01:00
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error getting the absolute path to the DMS directory (DMS does not exist) " ) ;
free ( relative_dms_path ) ;
return NULL ;
2016-08-29 17:30:31 +02:00
}
2017-11-24 17:58:47 +01:00
free ( relative_dms_path ) ;
// Check if the DMS is already opened
dms = check_if_dms_in_list ( absolute_dms_path ) ;
if ( dms ! = NULL )
2015-11-09 15:06:02 +01:00
{
2017-11-24 17:58:47 +01:00
list_dms ( dms ) ;
free ( absolute_dms_path ) ;
return dms ;
2015-11-09 15:06:02 +01:00
}
2017-11-24 17:58:47 +01:00
// Allocate the data structure
dms = ( OBIDMS_p ) malloc ( sizeof ( OBIDMS_t ) ) ;
if ( dms = = NULL )
2016-04-29 17:46:36 +02:00
{
2017-11-24 17:58:47 +01:00
obi_set_errno ( OBIDMS_MEMORY_ERROR ) ;
obidebug ( 1 , " \n Error allocating the memory for the OBIDMS structure " ) ;
2016-08-30 11:09:45 +02:00
return NULL ;
2016-04-29 17:46:36 +02:00
}
2016-08-29 17:30:31 +02:00
2017-11-24 17:58:47 +01:00
strcpy ( dms - > dms_name , basename ( ( char * ) dms_path ) ) ;
strcpy ( dms - > directory_path , absolute_dms_path ) ;
2015-05-23 16:29:06 +03:00
2015-06-23 18:35:34 +02:00
// Try to open the directory
2016-04-29 17:46:36 +02:00
dms - > directory = opendir ( dms - > directory_path ) ;
2015-11-09 15:06:02 +01:00
if ( dms - > directory = = NULL )
2015-06-23 18:35:34 +02:00
{
switch ( errno )
{
case ENOENT :
obi_set_errno ( OBIDMS_NOT_EXIST_ERROR ) ;
break ;
2015-05-23 16:29:06 +03:00
2015-06-23 18:35:34 +02:00
case EACCES :
obi_set_errno ( OBIDMS_ACCESS_ERROR ) ;
break ;
2015-05-23 16:29:06 +03:00
2015-06-23 18:35:34 +02:00
case ENOMEM :
obi_set_errno ( OBIDMS_MEMORY_ERROR ) ;
break ;
2015-05-23 16:29:06 +03:00
2015-06-23 18:35:34 +02:00
default :
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2015-05-23 16:29:06 +03:00
}
2015-08-03 15:10:39 +02:00
obidebug ( 1 , " \n Can't open OBIDMS directory " ) ;
2015-11-09 15:06:02 +01:00
free ( dms ) ;
2015-05-23 16:29:06 +03:00
return NULL ;
}
2018-10-07 18:53:25 +02:00
// Get and store file descriptor of DMS directory
2015-11-09 15:06:02 +01:00
dms - > dir_fd = dirfd ( dms - > directory ) ;
if ( dms - > dir_fd < 0 )
2015-11-03 14:22:00 +01:00
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error getting the file descriptor for a newly created OBIDMS directory " ) ;
2015-11-09 15:06:02 +01:00
closedir ( dms - > directory ) ;
free ( dms ) ;
2015-11-03 14:22:00 +01:00
return NULL ;
}
2018-10-07 18:53:25 +02:00
// Open the information file
dms - > infos = map_infos_file ( dms - > dir_fd , dms - > dms_name ) ;
if ( dms - > infos = = NULL )
2015-11-16 14:37:51 +01:00
{
2018-10-07 18:53:25 +02:00
obidebug ( 1 , " \n Error opening a DMS information file " ) ;
2015-11-16 14:37:51 +01:00
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
2019-09-20 20:37:19 +02:00
// Reset the working variable to false if cleaning the DMS
if ( cleaning )
( dms - > infos ) - > working = false ;
// Check that the DMS is not already working (being used by a process)
if ( ( dms - > infos ) - > working )
{
obidebug ( 1 , " \n \n ERROR: \n The DMS '%s' contains unfinished views or columns. Either another command is currently running, "
" in which case you have to wait for it to finish, or a previous command was interrupted, "
" in which case you can run 'obi clean_dms [your_dms]' to clean the DMS. \n " , dms - > dms_name ) ;
obi_set_errno ( OBIDMS_WORKING ) ;
unmap_infos_file ( dms ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
// Set the working variable to true
( dms - > infos ) - > working = true ;
2016-04-12 14:53:33 +02:00
// Open the indexer directory
dms - > indexer_directory = opendir_in_dms ( dms , INDEXER_DIR_NAME ) ;
if ( dms - > indexer_directory = = NULL )
2015-11-03 14:22:00 +01:00
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2016-04-12 14:53:33 +02:00
obidebug ( 1 , " \n Error opening the indexer directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2015-11-09 15:06:02 +01:00
closedir ( dms - > directory ) ;
free ( dms ) ;
2015-11-03 14:22:00 +01:00
return NULL ;
}
2016-04-12 14:53:33 +02:00
// Store the indexer directory's file descriptor
dms - > indexer_dir_fd = dirfd ( dms - > indexer_directory ) ;
if ( dms - > indexer_dir_fd < 0 )
2015-11-09 15:06:02 +01:00
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
2016-04-12 14:53:33 +02:00
obidebug ( 1 , " \n Error getting the file descriptor of the indexer directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2016-04-12 14:53:33 +02:00
closedir ( dms - > indexer_directory ) ;
2015-11-16 14:37:51 +01:00
closedir ( dms - > directory ) ;
2015-11-09 15:06:02 +01:00
free ( dms ) ;
return NULL ;
}
2015-06-23 18:35:34 +02:00
2016-06-30 11:41:30 +02:00
// Open the view directory
dms - > view_directory = opendir_in_dms ( dms , VIEW_DIR_NAME ) ;
if ( dms - > view_directory = = NULL )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening the view directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2016-06-30 11:41:30 +02:00
closedir ( dms - > indexer_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
// Store the view directory's file descriptor
dms - > view_dir_fd = dirfd ( dms - > view_directory ) ;
if ( dms - > view_dir_fd < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error getting the file descriptor of the view directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2016-06-30 11:41:30 +02:00
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
2016-10-14 17:03:10 +02:00
// Open the taxonomy directory
dms - > tax_directory = opendir_in_dms ( dms , TAXONOMY_DIR_NAME ) ;
if ( dms - > tax_directory = = NULL )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error opening the taxonomy directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2016-10-14 17:03:10 +02:00
closedir ( dms - > indexer_directory ) ;
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
// Store the taxonomy directory's file descriptor
dms - > tax_dir_fd = dirfd ( dms - > tax_directory ) ;
if ( dms - > tax_dir_fd < 0 )
{
obi_set_errno ( OBIDMS_UNKNOWN_ERROR ) ;
obidebug ( 1 , " \n Error getting the file descriptor of the taxonomy directory " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2016-10-14 17:03:10 +02:00
closedir ( dms - > indexer_directory ) ;
2017-10-26 18:58:48 +02:00
closedir ( dms - > tax_directory ) ;
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
2019-09-20 20:37:19 +02:00
// // Check for unfinished views and columns
// clean_dms = obi_dms_is_clean(dms);
// if (clean_dms < 0)
// {
// obi_set_errno(OBIDMS_UNKNOWN_ERROR);
// obidebug(1, "\nError checking if a DMS has unfinished views or columns when opening it");
// unmap_infos_file(dms);
// closedir(dms->indexer_directory);
// closedir(dms->tax_directory);
// closedir(dms->view_directory);
// closedir(dms->directory);
// free(dms);
// return NULL;
// }
// if (! clean_dms)
// obi_set_errno(OBIDMS_NOT_CLEAN);
2017-10-26 18:58:48 +02:00
// Clean unfinished views
if ( obi_clean_unfinished_views ( dms ) < 0 )
{
obidebug ( 1 , " \n Error cleaning unfinished views when opening an OBIDMS " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2017-10-26 18:58:48 +02:00
closedir ( dms - > indexer_directory ) ;
closedir ( dms - > tax_directory ) ;
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
// Clean unfinished columns
if ( obi_clean_unfinished_columns ( dms ) < 0 )
{
obidebug ( 1 , " \n Error cleaning unfinished columns when opening an OBIDMS " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2017-10-26 18:58:48 +02:00
closedir ( dms - > indexer_directory ) ;
2016-10-14 17:03:10 +02:00
closedir ( dms - > tax_directory ) ;
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms ) ;
return NULL ;
}
2015-12-02 17:32:07 +01:00
// Initialize the list of opened columns
dms - > opened_columns = ( Opened_columns_list_p ) malloc ( sizeof ( Opened_columns_list_t ) ) ;
( dms - > opened_columns ) - > nb_opened_columns = 0 ;
2016-04-22 11:28:09 +02:00
// Initialize the list of opened indexers
2016-04-12 14:53:33 +02:00
dms - > opened_indexers = ( Opened_indexers_list_p ) malloc ( sizeof ( Opened_indexers_list_t ) ) ;
( dms - > opened_indexers ) - > nb_opened_indexers = 0 ;
2015-12-02 17:32:07 +01:00
2017-10-16 10:35:07 +02:00
// Add in the global list of opened DMS
2017-11-24 17:58:47 +01:00
if ( list_dms ( dms ) < 0 )
{
obidebug ( 1 , " \n Error cleaning unfinished columns when opening an OBIDMS " ) ;
2018-10-07 18:53:25 +02:00
unmap_infos_file ( dms ) ;
2017-11-24 17:58:47 +01:00
closedir ( dms - > indexer_directory ) ;
closedir ( dms - > tax_directory ) ;
closedir ( dms - > view_directory ) ;
closedir ( dms - > directory ) ;
free ( dms - > opened_columns ) ;
free ( dms - > opened_indexers ) ;
free ( dms ) ;
return NULL ;
}
2017-10-16 10:35:07 +02:00
2015-05-23 16:29:06 +03:00
return dms ;
}
2015-06-10 15:19:02 +02:00
2017-07-05 15:38:22 +02:00
OBIDMS_p obi_test_open_dms ( const char * dms_name )
{
int exists ;
exists = obi_dms_exists ( dms_name ) ;
switch ( exists )
{
case 0 :
return NULL ;
case 1 :
2019-09-20 20:37:19 +02:00
return obi_open_dms ( dms_name , false ) ;
2017-07-05 15:38:22 +02:00
} ;
obidebug ( 1 , " \n Error checking if an OBIDMS directory exists " ) ;
return NULL ;
}
2015-06-17 16:51:16 +02:00
OBIDMS_p obi_dms ( const char * dms_name )
{
2015-06-23 18:35:34 +02:00
int exists ;
2015-05-26 21:36:55 +02:00
2015-06-23 18:35:34 +02:00
exists = obi_dms_exists ( dms_name ) ;
switch ( exists )
{
2015-05-26 21:36:55 +02:00
case 0 :
2015-06-17 16:51:16 +02:00
return obi_create_dms ( dms_name ) ;
2015-05-26 21:36:55 +02:00
case 1 :
2019-09-20 20:37:19 +02:00
return obi_open_dms ( dms_name , false ) ;
2015-05-26 21:36:55 +02:00
} ;
2015-08-03 15:10:39 +02:00
obidebug ( 1 , " \n Error checking if an OBIDMS directory exists " ) ;
2015-05-26 21:36:55 +02:00
return NULL ;
}
2015-05-23 16:29:06 +03:00
2017-11-24 17:58:47 +01:00
int obi_close_dms ( OBIDMS_p dms , bool force )
2015-06-17 16:51:16 +02:00
{
2017-11-24 17:58:47 +01:00
int dms_counter ;
if ( ! force )
{
dms_counter = dms_count_in_list ( dms ) ;
if ( dms_counter < 0 )
obidebug ( 1 , " \n Error checking the counter of an OBIDMS in the global list of opened OBIDMS " ) ;
if ( dms_counter > 1 ) // Don't close if the DMS is opened more than once
{
if ( unlist_dms ( dms , force ) < 0 )
{
obidebug ( 1 , " \n Error decrementing the counter of an OBIDMS in the global list of opened OBIDMS " ) ;
return - 1 ;
}
return 0 ;
}
}
2015-05-23 16:29:06 +03:00
if ( dms ! = NULL )
{
2015-12-02 17:32:07 +01:00
// Close all columns
while ( ( dms - > opened_columns ) - > nb_opened_columns > 0 )
obi_close_column ( * ( ( dms - > opened_columns ) - > columns ) ) ;
2016-10-14 17:03:10 +02:00
// Close dms, and view, indexer and taxonomy directories
2016-04-22 11:28:09 +02:00
if ( closedir ( dms - > indexer_directory ) < 0 )
2015-11-03 14:22:00 +01:00
{
2016-04-12 14:53:33 +02:00
obi_set_errno ( OBI_INDEXER_ERROR ) ;
obidebug ( 1 , " \n Error closing an indexer directory " ) ;
2015-05-23 16:29:06 +03:00
free ( dms ) ;
return - 1 ;
}
2016-06-30 11:41:30 +02:00
if ( closedir ( dms - > view_directory ) < 0 )
{
obi_set_errno ( OBIVIEW_ERROR ) ;
obidebug ( 1 , " \n Error closing a view directory " ) ;
free ( dms ) ;
return - 1 ;
}
2016-10-14 17:03:10 +02:00
if ( closedir ( dms - > tax_directory ) < 0 )
{
obi_set_errno ( OBIVIEW_ERROR ) ;
obidebug ( 1 , " \n Error closing a taxonomy directory " ) ;
free ( dms ) ;
return - 1 ;
}
2019-09-20 20:37:19 +02:00
// Set the working variable as false
( dms - > infos ) - > working = false ;
// Unmap information file
if ( unmap_infos_file ( dms ) < 0 )
{
obidebug ( 1 , " \n Error unmaping a DMS information file while closing a DMS " ) ;
free ( dms ) ;
return - 1 ;
}
2016-09-15 11:50:30 +02:00
if ( closedir ( dms - > directory ) < 0 )
{
obi_set_errno ( OBIDMS_MEMORY_ERROR ) ;
obidebug ( 1 , " \n Error closing an OBIDMS directory " ) ;
free ( dms ) ;
return - 1 ;
}
2017-10-16 10:35:07 +02:00
// Remove DMS from global list of opened DMS
2017-11-24 17:58:47 +01:00
if ( unlist_dms ( dms , force ) < 0 )
{
obidebug ( 1 , " \n Error removing an OBIDMS from the global list of opened OBIDMS when closing it " ) ;
free ( dms ) ;
return - 1 ;
}
2017-10-16 10:35:07 +02:00
2015-05-23 16:29:06 +03:00
free ( dms ) ;
}
return 0 ;
}
2016-04-15 10:49:12 +02:00
2018-10-07 18:53:25 +02:00
int obi_dms_write_comments ( OBIDMS_p dms , const char * comments )
{
size_t new_size ;
if ( comments = = NULL )
return 0 ; // TODO or error? discuss
new_size = sizeof ( OBIDMS_infos_t ) + strlen ( comments ) + 1 ;
// Check if the file has to be enlarged
if ( new_size > = ( dms - > infos ) - > file_size )
{
if ( enlarge_infos_file ( dms , new_size ) < 0 )
return - 1 ;
}
strcpy ( ( dms - > infos ) - > comments , comments ) ;
( dms - > infos ) - > used_size = new_size ;
return 0 ;
}
int obi_dms_add_comment ( OBIDMS_p dms , const char * key , const char * value )
{
char * new_comments = NULL ;
new_comments = obi_add_comment ( ( dms - > infos ) - > comments , key , value ) ;
if ( new_comments = = NULL )
{
obidebug ( 1 , " \n Error adding a comment to a dms, key: %s, value: %s " , key , value ) ;
return - 1 ;
}
if ( obi_dms_write_comments ( dms , new_comments ) < 0 )
{
obidebug ( 1 , " \n Error adding a comment to a dms, key: %s, value: %s " , key , value ) ;
return - 1 ;
}
free ( new_comments ) ;
return 0 ;
}
2016-04-15 10:49:12 +02:00
OBIDMS_column_p obi_dms_get_column_from_list ( OBIDMS_p dms , const char * column_name , obiversion_t version )
{
int i ;
for ( i = 0 ; i < ( ( dms - > opened_columns ) - > nb_opened_columns ) ; i + + )
{
if ( ! strcmp ( ( ( * ( ( ( dms - > opened_columns ) - > columns ) + i ) ) - > header ) - > name , column_name )
& & ( ( ( * ( ( ( dms - > opened_columns ) - > columns ) + i ) ) - > header ) - > version = = version ) )
{ // Found the column already opened, return it
return * ( ( ( dms - > opened_columns ) - > columns ) + i ) ;
}
}
// Didn't find the column
return NULL ;
}
2016-04-22 11:28:09 +02:00
void obi_dms_list_column ( OBIDMS_p dms , OBIDMS_column_p column ) // TODO add check if column already in list?
2016-04-15 10:49:12 +02:00
{
* ( ( ( dms - > opened_columns ) - > columns ) + ( ( dms - > opened_columns ) - > nb_opened_columns ) ) = column ;
( ( dms - > opened_columns ) - > nb_opened_columns ) + + ;
}
int obi_dms_unlist_column ( OBIDMS_p dms , OBIDMS_column_p column )
{
int i ;
Opened_columns_list_p columns_list ;
columns_list = dms - > opened_columns ;
for ( i = 0 ; i < columns_list - > nb_opened_columns ; i + + )
{
if ( ! strcmp ( ( ( * ( ( columns_list - > columns ) + i ) ) - > header ) - > name , ( column - > header ) - > name )
& & ( ( ( * ( ( columns_list - > columns ) + i ) ) - > header ) - > version = = ( column - > header ) - > version ) )
{ // Found the column. Rearrange list
( columns_list - > nb_opened_columns ) - - ;
( columns_list - > columns ) [ i ] = ( columns_list - > columns ) [ columns_list - > nb_opened_columns ] ;
return 0 ;
}
}
obidebug ( 1 , " \n Could not find the column to delete from list of open columns " ) ;
return - 1 ;
}
Obi_indexer_p obi_dms_get_indexer_from_list ( OBIDMS_p dms , const char * indexer_name )
{
int i ;
Opened_indexers_list_p indexers_list ;
indexers_list = dms - > opened_indexers ;
for ( i = 0 ; i < ( indexers_list - > nb_opened_indexers ) ; i + + )
{
2016-04-29 16:18:56 +02:00
if ( ! strcmp ( obi_indexer_get_name ( ( indexers_list - > indexers ) [ i ] ) , indexer_name ) )
2016-04-15 10:49:12 +02:00
{ // Found the indexer already opened, return it
return ( indexers_list - > indexers ) [ i ] ;
}
}
// Didn't find the indexer
return NULL ;
}
2016-04-29 16:06:01 +02:00
void obi_dms_list_indexer ( OBIDMS_p dms , Obi_indexer_p indexer ) // TODO add check if indexer already in list?
2016-04-15 10:49:12 +02:00
{
* ( ( ( dms - > opened_indexers ) - > indexers ) + ( ( dms - > opened_indexers ) - > nb_opened_indexers ) ) = indexer ;
( ( dms - > opened_indexers ) - > nb_opened_indexers ) + + ;
}
int obi_dms_unlist_indexer ( OBIDMS_p dms , Obi_indexer_p indexer )
{
int i ;
Opened_indexers_list_p indexers_list ;
indexers_list = dms - > opened_indexers ;
for ( i = 0 ; i < indexers_list - > nb_opened_indexers ; i + + )
{
2016-04-29 16:18:56 +02:00
if ( ! strcmp ( obi_indexer_get_name ( ( indexers_list - > indexers ) [ i ] ) , indexer - > name ) )
2016-04-15 10:49:12 +02:00
{ // Found the indexer. Rearrange list
( indexers_list - > nb_opened_indexers ) - - ;
( indexers_list - > indexers ) [ i ] = ( indexers_list - > indexers ) [ indexers_list - > nb_opened_indexers ] ;
return 0 ;
}
}
obidebug ( 1 , " \n Could not find the indexer to delete from list of open indexers " ) ;
return - 1 ;
}
2016-04-15 11:11:13 +02:00
char * obi_dms_get_dms_path ( OBIDMS_p dms )
2016-04-15 10:49:12 +02:00
{
char * full_path ;
full_path = ( char * ) malloc ( ( MAX_PATH_LEN ) * sizeof ( char ) ) ;
if ( full_path = = NULL )
{
obi_set_errno ( OBI_MALLOC_ERROR ) ;
obidebug ( 1 , " \n Error allocating memory for the char* path to a file or directory " ) ;
return NULL ;
}
2016-04-29 17:46:36 +02:00
strcpy ( full_path , dms - > directory_path ) ;
2016-04-15 11:11:13 +02:00
return full_path ;
}
char * obi_dms_get_full_path ( OBIDMS_p dms , const char * path_name )
{
char * full_path ;
full_path = obi_dms_get_dms_path ( dms ) ;
2016-04-15 10:49:12 +02:00
strcat ( full_path , " / " ) ;
strcat ( full_path , path_name ) ;
return full_path ;
}
DIR * opendir_in_dms ( OBIDMS_p dms , const char * path_name )
{
char * full_path ;
DIR * directory ;
2016-04-15 11:11:13 +02:00
full_path = obi_dms_get_full_path ( dms , path_name ) ;
2016-04-15 10:49:12 +02:00
if ( full_path = = NULL )
return NULL ;
directory = opendir ( full_path ) ;
if ( directory = = NULL )
{
obi_set_errno ( OBI_UTILS_ERROR ) ;
obidebug ( 1 , " \n Error opening a directory " ) ;
}
free ( full_path ) ;
return directory ;
}
2017-08-03 16:33:12 +02:00
// TODO move somewhere else maybe
// TODO discuss arguments
obiversion_t obi_import_column ( const char * dms_path_1 , const char * dms_path_2 , const char * column_name , obiversion_t version_number )
{
OBIDMS_p dms_1 ;
OBIDMS_p dms_2 ;
OBIDMS_column_p column_1 ;
OBIDMS_column_p column_2 ;
OBIDMS_column_header_p header_1 ;
OBIDMS_column_header_p header_2 ;
int avl_exists ;
const char * avl_name ;
char * new_avl_name ;
obiversion_t new_version ;
int i ;
int avl_count ;
char * avl_name_1 ;
char * avl_name_2 ;
char * avl_file_path_1 ;
char * avl_file_path_2 ;
char * avl_data_file_path_1 ;
char * avl_data_file_path_2 ;
char * complete_avl_name ;
Obi_indexer_p avl_group ;
2019-09-20 20:37:19 +02:00
dms_1 = obi_open_dms ( dms_path_1 , false ) ;
2017-08-03 16:33:12 +02:00
if ( dms_1 = = NULL )
{
obidebug ( 1 , " \n Error opening a DMS to import a column from it " ) ;
return - 1 ;
}
dms_2 = obi_dms ( dms_path_2 ) ;
if ( dms_2 = = NULL )
{
obidebug ( 1 , " \n Error opening or creating a DMS to import a column into it " ) ;
return - 1 ;
}
column_1 = obi_open_column ( dms_1 , column_name , version_number ) ;
if ( column_1 = = NULL )
{
obidebug ( 1 , " \n Error opening a column to import in another DMS " ) ;
return - 1 ;
}
header_1 = column_1 - > header ;
// Check if associated indexer exists BEFORE creating the new column as that will automatically create it if it doesn't already exist
avl_name = header_1 - > indexer_name ;
avl_exists = obi_indexer_exists ( dms_2 , avl_name ) ;
if ( avl_exists = = - 1 )
{
obidebug ( 1 , " \n Error checking if an indexer exists while importing a column " ) ;
return - 1 ;
}
if ( avl_exists )
// Use automatic name
new_avl_name = NULL ;
else
// Name can stay the same
new_avl_name = header_1 - > indexer_name ;
// Create new column
column_2 = obi_create_column ( dms_2 , column_name , header_1 - > returned_data_type , header_1 - > line_count ,
2017-11-15 13:48:59 +01:00
header_1 - > nb_elements_per_line , header_1 - > elements_names , true , header_1 - > tuples ,
2017-12-13 22:46:50 +01:00
header_1 - > to_eval , new_avl_name , ( header_1 - > associated_column ) . column_name ,
( header_1 - > associated_column ) . version , header_1 - > comments ) ;
2017-08-03 16:33:12 +02:00
if ( column_2 = = NULL )
{
obidebug ( 1 , " \n Error creating the new column while importing a column " ) ;
return - 1 ;
}
header_2 = column_2 - > header ;
// Get the new version to return
new_version = header_2 - > version ;
// Copy lines_used informations
header_2 - > lines_used = header_1 - > lines_used ;
// Copy data TODO check how much time and memory that costs, eventually use write() instead
memcpy ( column_2 - > data , column_1 - > data , header_1 - > data_size ) ;
// Copy the AVL files if there are some (overwriting the automatically created files)
if ( ( header_1 - > returned_data_type = = OBI_STR ) | | ( header_1 - > returned_data_type = = OBI_SEQ ) | | ( header_1 - > returned_data_type = = OBI_QUAL ) )
{
avl_name_1 = ( char * ) malloc ( ( strlen ( header_1 - > indexer_name ) + 1 ) * sizeof ( char ) ) ;
if ( avl_name_1 = = NULL )
{
obi_set_errno ( OBI_MALLOC_ERROR ) ;
obidebug ( 1 , " \n Error allocating memory for an AVL name when importing a column " ) ;
return - 1 ;
}
strcpy ( avl_name_1 , header_1 - > indexer_name ) ;
avl_name_2 = ( char * ) malloc ( ( strlen ( header_2 - > indexer_name ) + 1 ) * sizeof ( char ) ) ;
if ( avl_name_2 = = NULL )
{
obi_set_errno ( OBI_MALLOC_ERROR ) ;
obidebug ( 1 , " \n Error allocating memory for an AVL name when importing a column " ) ;
return - 1 ;
}
strcpy ( avl_name_2 , header_2 - > indexer_name ) ;
avl_count = ( column_1 - > indexer - > last_avl_idx ) + 1 ;
// Close column to manipulate AVL files safely (but not multithreading safe) (TODO not sure how important this is, can't find informations about conflicts when using write() on mmapped files)
if ( obi_close_column ( column_1 ) < 0 )
{
obidebug ( 1 , " \n Error closing an imported column " ) ;
return - 1 ;
}
2018-10-29 17:39:30 +01:00
( column_2 - > header ) - > finished = true ; // note: this is normally handled by the view that created the column
2017-08-03 16:33:12 +02:00
if ( obi_close_column ( column_2 ) < 0 )
{
obidebug ( 1 , " \n Error closing an imported column " ) ;
return - 1 ;
}
for ( i = 0 ; i < avl_count ; i + + )
{
avl_file_path_1 = obi_get_full_path_of_avl_file_name ( dms_1 , avl_name_1 , i ) ;
if ( avl_file_path_1 = = NULL )
{
obidebug ( 1 , " \n Error getting an AVL file path while importing a column " ) ;
return - 1 ;
}
avl_data_file_path_1 = obi_get_full_path_of_avl_data_file_name ( dms_1 , avl_name_1 , i ) ;
if ( avl_data_file_path_1 = = NULL )
{
obidebug ( 1 , " \n Error getting an AVL file path while importing a column " ) ;
return - 1 ;
}
avl_file_path_2 = obi_get_full_path_of_avl_file_name ( dms_2 , avl_name_2 , i ) ;
if ( avl_file_path_2 = = NULL )
{
obidebug ( 1 , " \n Error getting an AVL file path while importing a column " ) ;
return - 1 ;
}
avl_data_file_path_2 = obi_get_full_path_of_avl_data_file_name ( dms_2 , avl_name_2 , i ) ;
if ( avl_data_file_path_2 = = NULL )
{
obidebug ( 1 , " \n Error getting an AVL file path while importing a column " ) ;
return - 1 ;
}
// Copy AVL file
if ( copy_file ( avl_file_path_1 , avl_file_path_2 ) < 0 )
{
obidebug ( 1 , " \n Error copying an AVL file while importing a column " ) ;
return - 1 ;
}
// Copy AVL data file
if ( copy_file ( avl_data_file_path_1 , avl_data_file_path_2 ) < 0 )
{
obidebug ( 1 , " \n Error copying a data AVL file while importing a column " ) ;
return - 1 ;
}
free ( avl_file_path_1 ) ;
free ( avl_file_path_2 ) ;
free ( avl_data_file_path_1 ) ;
free ( avl_data_file_path_2 ) ;
}
// Update AVL names in headers
avl_group = obi_open_indexer ( dms_2 , avl_name_2 ) ;
for ( i = 0 ; i < avl_count ; i + + )
{
complete_avl_name = obi_build_avl_name_with_idx ( avl_name_2 , i ) ;
strcpy ( ( ( ( avl_group - > sub_avls ) [ i ] ) - > header ) - > avl_name , complete_avl_name ) ;
strcpy ( ( ( ( ( avl_group - > sub_avls ) [ i ] ) - > data ) - > header ) - > avl_name , complete_avl_name ) ;
free ( complete_avl_name ) ;
}
free ( avl_name_1 ) ;
free ( avl_name_2 ) ;
}
else
{
if ( obi_close_column ( column_1 ) < 0 )
{
obidebug ( 1 , " \n Error closing an imported column " ) ;
return - 1 ;
}
2018-10-29 17:39:30 +01:00
( column_2 - > header ) - > finished = true ; // note: this is normally handled by the view that created the column
2017-08-03 16:33:12 +02:00
if ( obi_close_column ( column_2 ) < 0 )
{
obidebug ( 1 , " \n Error closing an imported column " ) ;
return - 1 ;
}
}
// Copy associated column (update version)
//new_associated_col_version = import_column(dms_path_1, dms_path_2, header_1->associated_column_name, header_1->associated_column_version);
// TODO no? because if iterating over all columns in a view etc.... iterate and change associated columns version refs afterwards?
// Close the DMS
2017-11-24 17:58:47 +01:00
obi_close_dms ( dms_1 , false ) ;
obi_close_dms ( dms_2 , false ) ;
2017-08-03 16:33:12 +02:00
return new_version ;
}
// TODO move somewhere else maybe
// TODO discuss arguments
int obi_import_view ( const char * dms_path_1 , const char * dms_path_2 , const char * view_name_1 , const char * view_name_2 )
{
OBIDMS_p dms_1 ;
OBIDMS_p dms_2 ;
Obiview_p view_1 ;
Obiview_p view_2 ;
obiversion_t new_version ;
2018-11-07 13:35:11 +01:00
int i , j ;
OBIDMS_column_header_p header = NULL ;
OBIDMS_column_header_p header_2 = NULL ;
2017-08-03 16:33:12 +02:00
2019-09-21 16:47:22 +02:00
signal ( SIGINT , sig_handler ) ;
2019-09-20 20:37:19 +02:00
dms_1 = obi_open_dms ( dms_path_1 , false ) ;
2017-08-03 16:33:12 +02:00
if ( dms_1 = = NULL )
{
obidebug ( 1 , " \n Error opening a DMS to import a view from it " ) ;
return - 1 ;
}
dms_2 = obi_dms ( dms_path_2 ) ;
if ( dms_2 = = NULL )
{
obidebug ( 1 , " \n Error opening or creating a DMS to import a view into it " ) ;
return - 1 ;
}
// Open view to import
view_1 = obi_open_view ( dms_1 , view_name_1 ) ;
// Create new view
if ( strcmp ( ( view_1 - > infos ) - > view_type , VIEW_TYPE_NUC_SEQS ) = = 0 )
2018-10-29 16:12:37 +01:00
view_2 = obi_new_view_nuc_seqs ( dms_2 , view_name_2 , NULL , NULL , ( view_1 - > infos ) - > comments , false , false ) ;
2017-08-03 16:33:12 +02:00
else // Non-typed view
view_2 = obi_new_view ( dms_2 , view_name_2 , NULL , NULL , ( view_1 - > infos ) - > comments ) ;
// Import line count
view_2 - > infos - > line_count = view_1 - > infos - > line_count ;
// Import the line selection column if there is one
if ( ! view_1 - > infos - > all_lines )
{
view_2 - > infos - > all_lines = false ;
new_version = obi_import_column ( dms_path_1 , dms_path_2 , ( ( view_1 - > infos ) - > line_selection ) . column_name , ( ( view_1 - > infos ) - > line_selection ) . version ) ;
if ( new_version = = - 1 )
{
obidebug ( 1 , " \n Error importing a line selection column while importing a view " ) ;
return - 1 ;
}
strcpy ( ( ( view_2 - > infos ) - > line_selection ) . column_name , ( ( view_1 - > infos ) - > line_selection ) . column_name ) ;
( ( view_2 - > infos ) - > line_selection ) . version = new_version ;
view_2 - > line_selection = obi_open_column ( dms_2 , ( ( view_2 - > infos ) - > line_selection ) . column_name , ( ( view_2 - > infos ) - > line_selection ) . version ) ;
if ( view_2 - > line_selection = = NULL )
{
obidebug ( 1 , " \n Error opening a line selection column while importing a view " ) ;
return - 1 ;
}
}
// Import each column and update with the new version number
for ( i = 0 ; i < ( view_1 - > infos - > column_count ) ; i + + )
{
2019-09-21 16:47:22 +02:00
if ( ! keep_running )
return - 1 ;
2017-08-03 16:33:12 +02:00
new_version = obi_import_column ( dms_path_1 , dms_path_2 , ( ( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . column_refs ) . column_name , ( ( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . column_refs ) . version ) ;
if ( new_version = = - 1 )
{
obidebug ( 1 , " \n Error importing a column while importing a view " ) ;
return - 1 ;
}
if ( obi_view_add_column ( view_2 ,
( ( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . column_refs ) . column_name ,
new_version ,
( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . alias ,
0 ,
0 ,
0 ,
NULL ,
2017-11-15 13:48:59 +01:00
false ,
2017-12-13 22:46:50 +01:00
false ,
false ,
2017-08-03 16:33:12 +02:00
NULL ,
NULL ,
- 1 ,
NULL ,
false ) < 0 )
2018-10-29 16:12:37 +01:00
{
obidebug ( 1 , " \n Error adding a column to a view while importing it " ) ;
return - 1 ;
}
2017-08-03 16:33:12 +02:00
}
2018-11-07 13:35:11 +01:00
// Go through columns again to update associated columns
for ( i = 0 ; i < ( view_1 - > infos - > column_count ) ; i + + )
{
2019-09-21 16:47:22 +02:00
if ( ! keep_running )
return - 1 ;
2018-11-07 13:35:11 +01:00
header = obi_column_get_header_from_name ( dms_1 , ( ( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . column_refs ) . column_name , ( ( ( ( view_1 - > infos ) - > column_references ) [ i ] ) . column_refs ) . version ) ;
if ( header = = NULL )
{
obidebug ( 1 , " \n Error opening a column header while importing a view " ) ;
return - 1 ;
}
if ( header - > returned_data_type = = OBI_QUAL ) // TODO maybe there should be a bool in column headers
{
// Look for the index of the associated column in the list
for ( j = 0 ; j < ( view_1 - > infos - > column_count ) ; j + + )
{
if ( ( strcmp ( ( header - > associated_column ) . column_name , ( ( ( ( view_1 - > infos ) - > column_references ) [ j ] ) . column_refs ) . column_name ) = = 0 ) & &
( ( header - > associated_column ) . version = = ( ( ( ( view_1 - > infos ) - > column_references ) [ j ] ) . column_refs ) . version ) )
break ;
}
header_2 = obi_column_get_header_from_name ( dms_2 , ( ( ( ( view_2 - > infos ) - > column_references ) [ i ] ) . column_refs ) . column_name , ( ( ( ( view_2 - > infos ) - > column_references ) [ i ] ) . column_refs ) . version ) ;
if ( header_2 = = NULL )
{
obidebug ( 1 , " \n Error opening a column header while importing a view " ) ;
return - 1 ;
}
// Update version of associated column
( header_2 - > associated_column ) . version = ( ( ( ( view_2 - > infos ) - > column_references ) [ j ] ) . column_refs ) . version ;
if ( obi_close_header ( header_2 ) < 0 )
{
obidebug ( 1 , " \n Error closing a column header while importing a view " ) ;
return - 1 ;
}
}
if ( obi_close_header ( header ) < 0 )
{
obidebug ( 1 , " \n Error closing a column header while importing a view " ) ;
return - 1 ;
}
}
2019-09-21 16:47:22 +02:00
if ( ! keep_running )
return - 1 ;
2017-08-03 16:33:12 +02:00
// Close the views
if ( obi_save_and_close_view ( view_1 ) < 0 )
{
obidebug ( 1 , " \n Error closing a view after importing from it " ) ;
return - 1 ;
}
if ( obi_save_and_close_view ( view_2 ) < 0 )
{
obidebug ( 1 , " \n Error closing a view after importing it " ) ;
return - 1 ;
}
// Close the DMS
2017-11-24 17:58:47 +01:00
obi_close_dms ( dms_1 , false ) ;
obi_close_dms ( dms_2 , false ) ;
2017-08-03 16:33:12 +02:00
return 0 ;
}
2017-10-16 10:35:07 +02:00
void obi_close_atexit ( )
{
int i = 0 ;
2017-08-03 16:33:12 +02:00
2017-10-16 10:35:07 +02:00
while ( global_opened_dms_list [ i ] ! = NULL )
{
2017-11-24 17:58:47 +01:00
obi_close_dms ( global_opened_dms_list [ i ] , true ) ;
2017-10-16 10:35:07 +02:00
i + + ;
}
}
2017-08-03 16:33:12 +02:00