import * as fs from 'fs' ; import * as path from 'path' ; import { log } from './FsOps' ; import Conversion from './Conversion' ; import * as migrationStateManager from './MigrationStateManager' ; import DBAccess from './DBAccess' ; import DBVendors from './DBVendors' ; import DBAccessQueryResult from './DBAccessQueryResult' ; import IDBAccessQueryParams from './IDBAccessQueryParams' ; import ErrnoException = NodeJS . ErrnoException ; /**
 * Attempts to convert MySQL view to PostgreSQL view.
 */ const generateView = ( schema , viewName , mysqlViewCode ) : string => { mysqlViewCode = mysqlViewCode . split ( '`' ) . join ( '"' ) ; const queryStart = mysqlViewCode . indexOf ( 'AS' ) ; mysqlViewCode = mysqlViewCode . slice ( queryStart ) ; const arrMysqlViewCode = mysqlViewCode . split ( ' ' ) ; arrMysqlViewCode . forEach ( ( str , index ) => { if ( str . toLowerCase ( ) === 'from' || str . toLowerCase ( ) === 'join' && index + 1 < arrMysqlViewCode . length ) { arrMysqlViewCode [ index + 1 ] = `"${ schema }".${ arrMysqlViewCode [ index + 1 ] }` ; } } ) ; return `CREATE OR REPLACE VIEW "${ schema }"."${ viewName }" ${ arrMysqlViewCode . join ( ' ' ) };` ; } ; /**
 * Writes a log, containing a view code.
 */ const logNotCreatedView = ( conversion , viewName , sql ) : Promise < void > => { return new Promise < void > ( ( resolve ) => { const viewFilePath = path . join ( conversion . _notCreatedViewsPath , `${ viewName }.sql` ) ; fs . open ( viewFilePath , 'w' , conversion . _0777 , ( error , fd ) => { if ( error ) { log ( conversion , error ) ; return resolve ( ) ; } const buffer = Buffer . from ( sql , conversion . _encoding ) ; fs . write ( fd , buffer , 0 , buffer . length , null , ( ) => { fs . close ( fd , ( ) => { return resolve ( ) ; } ) ; } ) ; } ) ; } ) ; } ; /**
 * Attempts to convert MySQL view to PostgreSQL view.
 */ export default async ( conversion ) : Promise < void > => { const hasViewsLoaded = await migrationStateManager . get ( conversion , 'views_loaded' ) ; if ( hasViewsLoaded ) { return ; } const logTitle = 'ViewGenerator::default' ; const createViewPromises = conversion . _viewsToMigrate . map ( async ( view ) => { const params = { conversion : conversion , caller : logTitle , sql : `SHOW CREATE VIEW \`${ view }\`;` , vendor : DBVendors . MYSQL , processExitOnError : false , shouldReturnClient : false } ; const showCreateViewResult = await DBAccess . query ( params ) ; if ( showCreateViewResult . error ) { return ; } params . sql = generateView ( conversion . _schema , view , showCreateViewResult . data [ 0 ] [ 'Create View' ] ) ; params . vendor = DBVendors . PG ; const createPgViewResult = await DBAccess . query ( params ) ; if ( createPgViewResult . error ) { return logNotCreatedView ( conversion , view , params . sql ) ; } log ( conversion , `\t--[${ logTitle }] View "${ conversion . _schema }"."${ view }" is created...` ) ; } ) ; await Promise . all ( createViewPromises ) ; } ;