SQLScriptBuilder.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2025 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.core.commons;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.openspcoop2.utils.TipiDatabase;
import org.openspcoop2.utils.UtilsException;
import org.openspcoop2.utils.resources.FileSystemUtilities;
/**
* SQLScriptBuilder
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class SQLScriptBuilder {
private static final String UPGRADE_PREFIX = "upgrade_";
public static void main(String[] args) throws Exception {
// Metodo utilizzato dal setup antinstaller
String sqlSourceDir = args[0];
String sqlDestDir = args[1];
String sqlScriptName = args[2];
String modalitaInstallazione = args[3];
boolean splitDdlDml = true;
String versionePrecedente = null;
String versioneAttuale = null;
String tipoDatabase = null;
String configurazioneUpgrade = null;
boolean configurazioneUpgradeRuntime = true;
boolean configurazioneUpgradeConfig = true;
boolean configurazioneUpgradeTracce = true;
boolean configurazioneUpgradeStatistiche = true;
boolean configurazioneUpgradeMonitoraggio = true;
if(args.length>4){
versionePrecedente = args[4];
versioneAttuale = args[5];
tipoDatabase = args[6];
if("aggiornamento".equals(modalitaInstallazione) && args.length>7){
configurazioneUpgrade = args[7];
File f = new File(configurazioneUpgrade);
if(f.exists()) {
try(FileInputStream fin = new FileInputStream(f)){
Properties p = new Properties();
p.load(fin);
configurazioneUpgradeRuntime = readBooleanProperty(p, "upgrade.runtime");
configurazioneUpgradeConfig = readBooleanProperty(p, "upgrade.configurazione");
configurazioneUpgradeTracce = readBooleanProperty(p, "upgrade.tracciamento");
configurazioneUpgradeStatistiche = readBooleanProperty(p, "upgrade.statistiche");
configurazioneUpgradeMonitoraggio = readBooleanProperty(p, "upgrade.monitoraggio");
}
}
}
}
// NOTA: Non far stampare niente, viene usato come meccanismo di check per vedere se l'esecuzione e' andata a buon fine
/**System.out.println("Modalita ["+modalitaInstallazione+"]");*/
if("nuova".equals(modalitaInstallazione)){
buildSqlNuovaInstallazione(new File(sqlSourceDir),new File(sqlDestDir),sqlScriptName,splitDdlDml);
}
else if("aggiornamento".equals(modalitaInstallazione)){
/**System.out.println("versionePrecedente ["+versionePrecedente+"]");
System.out.println("versioneAttuale ["+versioneAttuale+"]");
System.out.println("tipoDatabase ["+tipoDatabase+"]");*/
buildSqlAggiornamento(new File(sqlSourceDir),new File(sqlDestDir),sqlScriptName,versionePrecedente,
versioneAttuale, tipoDatabase,
configurazioneUpgradeRuntime,
configurazioneUpgradeConfig,
configurazioneUpgradeTracce,
configurazioneUpgradeStatistiche,
configurazioneUpgradeMonitoraggio);
}
else{
throw new CoreException("Modalità installazione ["+modalitaInstallazione+"] sconosciuta");
}
}
private static boolean readBooleanProperty(Properties p, String name) throws CoreException {
String tmp = p.getProperty(name);
if(tmp==null) {
throw new CoreException("Configurazione Upgrade non corretta, proprietà ["+name+"] non presente");
}
tmp = tmp.trim();
try {
return Boolean.valueOf(tmp);
}catch(Exception e) {
throw new CoreException("Configurazione Upgrade non corretta, proprietà ["+name+"] non corretta: "+e.getMessage(),e);
}
}
private static void buildSqlNuovaInstallazione(File sqlSourceDir, File sqlDestDir, String sqlScriptName,
boolean splitDdlDml) throws CoreException, UtilsException, IOException {
if(!sqlSourceDir.exists()){
throw new CoreException("Source dir ["+sqlSourceDir.getAbsolutePath()+"] not exists");
}
if(!sqlSourceDir.canRead()){
throw new CoreException("Source dir ["+sqlSourceDir.getAbsolutePath()+"] cannot read");
}
if(!sqlDestDir.exists()){
throw new CoreException("Dest dir ["+sqlDestDir.getAbsolutePath()+"] not exists");
}
if(!sqlDestDir.canWrite()){
throw new CoreException("Dest dir ["+sqlDestDir.getAbsolutePath()+"] cannot write");
}
int prefix = 0;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
// BASE
File [] f = sqlSourceDir.listFiles();
if(f!=null) {
for (int i = 0; i < f.length; i++) {
if(f[i].isFile()) {
createSqlEngine(sqlSourceDir, f[i].getName(),
sqlDestDir, sqlScriptName, prefix, bout,
splitDdlDml);
}
}
}
File dest = new File(sqlDestDir, sqlScriptName);
bout.flush();
bout.close();
FileSystemUtilities.writeFile(dest, bout.toByteArray());
if(splitDdlDml){
/**System.out.println("Split init ...");*/
File destInit = new File(sqlDestDir, dest.getName().replace(".sql", "_init.sql"));
splitFileForDDLtoDML(dest, dest, destInit);
}
}
private static void buildSqlAggiornamento(File sqlSourceDir, File sqlDestDir, String sqlScriptName,
String precedenteVersione, String versioneAttuale, String tipoDatabase,
boolean configurazioneUpgradeRuntime,
boolean configurazioneUpgradeConfig,
boolean configurazioneUpgradeTracce,
boolean configurazioneUpgradeStatistiche,
boolean configurazioneUpgradeMonitoraggio) throws CoreException, IOException, UtilsException {
if(!sqlSourceDir.exists()){
throw new CoreException("Source dir ["+sqlSourceDir.getAbsolutePath()+"] not exists");
}
if(!sqlSourceDir.canRead()){
throw new CoreException("Source dir ["+sqlSourceDir.getAbsolutePath()+"] cannot read");
}
if(!sqlDestDir.exists()){
throw new CoreException("Dest dir ["+sqlDestDir.getAbsolutePath()+"] not exists");
}
if(!sqlDestDir.canWrite()){
throw new CoreException("Dest dir ["+sqlDestDir.getAbsolutePath()+"] cannot write");
}
if(precedenteVersione==null){
throw new CoreException("Precedente versione non fornita");
}
if(!precedenteVersione.contains(".")){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] ('.' not found)");
}
int indexOfFirstPoint = precedenteVersione.indexOf(".");
if(indexOfFirstPoint<=0){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] ('.' not found with index)");
}
String productVersionString = precedenteVersione.substring(0, indexOfFirstPoint);
int productVersion = -1;
try{
productVersion = Integer.parseInt(productVersionString);
}catch(Exception e){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (productVersion:"+productVersionString+"): "+e.getMessage(),e);
}
int indexOfSecondPoint = precedenteVersione.indexOf(".",indexOfFirstPoint+1);
if(indexOfSecondPoint<=0 || indexOfSecondPoint<=indexOfFirstPoint){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (second '.' not found)");
}
String majorVersionString = precedenteVersione.substring(indexOfFirstPoint+1, indexOfSecondPoint);
int majorVersion = -1;
try{
majorVersion = Integer.parseInt(majorVersionString);
}catch(Exception e){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (majorVersion:"+majorVersionString+"): "+e.getMessage(),e);
}
if(precedenteVersione.length()<=indexOfSecondPoint){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (length)");
}
String minorVersionString = precedenteVersione.substring(indexOfSecondPoint+1,precedenteVersione.length());
int minorVersion = -1;
try{
minorVersion = Integer.parseInt(minorVersionString);
}catch(Exception e){
/**throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (minorVersion:"+minorVersionString+"): "+e.getMessage(),e);*/
// Potrebbe essere una BUILD VERSION
if(minorVersionString.contains("_")){
String newMinor = minorVersionString.split("_")[0];
try{
minorVersion = Integer.parseInt(newMinor);
}catch(Exception eInternal){
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (minorVersion:"+minorVersionString+" minorVersionBuildNumber:"+newMinor+"): "+eInternal.getMessage(),eInternal);
}
}
else{
throw new CoreException("Precedente versione in un formato non corretto ["+precedenteVersione+"] (minorVersion:"+minorVersionString+"): "+e.getMessage(),e);
}
}
/**System.out.println(productVersion+"."+majorVersion+"."+minorVersion);*/
int tmpMajorVersion = majorVersion;
int tmpMinorVersion = minorVersion;
if(tipoDatabase==null){
throw new CoreException("TipoDatabase non fornito");
}
TipiDatabase tipiDatabase = TipiDatabase.toEnumConstant(tipoDatabase);
if(TipiDatabase.DEFAULT.equals(tipiDatabase)) {
throw new CoreException("TipoDatabase fornito ["+tipoDatabase+"] non valido");
}
// Set per tracciare i file SQL già processati (usando il checksum SHA-256 del contenuto per gestire i duplicati)
Set<String> processedSqlFiles = new HashSet<>();
// Pre-popola il Set con i checksum delle patch presenti nelle versioni precedenti o uguali alla versione di partenza
// Questo evita di applicare patch duplicate quando si parte da una versione intermedia
populateProcessedFilesFromPreviousVersions(sqlSourceDir, productVersion, majorVersion, minorVersion, tipoDatabase, processedSqlFiles);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
File infoVersion = null;
while(true){
String actualVersion = productVersion+"."+tmpMajorVersion+"."+tmpMinorVersion;
String nextVersion = productVersion+"."+tmpMajorVersion+"."+(tmpMinorVersion+1);
File version = new File(sqlSourceDir,UPGRADE_PREFIX+actualVersion+"_to_"+nextVersion);
/**System.out.println("CHECK ["+version.getAbsolutePath()+"] ["+version.exists()+"]");*/
if(version.exists()){
if(!version.canRead()){
throw new CoreException("Source version dir ["+version.getAbsolutePath()+"] cannot read");
}
File tmp = createSqlAggiornamentoEngine(version, sqlDestDir, bout, nextVersion, tipoDatabase,
configurazioneUpgradeRuntime,
configurazioneUpgradeConfig,
configurazioneUpgradeTracce,
configurazioneUpgradeStatistiche,
configurazioneUpgradeMonitoraggio,
processedSqlFiles);
if(tmp!=null) {
infoVersion = tmp;
}
tmpMinorVersion++;
}
else{
// check upgrade to major version +1
actualVersion = productVersion+"."+tmpMajorVersion+".x";
nextVersion = productVersion+"."+(tmpMajorVersion+1)+".0";
version = new File(sqlSourceDir,UPGRADE_PREFIX+actualVersion+"_to_"+nextVersion);
/**System.out.println("CHECK UPGRADE ["+version.getAbsolutePath()+"] ["+version.exists()+"]");*/
if(version.exists()){
if(!version.canRead()){
throw new CoreException("Source version dir ["+version.getAbsolutePath()+"] cannot read");
}
File tmp = createSqlAggiornamentoEngine(version, sqlDestDir, bout, nextVersion, tipoDatabase,
configurazioneUpgradeRuntime,
configurazioneUpgradeConfig,
configurazioneUpgradeTracce,
configurazioneUpgradeStatistiche,
configurazioneUpgradeMonitoraggio,
processedSqlFiles);
if(tmp!=null) {
infoVersion = tmp;
}
tmpMajorVersion++;
tmpMinorVersion=0;
}
else{
break;
}
}
}
if(infoVersion!=null) {
byte[] content = FileSystemUtilities.readBytesFromFile(infoVersion);
bout.write("\n\n".getBytes());
bout.write(content);
}
bout.flush();
bout.close();
String destFileScriptSql = sqlScriptName.replace(".sql", "_upgrade_"+versioneAttuale+".sql");
FileSystemUtilities.writeFile(new File(sqlDestDir, destFileScriptSql), bout.toByteArray());
}
private static File createSqlAggiornamentoEngine(File sqlVersionSourceDir, File sqlDestDir, ByteArrayOutputStream bout , String nextVersion, String tipoDatabase,
boolean configurazioneUpgradeRuntime,
boolean configurazioneUpgradeConfig,
boolean configurazioneUpgradeTracce,
boolean configurazioneUpgradeStatistiche,
boolean configurazioneUpgradeMonitoraggio,
Set<String> processedSqlFiles) throws IOException, CoreException, UtilsException {
if(sqlDestDir!=null) {
// nop
}
File sqlVersionSourceDirDatabase = new File(sqlVersionSourceDir, tipoDatabase);
File[] files = sqlVersionSourceDirDatabase.listFiles();
if(files!=null && files.length>0) {
boolean writeUpgrade = false;
boolean atLeastOneFileProcessed = false;
Arrays.sort(files); // sono ordinati per data
for(File upgradeFile : files) {
if(upgradeFile.getName().contains("-runtimePdD-")) {
// runtime
if(!configurazioneUpgradeRuntime) {
continue;
}
}
else if(upgradeFile.getName().contains("-archiviComunicazioni-")) {
// tracce
if(!configurazioneUpgradeTracce) {
continue;
}
}
else if(upgradeFile.getName().contains("-informazioniStatistiche-")) {
// statistiche
if(!configurazioneUpgradeStatistiche) {
continue;
}
}
else if(upgradeFile.getName().contains("-monitoraggio-")) {
// monitoraggio
if(!configurazioneUpgradeMonitoraggio) {
continue;
}
}
else {
// configurazione (configurazionePdD, registroServizi)
if(!configurazioneUpgradeConfig) {
continue;
}
}
// Verifica se il file è già stato processato (gestione patch duplicate)
// Usa il checksum del contenuto per identificare file identici
String fileChecksum = calculateFileChecksum(upgradeFile);
if(processedSqlFiles.contains(fileChecksum)) {
// File già processato in una versione precedente (stesso contenuto), skip
continue;
}
if(!writeUpgrade) {
if(bout!=null){
if(bout.size()>0){
bout.write("\n\n".getBytes());
}
bout.write("-- Upgrade to ".getBytes());
bout.write(nextVersion.getBytes());
bout.write("\n".getBytes());
}
writeUpgrade = true;
}
createSqlAggiornamentoEngine(upgradeFile, bout);
// Aggiungi il checksum del file al set dei file processati
processedSqlFiles.add(fileChecksum);
atLeastOneFileProcessed = true;
}
// Se la directory esiste ma nessun file è stato processato (tutti duplicati),
// scrivi comunque il commento di upgrade
if(!atLeastOneFileProcessed && bout!=null) {
if(bout.size()>0){
bout.write("\n\n".getBytes());
}
bout.write("-- Upgrade to ".getBytes());
bout.write(nextVersion.getBytes());
bout.write("\n".getBytes());
}
}
File sqlVersionSourceDirInfoVersioneUpgrade = new File(sqlVersionSourceDir, "info-patch.sql");
if(sqlVersionSourceDirInfoVersioneUpgrade.exists()) {
return sqlVersionSourceDirInfoVersioneUpgrade;
}
return null;
}
private static void createSqlEngine(File sqlSourceDir,String sourceFile,File sqlDestDir, String destFile,
int prefix,ByteArrayOutputStream bout,
boolean splitDdlDml) throws UtilsException, IOException {
File src = new File(sqlSourceDir, sourceFile);
if(bout!=null){
byte[] b = FileSystemUtilities.readBytesFromFile(src);
if(bout.size()>0){
bout.write("\n\n".getBytes());
}
bout.write(b);
}
else{
File dest = new File(sqlDestDir, parsePrefix(prefix)+destFile);
FileSystemUtilities.copy(src, dest);
if(splitDdlDml){
File destInit = new File(sqlDestDir, dest.getName().replace(".sql", "_init.sql"));
splitFileForDDLtoDML(dest, dest, destInit);
}
}
}
private static void createSqlAggiornamentoEngine(File upgradeFile,ByteArrayOutputStream bout) throws CoreException, UtilsException, IOException{
if(bout==null) {
throw new CoreException("Param bout is null");
}
byte[] b = FileSystemUtilities.readBytesFromFile(upgradeFile);
if(bout.size()>0){
bout.write("\n\n".getBytes());
}
bout.write(b);
}
private static String parsePrefix(int prefix){
if(prefix<10){
return "0"+prefix+"_";
}
else{
return prefix+"_";
}
}
private static String calculateFileChecksum(File file) throws CoreException {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] fileBytes = FileSystemUtilities.readBytesFromFile(file);
byte[] hashBytes = digest.digest(fileBytes);
// Converti hash in stringa esadecimale
StringBuilder hexString = new StringBuilder();
for (byte b : hashBytes) {
String hex = Integer.toHexString(0xff & b);
if(hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
throw new CoreException("Errore nel calcolo del checksum del file ["+file.getAbsolutePath()+"]: "+e.getMessage(), e);
}
}
private static void populateProcessedFilesFromPreviousVersions(File sqlSourceDir, int productVersion,
int startMajorVersion, int startMinorVersion, String tipoDatabase, Set<String> processedSqlFiles)
throws CoreException {
// Scansiona tutte le directory di upgrade dalla versione 0.0 fino ALLA PRECEDENTE della versione di riferimento
// per popolare il Set con i checksum delle patch già presenti nella versione di partenza
//
// IMPORTANTE:
// - Se parto da 3.3.17, includo nel Set le patch fino a upgrade_3.3.16_to_3.3.17 (esclusa upgrade_3.3.17_to_3.3.18)
// - Se parto da 3.3.18, includo nel Set le patch fino a upgrade_3.3.17_to_3.3.18 (esclusa upgrade_3.3.x_to_3.4.0)
//
// La semantica è: upgrade_X.Y.Z_to_X.Y.(Z+1) fa parte della versione X.Y.(Z+1), non della X.Y.Z
//
// BASELINE VERSION: Ogni directory di upgrade può contenere un file baseline-version.txt
// che specifica quale versione di base dati considerare come riferimento.
// Esempio: upgrade_3.4.0_to_3.4.1/baseline-version.txt contenente "3.3.17" indica che la 3.4.0
// è uscita dopo la 3.3.17 ma prima della 3.3.18, quindi partendo da 3.4.0 le patch della 3.3.18
// NON devono essere considerate già applicate.
// Controlla se esiste un file baseline-version.txt nella prima directory da processare (quella dell'upgrade in corso)
int[] baselineVersion = readBaselineVersionFromCurrentUpgradeDir(sqlSourceDir, productVersion,
startMajorVersion, startMinorVersion);
int effectiveMajorVersion = baselineVersion[0];
int effectiveMinorVersion = baselineVersion[1];
int tmpMajorVersion = 0;
int tmpMinorVersion = 0;
boolean continueScanning = true;
while(continueScanning) {
// Verifico se ho raggiunto la versione di riferimento (baseline o versione di partenza)
if(tmpMajorVersion == effectiveMajorVersion && tmpMinorVersion == effectiveMinorVersion) {
// Ho raggiunto la versione di riferimento, esco SENZA processarla
continueScanning = false;
continue;
}
boolean processed = scanMinorVersionUpgrade(sqlSourceDir, productVersion, tmpMajorVersion, tmpMinorVersion,
tipoDatabase, processedSqlFiles);
if(processed) {
tmpMinorVersion++;
}
else {
// Non ho trovato upgrade_X.Y.Z_to_X.Y.(Z+1)
// Potrebbe esserci upgrade_X.Y.x_to_X.(Y+1).0, ma questa directory
// NON va inclusa nel pre-popolamento se la versione di partenza è X.Y.Z
// Se ho già superato la versione di riferimento, esco
if(tmpMajorVersion > effectiveMajorVersion ||
(tmpMajorVersion == effectiveMajorVersion && tmpMinorVersion > effectiveMinorVersion)) {
continueScanning = false;
}
else {
// Provo la prossima minor version
tmpMinorVersion++;
if(tmpMinorVersion > 200) { // Safety check per evitare loop infiniti
// Passo alla major version successiva
tmpMajorVersion++;
tmpMinorVersion = 0;
if(tmpMajorVersion > effectiveMajorVersion) {
continueScanning = false;
}
}
}
}
}
}
private static int[] readBaselineVersionFromCurrentUpgradeDir(File sqlSourceDir, int productVersion,
int startMajorVersion, int startMinorVersion) throws CoreException {
// Determina la PRIMA directory di upgrade da processare (quella che parte dalla versione di partenza)
// Questa è la directory dell'upgrade in corso che può contenere un file baseline-version.txt
// con la versione di riferimento per il pre-popolamento
File currentUpgradeDir;
// La prima directory è upgrade_X.Y.Z_to_X.Y.(Z+1) oppure upgrade_X.Y.x_to_X.(Y+1).0
String fromVersion = productVersion+"."+startMajorVersion+"."+startMinorVersion;
String toVersion = productVersion+"."+startMajorVersion+"."+(startMinorVersion+1);
currentUpgradeDir = new File(sqlSourceDir, UPGRADE_PREFIX+fromVersion+"_to_"+toVersion);
// Se non esiste, potrebbe essere un upgrade major
if(!currentUpgradeDir.exists()) {
fromVersion = productVersion+"."+startMajorVersion+".x";
toVersion = productVersion+"."+(startMajorVersion+1)+".0";
currentUpgradeDir = new File(sqlSourceDir, UPGRADE_PREFIX+fromVersion+"_to_"+toVersion);
}
// Cerca il file baseline-version.txt nella directory dell'upgrade corrente
File baselineFile = new File(currentUpgradeDir, "baseline-version.txt");
if(!baselineFile.exists()) {
// Nessuna baseline specificata, usa la versione di partenza come riferimento per il pre-popolamento
return new int[]{startMajorVersion, startMinorVersion};
}
// Leggi e parse della baseline version
return parseBaselineVersionFile(baselineFile, productVersion);
}
private static int[] parseBaselineVersionFile(File baselineFile, int productVersion) throws CoreException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(baselineFile));
String baselineVersionString = br.readLine();
if(baselineVersionString == null || baselineVersionString.trim().isEmpty()) {
throw new CoreException("File baseline-version.txt ["+baselineFile.getAbsolutePath()+"] vuoto o non contiene una versione valida");
}
baselineVersionString = baselineVersionString.trim();
// Parse della baseline version (formato atteso: X.Y.Z, estraiamo Y e Z)
if(!baselineVersionString.contains(".")) {
throw new CoreException("Baseline version ["+baselineVersionString+"] in formato non corretto: '.' non trovato");
}
int firstDot = baselineVersionString.indexOf(".");
int secondDot = baselineVersionString.indexOf(".", firstDot + 1);
if(secondDot <= firstDot) {
throw new CoreException("Baseline version ["+baselineVersionString+"] in formato non corretto: secondo '.' non trovato");
}
// Verifica che il product version corrisponda
String productVersionString = baselineVersionString.substring(0, firstDot);
int baselineProductVersion;
try {
baselineProductVersion = Integer.parseInt(productVersionString);
} catch (Exception e) {
throw new CoreException("Baseline version ["+baselineVersionString+"] product version ["+productVersionString+"] non valida: "+e.getMessage(), e);
}
if(baselineProductVersion != productVersion) {
throw new CoreException("Baseline version ["+baselineVersionString+"] ha product version ["+baselineProductVersion+"] diversa da quella attesa ["+productVersion+"]");
}
String majorString = baselineVersionString.substring(firstDot + 1, secondDot);
String minorString = baselineVersionString.substring(secondDot + 1);
int baselineMajor;
int baselineMinor;
try {
baselineMajor = Integer.parseInt(majorString);
} catch (Exception e) {
throw new CoreException("Baseline version ["+baselineVersionString+"] major version ["+majorString+"] non valida: "+e.getMessage(), e);
}
try {
baselineMinor = Integer.parseInt(minorString);
} catch (Exception e) {
throw new CoreException("Baseline version ["+baselineVersionString+"] minor version ["+minorString+"] non valida: "+e.getMessage(), e);
}
return new int[]{baselineMajor, baselineMinor};
} catch (CoreException ce) {
throw ce;
} catch (Exception e) {
throw new CoreException("Errore nella lettura del file baseline-version.txt ["+baselineFile.getAbsolutePath()+"]: "+e.getMessage(), e);
} finally {
try {
if(br != null) {
br.close();
}
} catch (Throwable t) {
// ignore
}
}
}
private static boolean scanMinorVersionUpgrade(File sqlSourceDir, int productVersion, int tmpMajorVersion,
int tmpMinorVersion, String tipoDatabase, Set<String> processedSqlFiles) throws CoreException {
String actualVersion = productVersion+"."+tmpMajorVersion+"."+tmpMinorVersion;
String nextVersion = productVersion+"."+tmpMajorVersion+"."+(tmpMinorVersion+1);
File version = new File(sqlSourceDir,UPGRADE_PREFIX+actualVersion+"_to_"+nextVersion);
if(version.exists() && version.canRead()) {
addChecksumsFromDirectory(version, tipoDatabase, processedSqlFiles);
return true;
}
return false;
}
private static void addChecksumsFromDirectory(File versionDir, String tipoDatabase, Set<String> processedSqlFiles)
throws CoreException {
File sqlVersionSourceDirDatabase = new File(versionDir, tipoDatabase);
File[] files = sqlVersionSourceDirDatabase.listFiles();
if(files!=null && files.length>0) {
for(File upgradeFile : files) {
String fileChecksum = calculateFileChecksum(upgradeFile);
processedSqlFiles.add(fileChecksum);
}
}
}
private static void splitFileForDDLtoDML(File sqlFile,File sqlFileDest,File sqlFileInitDest) throws IOException, UtilsException{
boolean dmlOpen = false;
ByteArrayOutputStream boutDDL = new ByteArrayOutputStream();
ByteArrayOutputStream boutDML = new ByteArrayOutputStream();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(sqlFile));
String line;
while ((line = br.readLine()) != null) {
// process the line.
if(dmlOpen){
boutDML.write(line.getBytes());
boutDML.write("\n".getBytes());
if(line.contains(";")){
dmlOpen = false; // finish
}
}
else{
if(isDML(line)){
dmlOpen = true; // start
boutDML.write(line.getBytes());
boutDML.write("\n".getBytes());
if(line.contains(";")){
dmlOpen = false; // finish (in una unica riga)
}
}
else{
boutDDL.write(line.getBytes());
boutDDL.write("\n".getBytes());
}
}
}
}finally {
try {
if(br!=null)
br.close();
}catch(Throwable t) {
// ignore
}
}
/**System.out.println("DDL["+boutDDL.size()+"] DML["+boutDML.size()+"]");*/
if(boutDDL.size()>0){
FileSystemUtilities.writeFile(sqlFileDest, boutDDL.toByteArray());
}
if(boutDML.size()>0){
FileSystemUtilities.writeFile(sqlFileInitDest, boutDML.toByteArray());
}
}
private static boolean isDML(String line){
String tmp = line+"";
tmp = tmp.trim().toLowerCase();
if(tmp.startsWith("insert ")){
/** check hsql, es: INSERT INTO db_info_init_seq VALUES (NEXT VALUE FOR seq_db_info);*/
if(tmp.contains("_init_seq ") && tmp.contains("next value ") ){
return false;
}
// insert on tracce_ext_protocol_info
return !(tmp.contains("insert on "));
}
else if(tmp.startsWith("update ")){
return true;
}
else if(tmp.startsWith("delete ")){
// ON DELETE CASCADE
return !(tmp.contains("on delete cascade"));
}
return false;
}
}