/** * require necessary packages */ const express = require( 'express' ); const app = express(); const cors = require( 'cors' ); const bodyParser = require( 'body-parser' ); const db = require( 'mysql-promise' )(); const { promisify } = require( 'util' ); const readdir = promisify( require('fs').readdir ); const writeFile = promisify( require( 'fs' ).writeFile ); const { JavaClassFileReader } = require('java-class-tools'); const dao = require( './dao' ); const rowMapper = require( './rowMapper' ); const port = '3001'; /** * enable all cors and use body parser */ app.use( cors() ); app.use( bodyParser.json( { limit: '50mb' } ) ); app.use( bodyParser.urlencoded( { extended: true, limit: '50mb', parameterLimit: 1000000 } ) ); /** * datatypes */ let dataTypes = { 'Ljava/lang/String;': 'String', 'Ljava/lang/Long;': 'Long', 'Ljava/lang/Integer;': 'Integer', 'Ljava/math/BigInteger;': 'BigInteger', 'Ljava/math/BigDecimal;': 'BigDecimal', 'Ljava/lang/Double;': 'Double', 'Ljava/lang/Float;': 'Float', 'Ljava/lang/Boolean;': 'Boolean', 'Ljava/time/LocalDate;': 'LocalDate', 'Ljava/time/LocalDateTime;': 'LocalDateTime', 'Ljava/time/LocalTime;': 'LocalTime', 'J': 'long', 'I':'int', 'D':'double', 'F':'float', 'Z':'boolean', 'C':'char' }; /** * write file path */ const writeFileDir = `${__dirname}/files`; /** * reader */ const reader = new JavaClassFileReader(); /** * utility functions */ // camel case to underscore let camelCaseToUnderscore = function( str ) { return str.replace( /(?:^|\.?)([A-Z])/g, function ( x, y ){ return "_" + y.toLowerCase() }).replace( /^_/, "" ); }; // query db for tables let queryDbForTables = async function( req, db, dbName ) { let tables = []; // query for tables let tableResults = await db.query( 'SHOW TABLES' ); for ( tableRow of tableResults[0] ) { tables.push( tableRow[`Tables_in_${dbName}`] ) } return tables; }; // query a table for columns let queryTableForColumns = async function( req, table, db, dbName ) { let tableColumns = {}; let columnResults = await db.query( `DESCRIBE \`${dbName}\`.\`${table}\`` ); // iterate over columns for ( column of columnResults[0] ) { let columnType = ''; if ( column['Type'].indexOf( '(' ) > -1 ) { columnType = column['Type'].split( '(' )[0].toUpperCase(); } else { columnType = column['Type'].toUpperCase(); } tableColumns[column['Field']] = columnType; } return tableColumns; }; // get attributes of pojo let getPOJOAttributes = async function( classpath, db ) { // pojo info let pojoInfo = {}; let files = await readdir( classpath ); files.forEach(async function( file ) { try { const javaFile = reader.read( classpath + '\\' + file ); let pojoName = file.replace( '.class', '' ); pojoInfo[pojoName] = {}; javaFile.fields.forEach(function ( entry ) { // Get method name & descriptor from constant_pool let nameCpEntry = javaFile.constant_pool[entry.name_index]; let descriptorCpEntry = javaFile.constant_pool[entry.descriptor_index]; // Convert to string let name = String.fromCharCode.apply( null, nameCpEntry.bytes ); let descriptor = String.fromCharCode.apply( null, descriptorCpEntry.bytes ); pojoInfo[pojoName][name] = dataTypes[descriptor]; }); } catch ( e ) { console.log( e ); } }); return pojoInfo; }; /** * get schema info */ app.post( '/get-schema-info', async function( req, res ) { // schema info let schemaInfo = {}; // connection properties let connectionProperties = req.body.dbConfig; let dbName = connectionProperties.database; // create connection db.configure( connectionProperties ); // query for tables let tables = await queryDbForTables( req, db, dbName ); // query for table columns for ( table of tables ) { schemaInfo[table] = await queryTableForColumns( req, table, db, dbName ); } res.json( schemaInfo ); }); /** * map table and pojos */ app.post( '/map-tables-pojos', async function( req, res ) { try { // let table-pojo map let tablePojoInfo = {}; // schema info tablePojoInfo['schemaInfo'] = {}; // pojo info tablePojoInfo['pojoInfo'] = {}; // connection properties let connectionProperties = req.body.dbConfig; let dbName = connectionProperties.database; // create connection db.configure( connectionProperties ); // query for tables let tables = await queryDbForTables( req, db, dbName ); // query for table columns for ( table of tables ) { tablePojoInfo['schemaInfo'][table] = await queryTableForColumns( req, table, db, dbName ); } // get class attributes tablePojoInfo['pojoInfo'] = await getPOJOAttributes( req.body.classpath, db ); res.json( tablePojoInfo ); } catch ( e ) { console.log( e ); } }); /** * create files */ app.post( '/create-files', async function( req, res ) { let payload = req.body.payload; for ( mapping of payload.pojoTableMapping ) { await writeFile( `${writeFileDir}/${mapping.pojoName}DAO.java`, dao.createFileContent( mapping, payload ) ); await writeFile( `${writeFileDir}/${mapping.pojoName}RowMapper.java`, rowMapper.createFileContent( mapping, payload ) ); } res.status( 200 ).send( true ); }); /** * start the app */ app.listen( port, function() { console.log( `Listening on port: ${port}` ); });