package fr.lteconsulting.hexa.server.database;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Scanner;
import org.slf4j.Logger;
import com.google.gson.Gson;
import fr.lteconsulting.hexa.server.qpath.DatabaseDescription;
import fr.lteconsulting.hexa.server.qpath.DatabaseDescriptionInspector;
import fr.lteconsulting.hexa.server.tools.LoggerFactory;
public class DatabaseSchema
{
private final static Logger log = LoggerFactory.getLogger();
/**
* Updates a database schema with the schema stored in the given file.<br/>
* Several options are available.<br/>
* Returns the SQL statements that are to be executed to update the db
*
* @param file File with JSON information on the database schema
* @param ctx Database context. The database referenced by this context is updated.
* @param fDoDelete Tells if the drop colomn statements are generated or not
* @param fReallyExecute Tells if the SQL statements are executed or not
* @return The list of SQL statements needed to update the database schema
*/
public static ArrayList<String> updateDatabaseSchemaFromFile( File file, DatabaseContext ctx, boolean fDoDelete, boolean fReallyExecute )
{
log.info( "Updating database schema from file " + file.getAbsolutePath() );
try
{
StringBuilder targetJson = new StringBuilder();
Scanner scanner = new Scanner( new FileInputStream( file ) );
try
{
while( scanner.hasNextLine() )
targetJson.append( scanner.nextLine() );
}
finally
{
scanner.close();
}
Gson gson = new Gson();
DatabaseDescription targetDatabase = gson.fromJson( targetJson.toString(), DatabaseDescription.class );
if( targetDatabase == null )
{
log.error( "Cannot parse " + file.getAbsolutePath() + " to update DB, aborting schema update !" );
return null;
}
DatabaseDescriptionInspector inspector = new DatabaseDescriptionInspector();
DatabaseDescription dbDesc = inspector.getDatabaseDescription( ctx.db, ctx.dbh );
ArrayList<String> sqls = inspector.getSqlForUpdateDb( dbDesc, targetDatabase, fDoDelete, true/*
* table
* upper
* case
*/);
if( sqls != null && !sqls.isEmpty() )
{
log.info( " ... Needed to update database schema:" );
if( fReallyExecute )
{
for( String sql : sqls )
{
log.info( " ... Executing " + sql );
ctx.db.sqlUpdate( sql );
log.info( " --- ok" );
}
}
else
{
for( String sql : sqls )
log.info( sql );
}
}
log.info( " ... Your database schema is up to date" );
return sqls;
}
catch( FileNotFoundException exception )
{
log.info( " ... " + file.getAbsolutePath() + " does not exist to update the database schema !" );
return null;
}
}
/**
* Writes the current database schema to a file, in JSON format.
* This file can be used to update another database.
*
* @param ctx Database context
* @param file File to be written
* @return <code>true</code> if successful
*/
public static boolean dumpDatabaseSchemaToFile( DatabaseContext ctx, File file )
{
log.info( "Dumping database schema to file " + file.getAbsolutePath() );
DatabaseDescriptionInspector inspector = new DatabaseDescriptionInspector();
DatabaseDescription dbDesc = inspector.getDatabaseDescription( ctx.db, ctx.dbh );
Gson gson = new Gson();
String json = gson.toJson( dbDesc );
try
{
PrintWriter writer;
writer = new PrintWriter( file );
writer.print( json );
writer.close();
return true;
}
catch( FileNotFoundException e )
{
e.printStackTrace();
return false;
}
}
}