import * as fs from 'fs' ; import * as path from 'path' ; import Conversion from './Conversion' ; import ErrnoException = NodeJS . ErrnoException ; /**
 * Writes a detailed error message to the "/errors-only.log" file.
 */ export const generateError = ( conversion , message , sql = '' ) : Promise < void > => { return new Promise < void > ( resolve => { message += `\n\n\tSQL: ${ sql }\n\n` ; const buffer = Buffer . from ( message , conversion . _encoding ) ; log ( conversion , message , undefined ) ; fs . open ( conversion . _errorLogsPath , 'a' , conversion . _0777 , ( error , fd ) => { if ( error ) { return resolve ( ) ; } fs . write ( fd , buffer , 0 , buffer . length , null , ( ) => { fs . close ( fd , ( ) => resolve ( ) ) ; } ) ; } ) ; } ) ; } ; /**
 * Outputs given log.
 * Writes given log to the "/all.log" file.
 * If necessary, writes given log to the "/{tableName}.log" file.
 */ export const log = ( conversion , log , tableLogPath ? , callback ? ) : void => { console . log ( log ) ; const buffer = Buffer . from ( `${ log }\n\n` , conversion . _encoding ) ; fs . open ( conversion . _allLogsPath , 'a' , conversion . _0777 , ( error , fd ) => { if ( ! error ) { fs . write ( fd , buffer , 0 , buffer . length , null , ( ) => { fs . close ( fd , ( ) => { if ( tableLogPath ) { fs . open ( tableLogPath , 'a' , conversion . _0777 , ( error , fd ) => { if ( ! error ) { fs . write ( fd , buffer , 0 , buffer . length , null , ( ) => { fs . close ( fd , ( ) => { if ( callback ) { callback ( ) ; } } ) ; } ) ; } else if ( callback ) { callback ( error ) ; } } ) ; } else if ( callback ) { callback ( ) ; } } ) ; } ) ; } else if ( callback ) { callback ( error ) ; } } ) ; } ; /**
 * Reads and parses JOSN file under given path.
 */ const readAndParseJsonFile = ( pathToFile ) : Promise < any > => { return new Promise < any > ( resolve => { fs . readFile ( pathToFile , ( error , data ) => { if ( error ) { console . log ( `\n\t--Cannot run migration\nCannot read configuration info from  ${ pathToFile }` ) ; process . exit ( 1 ) ; } const config = JSON . parse ( data . toString ( ) ) ; resolve ( config ) ; } ) ; } ) ; } ; /**
 * Reads the configuration file.
 */ export const readConfig = async ( confPath , logsPath , configFileName = 'config.json' ) : Promise < any > => { const pathToConfig = path . join ( confPath , configFileName ) ; const config = await readAndParseJsonFile ( pathToConfig ) ; config . logsDirPath = path . join ( logsPath , 'logs_directory' ) ; config . dataTypesMapAddr = path . join ( confPath , 'data_types_map.json' ) ; config . indexTypesMapAddr = path . join ( confPath , 'index_types_map.json' ) ; return config ; } ; /**
 * Reads the extra configuration file, if necessary.
 */ export const readExtraConfig = async ( config , confPath , extraConfigFileName = 'extra_config.json' ) : Promise < any > => { if ( config . enable_extra_config !== true ) { config . extraConfig = null ; return config ; } const pathToExtraConfig = path . join ( confPath , extraConfigFileName ) ; config . extraConfig = await readAndParseJsonFile ( pathToExtraConfig ) ; return config ; } ; /**
 * Reads both "./config/data_types_map.json" and "./config/index_types_map.json" and converts its json content to js object.
 */ export const readDataAndIndexTypesMap = async ( conversion ) : Promise < Conversion > => { const logTitle = 'FsOps::readDataAndIndexTypesMap' ; conversion . _dataTypesMap = await readAndParseJsonFile ( conversion . _dataTypesMapAddr ) ; conversion . _indexTypesMap = await readAndParseJsonFile ( conversion . _indexTypesMapAddr ) ; log ( conversion , `\t--[${ logTitle }] Data and Index Types Maps are loaded...` ) ; return conversion ; } ; /**
 * Creates logs directory.
 */ export const createLogsDirectory = async ( conversion ) : Promise < Conversion > => { const logTitle = 'FsOps::createLogsDirectory' ; await createDirectory ( conversion , conversion . _logsDirPath , logTitle ) ; await createDirectory ( conversion , conversion . _notCreatedViewsPath , logTitle ) ; return conversion ; } ; /**
 * Creates a directory at the specified path.
 */ const createDirectory = ( conversion , directoryPath , logTitle ) : Promise < void > => { return new Promise < void > ( resolve => { console . log ( `\t--[${ logTitle }] Creating directory ${ directoryPath }...` ) ; fs . stat ( directoryPath , ( directoryDoesNotExist , stat ) => { if ( directoryDoesNotExist ) { fs . mkdir ( directoryPath , conversion . _0777 , e => { if ( e ) { console . log ( `\t--[${ logTitle }] Cannot perform a migration due to impossibility to create directory: ${ directoryPath }` ) ; process . exit ( 1 ) ; } else { log ( conversion , `\t--[${ logTitle }] Directory ${ directoryPath } is created...` ) ; resolve ( ) ; } } ) ; } else if ( ! stat . isDirectory ( ) ) { console . log ( `\t--[${ logTitle }] Cannot perform a migration due to unexpected error` ) ; process . exit ( 1 ) ; } else { log ( conversion , `\t--[${ logTitle }] Directory ${ directoryPath } already exists...` ) ; resolve ( ) ; } } ) ; } ) ; } ;